We need a similar drm_atomic_helper_buffer_damage_merged() helper function that takes into account if a framebuffer attached to the plane has changed since the last plane update (page-flip). Since both damage helpers will share most of the current logic, move it to an internal helper. The drm_atomic_helper_buffer_damage_merged() will have to use a different drm_atomic_helper_buffer_damage_iter_init() function so move that logic also to an internal helper. Fixes: 01f05940a9a7 ("drm/virtio: Enable fb damage clips property for the primary plane") Cc: <stable@xxxxxxxxxxxxxxx> # v6.4+ Reported-by: nerdopolis <bluescreen_avenger@xxxxxxxxxxx> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218115 Suggested-by: Sima Vetter <daniel.vetter@xxxxxxxx> Signed-off-by: Javier Martinez Canillas <javierm@xxxxxxxxxx> --- drivers/gpu/drm/drm_damage_helper.c | 95 +++++++++++++++++------------ 1 file changed, 55 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/drm_damage_helper.c b/drivers/gpu/drm/drm_damage_helper.c index d8b2955e88fd..aa2325567918 100644 --- a/drivers/gpu/drm/drm_damage_helper.c +++ b/drivers/gpu/drm/drm_damage_helper.c @@ -201,28 +201,10 @@ int drm_atomic_helper_dirtyfb(struct drm_framebuffer *fb, } EXPORT_SYMBOL(drm_atomic_helper_dirtyfb); -/** - * drm_atomic_helper_damage_iter_init - Initialize the damage iterator. - * @iter: The iterator to initialize. - * @old_state: Old plane state for validation. - * @state: Plane state from which to iterate the damage clips. - * - * Initialize an iterator, which clips plane damage - * &drm_plane_state.fb_damage_clips to plane &drm_plane_state.src. This iterator - * returns full plane src in case damage is not present because either - * user-space didn't sent or driver discarded it (it want to do full plane - * update). Currently this iterator returns full plane src in case plane src - * changed but that can be changed in future to return damage. - * - * For the case when plane is not visible or plane update should not happen the - * first call to iter_next will return false. Note that this helper use clipped - * &drm_plane_state.src, so driver calling this helper should have called - * drm_atomic_helper_check_plane_state() earlier. - */ -void -drm_atomic_helper_damage_iter_init(struct drm_atomic_helper_damage_iter *iter, - const struct drm_plane_state *old_state, - const struct drm_plane_state *state) +static void +__drm_atomic_helper_damage_iter_init(struct drm_atomic_helper_damage_iter *iter, + const struct drm_plane_state *old_state, + const struct drm_plane_state *state) { struct drm_rect src; memset(iter, 0, sizeof(*iter)); @@ -247,6 +229,32 @@ drm_atomic_helper_damage_iter_init(struct drm_atomic_helper_damage_iter *iter, iter->full_update = true; } } + +/** + * drm_atomic_helper_damage_iter_init - Initialize the damage iterator. + * @iter: The iterator to initialize. + * @old_state: Old plane state for validation. + * @state: Plane state from which to iterate the damage clips. + * + * Initialize an iterator, which clips plane damage + * &drm_plane_state.fb_damage_clips to plane &drm_plane_state.src. This iterator + * returns full plane src in case damage is not present because either + * user-space didn't sent or driver discarded it (it want to do full plane + * update). Currently this iterator returns full plane src in case plane src + * changed but that can be changed in future to return damage. + * + * For the case when plane is not visible or plane update should not happen the + * first call to iter_next will return false. Note that this helper use clipped + * &drm_plane_state.src, so driver calling this helper should have called + * drm_atomic_helper_check_plane_state() earlier. + */ +void +drm_atomic_helper_damage_iter_init(struct drm_atomic_helper_damage_iter *iter, + const struct drm_plane_state *old_state, + const struct drm_plane_state *state) +{ + __drm_atomic_helper_damage_iter_init(iter, old_state, state); +} EXPORT_SYMBOL(drm_atomic_helper_damage_iter_init); /** @@ -291,24 +299,9 @@ drm_atomic_helper_damage_iter_next(struct drm_atomic_helper_damage_iter *iter, } EXPORT_SYMBOL(drm_atomic_helper_damage_iter_next); -/** - * drm_atomic_helper_damage_merged - Merged plane damage - * @old_state: Old plane state for validation. - * @state: Plane state from which to iterate the damage clips. - * @rect: Returns the merged damage rectangle - * - * This function merges any valid plane damage clips into one rectangle and - * returns it in @rect. - * - * For details see: drm_atomic_helper_damage_iter_init() and - * drm_atomic_helper_damage_iter_next(). - * - * Returns: - * True if there is valid plane damage otherwise false. - */ -bool drm_atomic_helper_damage_merged(const struct drm_plane_state *old_state, - struct drm_plane_state *state, - struct drm_rect *rect) +static bool __drm_atomic_helper_damage_merged(const struct drm_plane_state *old_state, + struct drm_plane_state *state, + struct drm_rect *rect) { struct drm_atomic_helper_damage_iter iter; struct drm_rect clip; @@ -330,4 +323,26 @@ bool drm_atomic_helper_damage_merged(const struct drm_plane_state *old_state, return valid; } + +/** + * drm_atomic_helper_damage_merged - Merged plane damage + * @old_state: Old plane state for validation. + * @state: Plane state from which to iterate the damage clips. + * @rect: Returns the merged damage rectangle + * + * This function merges any valid plane damage clips into one rectangle and + * returns it in @rect. + * + * For details see: drm_atomic_helper_damage_iter_init() and + * drm_atomic_helper_damage_iter_next(). + * + * Returns: + * True if there is valid plane damage otherwise false. + */ +bool drm_atomic_helper_damage_merged(const struct drm_plane_state *old_state, + struct drm_plane_state *state, + struct drm_rect *rect) +{ + return __drm_atomic_helper_damage_merged(old_state, state, rect); +} EXPORT_SYMBOL(drm_atomic_helper_damage_merged); -- 2.41.0