cursor-renderer/native: Unpremultiply for color state transformation
Without doing this, a non-linear color state transformation could result in premultiplied colour values larger than the alpha value, which manifested with artifacts such as parts of the cursor shining brighter than SDR white (with HDR enabled). This was reported in the GNOME Shell Matrix room on August 8th 2024, and I later hit it myself. v2: * Fix add_pipeline_snippet function formatting. (Sebastian Wick) Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4224>
This commit is contained in:
parent
c945826a69
commit
ad754af151
@ -89,6 +89,9 @@ struct _MetaCursorRendererNativePrivate
|
||||
gboolean input_disconnected;
|
||||
GMutex input_mutex;
|
||||
GCond input_cond;
|
||||
|
||||
CoglSnippet *premult_snippet;
|
||||
CoglSnippet *unpremult_snippet;
|
||||
};
|
||||
typedef struct _MetaCursorRendererNativePrivate MetaCursorRendererNativePrivate;
|
||||
|
||||
@ -183,6 +186,8 @@ meta_cursor_renderer_native_finalize (GObject *object)
|
||||
g_clear_signal_handler (&priv->texture_changed_handler_id,
|
||||
priv->current_cursor);
|
||||
g_clear_object (&priv->current_cursor);
|
||||
g_clear_object (&priv->premult_snippet);
|
||||
g_clear_object (&priv->unpremult_snippet);
|
||||
g_clear_handle_id (&priv->animation_timeout_id, g_source_remove);
|
||||
|
||||
G_OBJECT_CLASS (meta_cursor_renderer_native_parent_class)->finalize (object);
|
||||
@ -725,6 +730,40 @@ load_cursor_sprite_gbm_buffer_for_crtc (MetaCursorRendererNative *native,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
add_pipeline_snippet (CoglPipeline *pipeline,
|
||||
CoglSnippet **snippet,
|
||||
const char *snippet_source)
|
||||
{
|
||||
if (!*snippet)
|
||||
*snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, "",
|
||||
snippet_source);
|
||||
|
||||
cogl_pipeline_add_snippet (pipeline, *snippet);
|
||||
}
|
||||
|
||||
static void
|
||||
add_pipeline_premultiply (MetaCursorRendererNative *cursor_renderer_native,
|
||||
CoglPipeline *pipeline)
|
||||
{
|
||||
MetaCursorRendererNativePrivate *priv =
|
||||
meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
|
||||
|
||||
add_pipeline_snippet (pipeline, &priv->premult_snippet,
|
||||
" cogl_color_out.rgb *= cogl_color_out.a;\n");
|
||||
}
|
||||
|
||||
static void
|
||||
add_pipeline_unpremultiply (MetaCursorRendererNative *cursor_renderer_native,
|
||||
CoglPipeline *pipeline)
|
||||
{
|
||||
MetaCursorRendererNativePrivate *priv =
|
||||
meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
|
||||
|
||||
add_pipeline_snippet (pipeline, &priv->unpremult_snippet,
|
||||
" cogl_color_out.rgb /= cogl_color_out.a;\n");
|
||||
}
|
||||
|
||||
static CoglTexture *
|
||||
scale_and_transform_cursor_sprite_cpu (MetaCursorRendererNative *cursor_renderer_native,
|
||||
ClutterColorState *target_color_state,
|
||||
@ -772,11 +811,17 @@ scale_and_transform_cursor_sprite_cpu (MetaCursorRendererNative *cursor_renderer
|
||||
cogl_pipeline_set_layer_texture (pipeline, 0, src_texture);
|
||||
cogl_pipeline_set_layer_matrix (pipeline, 0, matrix);
|
||||
|
||||
if (cogl_texture_get_premultiplied (src_texture))
|
||||
add_pipeline_unpremultiply (cursor_renderer_native, pipeline);
|
||||
|
||||
color_state = meta_cursor_sprite_get_color_state (cursor_sprite);
|
||||
clutter_color_state_add_pipeline_transform (color_state,
|
||||
target_color_state,
|
||||
pipeline);
|
||||
|
||||
if (cogl_texture_get_premultiplied (dst_texture))
|
||||
add_pipeline_premultiply (cursor_renderer_native, pipeline);
|
||||
|
||||
cogl_framebuffer_clear4f (COGL_FRAMEBUFFER (offscreen),
|
||||
COGL_BUFFER_BIT_COLOR,
|
||||
0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
Loading…
x
Reference in New Issue
Block a user