[PATCH mesa] egl/wayland: Don't invalidate drawable on swap buffers

Kristian Høgsberg hoegsberg at gmail.com
Fri Nov 30 10:43:59 PST 2012


On Fri, Nov 30, 2012 at 11:07:09AM -0500, Kristian Høgsberg wrote:
> On Fri, Nov 30, 2012 at 05:41:02PM +0200, Ander Conselvan de Oliveira wrote:
> > 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.
> 
> Yes, this is good, it's the right fix for that problem.  And with the
> resize callback we can avoid the getbuffers callback every frame which
> should save a few cycles as well.
> 
> Thanks, applied.
> Kristian

And now I'm banging my head against the table... since we always swap
buffers in wayland, we always need to invalidate after swap, so the
driver will ask for the new back buffer.  I pushed a fixup-commit to just
add the invalidate call back in dri2_swap_buffers().

Kristian

> > Note: this is a candidate for stable branches.
> > CC: wayland-devel at lists.freedesktop.org
> > ---
> >  src/egl/drivers/dri2/platform_wayland.c        |   20 +++++++++++++++++++-
> >  src/egl/wayland/wayland-egl/wayland-egl-priv.h |    3 +++
> >  src/egl/wayland/wayland-egl/wayland-egl.c      |    5 +++++
> >  3 files changed, 27 insertions(+), 1 deletion(-)
> > 
> > diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
> > index 8df22c0..e55f92b 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 = {
> >     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;
> > @@ -592,7 +611,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;
> >  }
> > diff --git a/src/egl/wayland/wayland-egl/wayland-egl-priv.h b/src/egl/wayland/wayland-egl/wayland-egl-priv.h
> > index bdbf32a..da25be9 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 {
> >  
> >  	int attached_width;
> >  	int attached_height;
> > +
> > +	void *private;
> > +	void (*resize_callback)(struct wl_egl_window *, void *);
> >  };
> >  
> >  #ifdef  __cplusplus
> > diff --git a/src/egl/wayland/wayland-egl/wayland-egl.c b/src/egl/wayland/wayland-egl/wayland-egl.c
> > index c61fb4f..8bd49cf 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,
> >  	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;
> > -- 
> > 1.7.10.4
> > 


More information about the wayland-devel mailing list