diff --git a/gsk/meson.build b/gsk/meson.build index 20fd33185d..4f984bf58c 100644 --- a/gsk/meson.build +++ b/gsk/meson.build @@ -51,7 +51,7 @@ gsk_private_sources = files([ 'ngl/gsknglshadowlibrary.c', 'ngl/gskngltexturelibrary.c', 'ngl/gskngluniformstate.c', - 'ngl/gskngltexturepool.c', + 'ngl/gskngltexture.c', 'ngl/gskglprofiler.c', 'ngl/stb_rect_pack.c', 'ngl/fp16.c', diff --git a/gsk/ngl/gskngldriver.c b/gsk/ngl/gskngldriver.c index c1a37c0245..11974dfc23 100644 --- a/gsk/ngl/gskngldriver.c +++ b/gsk/ngl/gskngldriver.c @@ -38,7 +38,8 @@ #include "gskngliconlibraryprivate.h" #include "gsknglprogramprivate.h" #include "gsknglshadowlibraryprivate.h" -#include "gskngltexturepoolprivate.h" +#include "gskngltextureprivate.h" +#include "fp16private.h" #define ATLAS_SIZE 512 #define MAX_OLD_RATIO 0.5 @@ -102,6 +103,15 @@ gsk_ngl_texture_destroyed (gpointer data) ((GskNglTexture *)data)->user = NULL; } +static void +gsk_ngl_driver_autorelease_texture (GskNglDriver *self, + guint texture_id) +{ + g_assert (GSK_IS_NGL_DRIVER (self)); + + g_array_append_val (self->texture_pool, texture_id); +} + static guint gsk_ngl_driver_collect_unused_textures (GskNglDriver *self, gint64 watermark) @@ -131,9 +141,10 @@ gsk_ngl_driver_collect_unused_textures (GskNglDriver *self, g_assert (t->link.next == NULL); g_assert (t->link.data == t); - /* Steal this texture and put it back into the pool */ remove_texture_key_for_id (self, t->texture_id); - gsk_ngl_texture_pool_put (&self->texture_pool, t); + gsk_ngl_driver_autorelease_texture (self, t->texture_id); + t->texture_id = 0; + gsk_ngl_texture_free (t); } } @@ -268,7 +279,7 @@ gsk_ngl_driver_dispose (GObject *object) self->autorelease_framebuffers->len = 0; } - gsk_ngl_texture_pool_clear (&self->texture_pool); + g_clear_pointer (&self->texture_pool, g_array_unref); g_assert (!self->textures || g_hash_table_size (self->textures) == 0); g_assert (!self->texture_id_to_key || g_hash_table_size (self->texture_id_to_key) == 0); @@ -313,7 +324,7 @@ gsk_ngl_driver_init (GskNglDriver *self) g_free, NULL); self->shader_cache = g_hash_table_new_full (NULL, NULL, NULL, remove_program); - gsk_ngl_texture_pool_init (&self->texture_pool); + self->texture_pool = g_array_new (FALSE, FALSE, sizeof (guint)); self->render_targets = g_ptr_array_new (); self->atlases = g_ptr_array_new_with_free_func ((GDestroyNotify)gsk_ngl_texture_atlas_free); } @@ -634,7 +645,7 @@ gsk_ngl_driver_after_frame (GskNglDriver *self) GskNglRenderTarget *render_target = g_ptr_array_index (self->render_targets, self->render_targets->len - 1); gsk_ngl_driver_autorelease_framebuffer (self, render_target->framebuffer_id); - glDeleteTextures (1, &render_target->texture_id); + gsk_ngl_driver_autorelease_texture (self, render_target->texture_id); g_slice_free (GskNglRenderTarget, render_target); self->render_targets->len--; @@ -649,7 +660,12 @@ gsk_ngl_driver_after_frame (GskNglDriver *self) } /* Release any cached textures we used during the frame */ - gsk_ngl_texture_pool_clear (&self->texture_pool); + if (self->texture_pool->len > 0) + { + glDeleteTextures (self->texture_pool->len, + (GLuint *)(gpointer)self->texture_pool->data); + self->texture_pool->len = 0; + } /* Reset command queue to our shared queue incase we have operations * that need to be processed outside of a frame (such as callbacks @@ -825,16 +841,21 @@ gsk_ngl_driver_create_texture (GskNglDriver *self, int mag_filter) { GskNglTexture *texture; + guint texture_id; g_return_val_if_fail (GSK_IS_NGL_DRIVER (self), NULL); - texture = gsk_ngl_texture_pool_get (&self->texture_pool, - width, height, - min_filter, mag_filter); + texture_id = gsk_ngl_command_queue_create_texture (self->command_queue, + width, height, + min_filter, mag_filter); + texture = gsk_ngl_texture_new (texture_id, + width, height, + min_filter, mag_filter, + self->current_frame_id); g_hash_table_insert (self->textures, GUINT_TO_POINTER (texture->texture_id), texture); - texture->last_used_in_frame = self->current_frame_id; + return texture; } @@ -851,8 +872,8 @@ gsk_ngl_driver_create_texture (GskNglDriver *self, * to free additional VRAM back to the system. */ void -gsk_ngl_driver_release_texture (GskNglDriver *self, - GskNglTexture *texture) +gsk_ngl_driver_release_texture (GskNglDriver *self, + GskNglTexture *texture) { guint texture_id; @@ -860,12 +881,14 @@ gsk_ngl_driver_release_texture (GskNglDriver *self, g_assert (texture != NULL); texture_id = texture->texture_id; + texture->texture_id = 0; + gsk_ngl_texture_free (texture); if (texture_id > 0) remove_texture_key_for_id (self, texture_id); g_hash_table_steal (self->textures, GUINT_TO_POINTER (texture_id)); - gsk_ngl_texture_pool_put (&self->texture_pool, texture); + gsk_ngl_driver_autorelease_texture (self, texture_id); } /** diff --git a/gsk/ngl/gskngldriverprivate.h b/gsk/ngl/gskngldriverprivate.h index b5b5e60600..9d40c81b2b 100644 --- a/gsk/ngl/gskngldriverprivate.h +++ b/gsk/ngl/gskngldriverprivate.h @@ -24,7 +24,7 @@ #include #include "gskngltypesprivate.h" -#include "gskngltexturepoolprivate.h" +#include "gskngltextureprivate.h" G_BEGIN_DECLS @@ -99,12 +99,11 @@ struct _GskNglDriver GskNglCommandQueue *shared_command_queue; GskNglCommandQueue *command_queue; - GskNglTexturePool texture_pool; - GskNglGlyphLibrary *glyphs; GskNglIconLibrary *icons; GskNglShadowLibrary *shadows; + GArray *texture_pool; GHashTable *textures; GHashTable *key_to_texture_id; GHashTable *texture_id_to_key; diff --git a/gsk/ngl/gskngltexturepool.c b/gsk/ngl/gskngltexture.c similarity index 53% rename from gsk/ngl/gskngltexturepool.c rename to gsk/ngl/gskngltexture.c index c5a1d04c4e..5ee38f69b6 100644 --- a/gsk/ngl/gskngltexturepool.c +++ b/gsk/ngl/gskngltexture.c @@ -1,4 +1,4 @@ -/* gskngltexturepool.c +/* gskngltexture.c * * Copyright 2020 Christian Hergert * @@ -22,7 +22,7 @@ #include -#include "gskngltexturepoolprivate.h" +#include "gskngltextureprivate.h" #include "ninesliceprivate.h" void @@ -55,96 +55,6 @@ gsk_ngl_texture_free (GskNglTexture *texture) } } -void -gsk_ngl_texture_pool_init (GskNglTexturePool *self) -{ - g_queue_init (&self->queue); -} - -void -gsk_ngl_texture_pool_clear (GskNglTexturePool *self) -{ - guint *free_me = NULL; - guint *texture_ids; - guint i = 0; - - if G_LIKELY (self->queue.length <= 1024) - texture_ids = g_newa (guint, self->queue.length); - else - texture_ids = free_me = g_new (guint, self->queue.length); - - while (self->queue.length > 0) - { - GskNglTexture *head = g_queue_peek_head (&self->queue); - - g_queue_unlink (&self->queue, &head->link); - - texture_ids[i++] = head->texture_id; - head->texture_id = 0; - - gsk_ngl_texture_free (head); - } - - g_assert (self->queue.length == 0); - - if (i > 0) - glDeleteTextures (i, texture_ids); - - g_free (free_me); -} - -void -gsk_ngl_texture_pool_put (GskNglTexturePool *self, - GskNglTexture *texture) -{ - g_assert (self != NULL); - g_assert (texture != NULL); - g_assert (texture->user == NULL); - g_assert (texture->link.prev == NULL); - g_assert (texture->link.next == NULL); - g_assert (texture->link.data == texture); - - if (texture->permanent) - gsk_ngl_texture_free (texture); - else - g_queue_push_tail_link (&self->queue, &texture->link); -} - -GskNglTexture * -gsk_ngl_texture_pool_get (GskNglTexturePool *self, - int width, - int height, - int min_filter, - int mag_filter) -{ - GskNglTexture *texture; - - g_assert (self != NULL); - - texture = g_slice_new0 (GskNglTexture); - texture->link.data = texture; - texture->min_filter = min_filter; - texture->mag_filter = mag_filter; - - glGenTextures (1, &texture->texture_id); - - glActiveTexture (GL_TEXTURE0); - glBindTexture (GL_TEXTURE_2D, texture->texture_id); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); - 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 (gdk_gl_context_get_current ())) - 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); - - return texture; -} - GskNglTexture * gsk_ngl_texture_new (guint texture_id, int width, diff --git a/gsk/ngl/gskngltexturelibraryprivate.h b/gsk/ngl/gskngltexturelibraryprivate.h index 13e651e0d7..0ccf69a054 100644 --- a/gsk/ngl/gskngltexturelibraryprivate.h +++ b/gsk/ngl/gskngltexturelibraryprivate.h @@ -22,7 +22,7 @@ #define __GSK_NGL_TEXTURE_LIBRARY_PRIVATE_H__ #include "gskngltypesprivate.h" -#include "gskngltexturepoolprivate.h" +#include "gskngltextureprivate.h" #include "stb_rect_pack.h" diff --git a/gsk/ngl/gskngltexturepoolprivate.h b/gsk/ngl/gskngltextureprivate.h similarity index 72% rename from gsk/ngl/gskngltexturepoolprivate.h rename to gsk/ngl/gskngltextureprivate.h index 548fe83f4f..1d9052f625 100644 --- a/gsk/ngl/gskngltexturepoolprivate.h +++ b/gsk/ngl/gskngltextureprivate.h @@ -1,4 +1,4 @@ -/* gskngltexturepoolprivate.h +/* gskngltextureprivate.h * * Copyright 2020 Christian Hergert * @@ -18,18 +18,13 @@ * SPDX-License-Identifier: LGPL-2.1-or-later */ -#ifndef _GSK_NGL_TEXTURE_POOL_PRIVATE_H__ -#define _GSK_NGL_TEXTURE_POOL_PRIVATE_H__ +#ifndef _GSK_NGL_TEXTURE_PRIVATE_H__ +#define _GSK_NGL_TEXTURE_PRIVATE_H__ #include "gskngltypesprivate.h" G_BEGIN_DECLS -typedef struct _GskNglTexturePool -{ - GQueue queue; -} GskNglTexturePool; - struct _GskNglTextureSlice { cairo_rectangle_int_t rect; @@ -77,15 +72,6 @@ struct _GskNglTexture guint permanent : 1; }; -void gsk_ngl_texture_pool_init (GskNglTexturePool *self); -void gsk_ngl_texture_pool_clear (GskNglTexturePool *self); -GskNglTexture *gsk_ngl_texture_pool_get (GskNglTexturePool *self, - int width, - int height, - int min_filter, - int mag_filter); -void gsk_ngl_texture_pool_put (GskNglTexturePool *self, - GskNglTexture *texture); GskNglTexture *gsk_ngl_texture_new (guint texture_id, int width, int height, @@ -100,4 +86,4 @@ void gsk_ngl_texture_free (GskNglTexture G_END_DECLS -#endif /* _GSK_NGL_TEXTURE_POOL_PRIVATE_H__ */ +#endif /* _GSK_NGL_TEXTURE_PRIVATE_H__ */ diff --git a/gsk/ngl/ninesliceprivate.h b/gsk/ngl/ninesliceprivate.h index 5fa191db39..b2b787b0c1 100644 --- a/gsk/ngl/ninesliceprivate.h +++ b/gsk/ngl/ninesliceprivate.h @@ -22,7 +22,7 @@ #ifndef __NINE_SLICE_PRIVATE_H__ #define __NINE_SLICE_PRIVATE_H__ -#include "gskngltexturepoolprivate.h" +#include "gskngltextureprivate.h" #if 0 # define DEBUG_NINE_SLICE