[gtk/snazzy-demo: 2/4] gl renderer: Fix render node texture cache
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/snazzy-demo: 2/4] gl renderer: Fix render node texture cache
- Date: Wed, 30 Sep 2020 14:26:53 +0000 (UTC)
commit e14d2be1e833c75aa48ba056464d4e23950864a9
Author: Alexander Larsson <alexl redhat com>
Date: Wed Sep 30 14:53:13 2020 +0200
gl renderer: Fix render node texture cache
We're caching two things, either a node itself being rendered, or a
parent storing a cached version of a child as rendered to an offscreen
the size and location of the parent.
If both the parent and child uses the cache this will cause a conflict in
the cache as it is currently use keying of a node pointer which will have
the same value for the node-as-itself and the child-node-of-the-parent.
We fix this by adding another part to the key "pointer_is_child" which means
we can have the same node pointer twice in the cache.
Additionally, in the child-is-rendered-offscreen case the offscreen
result actually depends on the position and size of the parent viewport,
so we need to store the parent bounds in that case.
gsk/gl/gskgldriver.c | 7 +++++--
gsk/gl/gskgldriverprivate.h | 2 ++
gsk/gl/gskglrenderer.c | 5 ++++-
3 files changed, 11 insertions(+), 3 deletions(-)
---
diff --git a/gsk/gl/gskgldriver.c b/gsk/gl/gskgldriver.c
index b1f8d6ea0e..6305add62c 100644
--- a/gsk/gl/gskgldriver.c
+++ b/gsk/gl/gskgldriver.c
@@ -587,7 +587,8 @@ texture_key_hash (gconstpointer v)
return GPOINTER_TO_UINT (k->pointer)
+ (guint)(k->scale*100)
- + (guint)k->filter;
+ + (guint)k->filter * 2 +
+ + (guint)k->pointer_is_child;
}
static gboolean
@@ -598,7 +599,9 @@ texture_key_equal (gconstpointer v1, gconstpointer v2)
return k1->pointer == k2->pointer &&
k1->scale == k2->scale &&
- k1->filter == k2->filter;
+ k1->filter == k2->filter &&
+ k1->pointer_is_child == k2->pointer_is_child &&
+ (!k1->pointer_is_child || graphene_rect_equal (&k1->parent_rect, &k2->parent_rect));
}
int
diff --git a/gsk/gl/gskgldriverprivate.h b/gsk/gl/gskgldriverprivate.h
index 0bf9ca89d2..7adf320057 100644
--- a/gsk/gl/gskgldriverprivate.h
+++ b/gsk/gl/gskgldriverprivate.h
@@ -25,6 +25,8 @@ typedef struct {
gpointer pointer;
float scale;
int filter;
+ int pointer_is_child;
+ graphene_rect_t parent_rect; /* Only set if pointer_is_child */
} GskTextureKey;
GskGLDriver * gsk_gl_driver_new (GdkGLContext *context);
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index 6efe62bca7..4cfe31535c 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -626,6 +626,7 @@ render_fallback_node (GskGLRenderer *self,
return;
key.pointer = node;
+ key.pointer_is_child = FALSE;
key.scale = scale;
key.filter = GL_NEAREST;
@@ -1922,6 +1923,7 @@ render_blur_node (GskGLRenderer *self,
}
key.pointer = node;
+ key.pointer_is_child = FALSE;
key.scale = ops_get_scale (builder);
key.filter = GL_NEAREST;
blurred_region.texture_id = gsk_gl_driver_get_texture_for_key (self->gl_driver, &key);
@@ -1982,6 +1984,7 @@ render_inset_shadow_node (GskGLRenderer *self,
texture_height = ceilf ((node_outline->bounds.size.height + blur_extra) * scale);
key.pointer = node;
+ key.pointer_is_child = FALSE;
key.scale = scale;
key.filter = GL_NEAREST;
blurred_texture_id = gsk_gl_driver_get_texture_for_key (self->gl_driver, &key);
@@ -3812,7 +3815,6 @@ add_offscreen_ops (GskGLRenderer *self,
(flags & FORCE_OFFSCREEN) == 0)
{
GdkTexture *texture = gsk_texture_node_get_texture (child_node);
-
upload_texture (self, texture, texture_region_out);
*is_offscreen = FALSE;
return TRUE;
@@ -3825,6 +3827,7 @@ add_offscreen_ops (GskGLRenderer *self,
/* Check if we've already cached the drawn texture. */
key.pointer = child_node;
+ key.pointer_is_child = TRUE; /* Don't conflict with the child using the cache too */
key.scale = ops_get_scale (builder);
key.filter = filter;
cached_id = gsk_gl_driver_get_texture_for_key (self->gl_driver, &key);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]