gpu: Pass compositing color states around

Make the node processor and the pattern writer track the current
compositing color state. Color state nodes change it. We pass
the surface color state down via the frame apis.
This commit is contained in:
Matthias Clasen
2024-06-08 21:33:56 -04:00
parent 6f37b64e4c
commit f7ff943d08
5 changed files with 50 additions and 5 deletions

View File

@@ -561,6 +561,7 @@ copy_texture (gpointer user_data,
static void
gsk_gpu_frame_record_rect (GskGpuFrame *self,
GskGpuImage *target,
GdkColorState *target_color_state,
const cairo_rectangle_int_t *clip,
GskRenderNode *node,
const graphene_rect_t *viewport)
@@ -572,6 +573,7 @@ gsk_gpu_frame_record_rect (GskGpuFrame *self,
gsk_gpu_node_processor_process (self,
target,
target_color_state,
clip,
node,
viewport);
@@ -585,6 +587,7 @@ static void
gsk_gpu_frame_record (GskGpuFrame *self,
gint64 timestamp,
GskGpuImage *target,
GdkColorState *target_color_state,
const cairo_region_t *clip,
GskRenderNode *node,
const graphene_rect_t *viewport,
@@ -603,13 +606,14 @@ gsk_gpu_frame_record (GskGpuFrame *self,
cairo_rectangle_int_t rect;
cairo_region_get_rectangle (clip, i, &rect);
gsk_gpu_frame_record_rect (self, target, &rect, node, viewport);
gsk_gpu_frame_record_rect (self, target, target_color_state, &rect, node, viewport);
}
}
else
{
gsk_gpu_frame_record_rect (self,
target,
target_color_state,
&(cairo_rectangle_int_t) {
0, 0,
gsk_gpu_image_get_width (target),
@@ -656,6 +660,7 @@ void
gsk_gpu_frame_render (GskGpuFrame *self,
gint64 timestamp,
GskGpuImage *target,
GdkColorState *target_color_state,
const cairo_region_t *region,
GskRenderNode *node,
const graphene_rect_t *viewport,
@@ -663,7 +668,7 @@ gsk_gpu_frame_render (GskGpuFrame *self,
{
gsk_gpu_frame_cleanup (self);
gsk_gpu_frame_record (self, timestamp, target, region, node, viewport, texture);
gsk_gpu_frame_record (self, timestamp, target, target_color_state, region, node, viewport, texture);
gsk_gpu_frame_submit (self);
}

View File

@@ -75,6 +75,7 @@ void gsk_gpu_frame_wait (GskGpuF
void gsk_gpu_frame_render (GskGpuFrame *self,
gint64 timestamp,
GskGpuImage *target,
GdkColorState *target_color_state,
const cairo_region_t *region,
GskRenderNode *node,
const graphene_rect_t *viewport,

View File

@@ -120,6 +120,7 @@ struct _GskGpuNodeProcessor
float opacity;
GskGpuGlobals pending_globals;
GdkColorState *color_state;
};
#define GDK_ARRAY_NAME pattern_buffer
@@ -141,6 +142,7 @@ struct _GskGpuPatternWriter
guint stack;
PatternBuffer buffer;
GdkColorState *color_state;
};
static void gsk_gpu_node_processor_add_node (GskGpuNodeProcessor *self,
@@ -153,6 +155,7 @@ gsk_gpu_node_processor_finish (GskGpuNodeProcessor *self)
{
g_clear_pointer (&self->modelview, gsk_transform_unref);
g_clear_object (&self->desc);
g_clear_pointer (&self->color_state, gdk_color_state_unref);
}
static void
@@ -160,6 +163,7 @@ gsk_gpu_node_processor_init (GskGpuNodeProcessor *self,
GskGpuFrame *frame,
GskGpuDescriptors *desc,
GskGpuImage *target,
GdkColorState *color_state,
const cairo_rectangle_int_t *clip,
const graphene_rect_t *viewport)
{
@@ -202,6 +206,8 @@ gsk_gpu_node_processor_init (GskGpuNodeProcessor *self,
-viewport->origin.y);
self->opacity = 1.0;
self->pending_globals = GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP | GSK_GPU_GLOBAL_SCISSOR | GSK_GPU_GLOBAL_BLEND;
self->color_state = gdk_color_state_ref (color_state);
}
static void
@@ -338,6 +344,7 @@ gsk_gpu_node_processor_init_draw (GskGpuNodeProcessor *self,
GskGpuFrame *frame,
GdkMemoryDepth depth,
const graphene_vec2_t *scale,
GdkColorState *color_state,
const graphene_rect_t *viewport)
{
GskGpuImage *image;
@@ -359,6 +366,7 @@ gsk_gpu_node_processor_init_draw (GskGpuNodeProcessor *self,
frame,
NULL,
image,
color_state,
&area,
viewport);
@@ -384,6 +392,7 @@ gsk_gpu_node_processor_finish_draw (GskGpuNodeProcessor *self,
void
gsk_gpu_node_processor_process (GskGpuFrame *frame,
GskGpuImage *target,
GdkColorState *target_color_state,
const cairo_rectangle_int_t *clip,
GskRenderNode *node,
const graphene_rect_t *viewport)
@@ -394,6 +403,7 @@ gsk_gpu_node_processor_process (GskGpuFrame *frame,
frame,
NULL,
target,
target_color_state,
clip,
viewport);
@@ -406,6 +416,7 @@ static void
gsk_gpu_pattern_writer_init (GskGpuPatternWriter *self,
GskGpuFrame *frame,
const graphene_vec2_t *scale,
GdkColorState *color_state,
const graphene_point_t *offset,
const graphene_rect_t *bounds)
{
@@ -419,6 +430,8 @@ gsk_gpu_pattern_writer_init (GskGpuPatternWriter *self,
self->scale = *scale;
self->stack = 0;
self->color_state = gdk_color_state_ref (color_state);
pattern_buffer_init (&self->buffer);
}
@@ -546,6 +559,7 @@ gsk_gpu_pattern_writer_finish (GskGpuPatternWriter *self)
pattern_buffer_clear (&self->buffer);
g_assert (self->stack == 0);
g_clear_object (&self->desc);
g_clear_pointer (&self->color_state, gdk_color_state_unref);
}
static gboolean
@@ -742,6 +756,7 @@ gsk_gpu_node_processor_image_op (GskGpuNodeProcessor *self,
static GskGpuImage *
gsk_gpu_node_processor_create_offscreen (GskGpuFrame *frame,
const graphene_vec2_t *scale,
GdkColorState *color_state,
const graphene_rect_t *viewport,
GskRenderNode *node)
{
@@ -752,6 +767,7 @@ gsk_gpu_node_processor_create_offscreen (GskGpuFrame *frame,
frame,
gsk_render_node_get_preferred_depth (node),
scale,
color_state,
viewport);
if (image == NULL)
return NULL;
@@ -768,6 +784,7 @@ gsk_gpu_node_processor_create_offscreen (GskGpuFrame *frame,
* @frame: frame to render in
* @clip_bounds: region of node that must be included in image
* @scale: scale factor to use for the image
* @color_state: the color state to composite in
* @node: the node to render
* @out_bounds: the actual bounds of the result
*
@@ -789,6 +806,7 @@ static GskGpuImage *
gsk_gpu_get_node_as_image (GskGpuFrame *frame,
const graphene_rect_t *clip_bounds,
const graphene_vec2_t *scale,
GdkColorState *color_state,
GskRenderNode *node,
graphene_rect_t *out_bounds)
{
@@ -833,6 +851,7 @@ gsk_gpu_get_node_as_image (GskGpuFrame *frame,
GSK_DEBUG (FALLBACK, "Offscreening node '%s'", g_type_name_from_instance ((GTypeInstance *) node));
result = gsk_gpu_node_processor_create_offscreen (frame,
scale,
color_state,
clip_bounds,
node);
@@ -843,6 +862,7 @@ gsk_gpu_get_node_as_image (GskGpuFrame *frame,
static GskGpuImage *
gsk_gpu_node_processor_ensure_image (GskGpuFrame *frame,
GskGpuImage *image,
GdkColorState *color_state,
GskGpuImageFlags required_flags,
GskGpuImageFlags disallowed_flags)
{
@@ -895,6 +915,7 @@ gsk_gpu_node_processor_ensure_image (GskGpuFrame *frame,
frame,
NULL,
copy,
color_state,
&(cairo_rectangle_int_t) { 0, 0, width, height },
&rect);
@@ -968,6 +989,7 @@ gsk_gpu_node_processor_get_node_as_image (GskGpuNodeProcessor *self,
image = gsk_gpu_get_node_as_image (self->frame,
&clip,
&self->scale,
self->color_state,
node,
out_bounds);
if (image == NULL)
@@ -975,6 +997,7 @@ gsk_gpu_node_processor_get_node_as_image (GskGpuNodeProcessor *self,
ensure = gsk_gpu_node_processor_ensure_image (self->frame,
image,
self->color_state,
required_flags,
disallowed_flags);
@@ -1026,6 +1049,7 @@ gsk_gpu_node_processor_blur_op (GskGpuNodeProcessor *self,
self->frame,
source_depth,
&self->scale,
self->color_state,
&intermediate_rect);
gsk_gpu_node_processor_sync_globals (&other, 0);
@@ -1205,6 +1229,7 @@ gsk_gpu_node_processor_try_node_as_pattern (GskGpuNodeProcessor *self,
gsk_gpu_pattern_writer_init (&writer,
self->frame,
&self->scale,
self->color_state,
&self->offset,
&clipped);
@@ -1454,6 +1479,7 @@ gsk_gpu_node_processor_add_rounded_clip_node_with_mask (GskGpuNodeProcessor *sel
self->frame,
gsk_render_node_get_preferred_depth (node),
&self->scale,
self->color_state,
&clip_bounds);
gsk_gpu_node_processor_sync_globals (&other, 0);
gsk_gpu_rounded_color_op (other.frame,
@@ -1955,6 +1981,7 @@ gsk_gpu_node_processor_add_texture_node (GskGpuNodeProcessor *self,
image = gsk_gpu_node_processor_ensure_image (self->frame,
image,
self->color_state,
GSK_GPU_IMAGE_MIPMAP,
GSK_GPU_IMAGE_STRAIGHT_ALPHA);
descriptor = gsk_gpu_node_processor_add_image (self, image, GSK_GPU_SAMPLER_MIPMAP_DEFAULT);
@@ -2020,6 +2047,7 @@ gsk_gpu_node_processor_create_texture_pattern (GskGpuPatternWriter *self,
{
image = gsk_gpu_node_processor_ensure_image (self->frame,
image,
self->color_state,
GSK_GPU_IMAGE_MIPMAP,
GSK_GPU_IMAGE_STRAIGHT_ALPHA);
sampler = GSK_GPU_SAMPLER_MIPMAP_DEFAULT;
@@ -2081,6 +2109,7 @@ gsk_gpu_node_processor_add_texture_scale_node (GskGpuNodeProcessor *self,
clip_bounds.size.height = ceilf (clip_bounds.size.height);
offscreen = gsk_gpu_node_processor_create_offscreen (self->frame,
graphene_vec2_one (),
self->color_state,
&clip_bounds,
node);
descriptor = gsk_gpu_node_processor_add_image (self, offscreen, GSK_GPU_SAMPLER_DEFAULT);
@@ -2118,6 +2147,7 @@ gsk_gpu_node_processor_add_texture_scale_node (GskGpuNodeProcessor *self,
image = gsk_gpu_node_processor_ensure_image (self->frame,
image,
self->color_state,
need_mipmap ? (GSK_GPU_IMAGE_CAN_MIPMAP | GSK_GPU_IMAGE_MIPMAP) : 0,
GSK_GPU_IMAGE_STRAIGHT_ALPHA);
@@ -2282,6 +2312,7 @@ gsk_gpu_node_processor_add_gradient_node (GskGpuNodeProcessor *self,
self->frame,
gsk_render_node_get_preferred_depth (node),
&self->scale,
self->color_state,
&bounds);
other.blend = GSK_GPU_BLEND_ADD;
@@ -3331,6 +3362,7 @@ gsk_gpu_node_processor_repeat_tile (GskGpuNodeProcessor *self,
GSK_DEBUG (FALLBACK, "Offscreening node '%s' for tiling", g_type_name_from_instance ((GTypeInstance *) child));
image = gsk_gpu_node_processor_create_offscreen (self->frame,
&self->scale,
self->color_state,
&clipped_child_bounds,
child);
@@ -4123,6 +4155,7 @@ gsk_gpu_node_processor_create_node_pattern (GskGpuPatternWriter *self,
image = gsk_gpu_get_node_as_image (self->frame,
&bounds,
&self->scale,
self->color_state,
node,
&bounds);
if (image == NULL)

View File

@@ -7,6 +7,7 @@ G_BEGIN_DECLS
void gsk_gpu_node_processor_process (GskGpuFrame *frame,
GskGpuImage *target,
GdkColorState *target_color_state,
const cairo_rectangle_int_t *clip,
GskRenderNode *node,
const graphene_rect_t *viewport);

View File

@@ -18,6 +18,7 @@
#include "gdk/gdktextureprivate.h"
#include "gdk/gdktexturedownloaderprivate.h"
#include "gdk/gdkdrawcontextprivate.h"
#include "gdk/gdkcolorstateprivate.h"
#include <graphene.h>
@@ -298,6 +299,7 @@ gsk_gpu_renderer_fallback_render_texture (GskGpuRenderer *self,
gsk_gpu_frame_render (frame,
g_get_monotonic_time (),
image,
GDK_COLOR_STATE_SRGB,
NULL,
root,
&GRAPHENE_RECT_INIT (rounded_viewport->origin.x + x,
@@ -360,6 +362,7 @@ gsk_gpu_renderer_render_texture (GskRenderer *renderer,
gsk_gpu_frame_render (frame,
g_get_monotonic_time (),
image,
GDK_COLOR_STATE_SRGB,
NULL,
root,
&rounded_viewport,
@@ -387,6 +390,7 @@ gsk_gpu_renderer_render (GskRenderer *renderer,
GskGpuImage *backbuffer;
cairo_region_t *render_region;
double scale;
GdkMemoryDepth depth;
if (cairo_region_is_empty (region))
{
@@ -394,9 +398,9 @@ gsk_gpu_renderer_render (GskRenderer *renderer,
return;
}
gdk_draw_context_begin_frame_full (priv->context,
gsk_render_node_get_preferred_depth (root),
region);
depth = gsk_render_node_get_preferred_depth (root);
gdk_draw_context_begin_frame_full (priv->context, depth, region);
gsk_gpu_device_maybe_gc (priv->device);
@@ -411,6 +415,7 @@ gsk_gpu_renderer_render (GskRenderer *renderer,
gsk_gpu_frame_render (frame,
g_get_monotonic_time (),
backbuffer,
GDK_COLOR_STATE_SRGB,
render_region,
root,
&GRAPHENE_RECT_INIT (