summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis-Francis Ratté-Boulianne <lfrb@collabora.com>2015-06-08 16:37:05 +0300
committerPekka Paalanen <pekka.paalanen@collabora.co.uk>2015-08-14 15:53:25 +0300
commit534defdf43a8a36966ea18e3d5eee09d2375479c (patch)
treec9e3d4263bf439a11e74377187e52b863000cc9c
parent230f3b1bf896fcf3fa76b4d7093122b3361f7e36 (diff)
gl-renderer: introduce struct egl_image
This is a reference-counted holder of an EGLImage. For now, direct EGLImage usage is simply converted to use egl_image. Use of reference counting will come in a later patch. v2: - this is a new patch, split from gl-renderer dmabuf import support Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Daniel Stone <daniels@collabora.com>
-rw-r--r--src/gl-renderer.c70
1 files changed, 62 insertions, 8 deletions
diff --git a/src/gl-renderer.c b/src/gl-renderer.c
index 88db26b3..4c7137dc 100644
--- a/src/gl-renderer.c
+++ b/src/gl-renderer.c
@@ -90,6 +90,14 @@ enum buffer_type {
BUFFER_TYPE_EGL
};
+struct gl_renderer;
+
+struct egl_image {
+ struct gl_renderer *renderer;
+ EGLImageKHR image;
+ int refcount;
+};
+
struct gl_surface_state {
GLfloat color[4];
struct gl_shader *shader;
@@ -105,7 +113,7 @@ struct gl_surface_state {
GLenum gl_format;
GLenum gl_pixel_type;
- EGLImageKHR images[3];
+ struct egl_image* images[3];
GLenum target;
int num_images;
@@ -197,6 +205,51 @@ get_renderer(struct weston_compositor *ec)
return (struct gl_renderer *)ec->renderer;
}
+static struct egl_image*
+egl_image_create(struct gl_renderer *gr, EGLenum target,
+ EGLClientBuffer buffer, const EGLint *attribs)
+{
+ struct egl_image *img;
+
+ img = zalloc(sizeof *img);
+ img->renderer = gr;
+ img->refcount = 1;
+ img->image = gr->create_image(gr->egl_display, EGL_NO_CONTEXT,
+ target, buffer, attribs);
+
+ if (img->image == EGL_NO_IMAGE_KHR) {
+ free(img);
+ return NULL;
+ }
+
+ return img;
+}
+
+static struct egl_image*
+egl_image_ref(struct egl_image *image)
+{
+ image->refcount++;
+
+ return image;
+}
+
+static int
+egl_image_unref(struct egl_image *image)
+{
+ struct gl_renderer *gr = image->renderer;
+
+ assert(image->refcount > 0);
+
+ image->refcount--;
+ if (image->refcount > 0)
+ return image->refcount;
+
+ gr->destroy_image(gr->egl_display, image->image);
+ free(image);
+
+ return 0;
+}
+
static const char *
egl_error_string(EGLint code)
{
@@ -1290,8 +1343,10 @@ gl_renderer_attach_egl(struct weston_surface *es, struct weston_buffer *buffer,
gr->query_buffer(gr->egl_display, buffer->legacy_buffer,
EGL_WAYLAND_Y_INVERTED_WL, &buffer->y_inverted);
- for (i = 0; i < gs->num_images; i++)
- gr->destroy_image(gr->egl_display, gs->images[i]);
+ for (i = 0; i < gs->num_images; i++) {
+ egl_image_unref(gs->images[i]);
+ gs->images[i] = NULL;
+ }
gs->num_images = 0;
gs->target = GL_TEXTURE_2D;
switch (format) {
@@ -1325,8 +1380,7 @@ gl_renderer_attach_egl(struct weston_surface *es, struct weston_buffer *buffer,
attribs[0] = EGL_WAYLAND_PLANE_WL;
attribs[1] = i;
attribs[2] = EGL_NONE;
- gs->images[i] = gr->create_image(gr->egl_display,
- NULL,
+ gs->images[i] = egl_image_create(gr,
EGL_WAYLAND_BUFFER_WL,
buffer->legacy_buffer,
attribs);
@@ -1339,7 +1393,7 @@ gl_renderer_attach_egl(struct weston_surface *es, struct weston_buffer *buffer,
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(gs->target, gs->textures[i]);
gr->image_target_texture_2d(gs->target,
- gs->images[i]);
+ gs->images[i]->image);
}
gs->pitch = buffer->width;
@@ -1362,7 +1416,7 @@ gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
if (!buffer) {
for (i = 0; i < gs->num_images; i++) {
- gr->destroy_image(gr->egl_display, gs->images[i]);
+ egl_image_unref(gs->images[i]);
gs->images[i] = NULL;
}
gs->num_images = 0;
@@ -1564,7 +1618,7 @@ surface_state_destroy(struct gl_surface_state *gs, struct gl_renderer *gr)
glDeleteTextures(gs->num_textures, gs->textures);
for (i = 0; i < gs->num_images; i++)
- gr->destroy_image(gr->egl_display, gs->images[i]);
+ egl_image_unref(gs->images[i]);
weston_buffer_reference(&gs->buffer_ref, NULL);
pixman_region32_fini(&gs->texture_damage);