[PATCH 4/5] drm/damage-helper: Do partial updates if framebuffer has not been changed
Thomas Zimmermann
tzimmermann at suse.de
Tue Sep 20 13:56:18 UTC 2022
Set partial updates on a plane if the framebuffer has not been changed
on an atomic commit. If such a plane has damage clips, the driver will
use them; otherwise the update is effectively empty. Planes that change
their framebuffer still perform a full update.
This heuristic optimizes the case of setting a new framebuffer on a
plane. This would trigger a full update of all other planes. With the
new optimization, only the changed plane performs an update.
The commit adds the flag fb_changed to struct plane_state. Besides
the damage-handling code, drivers can look at the flag to determine
if they need to commit a plane's framebuffer settings.
Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
drivers/gpu/drm/drm_atomic_helper.c | 3 +++
drivers/gpu/drm/drm_atomic_state_helper.c | 1 +
drivers/gpu/drm/drm_damage_helper.c | 19 +++++++++++++++----
include/drm/drm_plane.h | 6 ++++++
4 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index ee5fea48b5cb..f19405fbee14 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -99,6 +99,9 @@ drm_atomic_helper_plane_changed(struct drm_atomic_state *state,
crtc_state->planes_changed = true;
}
+
+ if (old_plane_state->fb != plane_state->fb)
+ plane_state->fb_changed = true;
}
static int handle_conflicting_encoders(struct drm_atomic_state *state,
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 85b13c221bd8..94818fd4dd8f 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -339,6 +339,7 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
state->commit = NULL;
state->fb_damage_clips = NULL;
state->fb_damage_partial_update = false;
+ state->fb_changed = 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 a603a3563c03..f43abf02df5b 100644
--- a/drivers/gpu/drm/drm_damage_helper.c
+++ b/drivers/gpu/drm/drm_damage_helper.c
@@ -97,11 +97,22 @@ void drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state,
}
}
- /*
- * Damage clips are a good indicator for partial updates.
- */
- if (new_plane_state->fb_damage_clips)
+ if (new_plane_state->fb_damage_clips) {
+ /*
+ * Damage clips are a good indicator for partial updates.
+ */
partial_update = true;
+ } else if (!new_plane_state->fb_changed) {
+ /*
+ * Also set a partial update if the framebuffer 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
+ * earlier in the function.
+ */
+ partial_update = true;
+ }
out:
new_plane_state->fb_damage_partial_update = partial_update;
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 3ba91349d799..8c2d0a2eb760 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -229,6 +229,12 @@ struct drm_plane_state {
*/
bool visible;
+ /**
+ * @fb_changed: @fb has been changed. Used by the atomic helpers and
+ * drivers to steer the atomic commit control flow.
+ */
+ bool fb_changed : 1;
+
/**
* @scaling_filter:
*
--
2.37.3
More information about the dri-devel
mailing list