gl-renderer: Attach buffer during surface state creation if possible
When a renderer switch happens, it is possible that when the surface
state is created, a buffer for the given surface is already available.
In that case, run the attach routine so that the pixel contents are
properly set. Otherwise, it would only be set when a new attach request
is made for that surface.
Also, change the drm backend so that it keeps the buffer reference in
the weston_surface when running with the pixman renderer. The pixman
renderer keeps a reference to it anyway, so it is never released
early.
This makes the renderer transition seamless, without leaving a black
screen as before.
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 5cb0fab..e89c768 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -1056,18 +1056,24 @@
pixman_region32_init(&overlap);
primary = &c->base.primary_plane;
- /* Flag all visible surfaces as keep_buffer = 1 */
- wl_list_for_each(ev, &c->base.view_list, link)
- ev->surface->keep_buffer = 1;
-
wl_list_for_each_safe(ev, next, &c->base.view_list, link) {
- /* test whether this buffer can ever go into a plane:
- * non-shm, or small enough to be a cursor
+ struct weston_surface *es = ev->surface;
+
+ /* Test whether this buffer can ever go into a plane:
+ * non-shm, or small enough to be a cursor.
+ *
+ * Also, keep a reference when using the pixman renderer.
+ * That makes it possible to do a seamless switch to the GL
+ * renderer and since the pixman renderer keeps a reference
+ * to the buffer anyway, there is no side effects.
*/
- if (!ev->surface->buffer_ref.buffer ||
- (wl_shm_buffer_get(ev->surface->buffer_ref.buffer->resource) &&
- (ev->geometry.width > 64 || ev->geometry.height > 64)))
- ev->surface->keep_buffer = 0;
+ if (c->use_pixman ||
+ (es->buffer_ref.buffer &&
+ (!wl_shm_buffer_get(es->buffer_ref.buffer->resource) ||
+ (ev->geometry.width <= 64 && ev->geometry.height <= 64))))
+ es->keep_buffer = 1;
+ else
+ es->keep_buffer = 0;
pixman_region32_init(&surface_overlap);
pixman_region32_intersect(&surface_overlap, &overlap,