[gtk+/wip/otte/vulkan: 62/62] vulkan: Implement texture caching
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/vulkan: 62/62] vulkan: Implement texture caching
- Date: Fri, 9 Dec 2016 17:40:09 +0000 (UTC)
commit f52dd125693c7518e3788af951dece0d8f0777f0
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]