pepper: keep buffer reference until buffer release
authorJunghoon <jh13.son@samsung.com>
Wed, 14 Oct 2015 10:51:07 +0000 (19:51 +0900)
committerJunghoon <jh13.son@samsung.com>
Thu, 15 Oct 2015 01:51:33 +0000 (10:51 +0900)
    - and generate textures on flush_surface_damage()

Change-Id: I5dae68a8ef4a1b2af03ba332724260a9d5b18146

src/lib/pepper/pepper-internal.h
src/lib/pepper/surface.c
src/lib/render/gl-renderer.c

index 411e98d2d18d89f4c585235e9013e979e868c723..1b2e36fc7db080d9a14f158e30c08d64a83de9bd 100644 (file)
@@ -151,6 +151,7 @@ struct pepper_surface
 
     struct {
         pepper_buffer_t         *buffer;
+        pepper_event_listener_t *release_listener;
         pepper_event_listener_t *destroy_listener;
         int32_t                  x, y;
         int32_t                  transform;
index 4987da05a3bebdd2f6a7d73721bbe917e76c915f..6736da034c50c48eba3becad13e6a71c4489694f 100644 (file)
@@ -41,6 +41,14 @@ surface_state_handle_buffer_destroy(pepper_event_listener_t *listener,
     state->buffer = NULL;
 }
 
+static void
+surface_handle_buffer_release(pepper_event_listener_t *listener,
+                              pepper_object_t *object, uint32_t id, void *info, void *data)
+{
+    pepper_surface_t *surface = data;
+    surface->buffer.buffer = NULL;
+}
+
 static void
 surface_handle_buffer_destroy(pepper_event_listener_t *listener,
                               pepper_object_t *object, uint32_t id, void *info, void *data)
@@ -369,6 +377,7 @@ pepper_surface_commit(pepper_surface_t *surface)
         if (surface->buffer.buffer)
         {
             pepper_buffer_unreference(surface->buffer.buffer);
+            pepper_event_listener_remove(surface->buffer.release_listener);
             pepper_event_listener_remove(surface->buffer.destroy_listener);
         }
 
@@ -376,6 +385,12 @@ pepper_surface_commit(pepper_surface_t *surface)
         {
             pepper_event_listener_remove(surface->pending.buffer_destroy_listener);
             pepper_buffer_reference(surface->pending.buffer);
+
+            surface->buffer.release_listener =
+                pepper_object_add_event_listener(&surface->pending.buffer->base,
+                                                 PEPPER_EVENT_BUFFER_RELEASE, 0,
+                                                 surface_handle_buffer_release, surface);
+
             surface->buffer.destroy_listener =
                 pepper_object_add_event_listener(&surface->pending.buffer->base,
                                                  PEPPER_EVENT_OBJECT_DESTROY, 0,
@@ -531,6 +546,5 @@ pepper_surface_flush_damage(pepper_surface_t *surface)
     {
         pepper_buffer_unreference(surface->buffer.buffer);
         pepper_event_listener_remove(surface->buffer.destroy_listener);
-        surface->buffer.buffer = NULL;
     }
 }
index b23c45059f8d795f6c5c32368c9482cca9c7823e..ab08f8d59a9e9fcbcc48d57820f18ea9eb97b76a 100644 (file)
@@ -561,9 +561,7 @@ surface_state_attach_shm(gl_surface_state_t *state, pepper_buffer_t *buffer)
     state->shm.pixel_format = pixel_format;
     state->shm.pitch        = pitch;
 
-    surface_state_ensure_textures(state, 1);
-
-    state->sampler = sampler;
+    state->sampler          = sampler;
 
     return PEPPER_TRUE;
 }
@@ -574,67 +572,12 @@ surface_state_attach_egl(gl_surface_state_t *state, pepper_buffer_t *buffer)
     gl_renderer_t      *gr = state->renderer;
     EGLDisplay          display = gr->display;
     struct wl_resource *resource = pepper_buffer_get_resource(buffer);
-    int                 num_planes;
-    int                 sampler;
-    EGLint              attribs[3];
-    int                 texture_format;
-    int                 i;
-
-    if (!gr->query_buffer(display, resource, EGL_TEXTURE_FORMAT, &texture_format))
-        return PEPPER_FALSE;
-
-    switch (texture_format)
-    {
-    case EGL_TEXTURE_RGB:
-        sampler = GL_SHADER_SAMPLER_RGBX;
-        num_planes = 1;
-        break;
-    case EGL_TEXTURE_RGBA:
-        sampler = GL_SHADER_SAMPLER_RGBA;
-        num_planes = 1;
-        break;
-    case EGL_TEXTURE_Y_UV_WL:
-        sampler = GL_SHADER_SAMPLER_Y_UV;
-        num_planes = 2;
-        break;
-    case EGL_TEXTURE_Y_U_V_WL:
-        sampler = GL_SHADER_SAMPLER_Y_U_V;
-        num_planes = 3;
-        break;
-    case EGL_TEXTURE_Y_XUXV_WL:
-        sampler = GL_SHADER_SAMPLER_Y_XUXV;
-        num_planes = 2;
-        break;
-    default:
-        PEPPER_ERROR("unknown EGL buffer format.\n");
-        return PEPPER_FALSE;
-    }
-
-    if (state->buffer_type != BUFFER_TYPE_EGL || num_planes != state->num_planes)
-        surface_state_ensure_textures(state, num_planes);
-
-    attribs[0] = EGL_WAYLAND_PLANE_WL;
-    attribs[2] = EGL_NONE;
-
-    for (i = 0; i < num_planes; i++)
-    {
-        attribs[1] = i;
-        state->images[i] = gr->create_image(display, NULL, EGL_WAYLAND_BUFFER_WL,
-                                            resource, attribs);
-
-        PEPPER_ASSERT(state->images[i] != EGL_NO_IMAGE_KHR);
-
-        glActiveTexture(GL_TEXTURE0 + i);
-        glBindTexture(GL_TEXTURE_2D, state->textures[i]);
-        gr->image_target_texture_2d(GL_TEXTURE_2D, state->images[i]);
-    }
 
     gr->query_buffer(display, resource, EGL_WIDTH, &state->buffer_width);
     gr->query_buffer(display, resource, EGL_HEIGHT, &state->buffer_height);
     gr->query_buffer(display, resource, EGL_WAYLAND_Y_INVERTED_WL, &state->y_inverted);
 
     state->buffer_type = BUFFER_TYPE_EGL;
-    state->sampler = sampler;
 
     return PEPPER_TRUE;
 }
