summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>2012-04-20 11:07:06 +0200
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>2012-04-27 16:27:28 +0200
commita77150b3bed630b612d2652ad3f6a06326e9886c (patch)
tree9aaa37ec6a87e3b3a85ab45f5c3bb357ada2c065
parent7890c4d36dbec14d44109ead6fb12adfece47a7b (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.c14
-rw-r--r--src/compositor.c87
-rw-r--r--src/compositor.h6
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;