From 9f548efd32489b7b276528c83d92fa5c12f7d2a0 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 3 Aug 2024 19:21:29 -0400 Subject: [PATCH] gsk: Change color op apis Make color-related ops take the ccs and a GdkColor, and make decisions about color conversion on the cpu vs the gpu. This makes the node processor code simpler, and lets use convert the color directly into the op instance without extra copying. We also pass opacity to the op, so it can be applied when we write the color into the instance. Lastly, rorder the offset to come right after the opacity argument. Treat the color and rounded color ops the same way. Update all callers. With this, the prepare_color apis in gskgpunodeprocessor.c are no longer used and have been dropped. --- gsk/gpu/gskgpucolorop.c | 14 +-- gsk/gpu/gskgpucoloropprivate.h | 8 +- gsk/gpu/gskgpucolorstatesprivate.h | 10 +++ gsk/gpu/gskgpunodeprocessor.c | 119 ++++++++++++++++---------- gsk/gpu/gskgpuroundedcolorop.c | 14 +-- gsk/gpu/gskgpuroundedcoloropprivate.h | 8 +- gsk/gpu/gskgpushaderopprivate.h | 13 ++- 7 files changed, 123 insertions(+), 63 deletions(-) diff --git a/gsk/gpu/gskgpucolorop.c b/gsk/gpu/gskgpucolorop.c index 9e8dcea329..2ac5a625db 100644 --- a/gsk/gpu/gskgpucolorop.c +++ b/gsk/gpu/gskgpucolorop.c @@ -53,16 +53,20 @@ static const GskGpuShaderOpClass GSK_GPU_COLOR_OP_CLASS = { void gsk_gpu_color_op (GskGpuFrame *frame, GskGpuShaderClip clip, - GskGpuColorStates color_states, - const graphene_rect_t *rect, + GdkColorState *ccs, + float opacity, const graphene_point_t *offset, - const float color[4]) + const graphene_rect_t *rect, + const GdkColor *color) { GskGpuColorInstance *instance; + GdkColorState *alt; + + alt = gsk_gpu_color_states_find (ccs, color); gsk_gpu_shader_op_alloc (frame, &GSK_GPU_COLOR_OP_CLASS, - color_states, + gsk_gpu_color_states_create (ccs, TRUE, alt, FALSE), 0, clip, NULL, @@ -70,5 +74,5 @@ gsk_gpu_color_op (GskGpuFrame *frame, &instance); gsk_gpu_rect_to_float (rect, offset, instance->rect); - gsk_gpu_vec4_to_float (color, instance->color); + gsk_gpu_color_to_float (color, alt, opacity, instance->color); } diff --git a/gsk/gpu/gskgpucoloropprivate.h b/gsk/gpu/gskgpucoloropprivate.h index 1f1a066133..18674fd388 100644 --- a/gsk/gpu/gskgpucoloropprivate.h +++ b/gsk/gpu/gskgpucoloropprivate.h @@ -1,6 +1,7 @@ #pragma once #include "gskgputypesprivate.h" +#include "gdkcolorprivate.h" #include @@ -8,10 +9,11 @@ G_BEGIN_DECLS void gsk_gpu_color_op (GskGpuFrame *frame, GskGpuShaderClip clip, - GskGpuColorStates color_states, - const graphene_rect_t *rect, + GdkColorState *ccs, + float opacity, const graphene_point_t *offset, - const float color[4]); + const graphene_rect_t *rect, + const GdkColor *color); G_END_DECLS diff --git a/gsk/gpu/gskgpucolorstatesprivate.h b/gsk/gpu/gskgpucolorstatesprivate.h index 8f4aaca682..354c37ff21 100644 --- a/gsk/gpu/gskgpucolorstatesprivate.h +++ b/gsk/gpu/gskgpucolorstatesprivate.h @@ -2,6 +2,7 @@ #include "gskgputypesprivate.h" +#include "gdk/gdkcolorprivate.h" #include "gdk/gdkcolorstateprivate.h" #define COLOR_SPACE_OUTPUT_PREMULTIPLIED (1u << 2) @@ -73,3 +74,12 @@ gsk_gpu_color_states_is_alt_premultiplied (GskGpuColorStates self) return !!(self & COLOR_SPACE_ALT_PREMULTIPLIED); } +static inline GdkColorState * +gsk_gpu_color_states_find (GdkColorState *ccs, + const GdkColor *color) +{ + if (GDK_IS_DEFAULT_COLOR_STATE (color->color_state)) + return color->color_state; + else + return ccs; +} diff --git a/gsk/gpu/gskgpunodeprocessor.c b/gsk/gpu/gskgpunodeprocessor.c index cbf037a258..4c46f46018 100644 --- a/gsk/gpu/gskgpunodeprocessor.c +++ b/gsk/gpu/gskgpunodeprocessor.c @@ -1011,6 +1011,7 @@ gsk_gpu_node_processor_add_rounded_clip_node_with_mask (GskGpuNodeProcessor *sel GskGpuNodeProcessor other; graphene_rect_t clip_bounds, child_rect; GskGpuImage *child_image, *mask_image; + GdkColor white; if (!gsk_gpu_node_processor_clip_node_bounds (self, node, &clip_bounds)) return; @@ -1030,13 +1031,16 @@ gsk_gpu_node_processor_add_rounded_clip_node_with_mask (GskGpuNodeProcessor *sel gsk_render_node_get_preferred_depth (node)), &self->scale, &clip_bounds); + + gdk_color_init (&white, self->ccs, ((float[]){ 1, 1, 1, 1 })); gsk_gpu_node_processor_sync_globals (&other, 0); gsk_gpu_rounded_color_op (other.frame, gsk_gpu_clip_get_shader_clip (&other.clip, &other.offset, &node->bounds), - gsk_gpu_node_processor_color_states_self (&other), - gsk_rounded_clip_node_get_clip (node), + self->ccs, + 1, &other.offset, - (float[4]) { 1, 1, 1, 1 }); + gsk_rounded_clip_node_get_clip (node), + &white); gsk_gpu_node_processor_finish_draw (&other, mask_image); gsk_gpu_node_processor_sync_globals (self, 0); @@ -1061,6 +1065,7 @@ gsk_gpu_node_processor_add_rounded_clip_node_with_mask (GskGpuNodeProcessor *sel g_object_unref (child_image); g_object_unref (mask_image); + gdk_color_finish (&white); } static void @@ -1080,15 +1085,20 @@ gsk_gpu_node_processor_add_rounded_clip_node (GskGpuNodeProcessor *self, if (gsk_render_node_get_node_type (child) == GSK_COLOR_NODE && gsk_rect_contains_rect (&child->bounds, &original_clip->bounds)) { - const GdkRGBA *rgba = gsk_color_node_get_color (child); + GdkColor color; + + gdk_color_init_from_rgba (&color, gsk_color_node_get_color (child)); + gsk_gpu_node_processor_sync_globals (self, 0); gsk_gpu_rounded_color_op (self->frame, gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &original_clip->bounds), - gsk_gpu_node_processor_color_states_for_rgba (self), - original_clip, + self->ccs, + self->opacity, &self->offset, - GSK_RGBA_TO_VEC4_ALPHA (rgba, self->opacity)); + original_clip, + &color); + gdk_color_finish (&color); return; } @@ -1470,17 +1480,18 @@ gsk_gpu_node_processor_add_color_node (GskGpuNodeProcessor *self, { cairo_rectangle_int_t int_clipped; graphene_rect_t rect, clipped; - const GdkRGBA *color; + GdkColor color; float clear_color[4]; - color = gsk_color_node_get_color (node); + gdk_color_init_from_rgba (&color, gsk_color_node_get_color (node)); + graphene_rect_offset_r (&node->bounds, self->offset.x, self->offset.y, &rect); gsk_rect_intersection (&self->clip.rect.bounds, &rect, &clipped); if (gsk_gpu_frame_should_optimize (self->frame, GSK_GPU_OPTIMIZE_CLEAR) && - gdk_rgba_is_opaque (color) && + gdk_color_is_opaque (&color) && self->opacity >= 1.0 && node->bounds.size.width * node->bounds.size.height > 100 * 100 && /* not worth the effort for small images */ gsk_gpu_node_processor_rect_is_integer (self, &clipped, &int_clipped)) @@ -1501,10 +1512,12 @@ gsk_gpu_node_processor_add_color_node (GskGpuNodeProcessor *self, /* Yuck, rounded clip and modelview. I give up. */ gsk_gpu_color_op (self->frame, gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds), - gsk_gpu_node_processor_color_states_for_rgba (self), - &node->bounds, + self->ccs, + self->opacity, &self->offset, - GSK_RGBA_TO_VEC4 (color)); + &node->bounds, + &color); + gdk_color_finish (&color); return; } @@ -1524,10 +1537,12 @@ gsk_gpu_node_processor_add_color_node (GskGpuNodeProcessor *self, { gsk_gpu_color_op (self->frame, shader_clip, - gsk_gpu_node_processor_color_states_for_rgba (self), - &clipped, + self->ccs, + self->opacity, graphene_point_zero (), - GSK_RGBA_TO_VEC4 (color)); + &clipped, + &color); + gdk_color_finish (&color); return; } cover = GRAPHENE_RECT_INIT (int_clipped.x / scale_x, int_clipped.y / scale_y, @@ -1535,51 +1550,58 @@ gsk_gpu_node_processor_add_color_node (GskGpuNodeProcessor *self, if (clipped.origin.x != cover.origin.x) gsk_gpu_color_op (self->frame, shader_clip, - gsk_gpu_node_processor_color_states_for_rgba (self), - &GRAPHENE_RECT_INIT (clipped.origin.x, clipped.origin.y, cover.origin.x - clipped.origin.x, clipped.size.height), + self->ccs, + self->opacity, graphene_point_zero (), - GSK_RGBA_TO_VEC4 (color)); + &GRAPHENE_RECT_INIT (clipped.origin.x, clipped.origin.y, cover.origin.x - clipped.origin.x, clipped.size.height), + &color); if (clipped.origin.y != cover.origin.y) gsk_gpu_color_op (self->frame, shader_clip, - gsk_gpu_node_processor_color_states_for_rgba (self), - &GRAPHENE_RECT_INIT (clipped.origin.x, clipped.origin.y, clipped.size.width, cover.origin.y - clipped.origin.y), + self->ccs, + self->opacity, graphene_point_zero (), - GSK_RGBA_TO_VEC4 (color)); + &GRAPHENE_RECT_INIT (clipped.origin.x, clipped.origin.y, clipped.size.width, cover.origin.y - clipped.origin.y), + &color); if (clipped.origin.x + clipped.size.width != cover.origin.x + cover.size.width) gsk_gpu_color_op (self->frame, shader_clip, - gsk_gpu_node_processor_color_states_for_rgba (self), + self->ccs, + self->opacity, + graphene_point_zero (), &GRAPHENE_RECT_INIT (cover.origin.x + cover.size.width, clipped.origin.y, clipped.origin.x + clipped.size.width - cover.origin.x - cover.size.width, clipped.size.height), - graphene_point_zero (), - GSK_RGBA_TO_VEC4 (color)); + &color); if (clipped.origin.y + clipped.size.height != cover.origin.y + cover.size.height) gsk_gpu_color_op (self->frame, shader_clip, - gsk_gpu_node_processor_color_states_for_rgba (self), + self->ccs, + self->opacity, + graphene_point_zero (), &GRAPHENE_RECT_INIT (clipped.origin.x, cover.origin.y + cover.size.height, clipped.size.width, clipped.origin.y + clipped.size.height - cover.origin.y - cover.size.height), - graphene_point_zero (), - GSK_RGBA_TO_VEC4 (color)); + &color); } } - gdk_color_state_from_rgba (self->ccs, color, clear_color); + gdk_color_to_float (&color, self->ccs, clear_color); gsk_gpu_clear_op (self->frame, &int_clipped, clear_color); + gdk_color_finish (&color); return; } gsk_gpu_color_op (self->frame, gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds), - gsk_gpu_node_processor_color_states_for_rgba (self), - &node->bounds, + self->ccs, + self->opacity, &self->offset, - GSK_RGBA_TO_VEC4_ALPHA (color, self->opacity)); + &node->bounds, + &color); + gdk_color_finish (&color); } static gboolean @@ -1590,7 +1612,8 @@ gsk_gpu_node_processor_add_first_color_node (GskGpuNodeProcessor *self, GskRenderNode *node) { graphene_rect_t clip_bounds; - float color[4]; + GdkColor color; + float clear_color[4]; if (!node->fully_opaque) return FALSE; @@ -1599,11 +1622,13 @@ gsk_gpu_node_processor_add_first_color_node (GskGpuNodeProcessor *self, if (!gsk_rect_contains_rect (&node->bounds, &clip_bounds)) return FALSE; - gdk_color_state_from_rgba (self->ccs, gsk_color_node_get_color (node), color); + gdk_color_init_from_rgba (&color, gsk_color_node_get_color (node)); + gdk_color_to_float (&color, self->ccs, clear_color); + gdk_color_finish (&color); gsk_gpu_render_pass_begin_op (self->frame, target, clip, - color, + clear_color, pass_type); return TRUE; @@ -2509,14 +2534,16 @@ static void gsk_gpu_node_processor_add_gl_shader_node (GskGpuNodeProcessor *self, GskRenderNode *node) { - GdkRGBA pink = { 255 / 255., 105 / 255., 180 / 255., 1.0 }; + GdkColor pink = GDK_COLOR_INIT_SRGB (1, 105/255., 180/255., 1); gsk_gpu_color_op (self->frame, gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds), - gsk_gpu_node_processor_color_states_for_rgba (self), - &node->bounds, + self->ccs, + self->opacity, &self->offset, - GSK_RGBA_TO_VEC4_ALPHA (&pink, self->opacity)); + &node->bounds, + &pink); + gdk_color_finish (&pink); } static void @@ -3321,9 +3348,7 @@ gsk_gpu_node_processor_add_subsurface_node (GskGpuNodeProcessor *self, { if (gdk_rectangle_intersect (&int_clipped, &self->scissor, &int_clipped)) { - float color[4]; - - gdk_color_state_from_rgba (self->ccs, &GDK_RGBA_TRANSPARENT, color); + float color[4] = { 0, 0, 0, 0 }; gsk_gpu_clear_op (self->frame, &int_clipped, color); } } @@ -3332,13 +3357,17 @@ gsk_gpu_node_processor_add_subsurface_node (GskGpuNodeProcessor *self, self->blend = GSK_GPU_BLEND_CLEAR; self->pending_globals |= GSK_GPU_GLOBAL_BLEND; gsk_gpu_node_processor_sync_globals (self, 0); + GdkColor white; + gdk_color_init (&white, self->ccs, ((float[]) { 1, 1, 1, 1 })); gsk_gpu_color_op (self->frame, gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds), - gsk_gpu_node_processor_color_states_self (self), - &node->bounds, + self->ccs, + 1, &self->offset, - (float[4]) { 1, 1, 1, 1 }); + &node->bounds, + &white); + gdk_color_finish (&white); self->blend = GSK_GPU_BLEND_OVER; self->pending_globals |= GSK_GPU_GLOBAL_BLEND; diff --git a/gsk/gpu/gskgpuroundedcolorop.c b/gsk/gpu/gskgpuroundedcolorop.c index 40d27b73fa..86b87293d4 100644 --- a/gsk/gpu/gskgpuroundedcolorop.c +++ b/gsk/gpu/gskgpuroundedcolorop.c @@ -52,16 +52,20 @@ static const GskGpuShaderOpClass GSK_GPU_ROUNDED_COLOR_OP_CLASS = { void gsk_gpu_rounded_color_op (GskGpuFrame *frame, GskGpuShaderClip clip, - GskGpuColorStates color_states, - const GskRoundedRect *outline, + GdkColorState *ccs, + float opacity, const graphene_point_t *offset, - const float color[4]) + const GskRoundedRect *outline, + const GdkColor *color) { GskGpuRoundedcolorInstance *instance; + GdkColorState *alt; + + alt = gsk_gpu_color_states_find (ccs, color); gsk_gpu_shader_op_alloc (frame, &GSK_GPU_ROUNDED_COLOR_OP_CLASS, - color_states, + gsk_gpu_color_states_create (ccs, TRUE, alt, FALSE), 0, clip, NULL, @@ -69,6 +73,6 @@ gsk_gpu_rounded_color_op (GskGpuFrame *frame, &instance); gsk_rounded_rect_to_float (outline, offset, instance->outline); - gsk_gpu_vec4_to_float (color, instance->color); + gsk_gpu_color_to_float (color, alt, opacity, instance->color); } diff --git a/gsk/gpu/gskgpuroundedcoloropprivate.h b/gsk/gpu/gskgpuroundedcoloropprivate.h index 2dd6b90f1f..4029920067 100644 --- a/gsk/gpu/gskgpuroundedcoloropprivate.h +++ b/gsk/gpu/gskgpuroundedcoloropprivate.h @@ -2,6 +2,7 @@ #include "gskgputypesprivate.h" #include "gsktypes.h" +#include "gdkcolorprivate.h" #include @@ -9,10 +10,11 @@ G_BEGIN_DECLS void gsk_gpu_rounded_color_op (GskGpuFrame *frame, GskGpuShaderClip clip, - GskGpuColorStates color_states, - const GskRoundedRect *outline, + GdkColorState *ccs, + float opacity, const graphene_point_t *offset, - const float color[4]); + const GskRoundedRect *outline, + const GdkColor *color); G_END_DECLS diff --git a/gsk/gpu/gskgpushaderopprivate.h b/gsk/gpu/gskgpushaderopprivate.h index 94edbd4558..b560c6c963 100644 --- a/gsk/gpu/gskgpushaderopprivate.h +++ b/gsk/gpu/gskgpushaderopprivate.h @@ -4,6 +4,7 @@ #include "gskgputypesprivate.h" #include "gskgpucolorstatesprivate.h" +#include "gdkcolorprivate.h" #include @@ -92,7 +93,6 @@ gsk_gpu_vec4_to_float (const float color[4], values[2] = color[2]; values[3] = color[3]; } -#include static inline void gsk_gpu_point_to_float (const graphene_point_t *point, @@ -103,5 +103,14 @@ gsk_gpu_point_to_float (const graphene_point_t *point, values[1] = point->y + offset->y; } -G_END_DECLS +static inline void +gsk_gpu_color_to_float (const GdkColor *color, + GdkColorState *target, + float opacity, + float values[4]) +{ + gdk_color_to_float (color, target, values); + values[3] *= opacity; +} +G_END_DECLS