compositor: prepare for multi-planar surfaces.
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>
Fri, 20 Apr 2012 09:07:06 +0000 (11:07 +0200)
committerKristian Høgsberg <krh@bitplanet.net>
Tue, 10 Jul 2012 19:44:33 +0000 (15:44 -0400)
Make weston_surface::texture and ::surface an array, while keeping
[0] for RGB surfaces.

Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
src/compositor-drm.c
src/compositor.c
src/compositor.h

index 4dffa1d..f943ef3 100644 (file)
@@ -257,12 +257,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;
 
        bo = gbm_bo_create_from_egl_image(c->gbm,
                                          c->base.egl_display,
-                                         es->image,
+                                         es->images[0],
                                          es->geometry.width,
                                          es->geometry.height,
                                          GBM_BO_USE_SCANOUT);
@@ -567,7 +567,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))
@@ -591,7 +591,7 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
                return -1;
 
        bo = gbm_bo_create_from_egl_image(c->gbm, c->base.egl_display,
-                                         es->image, es->geometry.width,
+                                         es->images[0], es->geometry.width,
                                          es->geometry.height,
                                          GBM_BO_USE_SCANOUT);
        format = gbm_bo_get_format(bo);
index 678e0bd..4da2d55 100644 (file)
@@ -238,7 +238,6 @@ weston_surface_create(struct weston_compositor *compositor)
        surface->surface.resource.client = NULL;
 
        surface->compositor = compositor;
-       surface->image = EGL_NO_IMAGE_KHR;
        surface->alpha = 1.0;
        surface->blend = 1;
        surface->opaque_rect[0] = 0.0;
@@ -247,6 +246,9 @@ weston_surface_create(struct weston_compositor *compositor)
        surface->opaque_rect[3] = 0.0;
        surface->pitch = 1;
 
+       surface->num_textures = 0;
+       surface->num_images = 0;
+
        surface->buffer = NULL;
        surface->output = NULL;
 
@@ -661,6 +663,8 @@ weston_surface_unmap(struct weston_surface *surface)
 static void
 destroy_surface(struct wl_resource *resource)
 {
+       int i;
+
        struct weston_surface *surface =
                container_of(resource,
                             struct weston_surface, surface.resource);
@@ -669,15 +673,14 @@ destroy_surface(struct wl_resource *resource)
        if (weston_surface_is_mapped(surface))
                weston_surface_unmap(surface);
 
-       if (surface->texture)
-               glDeleteTextures(1, &surface->texture);
+       glDeleteTextures(surface->num_textures, surface->textures);
 
        if (surface->buffer)
                wl_list_remove(&surface->buffer_destroy_listener.link);
 
-       if (surface->image != EGL_NO_IMAGE_KHR)
+       for (i = 0; i < surface->num_images; i++)
                compositor->destroy_image(compositor->egl_display,
-                                         surface->image);
+                                         surface->images[i]);
 
        pixman_region32_fini(&surface->transform.boundingbox);
        pixman_region32_fini(&surface->damage);
@@ -701,10 +704,31 @@ weston_surface_destroy(struct weston_surface *surface)
 }
 
 static void
+ensure_textures(struct weston_surface *es, int num_textures)
+{
+       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;
        struct weston_compositor *ec = es->compositor;
+       int i;
 
        if (es->buffer) {
                weston_buffer_post_release(es->buffer);
@@ -716,14 +740,13 @@ weston_surface_attach(struct wl_surface *surface, struct wl_buffer *buffer)
        if (!buffer) {
                if (weston_surface_is_mapped(es))
                        weston_surface_unmap(es);
-               if (es->image != EGL_NO_IMAGE_KHR) {
-                       ec->destroy_image(ec->egl_display, es->image);
-                       es->image = NULL;
-               }
-               if (es->texture) {
-                       glDeleteTextures(1, &es->texture);
-                       es->texture = 0;
+               for (i = 0; i < es->num_images; i++) {
+                       ec->destroy_image(ec->egl_display, es->images[i]);
+                       es->images[i] = NULL;
                }
+               es->num_images = 0;
+               glDeleteTextures(es->num_textures, es->textures);
+               es->num_textures = 0;
                return;
        }
 
@@ -738,20 +761,12 @@ 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);
@@ -760,15 +775,19 @@ weston_surface_attach(struct wl_surface *surface, struct wl_buffer *buffer)
                else
                        es->blend = 1;
        } else {
-               if (es->image != EGL_NO_IMAGE_KHR)
-                       ec->destroy_image(ec->egl_display, es->image);
-               es->image = ec->create_image(ec->egl_display, NULL,
-                                            EGL_WAYLAND_BUFFER_WL,
-                                            buffer, NULL);
+               if (es->images[0] != EGL_NO_IMAGE_KHR)
+                       ec->destroy_image(ec->egl_display, es->images[0]);
+               es->images[0] = ec->create_image(ec->egl_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;
        }
 }
 
@@ -877,7 +896,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);
 
@@ -980,7 +999,7 @@ update_shm_texture(struct weston_surface *surface)
        int i, n;
 #endif
 
-       glBindTexture(GL_TEXTURE_2D, surface->texture);
+       glBindTexture(GL_TEXTURE_2D, surface->textures[0]);
 
        if (!surface->compositor->has_unpack_subimage) {
                glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
index 0d49dec..8e3225f 100644 (file)
@@ -385,7 +385,8 @@ enum {
 struct weston_surface {
        struct wl_surface surface;
        struct weston_compositor *compositor;
-       GLuint texture;
+       GLuint textures[3];
+       int num_textures;
        pixman_region32_t clip;
        pixman_region32_t damage;
        pixman_region32_t opaque;
@@ -446,7 +447,8 @@ struct weston_surface {
 
        struct wl_list frame_callback_list;
 
-       EGLImageKHR image;
+       EGLImageKHR images[3];
+       int num_images;
 
        struct wl_buffer *buffer;
        struct wl_listener buffer_destroy_listener;