pepper: flush_surface_damage() returns keep_buffer flag 76/52376/1
authorTaekyun Kim <tkq.kim@samsung.com>
Wed, 18 Nov 2015 05:24:54 +0000 (14:24 +0900)
committerTaekyun Kim <tkq.kim@samsung.com>
Mon, 23 Nov 2015 05:48:42 +0000 (14:48 +0900)
keep_buffer flag is used for telling the pepper core that the buffer is no
longer required (by maintaining a copy of it). If no output wants to keep
the buffer, pepper core can safely unreference the buffer.

Change-Id: I13fccfba6f9cacb08c6619a56fb1ff03ad95883a

src/lib/drm/drm-output.c
src/lib/fbdev/fbdev-output.c
src/lib/pepper/pepper-internal.h
src/lib/pepper/pepper-output-backend.h
src/lib/pepper/surface.c
src/lib/render/gl-renderer.c
src/lib/render/pixman-renderer.c
src/lib/wayland/wayland-output.c
src/lib/x11/x11-output.c

index 008aaeb..196b14f 100644 (file)
@@ -525,9 +525,22 @@ drm_output_attach_surface(void *o, pepper_surface_t *surface, int *w, int *h)
 }
 
 static void
-drm_output_flush_surface_damage(void *o, pepper_surface_t *surface)
+drm_output_flush_surface_damage(void *o, pepper_surface_t *surface, pepper_bool_t *keep_buffer)
 {
-    pepper_renderer_flush_surface_damage(((drm_output_t *)o)->renderer, surface);
+    drm_output_t    *output = o;
+    pepper_buffer_t *buffer = pepper_surface_get_buffer(surface);
+
+    pepper_renderer_flush_surface_damage(output->renderer, surface);
+
+    if (output->render_type == DRM_RENDER_TYPE_PIXMAN ||
+        (buffer && !wl_shm_buffer_get(pepper_buffer_get_resource(buffer))))
+    {
+        *keep_buffer = PEPPER_TRUE;
+    }
+    else
+    {
+        *keep_buffer = PEPPER_FALSE;
+    }
 }
 
 struct pepper_output_backend drm_output_backend =
index 35e52d9..68998e2 100644 (file)
@@ -242,9 +242,10 @@ fbdev_output_attach_surface(void *o, pepper_surface_t *surface, int *w, int *h)
 }
 
 static void
-fbdev_output_flush_surface_damage(void *o, pepper_surface_t *surface)
+fbdev_output_flush_surface_damage(void *o, pepper_surface_t *surface, pepper_bool_t *keep_buffer)
 {
     pepper_renderer_flush_surface_damage(((fbdev_output_t *)o)->renderer, surface);
+    *keep_buffer = PEPPER_TRUE;
 }
 
 struct pepper_output_backend fbdev_output_backend =
