diff options
author | Louis-Francis Ratté-Boulianne <lfrb@collabora.com> | 2015-06-08 16:37:05 +0300 |
---|---|---|
committer | Pekka Paalanen <pekka.paalanen@collabora.co.uk> | 2015-08-14 15:53:25 +0300 |
commit | 534defdf43a8a36966ea18e3d5eee09d2375479c (patch) | |
tree | c9e3d4263bf439a11e74377187e52b863000cc9c /src/gl-renderer.c | |
parent | 230f3b1bf896fcf3fa76b4d7093122b3361f7e36 (diff) | |
download | weston-534defdf43a8a36966ea18e3d5eee09d2375479c.tar.gz |
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>
Diffstat (limited to 'src/gl-renderer.c')
-rw-r--r-- | src/gl-renderer.c | 70 |
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); |