Merge branch 'matthiasc/for-main' into 'main'

gsk: Small optimization

See merge request GNOME/gtk!7698
This commit is contained in:
Matthias Clasen 2024-09-08 17:29:27 +00:00
commit 6288be286f
6 changed files with 118 additions and 56 deletions

View File

@ -50,22 +50,19 @@ static const GskGpuShaderOpClass GSK_GPU_COLORIZE_OP_CLASS = {
};
void
gsk_gpu_colorize_op (GskGpuFrame *frame,
GskGpuShaderClip clip,
GdkColorState *ccs,
float opacity,
const graphene_point_t *offset,
const GskGpuShaderImage *image,
const GdkColor *color)
gsk_gpu_colorize_op2 (GskGpuFrame *frame,
GskGpuShaderClip clip,
GskGpuColorStates color_states,
float opacity,
const graphene_point_t *offset,
const GskGpuShaderImage *image,
const GdkColor *color)
{
GskGpuColorizeInstance *instance;
GdkColorState *alt;
alt = gsk_gpu_color_states_find (ccs, color);
gsk_gpu_shader_op_alloc (frame,
&GSK_GPU_COLORIZE_OP_CLASS,
gsk_gpu_color_states_create (ccs, TRUE, alt, FALSE),
color_states,
0,
clip,
(GskGpuImage *[1]) { image->image },
@ -74,5 +71,27 @@ gsk_gpu_colorize_op (GskGpuFrame *frame,
gsk_gpu_rect_to_float (image->coverage ? image->coverage : image->bounds, offset, instance->rect);
gsk_gpu_rect_to_float (image->bounds, offset, instance->tex_rect);
gsk_gpu_color_to_float (color, alt, opacity, instance->color);
gsk_gpu_color_to_float (color, gsk_gpu_color_states_get_alt (color_states), opacity, instance->color);
}
void
gsk_gpu_colorize_op (GskGpuFrame *frame,
GskGpuShaderClip clip,
GdkColorState *ccs,
float opacity,
const graphene_point_t *offset,
const GskGpuShaderImage *image,
const GdkColor *color)
{
GdkColorState *alt;
GskGpuColorStates color_states;
GdkColor color2;
alt = gsk_gpu_color_states_find (ccs, color);
color_states = gsk_gpu_color_states_create (ccs, TRUE, alt, FALSE);
gdk_color_convert (&color2, alt, color);
gsk_gpu_colorize_op2 (frame, clip, color_states, opacity, offset, image, &color2);
gdk_color_finish (&color2);
}

View File

@ -14,6 +14,14 @@ void gsk_gpu_colorize_op (GskGpuF
const GskGpuShaderImage *image,
const GdkColor *color);
void gsk_gpu_colorize_op2 (GskGpuFrame *frame,
GskGpuShaderClip clip,
GskGpuColorStates color_states,
float opacity,
const graphene_point_t *offset,
const GskGpuShaderImage *image,
const GdkColor *color);
G_END_DECLS

View File

@ -3007,8 +3007,13 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
float align_scale_x, align_scale_y;
float inv_align_scale_x, inv_align_scale_y;
unsigned int flags_mask;
GskGpuImage *last_image;
const float inv_pango_scale = 1.f / PANGO_SCALE;
cairo_hint_style_t hint_style;
const GdkColor *color;
GdkColorState *alt;
GskGpuColorStates color_states;
GdkColor color2;
GskGpuShaderClip node_clip;
if (self->opacity < 1.0 &&
gsk_text_node_has_color_glyphs (node))
@ -3023,12 +3028,21 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
glyphs = gsk_text_node_get_glyphs (node, NULL);
font = gsk_text_node_get_font (node);
offset = *gsk_text_node_get_offset (node);
hint_style = gsk_text_node_get_font_hint_style (node);
color = gsk_text_node_get_color2 (node);
alt = gsk_gpu_color_states_find (self->ccs, color);
color_states = gsk_gpu_color_states_create (self->ccs, TRUE, alt, FALSE);
gdk_color_convert (&color2, alt, color);
node_clip = gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
offset.x += self->offset.x;
offset.y += self->offset.y;
scale = MAX (graphene_vec2_get_x (&self->scale), graphene_vec2_get_y (&self->scale));
if (gsk_font_get_hint_style (font) != CAIRO_HINT_STYLE_NONE)
if (hint_style != CAIRO_HINT_STYLE_NONE)
{
align_scale_x = scale * 4;
align_scale_y = scale;
@ -3043,13 +3057,13 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
inv_align_scale_x = 1 / align_scale_x;
inv_align_scale_y = 1 / align_scale_y;
last_image = NULL;
for (i = 0; i < num_glyphs; i++)
{
GskGpuImage *image;
graphene_rect_t glyph_bounds, glyph_tex_rect;
graphene_point_t glyph_offset, glyph_origin;
GskGpuGlyphLookupFlags flags;
GskGpuShaderClip glyph_clip;
glyph_origin = GRAPHENE_POINT_INIT (offset.x + glyphs[i].geometry.x_offset * inv_pango_scale,
offset.y + glyphs[i].geometry.y_offset * inv_pango_scale);
@ -3080,12 +3094,14 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
glyph_origin = GRAPHENE_POINT_INIT (glyph_origin.x - glyph_offset.x / scale,
glyph_origin.y - glyph_offset.y / scale);
if (image != last_image)
last_image = image;
if (node_clip == GSK_GPU_SHADER_CLIP_NONE)
glyph_clip = GSK_GPU_SHADER_CLIP_NONE;
else
glyph_clip = gsk_gpu_clip_get_shader_clip (&self->clip, &glyph_origin, &glyph_bounds);
if (glyphs[i].attr.is_color)
gsk_gpu_texture_op (self->frame,
gsk_gpu_clip_get_shader_clip (&self->clip, &glyph_origin, &glyph_bounds),
glyph_clip,
&glyph_origin,
&(GskGpuShaderImage) {
image,
@ -3094,21 +3110,23 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
&glyph_tex_rect
});
else
gsk_gpu_colorize_op (self->frame,
gsk_gpu_clip_get_shader_clip (&self->clip, &glyph_origin, &glyph_bounds),
self->ccs,
self->opacity,
&glyph_origin,
&(GskGpuShaderImage) {
image,
GSK_GPU_SAMPLER_DEFAULT,
&glyph_bounds,
&glyph_tex_rect
},
gsk_text_node_get_color2 (node));
gsk_gpu_colorize_op2 (self->frame,
glyph_clip,
color_states,
self->opacity,
&glyph_origin,
&(GskGpuShaderImage) {
image,
GSK_GPU_SAMPLER_DEFAULT,
&glyph_bounds,
&glyph_tex_rect
},
&color2);
offset.x += glyphs[i].geometry.width * inv_pango_scale;
}
gdk_color_finish (&color2);
}
static void
@ -3657,7 +3675,8 @@ static void
gsk_gpu_node_processor_add_container_node (GskGpuNodeProcessor *self,
GskRenderNode *node)
{
gsize i;
GskRenderNode **children;
guint n_children;
if (self->opacity < 1.0 && !gsk_container_node_is_disjoint (node))
{
@ -3665,8 +3684,9 @@ gsk_gpu_node_processor_add_container_node (GskGpuNodeProcessor *self,
return;
}
for (i = 0; i < gsk_container_node_get_n_children (node); i++)
gsk_gpu_node_processor_add_node (self, gsk_container_node_get_child (node, i));
children = gsk_container_node_get_children (node, &n_children);
for (guint i = 0; i < n_children; i++)
gsk_gpu_node_processor_add_node (self, children[i]);
}
static gboolean
@ -3674,10 +3694,12 @@ gsk_gpu_node_processor_add_first_container_node (GskGpuNodeProcessor *self,
GskGpuFirstNodeInfo *info,
GskRenderNode *node)
{
GskRenderNode **children;
graphene_rect_t opaque;
int i, n;
int i;
guint n;
n = gsk_container_node_get_n_children (node);
children = gsk_container_node_get_children (node, &n);
if (n == 0)
return FALSE;
@ -3687,17 +3709,15 @@ gsk_gpu_node_processor_add_first_container_node (GskGpuNodeProcessor *self,
for (i = n; i-->0; )
{
if (gsk_gpu_node_processor_add_first_node (self,
info,
gsk_container_node_get_child (node, i)))
break;
if (gsk_gpu_node_processor_add_first_node (self, info, children[i]))
break;
}
if (i < 0)
gsk_gpu_first_node_begin_rendering (self, info, NULL);
for (i++; i < n; i++)
gsk_gpu_node_processor_add_node (self, gsk_container_node_get_child (node, i));
gsk_gpu_node_processor_add_node (self, children[i]);
return TRUE;
}

View File

@ -60,8 +60,6 @@
**/
G_DEFINE_QUARK (gsk-serialization-error-quark, gsk_serialization_error)
#define GSK_RENDER_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_RENDER_NODE, GskRenderNodeClass))
static void
value_render_node_init (GValue *value)
@ -341,20 +339,13 @@ void
* Returns: the type of the `GskRenderNode`
*/
GskRenderNodeType
gsk_render_node_get_node_type (const GskRenderNode *node)
(gsk_render_node_get_node_type) (const GskRenderNode *node)
{
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), GSK_NOT_A_RENDER_NODE);
return GSK_RENDER_NODE_GET_CLASS (node)->node_type;
}
G_GNUC_PURE static inline
GskRenderNodeType
_gsk_render_node_get_node_type (const GskRenderNode *node)
{
return GSK_RENDER_NODE_GET_CLASS (node)->node_type;
}
/**
* gsk_render_node_get_bounds:
* @node: a `GskRenderNode`
@ -535,11 +526,11 @@ gsk_render_node_can_diff (const GskRenderNode *node1,
if (node1 == node2)
return TRUE;
if (_gsk_render_node_get_node_type (node1) == _gsk_render_node_get_node_type (node2))
if (gsk_render_node_get_node_type (node1) == gsk_render_node_get_node_type (node2))
return GSK_RENDER_NODE_GET_CLASS (node1)->can_diff (node1, node2);
if (_gsk_render_node_get_node_type (node1) == GSK_CONTAINER_NODE ||
_gsk_render_node_get_node_type (node2) == GSK_CONTAINER_NODE)
if (gsk_render_node_get_node_type (node1) == GSK_CONTAINER_NODE ||
gsk_render_node_get_node_type (node2) == GSK_CONTAINER_NODE)
return TRUE;
return FALSE;
@ -594,15 +585,15 @@ gsk_render_node_diff (GskRenderNode *node1,
if (node1 == node2)
return;
if (_gsk_render_node_get_node_type (node1) == _gsk_render_node_get_node_type (node2))
if (gsk_render_node_get_node_type (node1) == gsk_render_node_get_node_type (node2))
{
GSK_RENDER_NODE_GET_CLASS (node1)->diff (node1, node2, data);
}
else if (_gsk_render_node_get_node_type (node1) == GSK_CONTAINER_NODE)
else if (gsk_render_node_get_node_type (node1) == GSK_CONTAINER_NODE)
{
gsk_container_node_diff_with (node1, node2, data);
}
else if (_gsk_render_node_get_node_type (node2) == GSK_CONTAINER_NODE)
else if (gsk_render_node_get_node_type (node2) == GSK_CONTAINER_NODE)
{
gsk_container_node_diff_with (node2, node1, data);
}

View File

@ -6332,6 +6332,7 @@ struct _GskTextNode
PangoFontMap *fontmap;
PangoFont *font;
gboolean has_color_glyphs;
cairo_hint_style_t hint_style;
GdkColor color;
graphene_point_t offset;
@ -6513,6 +6514,7 @@ gsk_text_node_new2 (PangoFont *font,
gdk_color_init_copy (&self->color, color);
self->offset = *offset;
self->has_color_glyphs = FALSE;
self->hint_style = gsk_font_get_hint_style (font);
glyph_infos = g_malloc_n (glyphs->num_glyphs, sizeof (PangoGlyphInfo));
@ -6596,6 +6598,14 @@ gsk_text_node_get_font (const GskRenderNode *node)
return self->font;
}
cairo_hint_style_t
gsk_text_node_get_font_hint_style (const GskRenderNode *node)
{
const GskTextNode *self = (const GskTextNode *) node;
return self->hint_style;
}
/**
* gsk_text_node_has_color_glyphs:
* @node: (type GskTextNode): a text `GskRenderNode`

View File

@ -100,6 +100,9 @@ bool gsk_border_node_get_uniform_color (const GskRenderNode
void gsk_text_node_serialize_glyphs (GskRenderNode *self,
GString *str);
cairo_hint_style_t
gsk_text_node_get_font_hint_style (const GskRenderNode *self) G_GNUC_PURE;
GskRenderNode ** gsk_container_node_get_children (const GskRenderNode *node,
guint *n_children);
@ -170,5 +173,16 @@ GskRenderNode * gsk_text_node_new2 (PangoFont
const graphene_point_t *offset);
const GdkColor *gsk_text_node_get_color2 (const GskRenderNode *node);
#define GSK_RENDER_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_RENDER_NODE, GskRenderNodeClass))
#define gsk_render_node_get_node_type(node) _gsk_render_node_get_node_type (node)
G_GNUC_PURE static inline
GskRenderNodeType
_gsk_render_node_get_node_type (const GskRenderNode *node)
{
return GSK_RENDER_NODE_GET_CLASS (node)->node_type;
}
G_END_DECLS