cogl/snippet: Add way to add an opaque capability

A snippet is assigned a capability, which is then transferred to the
pipeline it gets added to. Managers of pipelines can then check whether
a pipeline it got handed whether it has a certain capability, and if
not, handle the situation where it is not.

The intention is to allow Clutter to tag color state transformation
snippets with a capability, allowing generic paint nodes to handle color
transformations when needed.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3433>
This commit is contained in:
Jonas Ådahl 2024-05-27 11:16:04 +02:00 committed by Sebastian Wick
parent b7291cfe48
commit f67ace517f
8 changed files with 125 additions and 0 deletions

View File

@ -623,6 +623,8 @@ _cogl_pipeline_layer_add_vertex_snippet (CoglPipeline *pipeline,
_cogl_pipeline_snippet_list_add (&layer->big_state->vertex_snippets,
snippet);
cogl_pipeline_add_capability_from_snippet (pipeline, snippet);
/* If we weren't previously the authority on this state then we need
* to extended our differences mask and so it's possible that some
* of our ancestry will now become redundant, so we aim to reparent
@ -659,6 +661,8 @@ _cogl_pipeline_layer_add_fragment_snippet (CoglPipeline *pipeline,
_cogl_pipeline_snippet_list_add (&layer->big_state->fragment_snippets,
snippet);
cogl_pipeline_add_capability_from_snippet (pipeline, snippet);
/* If we weren't previously the authority on this state then we need
* to extended our differences mask and so it's possible that some
* of our ancestry will now become redundant, so we aim to reparent

View File

@ -323,6 +323,10 @@ struct _CoglPipeline
* and corresponding authorities_cache_dirty:1 bitfield
*/
/* Array of opaque capabilities tagged by owners of pipelines.
*/
GArray *capabilities;
/* bitfields */
/* Weak pipelines don't count as dependants on their parents which
@ -783,3 +787,7 @@ _cogl_pipeline_get_layer_state_for_fragment_codegen (CoglContext *context);
CoglPipelineState
_cogl_pipeline_get_state_for_fragment_codegen (CoglContext *context);
void
cogl_pipeline_add_capability_from_snippet (CoglPipeline *pipeline,
CoglSnippet *snippet);

View File

@ -1146,6 +1146,8 @@ _cogl_pipeline_add_vertex_snippet (CoglPipeline *pipeline,
_cogl_pipeline_snippet_list_add (&pipeline->big_state->vertex_snippets,
snippet);
cogl_pipeline_add_capability_from_snippet (pipeline, snippet);
}
static void
@ -1163,6 +1165,8 @@ _cogl_pipeline_add_fragment_snippet (CoglPipeline *pipeline,
_cogl_pipeline_snippet_list_add (&pipeline->big_state->fragment_snippets,
snippet);
cogl_pipeline_add_capability_from_snippet (pipeline, snippet);
}
void

View File

@ -45,6 +45,7 @@
#include "cogl/cogl-util.h"
#include "cogl/cogl-profile.h"
#include "cogl/cogl-depth-state-private.h"
#include "cogl/cogl-snippet-private.h"
#include "cogl/cogl1-context.h"
#include <glib.h>
@ -154,6 +155,8 @@ cogl_pipeline_dispose (GObject *object)
recursively_free_layer_caches (pipeline);
g_clear_pointer (&pipeline->capabilities, g_array_unref);
G_OBJECT_CLASS (cogl_pipeline_parent_class)->dispose (object);
}
@ -329,6 +332,9 @@ _cogl_pipeline_copy (CoglPipeline *src, gboolean is_weak)
pipeline->dirty_real_blend_enable = src->dirty_real_blend_enable;
pipeline->unknown_color_alpha = src->unknown_color_alpha;
if (src->capabilities)
pipeline->capabilities = g_array_copy (src->capabilities);
/* XXX:
* consider generalizing the idea of "cached" properties. These
* would still have an authority like other sparse properties but
@ -2792,3 +2798,60 @@ cogl_pipeline_get_uniform_location (CoglPipeline *pipeline,
return ctx->n_uniform_names++;
}
typedef struct
{
GQuark domain;
unsigned int capability;
} CapabilityEntry;
static void
cogl_pipeline_add_capability (CoglPipeline *pipeline,
GQuark domain,
unsigned int capability)
{
CapabilityEntry entry = {
.domain = domain,
.capability = capability,
};
if (!pipeline->capabilities)
pipeline->capabilities = g_array_new (FALSE, FALSE, sizeof (entry));
g_array_append_val (pipeline->capabilities, entry);
}
void
cogl_pipeline_add_capability_from_snippet (CoglPipeline *pipeline,
CoglSnippet *snippet)
{
GQuark capability_domain;
unsigned int capability;
if (cogl_snippet_get_capability (snippet, &capability_domain, &capability))
cogl_pipeline_add_capability (pipeline, capability_domain, capability);
}
gboolean
cogl_pipeline_has_capability (CoglPipeline *pipeline,
GQuark domain,
unsigned int capability)
{
int i;
if (!pipeline->capabilities)
return FALSE;
for (i = 0; i < pipeline->capabilities->len; i++)
{
CapabilityEntry *entry = &g_array_index (pipeline->capabilities,
CapabilityEntry,
i);
if (entry->domain == domain &&
entry->capability == capability)
return TRUE;
}
return FALSE;
}

View File

@ -155,4 +155,9 @@ COGL_EXPORT int
cogl_pipeline_get_uniform_location (CoglPipeline *pipeline,
const char *uniform_name);
COGL_EXPORT gboolean
cogl_pipeline_has_capability (CoglPipeline *pipeline,
GQuark domain,
unsigned int capability);
G_END_DECLS

View File

@ -66,7 +66,15 @@ struct _CoglSnippet
char *pre;
char *replace;
char *post;
GQuark capability_domain;
unsigned int capability;
};
void
_cogl_snippet_make_immutable (CoglSnippet *snippet);
gboolean
cogl_snippet_get_capability (CoglSnippet *snippet,
GQuark *domain,
unsigned int *capability);

View File

@ -194,3 +194,31 @@ _cogl_snippet_make_immutable (CoglSnippet *snippet)
{
snippet->immutable = TRUE;
}
void
cogl_snippet_set_capability (CoglSnippet *snippet,
GQuark domain,
unsigned int capability)
{
g_return_if_fail (!snippet->capability_domain);
snippet->capability_domain = domain;
snippet->capability = capability;
}
gboolean
cogl_snippet_get_capability (CoglSnippet *snippet,
GQuark *domain,
unsigned int *capability)
{
if (snippet->capability_domain)
{
*domain = snippet->capability_domain;
*capability = snippet->capability;
return TRUE;
}
else
{
return FALSE;
}
}

View File

@ -622,4 +622,9 @@ cogl_snippet_set_post (CoglSnippet *snippet,
COGL_EXPORT const char *
cogl_snippet_get_post (CoglSnippet *snippet);
COGL_EXPORT void
cogl_snippet_set_capability (CoglSnippet *snippet,
GQuark domain,
unsigned int capability);
G_END_DECLS