diff options
author | Gwenole Beauchesne <gwenole.beauchesne@intel.com> | 2012-04-20 11:07:06 +0200 |
---|---|---|
committer | Gwenole Beauchesne <gwenole.beauchesne@intel.com> | 2012-04-27 16:27:28 +0200 |
commit | a77150b3bed630b612d2652ad3f6a06326e9886c (patch) | |
tree | 9aaa37ec6a87e3b3a85ab45f5c3bb357ada2c065 | |
parent | 7890c4d36dbec14d44109ead6fb12adfece47a7b (diff) |
compositor: prepare for multi-planar surfaces.
Make weston_surface::texture and ::surface an array, while keeping
[0] for RGB surfaces.
Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
-rw-r--r-- | src/compositor-drm.c | 14 | ||||
-rw-r--r-- | src/compositor.c | 87 | ||||
-rw-r--r-- | src/compositor.h | 6 |
3 files changed, 73 insertions, 34 deletions
diff --git a/src/compositor-drm.c b/src/compositor-drm.c index dcd5e99..beb5a7c 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -176,12 +176,12 @@ drm_output_prepare_scanout_surface(struct drm_output *output) es->geometry.width != output->base.current->width || es->geometry.height != output->base.current->height || es->transform.enabled || - es->image == EGL_NO_IMAGE_KHR) + es->images[0] == EGL_NO_IMAGE_KHR) return -1; output->next_bo = gbm_bo_create_from_egl_image(c->gbm, - c->base.display, es->image, + c->base.display, es->images[0], es->geometry.width, es->geometry.height, GBM_BO_USE_SCANOUT); @@ -473,7 +473,7 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base, if (surface_is_primary(ec, es)) return -1; - if (es->image == EGL_NO_IMAGE_KHR) + if (es->num_images != 1 || es->images[0] == EGL_NO_IMAGE_KHR) return -1; if (!drm_surface_transform_supported(es)) @@ -496,7 +496,7 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base, if (!found) return -1; - bo = gbm_bo_create_from_egl_image(c->gbm, c->base.display, es->image, + bo = gbm_bo_create_from_egl_image(c->gbm, c->base.display, es->images[0], es->geometry.width, es->geometry.height, GBM_BO_USE_SCANOUT); format = gbm_bo_get_format(bo); @@ -683,7 +683,9 @@ drm_output_set_cursor(struct weston_output *output_base, return 0; } - if (eid->sprite->image == EGL_NO_IMAGE_KHR) + if (eid->sprite->num_images != 1) + goto out; + if (eid->sprite->images[0] == EGL_NO_IMAGE_KHR) goto out; if (eid->sprite->geometry.width > 64 || @@ -692,7 +694,7 @@ drm_output_set_cursor(struct weston_output *output_base, bo = gbm_bo_create_from_egl_image(c->gbm, c->base.display, - eid->sprite->image, 64, 64, + eid->sprite->images[0], 64, 64, GBM_BO_USE_CURSOR_64X64); /* Not suitable for hw cursor, fall back */ if (bo == NULL) diff --git a/src/compositor.c b/src/compositor.c index 768477d..77da190 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -211,6 +211,7 @@ WL_EXPORT struct weston_surface * weston_surface_create(struct weston_compositor *compositor) { struct weston_surface *surface; + unsigned int i; surface = calloc(1, sizeof *surface); if (surface == NULL) @@ -224,12 +225,19 @@ weston_surface_create(struct weston_compositor *compositor) surface->surface.resource.client = NULL; surface->compositor = compositor; - surface->image = EGL_NO_IMAGE_KHR; surface->alpha = 255; surface->brightness = 255; surface->saturation = 255; surface->pitch = 1; + for (i = 0; i < ARRAY_LENGTH(surface->textures); i++) + surface->textures[i] = 0; + surface->num_textures = 0; + + for (i = 0; i < ARRAY_LENGTH(surface->images); i++) + surface->images[i] = EGL_NO_IMAGE_KHR; + surface->num_images = 0; + surface->buffer = NULL; surface->output = NULL; @@ -638,25 +646,37 @@ weston_surface_unmap(struct weston_surface *surface) } static void +destroy_image(struct weston_compositor *compositor, EGLImageKHR *image_ptr) +{ + EGLImageKHR const image = *image_ptr; + + if (image != EGL_NO_IMAGE_KHR) { + compositor->destroy_image(compositor->display, image); + *image_ptr = EGL_NO_IMAGE_KHR; + } +} + +static void destroy_surface(struct wl_resource *resource) { struct weston_surface *surface = container_of(resource, struct weston_surface, surface.resource); struct weston_compositor *compositor = surface->compositor; + unsigned int i; if (weston_surface_is_mapped(surface)) weston_surface_unmap(surface); - if (surface->texture) - glDeleteTextures(1, &surface->texture); + glDeleteTextures(surface->num_textures, surface->textures); + surface->num_textures = 0; if (surface->buffer) wl_list_remove(&surface->buffer_destroy_listener.link); - if (surface->image != EGL_NO_IMAGE_KHR) - compositor->destroy_image(compositor->display, - surface->image); + for (i = 0; i < surface->num_images; i++) + destroy_image(compositor, &surface->images[i]); + surface->num_images = 0; pixman_region32_fini(&surface->transform.boundingbox); pixman_region32_fini(&surface->damage); @@ -678,6 +698,26 @@ weston_surface_destroy(struct weston_surface *surface) } static void +ensure_textures(struct weston_surface *es, unsigned int num_textures) +{ + unsigned int i; + + if (num_textures <= es->num_textures) + return; + + for (i = es->num_textures; i < num_textures; i++) { + glGenTextures(1, &es->textures[i]); + glBindTexture(GL_TEXTURE_2D, es->textures[i]); + glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + es->num_textures = num_textures; + glBindTexture(GL_TEXTURE_2D, 0); +} + +static void weston_surface_attach(struct wl_surface *surface, struct wl_buffer *buffer) { struct weston_surface *es = (struct weston_surface *) surface; @@ -707,33 +747,28 @@ weston_surface_attach(struct wl_surface *surface, struct wl_buffer *buffer) pixman_region32_init(&es->opaque); } - if (!es->texture) { - glGenTextures(1, &es->texture); - glBindTexture(GL_TEXTURE_2D, es->texture); - glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - es->shader = &ec->texture_shader; - } else { - glBindTexture(GL_TEXTURE_2D, es->texture); - } - if (wl_buffer_is_shm(buffer)) { es->pitch = wl_shm_buffer_get_stride(buffer) / 4; + es->shader = &ec->texture_shader; + + ensure_textures(es, 1); + glBindTexture(GL_TEXTURE_2D, es->textures[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, es->pitch, es->buffer->height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL); } else { - if (es->image != EGL_NO_IMAGE_KHR) - ec->destroy_image(ec->display, es->image); - es->image = ec->create_image(ec->display, NULL, - EGL_WAYLAND_BUFFER_WL, - buffer, NULL); + destroy_image(ec, &es->images[0]); + es->images[0] = ec->create_image(ec->display, NULL, + EGL_WAYLAND_BUFFER_WL, + buffer, NULL); + es->num_images = 1; - ec->image_target_texture_2d(GL_TEXTURE_2D, es->image); + ensure_textures(es, 1); + glBindTexture(GL_TEXTURE_2D, es->textures[0]); + ec->image_target_texture_2d(GL_TEXTURE_2D, es->images[0]); es->pitch = buffer->width; + es->shader = &ec->texture_shader; } } @@ -836,7 +871,7 @@ weston_surface_draw(struct weston_surface *es, struct weston_output *output, n = texture_region(es, &repaint); - glBindTexture(GL_TEXTURE_2D, es->texture); + glBindTexture(GL_TEXTURE_2D, es->textures[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); @@ -1229,7 +1264,7 @@ static void texture_set_subimage(struct weston_surface *surface, int32_t x, int32_t y, int32_t width, int32_t height) { - glBindTexture(GL_TEXTURE_2D, surface->texture); + glBindTexture(GL_TEXTURE_2D, surface->textures[0]); #ifdef GL_UNPACK_ROW_LENGTH /* Mesa does not define GL_EXT_unpack_subimage */ diff --git a/src/compositor.h b/src/compositor.h index 3722d32..0afab08 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -308,7 +308,8 @@ struct weston_region { struct weston_surface { struct wl_surface surface; struct weston_compositor *compositor; - GLuint texture; + GLuint textures[WL_BUFFER_MAX_PLANES]; + uint32_t num_textures; pixman_region32_t clip; pixman_region32_t damage; pixman_region32_t opaque; @@ -368,7 +369,8 @@ struct weston_surface { struct wl_list frame_callback_list; - EGLImageKHR image; + EGLImageKHR images[WL_BUFFER_MAX_PLANES]; + uint32_t num_images; struct wl_buffer *buffer; struct wl_listener buffer_destroy_listener; |