[gtk+/wip/otte/vulkan: 28/28] vulkan: Implement texture caching



commit 22b9d305aa1e1980309f553360f42b19de4d8982
Author: Benjamin Otte <otte redhat com>
Date:   Fri Dec 9 07:23:04 2016 +0100

    vulkan: Implement texture caching
    
    And with this change, the GPU looks bored again.

 gsk/gskvulkanrenderer.c        |   73 ++++++++++++++++++++++++++++++++++++++++
 gsk/gskvulkanrendererprivate.h |    6 +++
 gsk/gskvulkanrenderpass.c      |   13 ++-----
 3 files changed, 83 insertions(+), 9 deletions(-)
---
diff --git a/gsk/gskvulkanrenderer.c b/gsk/gskvulkanrenderer.c
index 2f71dc0..0e6a04b 100644
--- a/gsk/gskvulkanrenderer.c
+++ b/gsk/gskvulkanrenderer.c
@@ -15,6 +15,14 @@
 
 #include <graphene.h>
 
+typedef struct _GskVulkanTextureData GskVulkanTextureData;
+
+struct _GskVulkanTextureData {
+  GskTexture *texture;
+  GskVulkanImage *image;
+  GskVulkanRenderer *renderer;
+};
+
 #ifdef G_ENABLE_DEBUG
 typedef struct {
   GQuark cpu_time;
@@ -35,6 +43,8 @@ struct _GskVulkanRenderer
 
   GskVulkanRender *render;
 
+  GSList *textures;
+
 #ifdef G_ENABLE_DEBUG
   ProfileTimers profile_timers;
 #endif
@@ -133,6 +143,16 @@ gsk_vulkan_renderer_unrealize (GskRenderer *renderer)
 {
   GskVulkanRenderer *self = GSK_VULKAN_RENDERER (renderer);
   VkDevice device;
+  GSList *l;
+
+  for (l = self->textures; l; l = l->next)
+    {
+      GskVulkanTextureData *data = l->data;
+
+      data->renderer = NULL;
+      gsk_texture_clear_render_data (data->texture);
+    }
+  g_clear_pointer (&self->textures, (GDestroyNotify) g_slist_free);
 
   g_clear_pointer (&self->render, gsk_vulkan_render_free);
 
@@ -237,3 +257,56 @@ gsk_vulkan_renderer_init (GskVulkanRenderer *self)
   self->profile_timers.cpu_time = gsk_profiler_add_timer (profiler, "cpu-time", "CPU time", FALSE, TRUE);
 #endif
 }
+
+static void
+gsk_vulkan_renderer_clear_texture (gpointer p)
+{
+  GskVulkanTextureData *data = p;
+
+  if (data->renderer != NULL)
+    data->renderer->textures = g_slist_remove (data->renderer->textures, data);
+
+  g_object_unref (data->image);
+
+  g_slice_free (GskVulkanTextureData, data);
+}
+
+GskVulkanImage *
+gsk_vulkan_renderer_ref_texture_image (GskVulkanRenderer *self,
+                                       GskTexture        *texture,
+                                       VkCommandBuffer    command_buffer)
+{
+  GskVulkanTextureData *data;
+  cairo_surface_t *surface;
+  GskVulkanImage *image;
+
+  data = gsk_texture_get_render_data (texture, self);
+  if (data)
+    return g_object_ref (data->image);
+
+  surface = gsk_texture_download (texture);
+  image = gsk_vulkan_image_new_from_data (self->vulkan,
+                                          command_buffer,
+                                          cairo_image_surface_get_data (surface),
+                                          cairo_image_surface_get_width (surface),
+                                          cairo_image_surface_get_height (surface),
+                                          cairo_image_surface_get_stride (surface));
+  cairo_surface_destroy (surface);
+
+  data = g_slice_new0 (GskVulkanTextureData);
+  data->image = image;
+  data->texture = texture;
+  data->renderer = self;
+
+  if (gsk_texture_set_render_data (texture, self, data, gsk_vulkan_renderer_clear_texture))
+    {
+      g_object_ref (data->image);
+      self->textures = g_slist_prepend (self->textures, data);
+    }
+  else
+    {
+      g_slice_free (GskVulkanTextureData, data);
+    }
+
+  return image;
+}
diff --git a/gsk/gskvulkanrendererprivate.h b/gsk/gskvulkanrendererprivate.h
index a4a07f4..c3485f7 100644
--- a/gsk/gskvulkanrendererprivate.h
+++ b/gsk/gskvulkanrendererprivate.h
@@ -4,6 +4,8 @@
 #include <vulkan/vulkan.h>
 #include <gsk/gskrenderer.h>
 
+#include "gsk/gskvulkanimageprivate.h"
+
 G_BEGIN_DECLS
 
 #define GSK_TYPE_VULKAN_RENDERER (gsk_vulkan_renderer_get_type ())
@@ -19,6 +21,10 @@ typedef struct _GskVulkanRendererClass           GskVulkanRendererClass;
 
 GType gsk_vulkan_renderer_get_type (void) G_GNUC_CONST;
 
+GskVulkanImage *        gsk_vulkan_renderer_ref_texture_image           (GskVulkanRenderer      *self,
+                                                                         GskTexture             *texture,
+                                                                         VkCommandBuffer         
command_buffer);
+
 G_END_DECLS
 
 #endif /* __GSK_VULKAN_RENDERER_PRIVATE_H__ */
diff --git a/gsk/gskvulkanrenderpass.c b/gsk/gskvulkanrenderpass.c
index 8f9f12b..1d493b1 100644
--- a/gsk/gskvulkanrenderpass.c
+++ b/gsk/gskvulkanrenderpass.c
@@ -5,7 +5,7 @@
 #include "gskvulkanimageprivate.h"
 #include "gskrendernodeprivate.h"
 #include "gskrenderer.h"
-#include "gsktextureprivate.h"
+#include "gskvulkanrendererprivate.h"
 
 typedef struct _GskVulkanRenderOp GskVulkanRenderOp;
 
@@ -170,15 +170,10 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
 
         case GSK_VULKAN_OP_TEXTURE:
           {
-            cairo_surface_t *surface = gsk_texture_download (gsk_render_node_get_texture (op->node));
-            op->source = gsk_vulkan_image_new_from_data (self->vulkan,
-                                                         command_buffer,
-                                                         cairo_image_surface_get_data (surface),
-                                                         cairo_image_surface_get_width (surface),
-                                                         cairo_image_surface_get_height (surface),
-                                                         cairo_image_surface_get_stride (surface));
+            op->source = gsk_vulkan_renderer_ref_texture_image (GSK_VULKAN_RENDERER 
(gsk_vulkan_render_get_renderer (render)),
+                                                                gsk_render_node_get_texture (op->node),
+                                                                command_buffer);
             gsk_vulkan_render_add_cleanup_image (render, op->source);
-            cairo_surface_destroy (surface);
           }
           break;
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]