[gtk/wip/matthiasc/shared-glyph-cache] Make the icon cache shared too
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/matthiasc/shared-glyph-cache] Make the icon cache shared too
- Date: Tue, 4 Jun 2019 02:54:00 +0000 (UTC)
commit 86023b095381a50ea6d43b3c3c86b71363e8db6e
Author: Matthias Clasen <mclasen redhat com>
Date: Tue Jun 4 02:49:14 2019 +0000
Make the icon cache shared too
Use the same approach to the icon cache
that works for the glyph cache already.
gsk/gl/gskgliconcache.c | 108 +++++++++++++++++++++++++++++++-------
gsk/gl/gskgliconcacheprivate.h | 6 +--
gsk/gl/gskglrenderer.c | 25 +++++++--
gsk/gl/gskgltextureatlas.c | 1 -
gsk/gl/gskgltextureatlasprivate.h | 1 -
5 files changed, 112 insertions(+), 29 deletions(-)
---
diff --git a/gsk/gl/gskgliconcache.c b/gsk/gl/gskgliconcache.c
index 2ed2e568c5..6a4890d560 100644
--- a/gsk/gl/gskgliconcache.c
+++ b/gsk/gl/gskgliconcache.c
@@ -27,42 +27,54 @@ free_atlas (gpointer v)
{
GskGLTextureAtlas *atlas = v;
- g_assert (atlas->image.texture_id == 0);
gsk_gl_texture_atlas_free (atlas);
g_free (atlas);
}
-void
-gsk_gl_icon_cache_init (GskGLIconCache *self,
- GskRenderer *renderer,
- GskGLDriver *gl_driver)
+GskGLIconCache *
+gsk_gl_icon_cache_new (GdkDisplay *display)
{
- self->renderer = renderer;
- self->gl_driver = gl_driver;
+ GskGLIconCache *self;
+
+ self = g_new0 (GskGLIconCache, 1);
+
+ self->display = display;
self->atlases = g_ptr_array_new_with_free_func ((GDestroyNotify)free_atlas);
self->icons = g_hash_table_new_full (NULL, NULL, NULL, icon_data_free);
+
+ return self;
+}
+
+static GdkGLContext *
+get_context (GskGLIconCache *cache)
+{
+ return (GdkGLContext *)g_object_get_data (G_OBJECT (cache->display), "shared_data_gl_context");
}
void
gsk_gl_icon_cache_free (GskGLIconCache *self)
{
+ GdkGLContext *context = get_context (self);
guint i, p;
+ gdk_gl_context_make_current (context);
+
for (i = 0, p = self->atlases->len; i < p; i ++)
{
GskGLTextureAtlas *atlas = g_ptr_array_index (self->atlases, i);
- if (atlas->image.texture_id != 0)
+ if (atlas->texture_id != 0)
{
- gsk_gl_image_destroy (&atlas->image, self->gl_driver);
- atlas->image.texture_id = 0;
+ glDeleteTextures (1, &atlas->texture_id);
+ atlas->texture_id = 0;
}
}
g_ptr_array_free (self->atlases, TRUE);
-
g_hash_table_unref (self->icons);
+
+ g_free (self);
}
void
@@ -72,6 +84,7 @@ gsk_gl_icon_cache_begin_frame (GskGLIconCache *self)
GHashTableIter iter;
GdkTexture *texture;
IconData *icon_data;
+ GdkGLContext *previous = NULL;
/* Increase frame age of all icons */
g_hash_table_iter_init (&iter, self->icons);
@@ -108,16 +121,23 @@ gsk_gl_icon_cache_begin_frame (GskGLIconCache *self)
g_hash_table_iter_remove (&iter);
}
- if (atlas->image.texture_id != 0)
+ if (atlas->texture_id != 0)
{
- gsk_gl_image_destroy (&atlas->image, self->gl_driver);
- atlas->image.texture_id = 0;
+ previous = gdk_gl_context_get_current ();
+ if (previous != get_context (self))
+ gdk_gl_context_make_current (get_context (self));
+
+ glDeleteTextures (1, &atlas->texture_id);
+ atlas->texture_id = 0;
}
g_ptr_array_remove_index_fast (self->atlases, i);
i --; /* Check the current index again */
}
}
+
+ if (previous)
+ gdk_gl_context_make_current (previous);
}
/* FIXME: this could probably be done more efficiently */
@@ -150,6 +170,58 @@ pad_surface (cairo_surface_t *surface)
return padded;
}
+static guint
+create_shared_texture (GskGLIconCache *self,
+ int width,
+ int height)
+{
+ GdkGLContext *previous;
+ GdkGLContext *context;
+ guint texture_id;
+
+ previous = gdk_gl_context_get_current ();
+ context = get_context (self);
+
+ gdk_gl_context_make_current (context);
+
+ glGenTextures (1, &texture_id);
+ glBindTexture (GL_TEXTURE_2D, texture_id);
+
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ if (gdk_gl_context_get_use_es (context))
+ glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ else
+ glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
+
+ glBindTexture (GL_TEXTURE_2D, 0);
+
+ gdk_gl_context_make_current (previous);
+
+ return texture_id;
+}
+
+static void
+upload_region_or_else (GskGLIconCache *self,
+ guint texture_id,
+ GskImageRegion *region)
+{
+ GdkGLContext *previous;
+
+ previous = gdk_gl_context_get_current ();
+ gdk_gl_context_make_current (get_context (self));
+
+ glBindTexture (GL_TEXTURE_2D, texture_id);
+ glTextureSubImage2D (texture_id, 0, region->x, region->y, region->width, region->height,
+ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, region->data);
+
+ gdk_gl_context_make_current (previous);
+}
+
void
gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
GdkTexture *texture,
@@ -170,7 +242,7 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
icon_data->used = TRUE;
}
- *out_texture_id = icon_data->atlas->image.texture_id;
+ *out_texture_id = icon_data->atlas->texture_id;
*out_texture_rect = icon_data->texture_rect;
return;
}
@@ -208,7 +280,7 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
/* No atlas has enough space, so create a new one... */
atlas = g_malloc (sizeof (GskGLTextureAtlas));
gsk_gl_texture_atlas_init (atlas, ATLAS_SIZE, ATLAS_SIZE);
- gsk_gl_image_create (&atlas->image, self->gl_driver, atlas->width, atlas->height, GL_LINEAR,
GL_LINEAR);
+ atlas->texture_id = create_shared_texture (self, atlas->width, atlas->height);
/* Pack it onto that one, which surely has enought space... */
gsk_gl_texture_atlas_pack (atlas, twidth + 2, theight + 2, &packed_x, &packed_y);
packed_x += 1;
@@ -238,9 +310,9 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
region.height = theight + 2;
region.data = cairo_image_surface_get_data (padded_surface);
- gsk_gl_image_upload_region (&atlas->image, self->gl_driver, ®ion);
+ upload_region_or_else (self, atlas->texture_id, ®ion);
- *out_texture_id = atlas->image.texture_id;
+ *out_texture_id = atlas->texture_id;
*out_texture_rect = icon_data->texture_rect;
cairo_surface_destroy (surface);
diff --git a/gsk/gl/gskgliconcacheprivate.h b/gsk/gl/gskgliconcacheprivate.h
index 883a274ded..36f30087fa 100644
--- a/gsk/gl/gskgliconcacheprivate.h
+++ b/gsk/gl/gskgliconcacheprivate.h
@@ -10,17 +10,15 @@
typedef struct
{
+ GdkDisplay *display;
GskGLDriver *gl_driver;
- GskRenderer *renderer;
GPtrArray *atlases;
GHashTable *icons; /* GdkTexture -> IconData */
} GskGLIconCache;
-void gsk_gl_icon_cache_init (GskGLIconCache *self,
- GskRenderer *renderer,
- GskGLDriver *gl_driver);
+GskGLIconCache * gsk_gl_icon_cache_new (GdkDisplay *display);
void gsk_gl_icon_cache_free (GskGLIconCache *self);
void gsk_gl_icon_cache_begin_frame (GskGLIconCache *self);
void gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index 75a8e2969f..a090340f59 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -336,7 +336,7 @@ struct _GskGLRenderer
GArray *render_ops;
GskGLGlyphCache *glyph_cache;
- GskGLIconCache icon_cache;
+ GskGLIconCache *icon_cache;
GskGLShadowCache shadow_cache;
#ifdef G_ENABLE_DEBUG
@@ -832,7 +832,7 @@ render_texture_node (GskGLRenderer *self,
{
graphene_rect_t trect;
- gsk_gl_icon_cache_lookup_or_add (&self->icon_cache,
+ gsk_gl_icon_cache_lookup_or_add (self->icon_cache,
texture,
&texture_id,
&trect);
@@ -2479,6 +2479,21 @@ get_glyph_cache_for_display (GdkDisplay *display)
return glyph_cache;
}
+static GskGLIconCache *
+get_icon_cache_for_display (GdkDisplay *display)
+{
+ GskGLIconCache *icon_cache;
+
+ icon_cache = (GskGLIconCache*)g_object_get_data (G_OBJECT (display), "gl-icon-cache");
+ if (icon_cache == NULL)
+ {
+ icon_cache = gsk_gl_icon_cache_new (display);
+ g_object_set_data_full (G_OBJECT (display), "gl-icon-cache", icon_cache, (GDestroyNotify)
gsk_gl_icon_cache_free);
+ }
+
+ return icon_cache;
+}
+
static gboolean
gsk_gl_renderer_realize (GskRenderer *renderer,
GdkSurface *surface,
@@ -2510,7 +2525,7 @@ gsk_gl_renderer_realize (GskRenderer *renderer,
return FALSE;
self->glyph_cache = get_glyph_cache_for_display (gdk_surface_get_display (surface));
- gsk_gl_icon_cache_init (&self->icon_cache, renderer, self->gl_driver);
+ self->icon_cache = get_icon_cache_for_display (gdk_surface_get_display (surface));
gsk_gl_shadow_cache_init (&self->shadow_cache);
return TRUE;
@@ -2536,7 +2551,7 @@ gsk_gl_renderer_unrealize (GskRenderer *renderer)
glDeleteProgram (self->programs[i].id);
self->glyph_cache = NULL;
- gsk_gl_icon_cache_free (&self->icon_cache);
+ self->icon_cache = NULL;
gsk_gl_shadow_cache_free (&self->shadow_cache, self->gl_driver);
g_clear_object (&self->gl_profiler);
@@ -3103,7 +3118,7 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
graphene_matrix_scale (&projection, 1, -1, 1);
gsk_gl_glyph_cache_begin_frame (self->glyph_cache);
- gsk_gl_icon_cache_begin_frame (&self->icon_cache);
+ gsk_gl_icon_cache_begin_frame (self->icon_cache);
gsk_gl_shadow_cache_begin_frame (&self->shadow_cache, self->gl_driver);
ops_set_projection (&self->op_builder, &projection);
diff --git a/gsk/gl/gskgltextureatlas.c b/gsk/gl/gskgltextureatlas.c
index 370f97bd89..7befcfbbe3 100644
--- a/gsk/gl/gskgltextureatlas.c
+++ b/gsk/gl/gskgltextureatlas.c
@@ -10,7 +10,6 @@ gsk_gl_texture_atlas_init (GskGLTextureAtlas *self,
memset (self, 0, sizeof (*self));
self->texture_id = 0;
- self->image.texture_id = 0;
self->width = width;
self->height = height;
diff --git a/gsk/gl/gskgltextureatlasprivate.h b/gsk/gl/gskgltextureatlasprivate.h
index d780b13395..cfa865446d 100644
--- a/gsk/gl/gskgltextureatlasprivate.h
+++ b/gsk/gl/gskgltextureatlasprivate.h
@@ -15,7 +15,6 @@ struct _GskGLTextureAtlas
int height;
guint texture_id;
- GskGLImage image;
int unused_pixels; /* Pixels of rects that have been used at some point,
But are now unused. */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]