index 2769a1c..f03f06c 100644 (file)
@@ -191,12 +191,11 @@ struct pepper_surface
 
     struct {
         pepper_buffer_t         *buffer;
-        pepper_event_listener_t *release_listener;
+        pepper_bool_t            has_ref;
         pepper_event_listener_t *destroy_listener;
         int32_t                  x, y;
         int32_t                  transform;
         int32_t                  scale;
-        pepper_bool_t            flushed;
     } buffer;
 
     /* Surface size in surface local coordinate space.
index f42c8f6..88c2dd9 100644 (file)
@@ -55,7 +55,8 @@ struct pepper_output_backend
     void            (*start_repaint_loop)(void *output);
     void            (*repaint)(void *output, const pepper_list_t *plane_list);
     void            (*attach_surface)(void *output, pepper_surface_t *surface, int *w, int *h);
-    void            (*flush_surface_damage)(void *output, pepper_surface_t *surface);
+    void            (*flush_surface_damage)(void *output, pepper_surface_t *surface,
+                                            pepper_bool_t *keep_buffer);
 };
 
 PEPPER_API pepper_output_t *
index e12c807..7d54bab 100644 (file)
@@ -70,16 +70,6 @@ surface_state_handle_buffer_destroy(pepper_event_listener_t *listener,
 }
 
 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;
-    pepper_event_listener_remove(listener);
-    pepper_event_listener_remove(surface->buffer.destroy_listener);
-}
-
-static void
 surface_handle_buffer_destroy(pepper_event_listener_t *listener,
                               pepper_object_t *object, uint32_t id, void *info, void *data)
 {
@@ -364,7 +354,6 @@ pepper_surface_destroy(pepper_surface_t *surface)
     if (surface->buffer.buffer)
     {
         pepper_event_listener_remove(surface->buffer.destroy_listener);
-        pepper_event_listener_remove(surface->buffer.release_listener);
         pepper_buffer_unreference(surface->buffer.buffer);
     }
 
@@ -413,9 +402,8 @@ pepper_surface_commit(pepper_surface_t *surface)
         if (surface->buffer.buffer)
         {
             pepper_event_listener_remove(surface->buffer.destroy_listener);
-            pepper_event_listener_remove(surface->buffer.release_listener);
 
-            if (!surface->buffer.flushed)
+            if (surface->buffer.has_ref)
                 pepper_buffer_unreference(surface->buffer.buffer);
         }
 
@@ -423,11 +411,7 @@ 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.has_ref  = PEPPER_TRUE;
 
             surface->buffer.destroy_listener =
                 pepper_object_add_event_listener(&surface->pending.buffer->base,
@@ -438,7 +422,6 @@ pepper_surface_commit(pepper_surface_t *surface)
         surface->buffer.buffer   = surface->pending.buffer;
         surface->buffer.x       += surface->pending.x;
         surface->buffer.y       += surface->pending.y;
-        surface->buffer.flushed  = PEPPER_FALSE;
 
         surface->pending.newly_attached = PEPPER_FALSE;
         surface->pending.buffer = NULL;
@@ -595,6 +578,7 @@ pepper_surface_flush_damage(pepper_surface_t *surface)
 {
     pepper_view_t      *view;
     pepper_output_t    *output;
+    pepper_bool_t       release_buffer = PEPPER_TRUE;
 
     if (!pixman_region32_not_empty(&surface->damage_region))
         return;
@@ -603,13 +587,20 @@ pepper_surface_flush_damage(pepper_surface_t *surface)
         pepper_view_surface_damage(view);
 
     pepper_list_for_each(output, &surface->compositor->output_list, link)
-        output->backend->flush_surface_damage(output->data, surface);
+    {
+        pepper_bool_t keep_buffer;
+
+        output->backend->flush_surface_damage(output->data, surface, &keep_buffer);
+
+        if (keep_buffer)
+            release_buffer = PEPPER_FALSE;
+    }
 
     pixman_region32_clear(&surface->damage_region);
 
-    if (surface->buffer.buffer)
+    if (surface->buffer.buffer && release_buffer)
     {
         pepper_buffer_unreference(surface->buffer.buffer);
-        surface->buffer.flushed = PEPPER_TRUE;
+        surface->buffer.has_ref = PEPPER_FALSE;
     }
 }
index cbd03f4..843d86f 100644 (file)
@@ -466,7 +466,6 @@ surface_state_release_buffer(gl_surface_state_t *state)
 
     if (state->buffer)
     {
-        pepper_buffer_unreference(state->buffer);
         pepper_event_listener_remove(state->buffer_destroy_listener);
         state->buffer = NULL;
     }
@@ -634,7 +633,6 @@ done:
 
     if (state->buffer)
     {
-        pepper_buffer_reference(state->buffer);
         state->buffer_destroy_listener =
             pepper_object_add_event_listener((pepper_object_t *)buffer,
                                              PEPPER_EVENT_OBJECT_DESTROY, 0,
@@ -766,9 +764,7 @@ surface_state_flush_shm(gl_surface_state_t *state)
         wl_shm_buffer_end_access(state->shm.buffer);
     }
 
-    pepper_buffer_unreference(state->buffer);
     state->buffer = NULL;
-
     return PEPPER_TRUE;
 }
 
index 8e93747..3077e03 100644 (file)
@@ -90,7 +90,6 @@ surface_state_release_buffer(pixman_surface_state_t *state)
 
     if (state->buffer)
     {
-        pepper_buffer_unreference(state->buffer);
         pepper_event_listener_remove(state->buffer_destroy_listener);
         state->buffer = NULL;
     }
@@ -217,7 +216,6 @@ done:
 
     if (state->buffer)
     {
-        pepper_buffer_reference(state->buffer);
         state->buffer_destroy_listener =
             pepper_object_add_event_listener((pepper_object_t *)buffer,
                                              PEPPER_EVENT_OBJECT_DESTROY, 0,
index 2479f64..dfb5b66 100644 (file)
@@ -239,9 +239,22 @@ wayland_output_attach_surface(void *o, pepper_surface_t *surface, int *w, int *h
 }
 
 static void
-wayland_output_flush_surface_damage(void *o, pepper_surface_t *surface)
+wayland_output_flush_surface_damage(void *o, pepper_surface_t *surface, pepper_bool_t *keep_buffer)
 {
-    pepper_renderer_flush_surface_damage(((wayland_output_t *)o)->renderer, surface);
+    wayland_output_t   *output = o;
+    pepper_buffer_t    *buffer = pepper_surface_get_buffer(surface);
+
+    pepper_renderer_flush_surface_damage(output->renderer, surface);
+
+    if (output->renderer == output->conn->pixman_renderer ||
+        (buffer && !wl_shm_buffer_get(pepper_buffer_get_resource(buffer))))
+    {
+        *keep_buffer = PEPPER_TRUE;
+    }
+    else
+    {
+        *keep_buffer = PEPPER_FALSE;
+    }
 }
 
 static const pepper_output_backend_t wayland_output_backend =
index 6e9bfd6..74c62d8 100644 (file)
@@ -537,9 +537,22 @@ x11_output_attach_surface(void *o, pepper_surface_t *surface, int *w, int *h)
 }
 
 static void
-x11_output_flush_surface_damage(void *o, pepper_surface_t *surface)
+x11_output_flush_surface_damage(void *o, pepper_surface_t *surface, pepper_bool_t *keep_buffer)
 {
-    pepper_renderer_flush_surface_damage(((x11_output_t *)o)->renderer, surface);
+    x11_output_t    *output = o;
+    pepper_buffer_t *buffer = pepper_surface_get_buffer(surface);
+
+    pepper_renderer_flush_surface_damage(output->renderer, surface);
+
+    if (output->renderer == output->connection->pixman_renderer ||
+        (buffer && !wl_shm_buffer_get(pepper_buffer_get_resource(buffer))))
+    {
+        *keep_buffer = PEPPER_TRUE;
+    }
+    else
+    {
+        *keep_buffer = PEPPER_FALSE;
+    }
 }
 
 /* X11 output backend to export for PePPer core */