@@ -696,11 +639,73 @@ gl_renderer_flush_surface_damage(pepper_renderer_t *renderer, pepper_surface_t *
     gl_surface_state_t *state = get_surface_state(renderer, surface);
 
     if (!state->buffer)
-        goto done;
+        return PEPPER_FALSE;
+
+    if (state->buffer_type == BUFFER_TYPE_EGL)
+    {
+        int                 num_planes;
+        int                 sampler;
+        EGLint              attribs[3];
+        int                 texture_format;
+        int                 i;
+        EGLDisplay          display = gr->display;
+        struct wl_resource *resource = pepper_buffer_get_resource(state->buffer);
+
+        if (!gr->query_buffer(display, resource, EGL_TEXTURE_FORMAT, &texture_format))
+            return PEPPER_FALSE;
+
+        switch (texture_format)
+        {
+        case EGL_TEXTURE_RGB:
+            sampler = GL_SHADER_SAMPLER_RGBX;
+            num_planes = 1;
+            break;
+        case EGL_TEXTURE_RGBA:
+            sampler = GL_SHADER_SAMPLER_RGBA;
+            num_planes = 1;
+            break;
+        case EGL_TEXTURE_Y_UV_WL:
+            sampler = GL_SHADER_SAMPLER_Y_UV;
+            num_planes = 2;
+            break;
+        case EGL_TEXTURE_Y_U_V_WL:
+            sampler = GL_SHADER_SAMPLER_Y_U_V;
+            num_planes = 3;
+            break;
+        case EGL_TEXTURE_Y_XUXV_WL:
+            sampler = GL_SHADER_SAMPLER_Y_XUXV;
+            num_planes = 2;
+            break;
+        default:
+            PEPPER_ERROR("unknown EGL buffer format.\n");
+            return PEPPER_FALSE;
+        }
+
+        if (num_planes != state->num_planes)
+            surface_state_ensure_textures(state, num_planes);
+
+        attribs[0] = EGL_WAYLAND_PLANE_WL;
+        attribs[2] = EGL_NONE;
+
+        for (i = 0; i < num_planes; i++)
+        {
+            attribs[1] = i;
+            state->images[i] = gr->create_image(display, NULL, EGL_WAYLAND_BUFFER_WL,
+                                                resource, attribs);
 
-    if (state->buffer_type != BUFFER_TYPE_SHM)
+            PEPPER_ASSERT(state->images[i] != EGL_NO_IMAGE_KHR);
+
+            glActiveTexture(GL_TEXTURE0 + i);
+            glBindTexture(GL_TEXTURE_2D, state->textures[i]);
+            gr->image_target_texture_2d(GL_TEXTURE_2D, state->images[i]);
+        }
+
+        state->sampler = sampler;
         goto done;
+    }
 
+    /* state->buffer_type == BUFFER_TYPE_SHM */
+    surface_state_ensure_textures(state, 1);
     glBindTexture(GL_TEXTURE_2D, state->textures[0]);
 
     if (!gr->has_unpack_subimage)