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.
This commit is contained in:
Matthias Clasen 2024-08-03 19:21:29 -04:00
parent 9eebe8e547
commit 9f548efd32
7 changed files with 123 additions and 63 deletions

View File

@ -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);
}

View File

@ -1,6 +1,7 @@
#pragma once
#include "gskgputypesprivate.h"
#include "gdkcolorprivate.h"
#include <graphene.h>
@ -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

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}

View File

@ -2,6 +2,7 @@
#include "gskgputypesprivate.h"
#include "gsktypes.h"
#include "gdkcolorprivate.h"
#include <graphene.h>
@ -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

View File

@ -4,6 +4,7 @@
#include "gskgputypesprivate.h"
#include "gskgpucolorstatesprivate.h"
#include "gdkcolorprivate.h"
#include <graphene.h>
@ -92,7 +93,6 @@ gsk_gpu_vec4_to_float (const float color[4],
values[2] = color[2];
values[3] = color[3];
}
#include <graphene.h>
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