egl/wayland: Don't invalidate drawable on swap buffers
authorAnder Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
Fri, 30 Nov 2012 15:41:02 +0000 (17:41 +0200)
committerKristian Høgsberg <krh@bitplanet.net>
Fri, 30 Nov 2012 16:08:04 +0000 (11:08 -0500)
We used to invalidate the drawable after a call to eglSwapBuffers(),
so that a wl_egl_window_resize() would take effect for the next frame.
However, that leads to calling dri2_get_buffers() when eglMakeCurrent()
is called with the current context and surface, and a later call to
wl_egl_window_resize() would not take effect until the next buffer
swap.

Instead, add a callback from wl_egl_window_resize() back to the wayland
egl platform, and invalidate the drawable only when it is resized.

This solves a bug on wayland clients when going back to windowed mode
from fullscreen when clicking a pop up menu, where the window size
after this would be the fullscreen size.

Note: this is a candidate for stable branches.
CC: wayland-devel@lists.freedesktop.org
src/egl/drivers/dri2/platform_wayland.c
src/egl/wayland/wayland-egl/wayland-egl-priv.h
src/egl/wayland/wayland-egl/wayland-egl.c

index 772116a19252d5f210634f342f87f212814fc35d..7b90387a68fd0ddb723a33c33311fb9143ca6dec 100644 (file)
@@ -97,6 +97,16 @@ static struct wl_buffer_listener wl_buffer_listener = {
    wl_buffer_release
 };
 
+static void
+resize_callback(struct wl_egl_window *wl_win, void *data)
+{
+   struct dri2_egl_surface *dri2_surf = data;
+   struct dri2_egl_display *dri2_dpy =
+      dri2_egl_display(dri2_surf->base.Resource.Display);
+
+   (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
+}
+
 /**
  * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
  */
@@ -142,6 +152,9 @@ dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
    case EGL_WINDOW_BIT:
       dri2_surf->wl_win = (struct wl_egl_window *) window;
 
+      dri2_surf->wl_win->private = dri2_surf;
+      dri2_surf->wl_win->resize_callback = resize_callback;
+
       dri2_surf->base.Width =  -1;
       dri2_surf->base.Height = -1;
       break;
@@ -216,6 +229,12 @@ dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
    if (dri2_surf->frame_callback)
       wl_callback_destroy(dri2_surf->frame_callback);
 
+
+   if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
+      dri2_surf->wl_win->private = NULL;
+      dri2_surf->wl_win->resize_callback = NULL;
+   }
+
    free(surf);
 
    return EGL_TRUE;
@@ -587,7 +606,6 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
    }
 
    (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
-   (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
 
    return EGL_TRUE;
 }
index bdbf32a16898e65f7264327c3bd1c62a5ad826d1..da25be9f710e4abd2a15150fec85c140c5cc7541 100644 (file)
@@ -24,6 +24,9 @@ struct wl_egl_window {
 
        int attached_width;
        int attached_height;
+
+       void *private;
+       void (*resize_callback)(struct wl_egl_window *, void *);
 };
 
 #ifdef  __cplusplus
index c61fb4f2c3afef787490bdf7d37f1d5cf4e5787c..8bd49cf6c4fc324e7a193ff2bda58dd27a33a390 100644 (file)
@@ -13,6 +13,9 @@ wl_egl_window_resize(struct wl_egl_window *egl_window,
        egl_window->height = height;
        egl_window->dx     = dx;
        egl_window->dy     = dy;
+
+       if (egl_window->resize_callback)
+               egl_window->resize_callback(egl_window, egl_window->private);
 }
 
 WL_EGL_EXPORT struct wl_egl_window *
@@ -26,6 +29,8 @@ wl_egl_window_create(struct wl_surface *surface,
                return NULL;
 
        egl_window->surface = surface;
+       egl_window->private = NULL;
+       egl_window->resize_callback = NULL;
        wl_egl_window_resize(egl_window, width, height, 0, 0);
        egl_window->attached_width  = 0;
        egl_window->attached_height = 0;