[gtk/wip/baedert/transforms6: 4/31] gl renderer: Cache offscreen textures per node, not size
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/baedert/transforms6: 4/31] gl renderer: Cache offscreen textures per node, not size
- Date: Thu, 29 Nov 2018 08:08:44 +0000 (UTC)
commit c0cf592336370bcec95b60fde4cbe0fa5f067002
Author: Timm Bäder <mail baedert org>
Date: Wed Nov 28 18:40:48 2018 +0100
gl renderer: Cache offscreen textures per node, not size
gsk/gl/gskgldriver.c | 84 ++++++++++++++++++++++++++-------------------
gsk/gl/gskgldriverprivate.h | 5 +++
gsk/gl/gskglrenderer.c | 35 ++++++++++++++-----
3 files changed, 80 insertions(+), 44 deletions(-)
---
diff --git a/gsk/gl/gskgldriver.c b/gsk/gl/gskgldriver.c
index 2a2c980ce4..c88b93b52a 100644
--- a/gsk/gl/gskgldriver.c
+++ b/gsk/gl/gskgldriver.c
@@ -46,6 +46,7 @@ struct _GskGLDriver
Fbo default_fbo;
GHashTable *textures;
+ GHashTable *pointer_textures;
const Texture *bound_source_texture;
const Fbo *bound_fbo;
@@ -119,6 +120,7 @@ gsk_gl_driver_finalize (GObject *gobject)
gdk_gl_context_make_current (self->gl_context);
g_clear_pointer (&self->textures, g_hash_table_unref);
+ g_clear_pointer (&self->pointer_textures, g_hash_table_unref);
g_clear_object (&self->profiler);
if (self->gl_context == gdk_gl_context_get_current ())
@@ -263,7 +265,28 @@ gsk_gl_driver_collect_textures (GskGLDriver *self)
}
}
else
- g_hash_table_iter_remove (&iter);
+ {
+ /* Remove from self->pointer_textures. */
+ /* TODO: Is there a better way for this? */
+ if (self->pointer_textures)
+ {
+ GHashTableIter pointer_iter;
+ gpointer value;
+ gpointer p;
+
+ g_hash_table_iter_init (&pointer_iter, self->pointer_textures);
+ while (g_hash_table_iter_next (&pointer_iter, &p, &value))
+ {
+ if (GPOINTER_TO_INT (value) == t->texture_id)
+ {
+ g_hash_table_iter_remove (&pointer_iter);
+ break;
+ }
+ }
+ }
+
+ g_hash_table_iter_remove (&iter);
+ }
}
return old_size - g_hash_table_size (self->textures);
@@ -307,26 +330,6 @@ gsk_gl_driver_get_fbo (GskGLDriver *self,
return &t->fbo;
}
-static Texture *
-find_texture_by_size (GHashTable *textures,
- int width,
- int height)
-{
- GHashTableIter iter;
- gpointer value_p = NULL;
-
- g_hash_table_iter_init (&iter, textures);
- while (g_hash_table_iter_next (&iter, NULL, &value_p))
- {
- Texture *t = value_p;
-
- if (t->width == width && t->height == height)
- return t;
- }
-
- return NULL;
-}
-
static Texture *
create_texture (GskGLDriver *self,
float fwidth,
@@ -351,21 +354,7 @@ create_texture (GskGLDriver *self,
height = MIN (height, self->max_texture_size);
}
- t = find_texture_by_size (self->textures, width, height);
- if (t != NULL && !t->in_use && t->user == NULL)
- {
- GSK_NOTE (OPENGL, g_message ("Reusing Texture(%d) for size %dx%d",
- t->texture_id, t->width, t->height));
- t->in_use = TRUE;
-
-#ifdef G_ENABLE_DEBUG
- gsk_profiler_counter_inc (self->profiler, self->counters.reused_textures);
-#endif
- return t;
- }
-
glGenTextures (1, &texture_id);
-
t = texture_new ();
t->texture_id = texture_id;
t->width = width;
@@ -547,6 +536,31 @@ gsk_gl_driver_get_texture_for_texture (GskGLDriver *self,
return t->texture_id;
}
+int
+gsk_gl_driver_get_texture_for_pointer (GskGLDriver *self,
+ gpointer pointer)
+{
+ int id = 0;
+
+ if (G_UNLIKELY (self->pointer_textures == NULL))
+ self->pointer_textures = g_hash_table_new (NULL, NULL);
+
+ id = GPOINTER_TO_INT (g_hash_table_lookup (self->pointer_textures, pointer));
+
+ return id;
+}
+
+void
+gsk_gl_driver_set_texture_for_pointer (GskGLDriver *self,
+ gpointer pointer,
+ int texture_id)
+{
+ if (G_UNLIKELY (self->pointer_textures == NULL))
+ self->pointer_textures = g_hash_table_new (NULL, NULL);
+
+ g_hash_table_insert (self->pointer_textures, pointer, GINT_TO_POINTER (texture_id));
+}
+
int
gsk_gl_driver_create_permanent_texture (GskGLDriver *self,
float width,
diff --git a/gsk/gl/gskgldriverprivate.h b/gsk/gl/gskgldriverprivate.h
index 7d7a41fe28..8ceecb183a 100644
--- a/gsk/gl/gskgldriverprivate.h
+++ b/gsk/gl/gskgldriverprivate.h
@@ -33,6 +33,11 @@ int gsk_gl_driver_get_texture_for_texture (GskGLDriver *driver
GdkTexture *texture,
int min_filter,
int mag_filter);
+int gsk_gl_driver_get_texture_for_pointer (GskGLDriver *driver,
+ gpointer pointer);
+void gsk_gl_driver_set_texture_for_pointer (GskGLDriver *driver,
+ gpointer pointer,
+ int texture_id);
int gsk_gl_driver_create_permanent_texture (GskGLDriver *driver,
float width,
float height);
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index f8074a4531..a75f8b3823 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -2255,7 +2255,7 @@ add_offscreen_ops (GskGLRenderer *self,
float min_y,
float max_y,
GskRenderNode *child_node,
- int *texture_id,
+ int *texture_id_out,
gboolean *is_offscreen,
gboolean force_offscreen,
gboolean reset_clip)
@@ -2271,6 +2271,7 @@ add_offscreen_ops (GskGLRenderer *self,
graphene_rect_t prev_viewport;
graphene_matrix_t item_proj;
GskRoundedRect prev_clip;
+ int texture_id = 0;
/* We need the child node as a texture. If it already is one, we don't need to draw
* it on a framebuffer of course. */
@@ -2281,18 +2282,31 @@ add_offscreen_ops (GskGLRenderer *self,
get_gl_scaling_filters (child_node, &gl_min_filter, &gl_mag_filter);
- *texture_id = gsk_gl_driver_get_texture_for_texture (self->gl_driver,
- texture,
- gl_min_filter,
- gl_mag_filter);
+ *texture_id_out = gsk_gl_driver_get_texture_for_texture (self->gl_driver,
+ texture,
+ gl_min_filter,
+ gl_mag_filter);
*is_offscreen = FALSE;
return;
}
- *texture_id = gsk_gl_driver_create_texture (self->gl_driver, width, height);
- gsk_gl_driver_bind_source_texture (self->gl_driver, *texture_id);
- gsk_gl_driver_init_texture_empty (self->gl_driver, *texture_id);
- render_target = gsk_gl_driver_create_render_target (self->gl_driver, *texture_id, TRUE, TRUE);
+ /* Check if we've already cached the drawn texture. */
+ {
+ const int cached_id = gsk_gl_driver_get_texture_for_pointer (self->gl_driver, child_node);
+
+ if (cached_id != 0)
+ {
+ *texture_id_out = cached_id;
+ /* We didn't render it offscreen, but hand out an offscreen texture id */
+ *is_offscreen = TRUE;
+ return;
+ }
+ }
+
+ texture_id = gsk_gl_driver_create_texture (self->gl_driver, width, height);
+ gsk_gl_driver_bind_source_texture (self->gl_driver, texture_id);
+ gsk_gl_driver_init_texture_empty (self->gl_driver, texture_id);
+ render_target = gsk_gl_driver_create_render_target (self->gl_driver, texture_id, TRUE, TRUE);
graphene_matrix_init_ortho (&item_proj,
min_x * scale, max_x * scale,
@@ -2328,6 +2342,9 @@ add_offscreen_ops (GskGLRenderer *self,
ops_set_render_target (builder, prev_render_target);
*is_offscreen = TRUE;
+ *texture_id_out = texture_id;
+
+ gsk_gl_driver_set_texture_for_pointer (self->gl_driver, child_node, texture_id);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]