compositor/multi-texture-format: Cache snippets

These snippets are retrieved anew every time a window is resized. But
callers never modify them, they're effectively read-only so cache them
at the place of creation.

This is required to convince the pipeline hash that each reuse of the
same snippet really is the same snippet and so the pipeline is unchanged.
`CoglPipelineSnippetList` only does shallow comparisons and there's no
need right now to reimplement it as a deep comparison.

This eliminates the log message:

> Over 50 separate %s have been generated which is very unusual,
> so something is probably wrong!

which isn't actually a leak but more a warning about wasting time.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/6958
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3224>
This commit is contained in:
Daniel van Vugt 2023-08-30 16:59:59 +08:00 committed by Robert Mader
parent 6427b5b1f6
commit 7c8f1b4cc0

View File

@ -93,6 +93,8 @@ typedef struct _MetaMultiTextureFormatInfo
/* Shaders */
const char *rgb_shader; /* Shader to convert to RGBA (or NULL) */
GOnce snippet_once;
} MetaMultiTextureFormatInfo;
/* NOTE: The actual enum values are used as the index, so you don't need to
@ -109,6 +111,7 @@ static MetaMultiTextureFormatInfo multi_format_table[] = {
.hsub = { 1 },
.vsub = { 1 },
.rgb_shader = rgba_shader,
.snippet_once = G_ONCE_INIT,
},
/* Packed YUV */
{
@ -119,6 +122,7 @@ static MetaMultiTextureFormatInfo multi_format_table[] = {
.hsub = { 1, 2 },
.vsub = { 1, 1 },
.rgb_shader = y_xuxv_shader,
.snippet_once = G_ONCE_INIT,
},
/* 2 plane YUV */
{
@ -129,6 +133,7 @@ static MetaMultiTextureFormatInfo multi_format_table[] = {
.hsub = { 1, 2 },
.vsub = { 1, 2 },
.rgb_shader = nv12_shader,
.snippet_once = G_ONCE_INIT,
},
/* 3 plane YUV */
{
@ -139,6 +144,7 @@ static MetaMultiTextureFormatInfo multi_format_table[] = {
.hsub = { 1, 2, 2 },
.vsub = { 1, 2, 2 },
.rgb_shader = yuv420_shader,
.snippet_once = G_ONCE_INIT,
},
};
@ -198,6 +204,25 @@ meta_multi_texture_format_get_subsampling_factors (MetaMultiTextureFormat forma
}
}
static gpointer
create_globals_snippet (gpointer data)
{
return cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT_GLOBALS,
shader_global_conversions,
NULL);
}
static gpointer
create_format_snippet (gpointer data)
{
MetaMultiTextureFormat format =
(MetaMultiTextureFormat) GPOINTER_TO_INT (data);
return cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
NULL,
multi_format_table[format].rgb_shader);
}
gboolean
meta_multi_texture_format_get_snippets (MetaMultiTextureFormat format,
CoglSnippet **fragment_globals_snippet,
@ -210,18 +235,21 @@ meta_multi_texture_format_get_snippets (MetaMultiTextureFormat format,
if (fragment_globals_snippet)
{
*fragment_globals_snippet =
cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT_GLOBALS,
shader_global_conversions,
NULL);
static GOnce globals_once = G_ONCE_INIT;
CoglSnippet *globals_snippet;
globals_snippet = g_once (&globals_once, create_globals_snippet, NULL);
*fragment_globals_snippet = cogl_object_ref (globals_snippet);
}
if (fragment_snippet)
{
*fragment_snippet =
cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
NULL,
multi_format_table[format].rgb_shader);
CoglSnippet *format_snippet;
format_snippet = g_once (&multi_format_table[format].snippet_once,
create_format_snippet,
GINT_TO_POINTER (format));
*fragment_snippet = cogl_object_ref (format_snippet);
}
return TRUE;