Merge branch 'ngl-rect-borders' into 'master'

Speed up border rendering

See merge request GNOME/gtk!3278
This commit is contained in:
Matthias Clasen
2021-03-09 17:56:57 +00:00
5 changed files with 73 additions and 13 deletions

View File

@@ -1137,7 +1137,8 @@ struct _GskBorderNode
{
GskRenderNode render_node;
bool uniform: 1;
bool uniform_width: 1;
bool uniform_color: 1;
GskRoundedRect outline;
float border_width[4];
GdkRGBA border_color[4];
@@ -1286,16 +1287,18 @@ gsk_border_node_diff (GskRenderNode *node1,
{
GskBorderNode *self1 = (GskBorderNode *) node1;
GskBorderNode *self2 = (GskBorderNode *) node2;
gboolean uniform1 = self1->uniform_width && self1->uniform_color;
gboolean uniform2 = self2->uniform_width && self2->uniform_color;
if (self1->uniform &&
self2->uniform &&
if (uniform1 &&
uniform2 &&
self1->border_width[0] == self2->border_width[0] &&
gsk_rounded_rect_equal (&self1->outline, &self2->outline) &&
gdk_rgba_equal (&self1->border_color[0], &self2->border_color[0]))
return;
/* Different uniformity -> diff impossible */
if (self1->uniform ^ self2->uniform)
if (uniform1 ^ uniform1)
{
gsk_render_node_diff_impossible (node1, node2, region);
return;
@@ -1401,14 +1404,17 @@ gsk_border_node_new (const GskRoundedRect *outline,
if (border_width[0] == border_width[1] &&
border_width[0] == border_width[2] &&
border_width[0] == border_width[3] &&
gdk_rgba_equal (&border_color[0], &border_color[1]) &&
border_width[0] == border_width[3])
self->uniform_width = TRUE;
else
self->uniform_width = FALSE;
if (gdk_rgba_equal (&border_color[0], &border_color[1]) &&
gdk_rgba_equal (&border_color[0], &border_color[2]) &&
gdk_rgba_equal (&border_color[0], &border_color[3]))
self->uniform = TRUE;
self->uniform_color = TRUE;
else
self->uniform = FALSE;
self->uniform_color = FALSE;
graphene_rect_init_from_rect (&node->bounds, &self->outline.bounds);
@@ -1419,7 +1425,15 @@ gsk_border_node_new (const GskRoundedRect *outline,
bool
gsk_border_node_get_uniform (const GskRenderNode *self)
{
return ((const GskBorderNode *)self)->uniform;
const GskBorderNode *node = (const GskBorderNode *)self;
return node->uniform_width && node->uniform_color;
}
bool
gsk_border_node_get_uniform_color (const GskRenderNode *self)
{
const GskBorderNode *node = (const GskBorderNode *)self;
return node->uniform_color;
}
/*** GSK_TEXTURE_NODE ***/

View File

@@ -2767,13 +2767,13 @@ render_node_print (Printer *p,
start_node (p, "debug");
append_node_param (p, "child", gsk_debug_node_get_child (node));
/* TODO: We potentially need to escape certain characters in the message */
if (message)
{
_indent (p);
g_string_append_printf (p->str, "message: \"%s\";\n", message);
}
append_node_param (p, "child", gsk_debug_node_get_child (node));
end_node (p);
}

View File

@@ -95,6 +95,7 @@ void gsk_render_node_diff_impossible (GskRenderNode
cairo_region_t *region);
bool gsk_border_node_get_uniform (const GskRenderNode *self);
bool gsk_border_node_get_uniform_color (const GskRenderNode *self);
void gsk_text_node_serialize_glyphs (GskRenderNode *self,
GString *str);

View File

@@ -1683,6 +1683,48 @@ sort_border_sides (const GdkRGBA *colors,
}
}
static inline void
gsk_ngl_render_job_visit_rect_border_node (GskNglRenderJob *job,
const GskRenderNode *node)
{
const GdkRGBA *colors = gsk_border_node_get_colors (node);
const float *widths = gsk_border_node_get_widths (node);
const graphene_point_t *origin = &node->bounds.origin;
const graphene_size_t *size = &node->bounds.size;
gsk_ngl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, color));
gsk_ngl_program_set_uniform_color (job->current_program,
UNIFORM_COLOR_COLOR, 0,
&colors[0]);
gsk_ngl_render_job_draw_rect (job,
&GRAPHENE_RECT_INIT (origin->x,
origin->y,
size->width - widths[1],
widths[0]));
gsk_ngl_render_job_draw_rect (job,
&GRAPHENE_RECT_INIT (origin->x + size->width - widths[1],
origin->y,
widths[1],
size->height - widths[2]));
gsk_ngl_render_job_draw_rect (job,
&GRAPHENE_RECT_INIT (origin->x + widths[3],
origin->y + size->height - widths[2],
size->width - widths[1],
widths[2]));
gsk_ngl_render_job_draw_rect (job,
&GRAPHENE_RECT_INIT (origin->x,
origin->y + widths[0],
widths[3],
size->height - widths[0]));
gsk_ngl_render_job_end_draw (job);
}
static inline void
gsk_ngl_render_job_visit_uniform_border_node (GskNglRenderJob *job,
const GskRenderNode *node)
@@ -3414,7 +3456,10 @@ gsk_ngl_render_job_visit_node (GskNglRenderJob *job,
break;
case GSK_BORDER_NODE:
if (gsk_border_node_get_uniform (node))
if (gsk_border_node_get_uniform_color (node) &&
gsk_rounded_rect_is_rectilinear (gsk_border_node_get_outline (node)))
gsk_ngl_render_job_visit_rect_border_node (job, node);
else if (gsk_border_node_get_uniform (node))
gsk_ngl_render_job_visit_uniform_border_node (job, node);
else
gsk_ngl_render_job_visit_border_node (job, node);

View File

@@ -1,5 +1,5 @@
debug {
message: "I'm a debug node.";
child: container {
}
message: "I'm a debug node.";
}