Always do a full plane update when userspace sends a DIRTYFB ioctl without damage information. Userspace not changing the framebuffer or marking changed regions can easily be interpreted as if there was no change at all. Therefore set the new fb_dirty flag on all plane's with a dirty framebuffer and fallback to a full plane update if necessary. Signed-off-by: Thomas Zimmermann <tzimmermann@xxxxxxx> --- drivers/gpu/drm/drm_atomic_state_helper.c | 1 + drivers/gpu/drm/drm_damage_helper.c | 7 ++++--- include/drm/drm_plane.h | 8 ++++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index 94818fd4dd8f..b7523d56b06f 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -340,6 +340,7 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane, state->fb_damage_clips = NULL; state->fb_damage_partial_update = false; state->fb_changed = false; + state->fb_dirty = false; } EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state); diff --git a/drivers/gpu/drm/drm_damage_helper.c b/drivers/gpu/drm/drm_damage_helper.c index f43abf02df5b..e884987a944c 100644 --- a/drivers/gpu/drm/drm_damage_helper.c +++ b/drivers/gpu/drm/drm_damage_helper.c @@ -102,10 +102,10 @@ void drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state, * Damage clips are a good indicator for partial updates. */ partial_update = true; - } else if (!new_plane_state->fb_changed) { + } else if (!new_plane_state->fb_changed && !new_plane_state->fb_dirty) { /* - * Also set a partial update if the framebuffer did not - * change. Without damage clips set, this will effectively + * Also set a partial update if the framebuffer or its content + * did not change. Without damage clips set, this will effectively * not update the plane. The exception is with full modeset * operations, where we do full plane update even if the * framebuffer did not change. We already handled this case @@ -214,6 +214,7 @@ int drm_atomic_helper_dirtyfb(struct drm_framebuffer *fb, goto out; } + plane_state->fb_dirty = true; drm_property_replace_blob(&plane_state->fb_damage_clips, damage); } diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 8c2d0a2eb760..2b22707eb116 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -235,6 +235,14 @@ struct drm_plane_state { */ bool fb_changed : 1; + /** + * @fb_dirty: @fb's content has been marked as dirty. Used by the + * atomic helpers and drivers to steer the atomic commit control flow. + * The flag signals that the frambuffer's content has been changed even + * if no damage clips have been installed. + */ + bool fb_dirty : 1; + /** * @scaling_filter: * -- 2.37.3