[PATCH v2 weston 4/7] gl: take, hold, and release a buffer reference

Pekka Paalanen ppaalanen at gmail.com
Tue Dec 4 05:58:13 PST 2012


Instead of relying on the compositor core to keep the wl_buffer around
and unreleased, take a new reference to it in gl-renderer. This makes
sure in the future, that the gl-renderer always has the buffer at hand,
client misbehaviour excluded.

The reference is taken in the attach callback, and released in the
flush_damage callback after copy to texture, or when the next attach
callback with a different buffer occurs.

If the surface is not on the primary plane, the buffer is not released
in flush_damage. This ensures, that the buffer stays valid in case the
surface migrates to the primary plane later.

Signed-off-by: Pekka Paalanen <ppaalanen at gmail.com>
---
 src/gl-renderer.c |   19 ++++++++++++++++---
 1 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/src/gl-renderer.c b/src/gl-renderer.c
index f581482..4ab8b0c 100644
--- a/src/gl-renderer.c
+++ b/src/gl-renderer.c
@@ -62,6 +62,8 @@ struct gl_surface_state {
 	EGLImageKHR images[3];
 	GLenum target;
 	int num_images;
+
+	struct weston_buffer_reference buffer_ref;
 };
 
 struct gl_renderer {
@@ -1038,7 +1040,7 @@ gl_renderer_flush_damage(struct weston_surface *surface)
 {
 	struct gl_renderer *gr = get_renderer(surface->compositor);
 	struct gl_surface_state *gs = get_surface_state(surface);
-	struct wl_buffer *buffer = surface->buffer_ref.buffer;
+	struct wl_buffer *buffer = gs->buffer_ref.buffer;
 
 #ifdef GL_UNPACK_ROW_LENGTH
 	pixman_box32_t *rectangles;
@@ -1049,14 +1051,19 @@ gl_renderer_flush_damage(struct weston_surface *surface)
 	pixman_region32_union(&surface->texture_damage,
 			      &surface->texture_damage, &surface->damage);
 
+	if (!buffer)
+		return;
+
 	/* Avoid upload, if the texture won't be used this time.
-	 * We still accumulate the damage in texture_damage.
+	 * We still accumulate the damage in texture_damage, and
+	 * hold the reference to the buffer, in case the surface
+	 * migrates back to the primary plane.
 	 */
 	if (surface->plane != &surface->compositor->primary_plane)
 		return;
 
 	if (!pixman_region32_not_empty(&surface->texture_damage))
-		return;
+		goto done;
 
 	glBindTexture(GL_TEXTURE_2D, gs->textures[0]);
 
@@ -1090,6 +1097,8 @@ gl_renderer_flush_damage(struct weston_surface *surface)
 done:
 	pixman_region32_fini(&surface->texture_damage);
 	pixman_region32_init(&surface->texture_damage);
+
+	weston_buffer_reference(&gs->buffer_ref, NULL);
 }
 
 static void
@@ -1121,6 +1130,8 @@ gl_renderer_attach(struct weston_surface *es, struct wl_buffer *buffer)
 	EGLint attribs[3], format;
 	int i, num_planes;
 
+	weston_buffer_reference(&gs->buffer_ref, buffer);
+
 	if (!buffer) {
 		for (i = 0; i < gs->num_images; i++) {
 			gr->destroy_image(gr->egl_display, gs->images[i]);
@@ -1201,6 +1212,7 @@ gl_renderer_attach(struct weston_surface *es, struct wl_buffer *buffer)
 		es->pitch = buffer->width;
 	} else {
 		weston_log("unhandled buffer type!\n");
+		weston_buffer_reference(&gs->buffer_ref, NULL);
 	}
 }
 
@@ -1246,6 +1258,7 @@ gl_renderer_destroy_surface(struct weston_surface *surface)
 	for (i = 0; i < gs->num_images; i++)
 		gr->destroy_image(gr->egl_display, gs->images[i]);
 
+	weston_buffer_reference(&gs->buffer_ref, NULL);
 	free(gs);
 }
 
-- 
1.7.8.6



More information about the wayland-devel mailing list