wayland: Prevent stale paints and weird artifacts when using Weston

Weston releases buffers almost immediately after they're done, which
means that GTK+ doesn't use a temporary surface and instead paints
directly onto the SHM backing store that Weston will use.

Normally, after painting to the temporary surface, GTK+ *replaces*
the existing backing surface with CAIRO_OPERATOR_SOURCE. However,
if we immediately paint to the backing surface, it might have junk
from the last paint in it. So clear out the backing surface whenever
somebody calls begin_paint_region().

Maybe we should just always use the temporary surface like the X11
codepath, since that prevents us from having to do weird things like
this, but oh well.
This commit is contained in:
Jasper St. Pierre 2014-06-20 08:55:19 -04:00
parent 2672837a14
commit 76922c169f
3 changed files with 25 additions and 1 deletions

View File

@ -889,3 +889,10 @@ _gdk_wayland_shm_surface_get_busy (cairo_surface_t *surface)
GdkWaylandCairoSurfaceData *data = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key);
return data->busy;
}
void
_gdk_wayland_shm_surface_clear (cairo_surface_t *surface)
{
GdkWaylandCairoSurfaceData *data = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key);
memset (data->buf, 0, data->buf_length);
}

View File

@ -185,5 +185,6 @@ cairo_surface_t * _gdk_wayland_display_create_shm_surface (GdkWaylandDisplay *di
struct wl_buffer *_gdk_wayland_shm_surface_get_wl_buffer (cairo_surface_t *surface);
void _gdk_wayland_shm_surface_set_busy (cairo_surface_t *surface);
gboolean _gdk_wayland_shm_surface_get_busy (cairo_surface_t *surface);
void _gdk_wayland_shm_surface_clear (cairo_surface_t *surface);
#endif /* __GDK_PRIVATE_WAYLAND_H__ */

View File

@ -568,7 +568,23 @@ gdk_window_impl_wayland_begin_paint_region (GdkWindow *window,
{
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
gdk_wayland_window_ensure_cairo_surface (window);
return _gdk_wayland_shm_surface_get_busy (impl->cairo_surface);
if (_gdk_wayland_shm_surface_get_busy (impl->cairo_surface))
{
/* The surface is busy, so create a temporary surface which we paint
* to and hope that by the time we're done painting the surface isn't
* busy any more. */
return TRUE;
}
else
{
/* Returning FALSE from begin_paint_region says to use the native
* backing surface, which is our SHM surface. We need to make sure
* to clear it before the code tries to paint to it to prevent
* artifacts from the last paint. */
_gdk_wayland_shm_surface_clear (impl->cairo_surface);
return FALSE;
}
}
static void