YaGL: Block for the frame callback in lock_back not swap_buffers 65/27565/1
authorTina Zhang <tina.zhang@intel.com>
Tue, 16 Sep 2014 07:01:04 +0000 (15:01 +0800)
committerTina Zhang <tina.zhang@intel.com>
Tue, 16 Sep 2014 07:15:15 +0000 (15:15 +0800)
If the throttle only be used in the yagl_wayland_window_swap_buffers(),
then in some situations the yagl_wayland_window_get_buffer() may get the
NULL buffer. This could let the App draw into the wrong surface.
Do throttle in the yagl_wayland_window_lock_back() will solve the problem.

Change-Id: Id1d2bc8f1c95b3c956118b36b07b20cc1615046c
Signed-off-by: Tina Zhang <tina.zhang@intel.com>
EGL/wayland/yagl_wayland_window.c

index fd49b6d7ba5fecfb0f23134bb16f85c2759c6d07..8854dabf0189c37ec63a15446e9c628af598abf9 100644 (file)
@@ -74,10 +74,19 @@ static int yagl_wayland_window_lock_back(struct yagl_wayland_window *window)
     struct wl_display *wl_dpy = YAGL_WAYLAND_DPY(dpy->base.os_dpy);
     int i, ret;
 
-    /*
-     * There might be a buffer release already queued that wasn't processed.
-     */
-    wl_display_dispatch_queue_pending(wl_dpy, dpy->queue);
+    if (window->frame_callback == NULL) {
+        /* There might be a buffer release already queued that wasn't processed
+        */
+        wl_display_dispatch_queue_pending(wl_dpy, dpy->queue);
+    } else {
+        /* We throttle to the frame callback here so that we can be sure to have
+        * received any release events before trying to decide whether to
+        * allocate a new buffer */
+        do {
+            if (wl_display_dispatch_queue(wl_dpy, dpy->queue) == -1)
+                    return EGL_FALSE;
+        } while (window->frame_callback != NULL);
+    }
 
     if (!window->back) {
         for (i = 0;
@@ -241,25 +250,6 @@ static void yagl_wayland_window_swap_buffers(struct yagl_native_drawable *drawab
     int i, ret = 0;
 
     YAGL_LOG_FUNC_SET(yagl_wayland_window_swap_buffers);
-
-    /*
-     * Throttle.
-     */
-    while (window->frame_callback && (ret != -1)) {
-        ret = wl_display_dispatch_queue(wl_dpy, dpy->queue);
-    }
-
-    if (ret < 0) {
-        YAGL_LOG_ERROR("wl_display_dispatch_queue failed for egl_window %p: %d", egl_window, ret);
-        return;
-    }
-
-    window->frame_callback = wl_surface_frame(egl_window->surface);
-    wl_callback_add_listener(window->frame_callback,
-                             &yagl_wayland_window_frame_listener,
-                             window);
-    wl_proxy_set_queue((struct wl_proxy*)window->frame_callback, dpy->queue);
-
     for (i = 0;
          i < sizeof(window->color_buffers)/sizeof(window->color_buffers[0]);
          ++i) {
@@ -277,6 +267,12 @@ static void yagl_wayland_window_swap_buffers(struct yagl_native_drawable *drawab
         return;
     }
 
+    window->frame_callback = wl_surface_frame(egl_window->surface);
+    wl_callback_add_listener(window->frame_callback,
+                             &yagl_wayland_window_frame_listener, window);
+    wl_proxy_set_queue((struct wl_proxy *) window->frame_callback,
+                       dpy->queue);
+
     window->front = window->back;
     window->front->age = 1;
     window->back = NULL;