[PATCH v19 07/10] compositor-drm: Add planes-only mode to state proposal

Daniel Stone daniels at collabora.com
Tue Jul 10 17:58:46 UTC 2018


Add a new mode, which attempts to construct a scene exclusively using
planes. This is a building block for incrementally testing and
constructing state: in the plane-only mode, we test the state exactly
once, when we have constructed a full set of planes and want to know if
it works or not.

When using the renderer, we need to incrementally test views one by one
to see if they will work on planes, falling back to the renderer if not.
This test is different, since the scanout plane will be occupied by the
renderer's buffer. Testing using the renderer or client buffers may have
completely different characteristics, so we need two passes: first,
constructing a state with only planes and testing if that succeeds,
falling back later to a mixed renderer/plane mode which tests
incrementally.

This implements the first mode, and preferentially attempts to use it.

Signed-off-by: Daniel Stone <daniels at collabora.com>
---
 libweston/compositor-drm.c | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 282d6d67f..3a627dd34 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -1944,6 +1944,7 @@ drm_output_assign_state(struct drm_output_state *state,
 enum drm_output_propose_state_mode {
 	DRM_OUTPUT_PROPOSE_STATE_MIXED, /**< mix renderer & planes */
 	DRM_OUTPUT_PROPOSE_STATE_RENDERER_ONLY, /**< only assign to renderer & cursor */
+	DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY, /**< no renderer use, only planes */
 };
 
 static struct drm_plane_state *
@@ -3296,6 +3297,7 @@ drm_output_propose_state(struct weston_output *output_base,
 	struct weston_view *ev;
 	pixman_region32_t surface_overlap, renderer_region, occluded_region;
 	bool planes_ok = (mode != DRM_OUTPUT_PROPOSE_STATE_RENDERER_ONLY);
+	bool renderer_ok = (mode != DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY);
 	int ret;
 
 	assert(!output->state_last);
@@ -3387,6 +3389,11 @@ drm_output_propose_state(struct weston_output *output_base,
 		if (!drm_view_is_opaque(ev))
 			force_renderer = true;
 
+		if (force_renderer && !renderer_ok) {
+			pixman_region32_fini(&clipped_view);
+			goto err;
+		}
+
 		if (!force_renderer && !ps)
 			ps = drm_output_prepare_scanout_view(state, ev);
 		if (!force_renderer && !ps)
@@ -3409,6 +3416,14 @@ drm_output_propose_state(struct weston_output *output_base,
 			continue;
 		}
 
+		/* We have been assigned to the primary (renderer) plane:
+		 * check if this is OK, and add ourselves to the renderer
+		 * region if so. */
+		if (!renderer_ok) {
+			pixman_region32_fini(&clipped_view);
+			goto err;
+		}
+
 		pixman_region32_union(&renderer_region,
 				      &renderer_region,
 				      &clipped_view);
@@ -3441,16 +3456,21 @@ drm_assign_planes(struct weston_output *output_base, void *repaint_data)
 	struct drm_plane_state *plane_state;
 	struct weston_view *ev;
 	struct weston_plane *primary = &output_base->compositor->primary_plane;
-	enum drm_output_propose_state_mode mode;
 
-	if (!b->sprites_are_broken)
+	if (!b->sprites_are_broken) {
 		state = drm_output_propose_state(output_base, pending_state,
-						 DRM_OUTPUT_PROPOSE_STATE_MIXED);
+						 DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY);
+		if (!state)
+			state = drm_output_propose_state(output_base, pending_state,
+							 DRM_OUTPUT_PROPOSE_STATE_MIXED);
+	}
 
 	if (!state)
 		state = drm_output_propose_state(output_base, pending_state,
 						 DRM_OUTPUT_PROPOSE_STATE_RENDERER_ONLY);
 
+	assert(state);
+
 	wl_list_for_each(ev, &output_base->compositor->view_list, link) {
 		struct drm_plane *target_plane = NULL;
 
-- 
2.17.1



More information about the wayland-devel mailing list