Skip drawing transparent borders and backgrounds
We were always drawing the border and background of each StThemeNode, even if they were transparent. The simple optimization of checking the alpha provides a significant performance boost (in a quick test, it increased the overviewFpsSubsequent metric in the core performance test from 28fps to 35fps). https://bugzilla.gnome.org/show_bug.cgi?id=634752
This commit is contained in:
parent
c3fb3a98b8
commit
3138b20b11
@ -262,6 +262,11 @@ st_theme_node_lookup_corner (StThemeNode *node,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (corner.color.alpha == 0 &&
|
||||||
|
corner.border_color_1.alpha == 0 &&
|
||||||
|
corner.border_color_2.alpha == 0)
|
||||||
|
return COGL_INVALID_HANDLE;
|
||||||
|
|
||||||
key = corner_to_string (&corner);
|
key = corner_to_string (&corner);
|
||||||
|
|
||||||
data.node = node;
|
data.node = node;
|
||||||
@ -676,6 +681,7 @@ st_theme_node_paint_borders (StThemeNode *node,
|
|||||||
int max_width_radius[4];
|
int max_width_radius[4];
|
||||||
int corner_id;
|
int corner_id;
|
||||||
ClutterColor border_color;
|
ClutterColor border_color;
|
||||||
|
guint8 alpha;
|
||||||
|
|
||||||
width = box->x2 - box->x1;
|
width = box->x2 - box->x1;
|
||||||
height = box->y2 - box->y1;
|
height = box->y2 - box->y1;
|
||||||
@ -697,58 +703,62 @@ st_theme_node_paint_borders (StThemeNode *node,
|
|||||||
float x1, y1, x2, y2;
|
float x1, y1, x2, y2;
|
||||||
|
|
||||||
over (&border_color, &node->background_color, &effective_border);
|
over (&border_color, &node->background_color, &effective_border);
|
||||||
|
alpha = paint_opacity * effective_border.alpha / 255;
|
||||||
|
|
||||||
cogl_set_source_color4ub (effective_border.red,
|
if (alpha > 0)
|
||||||
effective_border.green,
|
{
|
||||||
effective_border.blue,
|
cogl_set_source_color4ub (effective_border.red,
|
||||||
paint_opacity * effective_border.alpha / 255);
|
effective_border.green,
|
||||||
|
effective_border.blue,
|
||||||
|
alpha);
|
||||||
|
|
||||||
/* NORTH */
|
/* NORTH */
|
||||||
skip_corner_1 = node->border_radius[ST_CORNER_TOPLEFT] > 0;
|
skip_corner_1 = node->border_radius[ST_CORNER_TOPLEFT] > 0;
|
||||||
skip_corner_2 = node->border_radius[ST_CORNER_TOPRIGHT] > 0;
|
skip_corner_2 = node->border_radius[ST_CORNER_TOPRIGHT] > 0;
|
||||||
|
|
||||||
x1 = skip_corner_1 ? max_width_radius[ST_CORNER_TOPLEFT] : 0;
|
x1 = skip_corner_1 ? max_width_radius[ST_CORNER_TOPLEFT] : 0;
|
||||||
y1 = 0;
|
y1 = 0;
|
||||||
x2 = skip_corner_2 ? width - max_width_radius[ST_CORNER_TOPRIGHT] : width;
|
x2 = skip_corner_2 ? width - max_width_radius[ST_CORNER_TOPRIGHT] : width;
|
||||||
y2 = border_width;
|
y2 = border_width;
|
||||||
cogl_rectangle (x1, y1, x2, y2);
|
cogl_rectangle (x1, y1, x2, y2);
|
||||||
|
|
||||||
/* EAST */
|
/* EAST */
|
||||||
skip_corner_1 = node->border_radius[ST_CORNER_TOPRIGHT] > 0;
|
skip_corner_1 = node->border_radius[ST_CORNER_TOPRIGHT] > 0;
|
||||||
skip_corner_2 = node->border_radius[ST_CORNER_BOTTOMRIGHT] > 0;
|
skip_corner_2 = node->border_radius[ST_CORNER_BOTTOMRIGHT] > 0;
|
||||||
|
|
||||||
x1 = width - border_width;
|
x1 = width - border_width;
|
||||||
y1 = skip_corner_1 ? max_width_radius[ST_CORNER_TOPRIGHT] : border_width;
|
y1 = skip_corner_1 ? max_width_radius[ST_CORNER_TOPRIGHT] : border_width;
|
||||||
x2 = width;
|
x2 = width;
|
||||||
y2 = skip_corner_2 ? height - max_width_radius[ST_CORNER_BOTTOMRIGHT]
|
y2 = skip_corner_2 ? height - max_width_radius[ST_CORNER_BOTTOMRIGHT]
|
||||||
: height - border_width;
|
: height - border_width;
|
||||||
cogl_rectangle (x1, y1, x2, y2);
|
cogl_rectangle (x1, y1, x2, y2);
|
||||||
|
|
||||||
/* SOUTH */
|
/* SOUTH */
|
||||||
skip_corner_1 = node->border_radius[ST_CORNER_BOTTOMLEFT] > 0;
|
skip_corner_1 = node->border_radius[ST_CORNER_BOTTOMLEFT] > 0;
|
||||||
skip_corner_2 = node->border_radius[ST_CORNER_BOTTOMRIGHT] > 0;
|
skip_corner_2 = node->border_radius[ST_CORNER_BOTTOMRIGHT] > 0;
|
||||||
|
|
||||||
x1 = skip_corner_1 ? max_width_radius[ST_CORNER_BOTTOMLEFT] : 0;
|
x1 = skip_corner_1 ? max_width_radius[ST_CORNER_BOTTOMLEFT] : 0;
|
||||||
y1 = height - border_width;
|
y1 = height - border_width;
|
||||||
x2 = skip_corner_2 ? width - max_width_radius[ST_CORNER_BOTTOMRIGHT]
|
x2 = skip_corner_2 ? width - max_width_radius[ST_CORNER_BOTTOMRIGHT]
|
||||||
: width;
|
: width;
|
||||||
y2 = height;
|
y2 = height;
|
||||||
cogl_rectangle (x1, y1, x2, y2);
|
cogl_rectangle (x1, y1, x2, y2);
|
||||||
|
|
||||||
/* WEST */
|
/* WEST */
|
||||||
skip_corner_1 = node->border_radius[ST_CORNER_TOPLEFT] > 0;
|
skip_corner_1 = node->border_radius[ST_CORNER_TOPLEFT] > 0;
|
||||||
skip_corner_2 = node->border_radius[ST_CORNER_BOTTOMLEFT] > 0;
|
skip_corner_2 = node->border_radius[ST_CORNER_BOTTOMLEFT] > 0;
|
||||||
|
|
||||||
x1 = 0;
|
x1 = 0;
|
||||||
y1 = skip_corner_1 ? max_width_radius[ST_CORNER_TOPLEFT] : border_width;
|
y1 = skip_corner_1 ? max_width_radius[ST_CORNER_TOPLEFT] : border_width;
|
||||||
x2 = border_width;
|
x2 = border_width;
|
||||||
y2 = skip_corner_2 ? height - max_width_radius[ST_CORNER_BOTTOMLEFT]
|
y2 = skip_corner_2 ? height - max_width_radius[ST_CORNER_BOTTOMLEFT]
|
||||||
: height - border_width;
|
: height - border_width;
|
||||||
cogl_rectangle (x1, y1, x2, y2);
|
cogl_rectangle (x1, y1, x2, y2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* corners */
|
/* corners */
|
||||||
if (max_border_radius > 0)
|
if (max_border_radius > 0 && paint_opacity > 0)
|
||||||
{
|
{
|
||||||
for (corner_id = 0; corner_id < 4; corner_id++)
|
for (corner_id = 0; corner_id < 4; corner_id++)
|
||||||
{
|
{
|
||||||
@ -787,105 +797,109 @@ st_theme_node_paint_borders (StThemeNode *node,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* background color */
|
/* background color */
|
||||||
cogl_set_source_color4ub (node->background_color.red,
|
alpha = paint_opacity * node->background_color.alpha / 255;
|
||||||
node->background_color.green,
|
if (alpha > 0)
|
||||||
node->background_color.blue,
|
|
||||||
paint_opacity * node->background_color.alpha / 255);
|
|
||||||
|
|
||||||
/* We add padding to each corner, so that all corners end up as if they
|
|
||||||
* had a border-radius of max_border_radius, which allows us to treat
|
|
||||||
* corners as uniform further on.
|
|
||||||
*/
|
|
||||||
for (corner_id = 0; corner_id < 4; corner_id++)
|
|
||||||
{
|
{
|
||||||
float verts[8];
|
cogl_set_source_color4ub (node->background_color.red,
|
||||||
int n_rects;
|
node->background_color.green,
|
||||||
|
node->background_color.blue,
|
||||||
|
alpha);
|
||||||
|
|
||||||
/* corner texture does not need padding */
|
/* We add padding to each corner, so that all corners end up as if they
|
||||||
if (max_border_radius == node->border_radius[corner_id])
|
* had a border-radius of max_border_radius, which allows us to treat
|
||||||
continue;
|
* corners as uniform further on.
|
||||||
|
|
||||||
n_rects = node->border_radius[corner_id] == 0 ? 1 : 2;
|
|
||||||
|
|
||||||
switch (corner_id)
|
|
||||||
{
|
|
||||||
case ST_CORNER_TOPLEFT:
|
|
||||||
verts[0] = border_width;
|
|
||||||
verts[1] = max_width_radius[ST_CORNER_TOPLEFT];
|
|
||||||
verts[2] = max_border_radius;
|
|
||||||
verts[3] = max_border_radius;
|
|
||||||
if (n_rects == 2)
|
|
||||||
{
|
|
||||||
verts[4] = max_width_radius[ST_CORNER_TOPLEFT];
|
|
||||||
verts[5] = border_width;
|
|
||||||
verts[6] = max_border_radius;
|
|
||||||
verts[7] = max_width_radius[ST_CORNER_TOPLEFT];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ST_CORNER_TOPRIGHT:
|
|
||||||
verts[0] = width - max_border_radius;
|
|
||||||
verts[1] = max_width_radius[ST_CORNER_TOPRIGHT];
|
|
||||||
verts[2] = width - border_width;
|
|
||||||
verts[3] = max_border_radius;
|
|
||||||
if (n_rects == 2)
|
|
||||||
{
|
|
||||||
verts[4] = width - max_border_radius;
|
|
||||||
verts[5] = border_width;
|
|
||||||
verts[6] = width - max_width_radius[ST_CORNER_TOPRIGHT];
|
|
||||||
verts[7] = max_width_radius[ST_CORNER_TOPRIGHT];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ST_CORNER_BOTTOMRIGHT:
|
|
||||||
verts[0] = width - max_border_radius;
|
|
||||||
verts[1] = height - max_border_radius;
|
|
||||||
verts[2] = width - border_width;
|
|
||||||
verts[3] = height - max_width_radius[ST_CORNER_BOTTOMRIGHT];
|
|
||||||
if (n_rects == 2)
|
|
||||||
{
|
|
||||||
verts[4] = width - max_border_radius;
|
|
||||||
verts[5] = height - max_width_radius[ST_CORNER_BOTTOMRIGHT];
|
|
||||||
verts[6] = width - max_width_radius[ST_CORNER_BOTTOMRIGHT];
|
|
||||||
verts[7] = height - border_width;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ST_CORNER_BOTTOMLEFT:
|
|
||||||
verts[0] = border_width;
|
|
||||||
verts[1] = height - max_border_radius;
|
|
||||||
verts[2] = max_border_radius;
|
|
||||||
verts[3] = height - max_width_radius[ST_CORNER_BOTTOMLEFT];
|
|
||||||
if (n_rects == 2)
|
|
||||||
{
|
|
||||||
verts[4] = max_width_radius[ST_CORNER_BOTTOMLEFT];
|
|
||||||
verts[5] = height - max_width_radius[ST_CORNER_BOTTOMLEFT];
|
|
||||||
verts[6] = max_border_radius;
|
|
||||||
verts[7] = height - border_width;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
cogl_rectangles (verts, n_rects);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (max_border_radius > border_width)
|
|
||||||
{
|
|
||||||
/* Once we've drawn the borders and corners, if the corners are bigger
|
|
||||||
* the the border width, the remaining area is shaped like
|
|
||||||
*
|
|
||||||
* ########
|
|
||||||
* ##########
|
|
||||||
* ##########
|
|
||||||
* ########
|
|
||||||
*
|
|
||||||
* We draw it in 3 pieces - first the top and bottom, then the main
|
|
||||||
* rectangle
|
|
||||||
*/
|
*/
|
||||||
cogl_rectangle (max_border_radius, border_width,
|
for (corner_id = 0; corner_id < 4; corner_id++)
|
||||||
width - max_border_radius, max_border_radius);
|
{
|
||||||
cogl_rectangle (max_border_radius, height - max_border_radius,
|
float verts[8];
|
||||||
width - max_border_radius, height - border_width);
|
int n_rects;
|
||||||
}
|
|
||||||
|
|
||||||
cogl_rectangle (border_width, MAX(border_width, max_border_radius),
|
/* corner texture does not need padding */
|
||||||
width - border_width, height - MAX(border_width, max_border_radius));
|
if (max_border_radius == node->border_radius[corner_id])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
n_rects = node->border_radius[corner_id] == 0 ? 1 : 2;
|
||||||
|
|
||||||
|
switch (corner_id)
|
||||||
|
{
|
||||||
|
case ST_CORNER_TOPLEFT:
|
||||||
|
verts[0] = border_width;
|
||||||
|
verts[1] = max_width_radius[ST_CORNER_TOPLEFT];
|
||||||
|
verts[2] = max_border_radius;
|
||||||
|
verts[3] = max_border_radius;
|
||||||
|
if (n_rects == 2)
|
||||||
|
{
|
||||||
|
verts[4] = max_width_radius[ST_CORNER_TOPLEFT];
|
||||||
|
verts[5] = border_width;
|
||||||
|
verts[6] = max_border_radius;
|
||||||
|
verts[7] = max_width_radius[ST_CORNER_TOPLEFT];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ST_CORNER_TOPRIGHT:
|
||||||
|
verts[0] = width - max_border_radius;
|
||||||
|
verts[1] = max_width_radius[ST_CORNER_TOPRIGHT];
|
||||||
|
verts[2] = width - border_width;
|
||||||
|
verts[3] = max_border_radius;
|
||||||
|
if (n_rects == 2)
|
||||||
|
{
|
||||||
|
verts[4] = width - max_border_radius;
|
||||||
|
verts[5] = border_width;
|
||||||
|
verts[6] = width - max_width_radius[ST_CORNER_TOPRIGHT];
|
||||||
|
verts[7] = max_width_radius[ST_CORNER_TOPRIGHT];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ST_CORNER_BOTTOMRIGHT:
|
||||||
|
verts[0] = width - max_border_radius;
|
||||||
|
verts[1] = height - max_border_radius;
|
||||||
|
verts[2] = width - border_width;
|
||||||
|
verts[3] = height - max_width_radius[ST_CORNER_BOTTOMRIGHT];
|
||||||
|
if (n_rects == 2)
|
||||||
|
{
|
||||||
|
verts[4] = width - max_border_radius;
|
||||||
|
verts[5] = height - max_width_radius[ST_CORNER_BOTTOMRIGHT];
|
||||||
|
verts[6] = width - max_width_radius[ST_CORNER_BOTTOMRIGHT];
|
||||||
|
verts[7] = height - border_width;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ST_CORNER_BOTTOMLEFT:
|
||||||
|
verts[0] = border_width;
|
||||||
|
verts[1] = height - max_border_radius;
|
||||||
|
verts[2] = max_border_radius;
|
||||||
|
verts[3] = height - max_width_radius[ST_CORNER_BOTTOMLEFT];
|
||||||
|
if (n_rects == 2)
|
||||||
|
{
|
||||||
|
verts[4] = max_width_radius[ST_CORNER_BOTTOMLEFT];
|
||||||
|
verts[5] = height - max_width_radius[ST_CORNER_BOTTOMLEFT];
|
||||||
|
verts[6] = max_border_radius;
|
||||||
|
verts[7] = height - border_width;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cogl_rectangles (verts, n_rects);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max_border_radius > border_width)
|
||||||
|
{
|
||||||
|
/* Once we've drawn the borders and corners, if the corners are bigger
|
||||||
|
* the the border width, the remaining area is shaped like
|
||||||
|
*
|
||||||
|
* ########
|
||||||
|
* ##########
|
||||||
|
* ##########
|
||||||
|
* ########
|
||||||
|
*
|
||||||
|
* We draw it in 3 pieces - first the top and bottom, then the main
|
||||||
|
* rectangle
|
||||||
|
*/
|
||||||
|
cogl_rectangle (max_border_radius, border_width,
|
||||||
|
width - max_border_radius, max_border_radius);
|
||||||
|
cogl_rectangle (max_border_radius, height - max_border_radius,
|
||||||
|
width - max_border_radius, height - border_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
cogl_rectangle (border_width, MAX(border_width, max_border_radius),
|
||||||
|
width - border_width, height - MAX(border_width, max_border_radius));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
Reference in New Issue
Block a user