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> | 2012-11-30 11:08:04 -0500 |
commit | ca3ed3e024864e91ca3cccc59fb96950e1d079b5 (patch) | |
tree | b93557df91947ab72cff269c8d6c3800fc8500cf | |
parent | b5c53245afcb35632cc662ff7f84a578eba864c3 (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 772116a1925..7b90387a68f 100644 --- a/src/egl/drivers/dri2/platform_wayland.c +++ b/src/egl/drivers/dri2/platform_wayland.c | |||
@@ -97,6 +97,16 @@ static struct wl_buffer_listener wl_buffer_listener = { | |||
97 | wl_buffer_release | 97 | wl_buffer_release |
98 | }; | 98 | }; |
99 | 99 | ||
100 | static void | ||
101 | resize_callback(struct wl_egl_window *wl_win, void *data) | ||
102 | { | ||
103 | struct dri2_egl_surface *dri2_surf = data; | ||
104 | struct dri2_egl_display *dri2_dpy = | ||
105 | dri2_egl_display(dri2_surf->base.Resource.Display); | ||
106 | |||
107 | (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable); | ||
108 | } | ||
109 | |||
100 | /** | 110 | /** |
101 | * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). | 111 | * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). |
102 | */ | 112 | */ |
@@ -142,6 +152,9 @@ dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, | |||
142 | case EGL_WINDOW_BIT: | 152 | case EGL_WINDOW_BIT: |
143 | dri2_surf->wl_win = (struct wl_egl_window *) window; | 153 | dri2_surf->wl_win = (struct wl_egl_window *) window; |
144 | 154 | ||
155 | dri2_surf->wl_win->private = dri2_surf; | ||
156 | dri2_surf->wl_win->resize_callback = resize_callback; | ||
157 | |||
145 | dri2_surf->base.Width = -1; | 158 | dri2_surf->base.Width = -1; |
146 | dri2_surf->base.Height = -1; | 159 | dri2_surf->base.Height = -1; |
147 | break; | 160 | break; |
@@ -216,6 +229,12 @@ dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) | |||
216 | if (dri2_surf->frame_callback) | 229 | if (dri2_surf->frame_callback) |
217 | wl_callback_destroy(dri2_surf->frame_callback); | 230 | wl_callback_destroy(dri2_surf->frame_callback); |
218 | 231 | ||
232 | |||
233 | if (dri2_surf->base.Type == EGL_WINDOW_BIT) { | ||
234 | dri2_surf->wl_win->private = NULL; | ||
235 | dri2_surf->wl_win->resize_callback = NULL; | ||
236 | } | ||
237 | |||
219 | free(surf); | 238 | free(surf); |
220 | 239 | ||
221 | return EGL_TRUE; | 240 | return EGL_TRUE; |
@@ -587,7 +606,6 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) | |||
587 | } | 606 | } |
588 | 607 | ||
589 | (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable); | 608 | (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable); |
590 | (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable); | ||
591 | 609 | ||
592 | return EGL_TRUE; | 610 | return EGL_TRUE; |
593 | } | 611 | } |
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 | |||
@@ -24,6 +24,9 @@ struct wl_egl_window { | |||
24 | 24 | ||
25 | int attached_width; | 25 | int attached_width; |
26 | int attached_height; | 26 | int attached_height; |
27 | |||
28 | void *private; | ||
29 | void (*resize_callback)(struct wl_egl_window *, void *); | ||
27 | }; | 30 | }; |
28 | 31 | ||
29 | #ifdef __cplusplus | 32 | #ifdef __cplusplus |
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 | |||
@@ -13,6 +13,9 @@ wl_egl_window_resize(struct wl_egl_window *egl_window, | |||
13 | egl_window->height = height; | 13 | egl_window->height = height; |
14 | egl_window->dx = dx; | 14 | egl_window->dx = dx; |
15 | egl_window->dy = dy; | 15 | egl_window->dy = dy; |
16 | |||
17 | if (egl_window->resize_callback) | ||
18 | egl_window->resize_callback(egl_window, egl_window->private); | ||
16 | } | 19 | } |
17 | 20 | ||
18 | WL_EGL_EXPORT struct wl_egl_window * | 21 | WL_EGL_EXPORT struct wl_egl_window * |
@@ -26,6 +29,8 @@ wl_egl_window_create(struct wl_surface *surface, | |||
26 | return NULL; | 29 | return NULL; |
27 | 30 | ||
28 | egl_window->surface = surface; | 31 | egl_window->surface = surface; |
32 | egl_window->private = NULL; | ||
33 | egl_window->resize_callback = NULL; | ||
29 | wl_egl_window_resize(egl_window, width, height, 0, 0); | 34 | wl_egl_window_resize(egl_window, width, height, 0, 0); |
30 | egl_window->attached_width = 0; | 35 | egl_window->attached_width = 0; |
31 | egl_window->attached_height = 0; | 36 | egl_window->attached_height = 0; |