page_flip_pending is only be set when do a pageflip to a newly-rendered
buffer; if the flag is not set, we have landed in the start_repaint_loop
path where the vblank query fails, and thus we must pageflip to the same
buffer.

This test was not sufficient for what it was supposed to guard:
releasing framebuffers back. When using client-supplied framebuffers, it
is possible to reuse the same buffer multiple times, and we would send a
framebuffer-release event too early.

However, since we have a properly reference-counted drm_fb now, we can
just drop this test, and rely on the reference counting to prevent
too-early release of client framebuffers.

page_flip_pending now becomes exactly what the name suggests: a flag
which indicates whether or not we are expecting a pageflip event. Add
asserts here to verify that we never receive a pageflip event we weren't
expecting.

Signed-off-by: Daniel Stone <dani...@collabora.com>

Differential Revision: https://phabricator.freedesktop.org/D1417

Signed-off-by: Daniel Stone <dani...@collabora.com>
---
 libweston/compositor-drm.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 84aa57f..ee38983 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -825,6 +825,7 @@ drm_output_repaint(struct weston_output *output_base,
        output->fb_current = output->fb_pending;
        output->fb_pending = NULL;
 
+       assert(!output->page_flip_pending);
        output->page_flip_pending = 1;
 
        drm_output_set_cursor(output);
@@ -946,12 +947,18 @@ drm_output_start_repaint_loop(struct weston_output 
*output_base)
         */
        fb_id = output->fb_current->fb_id;
 
+       assert(!output->page_flip_pending);
+       assert(!output->fb_last);
+
        if (drmModePageFlip(backend->drm.fd, output->crtc_id, fb_id,
                            DRM_MODE_PAGE_FLIP_EVENT, output) < 0) {
                weston_log("queueing pageflip failed: %m\n");
                goto finish_frame;
        }
 
+       output->fb_last = drm_fb_ref(output->fb_current);
+       output->page_flip_pending = 1;
+
        return;
 
 finish_frame:
@@ -1011,16 +1018,12 @@ page_flip_handler(int fd, unsigned int frame,
 
        drm_output_update_msc(output, frame);
 
-       /* We don't set page_flip_pending on start_repaint_loop, in that case
-        * we just want to page flip to the current buffer to get an accurate
-        * timestamp */
-       if (output->page_flip_pending) {
-               drm_fb_unref(output->fb_last);
-               output->fb_last = NULL;
-       }
-
+       assert(output->page_flip_pending);
        output->page_flip_pending = 0;
 
+       drm_fb_unref(output->fb_last);
+       output->fb_last = NULL;
+
        if (output->destroy_pending)
                drm_output_destroy(&output->base);
        else if (output->disable_pending)
-- 
2.9.3

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to