diff options
author | Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> | 2012-11-30 17:41:02 +0200 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2013-01-10 16:33:50 -0500 |
commit | eaf6884621661288624fc060974c3aa485771324 (patch) | |
tree | 6b226ef2180c5afad061e1d1b987ec620bf0b47a | |
parent | 0ac90296a092f846647812318913b0e492775f31 (diff) |
egl/wayland: Don't invalidate drawable on swap buffers
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
-rw-r--r-- | src/egl/drivers/dri2/platform_wayland.c | 20 | ||||
-rw-r--r-- | src/egl/wayland/wayland-egl/wayland-egl-priv.h | 3 | ||||
-rw-r--r-- | src/egl/wayland/wayland-egl/wayland-egl.c | 5 |
3 files changed, 27 insertions, 1 deletions
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c index 2fde1715b6a..294413c8095 100644 --- a/src/egl/drivers/dri2/platform_wayland.c +++ b/src/egl/drivers/dri2/platform_wayland.c @@ -94,12 +94,22 @@ wl_buffer_release(void *data, struct wl_buffer *buffer) } 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(). */ static _EGLSurface * dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, _EGLConfig *conf, EGLNativeWindowType window, @@ -139,12 +149,15 @@ dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, dri2_surf->format = WL_DRM_FORMAT_ARGB8888; switch (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; default: goto cleanup_surf; } @@ -213,12 +226,18 @@ dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) dri2_surf->third_buffer); } 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; } static struct wl_buffer * @@ -584,13 +603,12 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) ctx = _eglGetCurrentContext(); if (ctx && ctx->DrawSurface == &dri2_surf->base) dri2_drv->glFlush(); } (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable); - (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable); return EGL_TRUE; } static int dri2_wayland_authenticate(_EGLDisplay *disp, uint32_t id) diff --git a/src/egl/wayland/wayland-egl/wayland-egl-priv.h b/src/egl/wayland/wayland-egl/wayland-egl-priv.h index bdbf32a1689..da25be9f710 100644 --- a/src/egl/wayland/wayland-egl/wayland-egl-priv.h +++ b/src/egl/wayland/wayland-egl/wayland-egl-priv.h @@ -21,12 +21,15 @@ struct wl_egl_window { int height; int dx; int dy; int attached_width; int attached_height; + + void *private; + void (*resize_callback)(struct wl_egl_window *, void *); }; #ifdef __cplusplus } #endif diff --git a/src/egl/wayland/wayland-egl/wayland-egl.c b/src/egl/wayland/wayland-egl/wayland-egl.c index c61fb4f2c3a..8bd49cf6c4f 100644 --- a/src/egl/wayland/wayland-egl/wayland-egl.c +++ b/src/egl/wayland/wayland-egl/wayland-egl.c @@ -10,12 +10,15 @@ wl_egl_window_resize(struct wl_egl_window *egl_window, int dx, int dy) { egl_window->width = width; 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 * wl_egl_window_create(struct wl_surface *surface, int width, int height) { @@ -23,12 +26,14 @@ wl_egl_window_create(struct wl_surface *surface, egl_window = malloc(sizeof *egl_window); if (!egl_window) 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; return egl_window; } |