[PATCH 2/2] gl-renderer: Attach buffer during surface state creation if possible

Ander Conselvan de Oliveira conselvan2 at gmail.com
Tue Nov 19 05:22:05 PST 2013


From: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira at intel.com>

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.
---
 src/compositor-drm.c |   26 ++++++++++++++++----------
 src/gl-renderer.c    |    8 +++++++-
 2 files changed, 23 insertions(+), 11 deletions(-)

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 @@ drm_assign_planes(struct weston_output *output)
 	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,
diff --git a/src/gl-renderer.c b/src/gl-renderer.c
index 5e1b396..218fca4 100644
--- a/src/gl-renderer.c
+++ b/src/gl-renderer.c
@@ -883,7 +883,8 @@ gl_renderer_flush_damage(struct weston_surface *surface)
 	if (!texture_used)
 		return;
 
-	if (!pixman_region32_not_empty(&gs->texture_damage))
+	if (!pixman_region32_not_empty(&gs->texture_damage) &&
+	    !gs->needs_full_upload)
 		goto done;
 
 	switch (wl_shm_buffer_get_format(buffer->shm_buffer)) {
@@ -1240,6 +1241,11 @@ gl_renderer_create_surface(struct weston_surface *surface)
 	wl_signal_add(&gr->destroy_signal,
 		      &gs->renderer_destroy_listener);
 
+	if (surface->buffer_ref.buffer) {
+		gl_renderer_attach(surface, surface->buffer_ref.buffer);
+		gl_renderer_flush_damage(surface);
+	}
+
 	return 0;
 }
 
-- 
1.7.9.5



More information about the wayland-devel mailing list