[PATCH 5/5] drm/damage-helper: Avoid partial updates for DIRTYFB without damage

Thomas Zimmermann tzimmermann at suse.de
Tue Sep 20 13:56:19 UTC 2022


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 at suse.de>
---
 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



More information about the dri-devel mailing list