diff --git a/clutter/clutter/clutter-color-manager-private.h b/clutter/clutter/clutter-color-manager-private.h new file mode 100644 index 000000000..9645ecaef --- /dev/null +++ b/clutter/clutter/clutter-color-manager-private.h @@ -0,0 +1,33 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Copyright (C) 2024 Red Hat + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + */ + +#pragma once + +#include "clutter/clutter-color-manager.h" +#include "clutter/clutter-private.h" + +CoglSnippet * clutter_color_manager_lookup_snippet (ClutterColorManager *color_manager, + const ClutterColorTransformKey *key); + +void clutter_color_manager_add_snippet (ClutterColorManager *color_manager, + const ClutterColorTransformKey *key, + CoglSnippet *snippet); diff --git a/clutter/clutter/clutter-color-manager.c b/clutter/clutter/clutter-color-manager.c index 77be36da2..c9d83175d 100644 --- a/clutter/clutter/clutter-color-manager.c +++ b/clutter/clutter/clutter-color-manager.c @@ -22,8 +22,9 @@ #include "config.h" -#include "clutter/clutter-color-manager.h" +#include "clutter/clutter-color-manager-private.h" +#include "clutter/clutter-color-state-private.h" #include "clutter/clutter-context.h" enum @@ -42,10 +43,22 @@ struct _ClutterColorManager GObject parent; ClutterContext *context; + + GHashTable *snippet_cache; }; G_DEFINE_FINAL_TYPE (ClutterColorManager, clutter_color_manager, G_TYPE_OBJECT) +static void +clutter_color_manager_finalize (GObject *object) +{ + ClutterColorManager *color_manager = CLUTTER_COLOR_MANAGER (object); + + g_clear_pointer (&color_manager->snippet_cache, g_hash_table_unref); + + G_OBJECT_CLASS (clutter_color_manager_parent_class)->finalize (object); +} + static void clutter_color_manager_set_property (GObject *object, guint prop_id, @@ -91,6 +104,7 @@ clutter_color_manager_class_init (ClutterColorManagerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->finalize = clutter_color_manager_finalize; object_class->set_property = clutter_color_manager_set_property; object_class->get_property = clutter_color_manager_get_property; @@ -112,4 +126,26 @@ clutter_color_manager_class_init (ClutterColorManagerClass *klass) static void clutter_color_manager_init (ClutterColorManager *color_manager) { + color_manager->snippet_cache = + g_hash_table_new_full (clutter_color_transform_key_hash, + clutter_color_transform_key_equal, + g_free, + g_object_unref); +} + +CoglSnippet * +clutter_color_manager_lookup_snippet (ClutterColorManager *color_manager, + const ClutterColorTransformKey *key) +{ + return g_hash_table_lookup (color_manager->snippet_cache, key); +} + +void +clutter_color_manager_add_snippet (ClutterColorManager *color_manager, + const ClutterColorTransformKey *key, + CoglSnippet *snippet) +{ + g_hash_table_insert (color_manager->snippet_cache, + g_memdup2 (key, sizeof (*key)), + g_object_ref (snippet)); } diff --git a/clutter/clutter/clutter-color-state-private.h b/clutter/clutter/clutter-color-state-private.h new file mode 100644 index 000000000..21b8519a7 --- /dev/null +++ b/clutter/clutter/clutter-color-state-private.h @@ -0,0 +1,42 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Copyright (C) 2024 Red Hat + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + */ + +#pragma once + +#include "clutter/clutter-color-state.h" + +typedef struct _ClutterColorTransformKey +{ + struct { + ClutterColorspace colorspace; + ClutterTransferFunction transfer_function; + } source; + struct { + ClutterColorspace colorspace; + ClutterTransferFunction transfer_function; + } target; +} ClutterColorTransformKey; + +guint clutter_color_transform_key_hash (gconstpointer data); + +gboolean clutter_color_transform_key_equal (gconstpointer data1, + gconstpointer data2); diff --git a/clutter/clutter/clutter-color-state.c b/clutter/clutter/clutter-color-state.c index d18b24033..546cbdb54 100644 --- a/clutter/clutter/clutter-color-state.c +++ b/clutter/clutter/clutter-color-state.c @@ -47,8 +47,9 @@ #include "config.h" -#include "clutter/clutter-color-state.h" +#include "clutter/clutter-color-state-private.h" +#include "clutter/clutter-color-manager-private.h" #include "clutter/clutter-debug.h" #include "clutter/clutter-enum-types.h" #include "clutter/clutter-private.h" @@ -81,86 +82,48 @@ struct _ClutterColorStatePrivate ClutterTransferFunction transfer_function; }; -typedef struct _SnippetCacheKey -{ - struct { - ClutterColorspace colorspace; - ClutterTransferFunction transfer_function; - } source; - struct { - ClutterColorspace colorspace; - ClutterTransferFunction transfer_function; - } target; -} SnippetCacheKey; - G_DEFINE_TYPE_WITH_PRIVATE (ClutterColorState, clutter_color_state, G_TYPE_OBJECT) -static GQuark snippet_cache_quark; - -static guint -snippet_cache_key_hash (gconstpointer key) +guint +clutter_color_transform_key_hash (gconstpointer data) { - const SnippetCacheKey *cache_key = key; + const ClutterColorTransformKey *key = data; - return (cache_key->source.colorspace ^ - cache_key->source.transfer_function ^ - cache_key->target.colorspace ^ - cache_key->target.transfer_function); + return (key->source.colorspace ^ + key->source.transfer_function ^ + key->target.colorspace ^ + key->target.transfer_function); } -static gboolean -snippet_cache_key_equal (gconstpointer key1, - gconstpointer key2) +gboolean +clutter_color_transform_key_equal (gconstpointer data1, + gconstpointer data2) { - const SnippetCacheKey *cache_key1 = key1; - const SnippetCacheKey *cache_key2 = key2; + const ClutterColorTransformKey *key1 = data1; + const ClutterColorTransformKey *key2 = data2; - return (cache_key1->source.colorspace == cache_key2->source.colorspace && - cache_key1->source.transfer_function == cache_key2->source.transfer_function && - cache_key1->target.colorspace == cache_key2->target.colorspace && - cache_key1->target.transfer_function == cache_key2->target.transfer_function); + return (key1->source.colorspace == key2->source.colorspace && + key1->source.transfer_function == key2->source.transfer_function && + key1->target.colorspace == key2->target.colorspace && + key1->target.transfer_function == key2->target.transfer_function); } static void -init_snippet_cache_key (SnippetCacheKey *cache_key, - ClutterColorState *color_state, - ClutterColorState *target_color_state) +clutter_color_transform_key_init (ClutterColorTransformKey *key, + ClutterColorState *color_state, + ClutterColorState *target_color_state) { ClutterColorStatePrivate *priv = clutter_color_state_get_instance_private (color_state); ClutterColorStatePrivate *target_priv = clutter_color_state_get_instance_private (target_color_state); - cache_key->source.colorspace = priv->colorspace; - cache_key->source.transfer_function = priv->transfer_function; - cache_key->target.colorspace = target_priv->colorspace; - cache_key->target.transfer_function = target_priv->transfer_function; -} - -static GHashTable * -ensure_snippet_cache (ClutterColorState *color_state) -{ - ClutterColorStatePrivate *priv = - clutter_color_state_get_instance_private (color_state); - GHashTable *snippet_cache; - - snippet_cache = g_object_get_qdata (G_OBJECT (priv->context), - snippet_cache_quark); - if (snippet_cache) - return snippet_cache; - - snippet_cache = g_hash_table_new_full (snippet_cache_key_hash, - snippet_cache_key_equal, - g_free, - g_object_unref); - g_object_set_qdata_full (G_OBJECT (priv->context), - snippet_cache_quark, - snippet_cache, - (GDestroyNotify) g_hash_table_unref); - - return snippet_cache; + key->source.colorspace = priv->colorspace; + key->source.transfer_function = priv->transfer_function; + key->target.colorspace = target_priv->colorspace; + key->target.transfer_function = target_priv->transfer_function; } static const char * @@ -345,9 +308,6 @@ clutter_color_state_class_init (ClutterColorStateClass *klass) G_PARAM_CONSTRUCT_ONLY); g_object_class_install_properties (gobject_class, N_PROPS, obj_props); - - snippet_cache_quark = - g_quark_from_static_string ("clutter-color-state-snippet-cache"); } static void @@ -737,8 +697,9 @@ CoglSnippet * clutter_color_state_get_transform_snippet (ClutterColorState *color_state, ClutterColorState *target_color_state) { - GHashTable *snippet_cache; - SnippetCacheKey cache_key; + ClutterColorStatePrivate *priv; + ClutterColorManager *color_manager; + ClutterColorTransformKey transform_key; CoglSnippet *snippet; const MatrixMultiplication *color_space_mapping = NULL; const TransferFunction *pre_transfer_function = NULL; @@ -749,9 +710,14 @@ clutter_color_state_get_transform_snippet (ClutterColorState *color_state, g_return_val_if_fail (CLUTTER_IS_COLOR_STATE (target_color_state), NULL); - init_snippet_cache_key (&cache_key, color_state, target_color_state); - snippet_cache = ensure_snippet_cache (color_state); - snippet = g_hash_table_lookup (snippet_cache, &cache_key); + priv = clutter_color_state_get_instance_private (color_state); + color_manager = clutter_context_get_color_manager (priv->context); + + clutter_color_transform_key_init (&transform_key, + color_state, + target_color_state); + snippet = clutter_color_manager_lookup_snippet (color_manager, + &transform_key); if (snippet) return g_object_ref (snippet); @@ -838,9 +804,9 @@ clutter_color_state_get_transform_snippet (ClutterColorState *color_state, cogl_snippet_set_capability (snippet, CLUTTER_PIPELINE_CAPABILITY, CLUTTER_PIPELINE_CAPABILITY_COLOR_STATE); - g_hash_table_insert (snippet_cache, - g_memdup2 (&cache_key, sizeof (cache_key)), - g_object_ref (snippet)); + clutter_color_manager_add_snippet (color_manager, + &transform_key, + g_object_ref (snippet)); return snippet; } diff --git a/clutter/clutter/clutter-context.c b/clutter/clutter/clutter-context.c index 0f2e46505..8c2c31729 100644 --- a/clutter/clutter/clutter-context.c +++ b/clutter/clutter/clutter-context.c @@ -346,3 +346,11 @@ clutter_context_get_pipeline_cache (ClutterContext *context) return priv->pipeline_cache; } + +ClutterColorManager * +clutter_context_get_color_manager (ClutterContext *context) +{ + ClutterContextPrivate *priv = clutter_context_get_instance_private (context); + + return priv->color_manager; +} diff --git a/clutter/clutter/clutter-context.h b/clutter/clutter/clutter-context.h index d4be1f631..3b4d152c6 100644 --- a/clutter/clutter/clutter-context.h +++ b/clutter/clutter/clutter-context.h @@ -68,3 +68,11 @@ ClutterTextDirection clutter_context_get_text_direction (ClutterContext *context CLUTTER_EXPORT ClutterPipelineCache * clutter_context_get_pipeline_cache (ClutterContext *clutter_context); + +/** + * clutter_context_get_color_manager: + * + * Returns: (transfer none): The %ClutterColorManager + */ +CLUTTER_EXPORT +ClutterColorManager * clutter_context_get_color_manager (ClutterContext *context); diff --git a/clutter/clutter/clutter-private.h b/clutter/clutter/clutter-private.h index 48cfef25d..affc79f7e 100644 --- a/clutter/clutter/clutter-private.h +++ b/clutter/clutter/clutter-private.h @@ -72,6 +72,8 @@ typedef struct _ClutterContext ClutterContext; * because it will break for negative numbers. */ #define CLUTTER_NEARBYINT(x) ((int) ((x) < 0.0f ? (x) - 0.5f : (x) + 0.5f)) +typedef struct _ClutterColorTransformKey ClutterColorTransformKey; + typedef enum { CLUTTER_ACTOR_UNUSED_FLAG = 0,