mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-25 21:21:21 +00:00
gpu: Pass compositing color states
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. The name of the variable is "ccs" for "compositing color space". It's an unused variable name and it's common enough to deserve a short and sweet name.
This commit is contained in:
parent
eccdb594eb
commit
3ba63315d5
@ -562,6 +562,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,
|
||||
@ -581,13 +582,14 @@ gsk_gpu_frame_record (GskGpuFrame *self,
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
cairo_region_get_rectangle (clip, i, &rect);
|
||||
gsk_gpu_node_processor_process (self, target, &rect, node, viewport, pass_type);
|
||||
gsk_gpu_node_processor_process (self, target, target_color_state, &rect, node, viewport, pass_type);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_gpu_node_processor_process (self,
|
||||
target,
|
||||
target_color_state,
|
||||
&(cairo_rectangle_int_t) {
|
||||
0, 0,
|
||||
gsk_gpu_image_get_width (target),
|
||||
@ -635,6 +637,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,
|
||||
@ -642,7 +645,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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -109,6 +109,7 @@ typedef enum {
|
||||
struct _GskGpuNodeProcessor
|
||||
{
|
||||
GskGpuFrame *frame;
|
||||
GdkColorState *ccs;
|
||||
GskGpuDescriptors *desc;
|
||||
cairo_rectangle_int_t scissor;
|
||||
GskGpuBlend blend;
|
||||
@ -130,6 +131,7 @@ static gboolean gsk_gpu_node_processor_add_first_node (GskGpuN
|
||||
GskRenderPassType pass_type,
|
||||
GskRenderNode *node);
|
||||
static GskGpuImage * gsk_gpu_get_node_as_image (GskGpuFrame *frame,
|
||||
GdkColorState *ccs,
|
||||
const graphene_rect_t *clip_bounds,
|
||||
const graphene_vec2_t *scale,
|
||||
GskRenderNode *node,
|
||||
@ -145,8 +147,9 @@ gsk_gpu_node_processor_finish (GskGpuNodeProcessor *self)
|
||||
static void
|
||||
gsk_gpu_node_processor_init (GskGpuNodeProcessor *self,
|
||||
GskGpuFrame *frame,
|
||||
GskGpuDescriptors *desc,
|
||||
GskGpuImage *target,
|
||||
GdkColorState *ccs,
|
||||
GskGpuDescriptors *desc,
|
||||
const cairo_rectangle_int_t *clip,
|
||||
const graphene_rect_t *viewport)
|
||||
{
|
||||
@ -156,6 +159,7 @@ gsk_gpu_node_processor_init (GskGpuNodeProcessor *self,
|
||||
height = gsk_gpu_image_get_height (target);
|
||||
|
||||
self->frame = frame;
|
||||
self->ccs = ccs;
|
||||
if (desc)
|
||||
self->desc = g_object_ref (desc);
|
||||
else
|
||||
@ -323,6 +327,7 @@ rect_round_to_pixels (const graphene_rect_t *src,
|
||||
static GskGpuImage *
|
||||
gsk_gpu_node_processor_init_draw (GskGpuNodeProcessor *self,
|
||||
GskGpuFrame *frame,
|
||||
GdkColorState *ccs,
|
||||
GdkMemoryDepth depth,
|
||||
const graphene_vec2_t *scale,
|
||||
const graphene_rect_t *viewport)
|
||||
@ -344,8 +349,9 @@ gsk_gpu_node_processor_init_draw (GskGpuNodeProcessor *self,
|
||||
|
||||
gsk_gpu_node_processor_init (self,
|
||||
frame,
|
||||
NULL,
|
||||
image,
|
||||
ccs,
|
||||
NULL,
|
||||
&area,
|
||||
viewport);
|
||||
|
||||
@ -372,6 +378,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,
|
||||
@ -381,8 +388,9 @@ gsk_gpu_node_processor_process (GskGpuFrame *frame,
|
||||
|
||||
gsk_gpu_node_processor_init (&self,
|
||||
frame,
|
||||
NULL,
|
||||
target,
|
||||
target_color_state,
|
||||
NULL,
|
||||
clip,
|
||||
viewport);
|
||||
|
||||
@ -596,6 +604,7 @@ gsk_gpu_node_processor_image_op (GskGpuNodeProcessor *self,
|
||||
|
||||
static GskGpuImage *
|
||||
gsk_gpu_node_processor_create_offscreen (GskGpuFrame *frame,
|
||||
GdkColorState *ccs,
|
||||
const graphene_vec2_t *scale,
|
||||
const graphene_rect_t *viewport,
|
||||
GskRenderNode *node)
|
||||
@ -617,6 +626,7 @@ gsk_gpu_node_processor_create_offscreen (GskGpuFrame *frame,
|
||||
|
||||
gsk_gpu_node_processor_process (frame,
|
||||
image,
|
||||
ccs,
|
||||
&area,
|
||||
node,
|
||||
viewport,
|
||||
@ -627,6 +637,7 @@ gsk_gpu_node_processor_create_offscreen (GskGpuFrame *frame,
|
||||
|
||||
static GskGpuImage *
|
||||
gsk_gpu_get_node_as_image_via_offscreen (GskGpuFrame *frame,
|
||||
GdkColorState *ccs,
|
||||
const graphene_rect_t *clip_bounds,
|
||||
const graphene_vec2_t *scale,
|
||||
GskRenderNode *node,
|
||||
@ -636,6 +647,7 @@ gsk_gpu_get_node_as_image_via_offscreen (GskGpuFrame *frame,
|
||||
|
||||
GSK_DEBUG (FALLBACK, "Offscreening node '%s'", g_type_name_from_instance ((GTypeInstance *) node));
|
||||
result = gsk_gpu_node_processor_create_offscreen (frame,
|
||||
ccs,
|
||||
scale,
|
||||
clip_bounds,
|
||||
node);
|
||||
@ -647,6 +659,7 @@ gsk_gpu_get_node_as_image_via_offscreen (GskGpuFrame *frame,
|
||||
/*
|
||||
* gsk_gpu_node_copy_image:
|
||||
* @frame: The frame the image will be copied in
|
||||
* @ccs: color state the copy will be in
|
||||
* @image: (transfer full): The image to copy
|
||||
* @prepare_mipmap: If the copied image should reserve space for
|
||||
* mipmaps
|
||||
@ -658,6 +671,7 @@ gsk_gpu_get_node_as_image_via_offscreen (GskGpuFrame *frame,
|
||||
**/
|
||||
static GskGpuImage *
|
||||
gsk_gpu_copy_image (GskGpuFrame *frame,
|
||||
GdkColorState *ccs,
|
||||
GskGpuImage *image,
|
||||
gboolean prepare_mipmap)
|
||||
{
|
||||
@ -692,8 +706,9 @@ gsk_gpu_copy_image (GskGpuFrame *frame,
|
||||
|
||||
gsk_gpu_node_processor_init (&other,
|
||||
frame,
|
||||
NULL,
|
||||
copy,
|
||||
ccs,
|
||||
NULL,
|
||||
&(cairo_rectangle_int_t) { 0, 0, width, height },
|
||||
&rect);
|
||||
|
||||
@ -760,6 +775,7 @@ gsk_gpu_node_processor_get_node_as_image (GskGpuNodeProcessor *self,
|
||||
rect_round_to_pixels (&clip, &self->scale, &self->offset, &clip);
|
||||
|
||||
return gsk_gpu_get_node_as_image (self->frame,
|
||||
self->ccs,
|
||||
&clip,
|
||||
&self->scale,
|
||||
node,
|
||||
@ -799,6 +815,7 @@ gsk_gpu_node_processor_blur_op (GskGpuNodeProcessor *self,
|
||||
|
||||
intermediate = gsk_gpu_node_processor_init_draw (&other,
|
||||
self->frame,
|
||||
self->ccs,
|
||||
source_depth,
|
||||
&self->scale,
|
||||
&intermediate_rect);
|
||||
@ -1061,6 +1078,7 @@ gsk_gpu_node_processor_add_rounded_clip_node_with_mask (GskGpuNodeProcessor *sel
|
||||
|
||||
mask_image = gsk_gpu_node_processor_init_draw (&other,
|
||||
self->frame,
|
||||
self->ccs,
|
||||
gsk_render_node_get_preferred_depth (node),
|
||||
&self->scale,
|
||||
&clip_bounds);
|
||||
@ -1697,7 +1715,7 @@ gsk_gpu_node_processor_add_texture_node (GskGpuNodeProcessor *self,
|
||||
guint32 descriptor;
|
||||
|
||||
if ((gsk_gpu_image_get_flags (image) & (GSK_GPU_IMAGE_STRAIGHT_ALPHA | GSK_GPU_IMAGE_CAN_MIPMAP)) != GSK_GPU_IMAGE_CAN_MIPMAP)
|
||||
image = gsk_gpu_copy_image (self->frame, image, TRUE);
|
||||
image = gsk_gpu_copy_image (self->frame, self->ccs, image, TRUE);
|
||||
|
||||
if (!(gsk_gpu_image_get_flags (image) & GSK_GPU_IMAGE_MIPMAP))
|
||||
gsk_gpu_mipmap_op (self->frame, image);
|
||||
@ -1738,6 +1756,7 @@ gsk_gpu_node_processor_add_texture_node (GskGpuNodeProcessor *self,
|
||||
|
||||
static GskGpuImage *
|
||||
gsk_gpu_get_texture_node_as_image (GskGpuFrame *frame,
|
||||
GdkColorState *ccs,
|
||||
const graphene_rect_t *clip_bounds,
|
||||
const graphene_vec2_t *scale,
|
||||
GskRenderNode *node,
|
||||
@ -1749,7 +1768,7 @@ gsk_gpu_get_texture_node_as_image (GskGpuFrame *frame,
|
||||
GskGpuImage *image;
|
||||
|
||||
if (texture_node_should_mipmap (node, frame, scale))
|
||||
return gsk_gpu_get_node_as_image_via_offscreen (frame, clip_bounds, scale, node, out_bounds);
|
||||
return gsk_gpu_get_node_as_image_via_offscreen (frame, ccs, clip_bounds, scale, node, out_bounds);
|
||||
|
||||
image = gsk_gpu_cache_lookup_texture_image (gsk_gpu_device_get_cache (device), texture, timestamp);
|
||||
if (image == NULL)
|
||||
@ -1763,7 +1782,7 @@ gsk_gpu_get_texture_node_as_image (GskGpuFrame *frame,
|
||||
|
||||
if (gsk_gpu_image_get_flags (image) & GSK_GPU_IMAGE_STRAIGHT_ALPHA)
|
||||
{
|
||||
image = gsk_gpu_copy_image (frame, image, FALSE);
|
||||
image = gsk_gpu_copy_image (frame, ccs, image, FALSE);
|
||||
/* We fixed up a cached texture, cache the fixed up version instead */
|
||||
gsk_gpu_cache_cache_texture_image (gsk_gpu_device_get_cache (gsk_gpu_frame_get_device (frame)),
|
||||
texture,
|
||||
@ -1772,7 +1791,7 @@ gsk_gpu_get_texture_node_as_image (GskGpuFrame *frame,
|
||||
}
|
||||
|
||||
/* Happens for oversized textures */
|
||||
return gsk_gpu_get_node_as_image_via_offscreen (frame, clip_bounds, scale, node, out_bounds);
|
||||
return gsk_gpu_get_node_as_image_via_offscreen (frame, ccs, clip_bounds, scale, node, out_bounds);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1808,6 +1827,7 @@ gsk_gpu_node_processor_add_texture_scale_node (GskGpuNodeProcessor *self,
|
||||
clip_bounds.size.width = ceilf (clip_bounds.size.width);
|
||||
clip_bounds.size.height = ceilf (clip_bounds.size.height);
|
||||
offscreen = gsk_gpu_node_processor_create_offscreen (self->frame,
|
||||
self->ccs,
|
||||
graphene_vec2_one (),
|
||||
&clip_bounds,
|
||||
node);
|
||||
@ -1846,7 +1866,7 @@ gsk_gpu_node_processor_add_texture_scale_node (GskGpuNodeProcessor *self,
|
||||
|
||||
if ((gsk_gpu_image_get_flags (image) & GSK_GPU_IMAGE_STRAIGHT_ALPHA) ||
|
||||
(need_mipmap && !(gsk_gpu_image_get_flags (image) & GSK_GPU_IMAGE_CAN_MIPMAP)))
|
||||
image = gsk_gpu_copy_image (self->frame, image, need_mipmap);
|
||||
image = gsk_gpu_copy_image (self->frame, self->ccs, image, need_mipmap);
|
||||
|
||||
if (need_mipmap && !(gsk_gpu_image_get_flags (image) & GSK_GPU_IMAGE_MIPMAP))
|
||||
gsk_gpu_mipmap_op (self->frame, image);
|
||||
@ -1883,6 +1903,7 @@ gsk_gpu_node_processor_add_texture_scale_node (GskGpuNodeProcessor *self,
|
||||
|
||||
static GskGpuImage *
|
||||
gsk_gpu_get_cairo_node_as_image (GskGpuFrame *frame,
|
||||
GdkColorState *ccs,
|
||||
const graphene_rect_t *clip_bounds,
|
||||
const graphene_vec2_t *scale,
|
||||
GskRenderNode *node,
|
||||
@ -1890,6 +1911,9 @@ gsk_gpu_get_cairo_node_as_image (GskGpuFrame *frame,
|
||||
{
|
||||
GskGpuImage *result;
|
||||
|
||||
if (!gdk_color_state_equal (ccs, GDK_COLOR_STATE_SRGB))
|
||||
return gsk_gpu_get_node_as_image_via_offscreen (frame, ccs, clip_bounds, scale, node, out_bounds);
|
||||
|
||||
result = gsk_gpu_upload_cairo_op (frame,
|
||||
scale,
|
||||
clip_bounds,
|
||||
@ -2029,6 +2053,7 @@ gsk_gpu_node_processor_add_gradient_node (GskGpuNodeProcessor *self,
|
||||
|
||||
image = gsk_gpu_node_processor_init_draw (&other,
|
||||
self->frame,
|
||||
self->ccs,
|
||||
gsk_render_node_get_preferred_depth (node),
|
||||
&self->scale,
|
||||
&bounds);
|
||||
@ -2714,6 +2739,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->ccs,
|
||||
&self->scale,
|
||||
&clipped_child_bounds,
|
||||
child);
|
||||
@ -3115,6 +3141,7 @@ gsk_gpu_node_processor_add_subsurface_node (GskGpuNodeProcessor *self,
|
||||
|
||||
static GskGpuImage *
|
||||
gsk_gpu_get_subsurface_node_as_image (GskGpuFrame *frame,
|
||||
GdkColorState *ccs,
|
||||
const graphene_rect_t *clip_bounds,
|
||||
const graphene_vec2_t *scale,
|
||||
GskRenderNode *node,
|
||||
@ -3130,6 +3157,7 @@ gsk_gpu_get_subsurface_node_as_image (GskGpuFrame *frame,
|
||||
#endif
|
||||
|
||||
return gsk_gpu_get_node_as_image (frame,
|
||||
ccs,
|
||||
clip_bounds,
|
||||
scale,
|
||||
gsk_subsurface_node_get_child (node),
|
||||
@ -3208,12 +3236,14 @@ gsk_gpu_node_processor_add_debug_node (GskGpuNodeProcessor *self,
|
||||
|
||||
static GskGpuImage *
|
||||
gsk_gpu_get_debug_node_as_image (GskGpuFrame *frame,
|
||||
GdkColorState *ccs,
|
||||
const graphene_rect_t *clip_bounds,
|
||||
const graphene_vec2_t *scale,
|
||||
GskRenderNode *node,
|
||||
graphene_rect_t *out_bounds)
|
||||
{
|
||||
return gsk_gpu_get_node_as_image (frame,
|
||||
ccs,
|
||||
clip_bounds,
|
||||
scale,
|
||||
gsk_debug_node_get_child (node),
|
||||
@ -3236,6 +3266,7 @@ static const struct
|
||||
GskRenderPassType pass_type,
|
||||
GskRenderNode *node);
|
||||
GskGpuImage * (* get_node_as_image) (GskGpuFrame *self,
|
||||
GdkColorState *ccs,
|
||||
const graphene_rect_t *clip_bounds,
|
||||
const graphene_vec2_t *scale,
|
||||
GskRenderNode *node,
|
||||
@ -3566,6 +3597,7 @@ gsk_gpu_node_processor_add_first_node (GskGpuNodeProcessor *self,
|
||||
/*
|
||||
* gsk_gpu_get_node_as_image:
|
||||
* @frame: frame to render in
|
||||
* @ccs: the color state to composite the image in
|
||||
* @clip_bounds: region of node that must be included in image
|
||||
* @scale: scale factor to use for the image
|
||||
* @node: the node to render
|
||||
@ -3573,7 +3605,7 @@ gsk_gpu_node_processor_add_first_node (GskGpuNodeProcessor *self,
|
||||
*
|
||||
* Get the part of the node indicated by the clip bounds as an image.
|
||||
*
|
||||
* The resulting image will be premultiplied.
|
||||
* The resulting image will be in the given colorstate and premultiplied.
|
||||
*
|
||||
* It is perfectly valid for this function to return an image covering
|
||||
* a larger or smaller rectangle than the given clip bounds.
|
||||
@ -3589,6 +3621,7 @@ gsk_gpu_node_processor_add_first_node (GskGpuNodeProcessor *self,
|
||||
**/
|
||||
static GskGpuImage *
|
||||
gsk_gpu_get_node_as_image (GskGpuFrame *frame,
|
||||
GdkColorState *ccs,
|
||||
const graphene_rect_t *clip_bounds,
|
||||
const graphene_vec2_t *scale,
|
||||
GskRenderNode *node,
|
||||
@ -3606,13 +3639,13 @@ gsk_gpu_get_node_as_image (GskGpuFrame *frame,
|
||||
if (gsk_gpu_frame_should_optimize (frame, GSK_GPU_OPTIMIZE_TO_IMAGE) &&
|
||||
nodes_vtable[node_type].get_node_as_image)
|
||||
{
|
||||
return nodes_vtable[node_type].get_node_as_image (frame, clip_bounds, scale, node, out_bounds);
|
||||
return nodes_vtable[node_type].get_node_as_image (frame, ccs, clip_bounds, scale, node, out_bounds);
|
||||
}
|
||||
else
|
||||
{
|
||||
GSK_DEBUG (FALLBACK, "Unsupported node '%s'",
|
||||
g_type_name_from_instance ((GTypeInstance *) node));
|
||||
return gsk_gpu_get_node_as_image_via_offscreen (frame, clip_bounds, scale, node, out_bounds);
|
||||
return gsk_gpu_get_node_as_image_via_offscreen (frame, ccs, clip_bounds, scale, node, out_bounds);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "gdk/gdktextureprivate.h"
|
||||
#include "gdk/gdktexturedownloaderprivate.h"
|
||||
#include "gdk/gdkdrawcontextprivate.h"
|
||||
#include "gdk/gdkcolorstateprivate.h"
|
||||
|
||||
#include <graphene.h>
|
||||
|
||||
@ -299,6 +300,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,
|
||||
@ -361,6 +363,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,
|
||||
@ -388,6 +391,7 @@ gsk_gpu_renderer_render (GskRenderer *renderer,
|
||||
GskGpuImage *backbuffer;
|
||||
cairo_region_t *render_region;
|
||||
double scale;
|
||||
GdkMemoryDepth depth;
|
||||
|
||||
if (cairo_region_is_empty (region))
|
||||
{
|
||||
@ -395,9 +399,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);
|
||||
|
||||
@ -412,6 +416,7 @@ gsk_gpu_renderer_render (GskRenderer *renderer,
|
||||
gsk_gpu_frame_render (frame,
|
||||
g_get_monotonic_time (),
|
||||
backbuffer,
|
||||
gdk_draw_context_get_color_state (priv->context),
|
||||
render_region,
|
||||
root,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
|
Loading…
Reference in New Issue
Block a user