We can separate repainting into two phases: one performing the actual repaint (essentially drm_output_render) and populating the plane state that wasn't already populated by drm_output_assign_planes, and another applying this state to the device.
Signed-off-by: Daniel Stone <dani...@collabora.com> Differential Revision: https://phabricator.freedesktop.org/D1500 --- libweston/compositor-drm.c | 61 +++++++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c index 95f7f8d..a368792 100644 --- a/libweston/compositor-drm.c +++ b/libweston/compositor-drm.c @@ -1498,12 +1498,10 @@ drm_waitvblank_pipe(struct drm_output *output) } static int -drm_output_repaint(struct weston_output *output_base, - pixman_region32_t *damage) +drm_output_apply_state(struct drm_output_state *state) { - struct drm_output *output = to_drm_output(output_base); - struct drm_backend *backend = - to_drm_backend(output->base.compositor); + struct drm_output *output = state->output; + struct drm_backend *backend = to_drm_backend(output->base.compositor); struct drm_plane *scanout_plane = output->scanout_plane; struct drm_plane_state *scanout_state; struct drm_plane_state *ps; @@ -1511,20 +1509,7 @@ drm_output_repaint(struct weston_output *output_base, struct drm_mode *mode; int ret = 0; - if (output->disable_pending || output->destroy_pending) - goto err; - - assert(!output->state_last); - if (!output->state_pending) - output->state_pending = - drm_output_state_duplicate(output->state_cur, - DRM_OUTPUT_STATE_CLEAR_PLANES); - - drm_output_render(output, damage); - scanout_state = drm_output_state_get_plane(output->state_pending, - scanout_plane); - if (!scanout_state || !scanout_state->fb) - goto err; + scanout_state = drm_output_state_get_plane(state, scanout_plane); /* The legacy SetCrtc API doesn't allow us to do scaling, and the * legacy PageFlip API doesn't allow us to do clipping either. */ @@ -1549,7 +1534,7 @@ drm_output_repaint(struct weston_output *output_base, weston_log("set mode failed: %m\n"); goto err; } - output_base->set_dpms(output_base, WESTON_DPMS_ON); + output->base.set_dpms(&output->base, WESTON_DPMS_ON); } if (drmModePageFlip(backend->drm.fd, output->crtc_id, @@ -1561,7 +1546,7 @@ drm_output_repaint(struct weston_output *output_base, assert(!output->page_flip_pending); - drm_output_set_cursor(output->state_pending); + drm_output_set_cursor(state); /* * Now, update all the sprite surfaces @@ -1624,6 +1609,37 @@ err: return -1; } +static int +drm_output_repaint(struct weston_output *output_base, + pixman_region32_t *damage) +{ + struct drm_output *output = to_drm_output(output_base); + struct drm_plane_state *scanout_state; + + if (output->disable_pending || output->destroy_pending) + goto err; + + assert(!output->state_last); + if (!output->state_pending) + output->state_pending = + drm_output_state_duplicate(output->state_cur, + DRM_OUTPUT_STATE_CLEAR_PLANES); + + drm_output_render(output, damage); + scanout_state = drm_output_state_get_plane(output->state_pending, + output->scanout_plane); + if (!scanout_state || !scanout_state->fb) + goto err; + + return drm_output_apply_state(output->state_pending); + +err: + drm_output_state_free(output->state_pending); + output->state_pending = NULL; + return -1; +} + + static void drm_output_start_repaint_loop(struct weston_output *output_base) { @@ -2501,8 +2517,7 @@ create_gbm_device(int fd) * legitimate format for other EGL platforms, so the caller is * responsible for checking for 0 before calling gl_renderer->create(). * - * This works around https://bugs.freedesktop.org/show_bug.cgi?id=89689 - * but it's entirely possible we'll see this again on other implementations. + * This works around https://bugs.freedesktop.org/show_bug.cgi?id=89689 * but it's entirely possible we'll see this again on other implementations. */ static int fallback_format_for(uint32_t format) -- 2.9.3 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel