[gtk/mask-nodes: 7/8] gl: Add a path cache
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/mask-nodes: 7/8] gl: Add a path cache
- Date: Wed, 16 Dec 2020 05:04:13 +0000 (UTC)
commit 9135288893acc11cf2a6f780a677d42287c4db0b
Author: Matthias Clasen <mclasen redhat com>
Date: Tue Dec 15 19:07:06 2020 -0500
gl: Add a path cache
This is very similar to the shadow cache.
We cache masks that we've rendered for paths,
including the fill rule and the stroke parameters
in the cache.
gsk/gl/gskglpathcache.c | 134 +++++++++++++++++++++++++++++++++++++++++
gsk/gl/gskglpathcacheprivate.h | 31 ++++++++++
gsk/meson.build | 1 +
3 files changed, 166 insertions(+)
---
diff --git a/gsk/gl/gskglpathcache.c b/gsk/gl/gskglpathcache.c
new file mode 100644
index 0000000000..0fdf0d45df
--- /dev/null
+++ b/gsk/gl/gskglpathcache.c
@@ -0,0 +1,134 @@
+#include "config.h"
+
+#include "gskglpathcacheprivate.h"
+#include "gskstrokeprivate.h"
+
+#define MAX_UNUSED_FRAMES (16 * 5)
+
+typedef struct
+{
+ GskPath *path;
+ GskFillRule fill_rule;
+ gboolean has_stroke;
+ GskStroke stroke;
+
+ graphene_rect_t bounds;
+ int texture_id;
+ int unused_frames;
+} CacheItem;
+
+void
+gsk_gl_path_cache_init (GskGLPathCache *self)
+{
+ self->textures = g_array_new (FALSE, TRUE, sizeof (CacheItem));
+}
+
+void
+gsk_gl_path_cache_free (GskGLPathCache *self,
+ GskGLDriver *gl_driver)
+{
+ guint i, p;
+
+ for (i = 0, p = self->textures->len; i < p; i ++)
+ {
+ const CacheItem *item = &g_array_index (self->textures, CacheItem, i);
+
+ gsk_gl_driver_destroy_texture (gl_driver, item->texture_id);
+ }
+
+ g_array_free (self->textures, TRUE);
+ self->textures = NULL;
+}
+
+void
+gsk_gl_path_cache_begin_frame (GskGLPathCache *self,
+ GskGLDriver *gl_driver)
+{
+ guint i, p;
+
+ for (i = 0, p = self->textures->len; i < p; i ++)
+ {
+ CacheItem *item = &g_array_index (self->textures, CacheItem, i);
+
+ if (item->unused_frames > MAX_UNUSED_FRAMES)
+ {
+ gsk_gl_driver_destroy_texture (gl_driver, item->texture_id);
+ g_array_remove_index_fast (self->textures, i);
+ p --;
+ i --;
+ }
+ else
+ {
+ item->unused_frames ++;
+ }
+ }
+}
+
+int
+gsk_gl_path_cache_get_texture_id (GskGLPathCache *self,
+ GskPath *path,
+ GskFillRule fill_rule,
+ const GskStroke *stroke,
+ graphene_rect_t *out_bounds)
+{
+ CacheItem *item = NULL;
+ guint i;
+
+ g_assert (self != NULL);
+
+ for (i = 0; i < self->textures->len; i ++)
+ {
+ CacheItem *k = &g_array_index (self->textures, CacheItem, i);
+
+ if (k->path == path &&
+ k->fill_rule == fill_rule &&
+ ((k->has_stroke && stroke && gsk_stroke_equal (&k->stroke, stroke)) ||
+ (!k->has_stroke && !stroke)))
+ {
+ item = k;
+ break;
+ }
+ }
+
+ if (item == NULL)
+ return 0;
+
+ item->unused_frames = 0;
+
+ g_assert (item->texture_id != 0);
+
+ *out_bounds = item->bounds;
+
+ return item->texture_id;
+}
+
+void
+gsk_gl_path_cache_commit (GskGLPathCache *self,
+ GskPath *path,
+ GskFillRule fill_rule,
+ const GskStroke *stroke,
+ int texture_id,
+ const graphene_rect_t *bounds)
+{
+ CacheItem *item;
+
+ g_assert (self != NULL);
+ g_assert (texture_id > 0);
+
+ g_array_set_size (self->textures, self->textures->len + 1);
+ item = &g_array_index (self->textures, CacheItem, self->textures->len - 1);
+
+ item->path = path;
+ item->fill_rule = fill_rule;
+ if (stroke)
+ {
+ item->has_stroke = TRUE;
+ gsk_stroke_init_copy (&item->stroke, stroke);
+ }
+ else
+ item->has_stroke = FALSE;
+
+ item->unused_frames = 0;
+ item->texture_id = texture_id;
+ item->bounds = *bounds;
+}
diff --git a/gsk/gl/gskglpathcacheprivate.h b/gsk/gl/gskglpathcacheprivate.h
new file mode 100644
index 0000000000..d56cacbc15
--- /dev/null
+++ b/gsk/gl/gskglpathcacheprivate.h
@@ -0,0 +1,31 @@
+#ifndef __GSK_GL_PATH_CACHE_H__
+#define __GSK_GL_PATH_CACHE_H__
+
+#include <glib.h>
+#include "gskgldriverprivate.h"
+#include "gskpath.h"
+
+typedef struct
+{
+ GArray *textures;
+} GskGLPathCache;
+
+
+void gsk_gl_path_cache_init (GskGLPathCache *self);
+void gsk_gl_path_cache_free (GskGLPathCache *self,
+ GskGLDriver *gl_driver);
+void gsk_gl_path_cache_begin_frame (GskGLPathCache *self,
+ GskGLDriver *gl_driver);
+int gsk_gl_path_cache_get_texture_id (GskGLPathCache *self,
+ GskPath *path,
+ GskFillRule fill_rule,
+ const GskStroke *stroke,
+ graphene_rect_t *out_bounds);
+void gsk_gl_path_cache_commit (GskGLPathCache *self,
+ GskPath *path,
+ GskFillRule fill_rule,
+ const GskStroke *stroke,
+ int texture_id,
+ const graphene_rect_t *bounds);
+
+#endif
diff --git a/gsk/meson.build b/gsk/meson.build
index f7f3894e23..e16cae8f4f 100644
--- a/gsk/meson.build
+++ b/gsk/meson.build
@@ -59,6 +59,7 @@ gsk_private_sources = files([
'gl/gskgliconcache.c',
'gl/opbuffer.c',
'gl/stb_rect_pack.c',
+ 'gl/gskglpathcache.c',
])
gsk_public_headers = files([
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]