summaryrefslogtreecommitdiff
path: root/gsk
diff options
context:
space:
mode:
authorTimm Bäder <tbaeder@redhat.com>2019-06-04 17:28:59 +0000
committerMatthias Clasen <mclasen@redhat.com>2019-06-04 23:00:02 +0000
commitecb353f4af766b951fb34ab148d42b8a451b75e0 (patch)
treec01790f32a4f49c4f89efbdc3734aaa976928c81 /gsk
parent259bbdcb099fd1fd73c0e9839efd5e66e3ebe31d (diff)
downloadgtk+-ecb353f4af766b951fb34ab148d42b8a451b75e0.tar.gz
Consider all offscreen drawings for the icon cache
Diffstat (limited to 'gsk')
-rw-r--r--gsk/gl/gskglrenderer.c253
1 files changed, 140 insertions, 113 deletions
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index a288fea50b..ab7fcd1f01 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -67,6 +67,26 @@ typedef enum
DUMP_FRAMEBUFFER = 1 << 3
} OffscreenFlags;
+typedef struct
+{
+ int texture_id;
+ float x;
+ float y;
+ float x2;
+ float y2;
+} TextureRegion;
+
+static inline void
+init_full_texture_region (TextureRegion *r,
+ int texture_id)
+{
+ r->texture_id = texture_id;
+ r->x = 0;
+ r->y = 0;
+ r->x2 = 1;
+ r->y2 = 1;
+}
+
static void G_GNUC_UNUSED
print_render_node_tree (GskRenderNode *root, int level)
{
@@ -187,15 +207,6 @@ font_has_color_glyphs (const PangoFont *font)
return has_color;
}
-static void
-get_gl_scaling_filters (GskRenderNode *node,
- int *min_filter_r,
- int *mag_filter_r)
-{
- *min_filter_r = GL_LINEAR;
- *mag_filter_r = GL_LINEAR;
-}
-
static inline void
rgba_to_float (const GdkRGBA *c,
float *f)
@@ -297,7 +308,7 @@ static void add_offscreen_ops (GskGLRenderer *self,
RenderOpBuilder *builder,
const graphene_rect_t *bounds,
GskRenderNode *child_node,
- int *texture_id,
+ TextureRegion *region_out,
gboolean *is_offscreen,
guint flags);
static void gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
@@ -790,6 +801,42 @@ render_color_node (GskGLRenderer *self,
}
static inline void
+upload_texture (GskGLRenderer *self,
+ GdkTexture *texture,
+ TextureRegion *out_region)
+{
+ int texture_id;
+
+ if (texture->width <= 128 &&
+ texture->height <= 128)
+ {
+ graphene_rect_t trect;
+
+ gsk_gl_icon_cache_lookup_or_add (self->icon_cache,
+ texture,
+ &texture_id,
+ &trect);
+ out_region->x = trect.origin.x;
+ out_region->y = trect.origin.y;
+ out_region->x2 = out_region->x + trect.size.width;
+ out_region->y2 = out_region->y + trect.size.height;
+ }
+ else
+ {
+ texture_id = gsk_gl_driver_get_texture_for_texture (self->gl_driver,
+ texture,
+ GL_LINEAR,
+ GL_LINEAR);
+ out_region->x = 0;
+ out_region->y = 0;
+ out_region->x2 = 1;
+ out_region->y2 = 1;
+ }
+
+ out_region->texture_id = texture_id;
+}
+
+static inline void
render_texture_node (GskGLRenderer *self,
GskRenderNode *node,
RenderOpBuilder *builder)
@@ -836,45 +883,21 @@ render_texture_node (GskGLRenderer *self,
}
else
{
- int texture_id;
- float tx = 0, ty = 0, tx2 = 1, ty2 = 1;
-
- if (texture->width <= 128 &&
- texture->height <= 128)
- {
- graphene_rect_t trect;
-
- gsk_gl_icon_cache_lookup_or_add (self->icon_cache,
- texture,
- &texture_id,
- &trect);
- tx = trect.origin.x;
- ty = trect.origin.y;
- tx2 = tx + trect.size.width;
- ty2 = ty + trect.size.height;
- }
- else
- {
- int gl_min_filter = GL_NEAREST, gl_mag_filter = GL_NEAREST;
- get_gl_scaling_filters (node, &gl_min_filter, &gl_mag_filter);
+ TextureRegion r;
- texture_id = gsk_gl_driver_get_texture_for_texture (self->gl_driver,
- texture,
- gl_min_filter,
- gl_mag_filter);
- }
+ upload_texture (self, texture, &r);
ops_set_program (builder, &self->blit_program);
- ops_set_texture (builder, texture_id);
+ ops_set_texture (builder, r.texture_id);
ops_draw (builder, (GskQuadVertex[GL_N_VERTICES]) {
- { { min_x, min_y }, { tx, ty }, },
- { { min_x, max_y }, { tx, ty2 }, },
- { { max_x, min_y }, { tx2, ty }, },
+ { { min_x, min_y }, { r.x, r.y }, },
+ { { min_x, max_y }, { r.x, r.y2 }, },
+ { { max_x, min_y }, { r.x2, r.y }, },
- { { max_x, max_y }, { tx2, ty2 }, },
- { { min_x, max_y }, { tx, ty2 }, },
- { { max_x, min_y }, { tx2, ty }, },
+ { { max_x, max_y }, { r.x2, r.y2 }, },
+ { { min_x, max_y }, { r.x, r.y2 }, },
+ { { max_x, min_y }, { r.x2, r.y }, },
});
}
}
@@ -935,7 +958,7 @@ render_transform_node (GskGLRenderer *self,
const float min_y = child->bounds.origin.y;
const float max_x = min_x + child->bounds.size.width;
const float max_y = min_y + child->bounds.size.height;
- int texture_id;
+ TextureRegion region;
gboolean is_offscreen;
/* For non-trivial transforms, we draw everything on a texture and then
* draw the texture transformed. */
@@ -946,24 +969,24 @@ render_transform_node (GskGLRenderer *self,
add_offscreen_ops (self, builder,
&child->bounds,
child,
- &texture_id, &is_offscreen,
+ &region, &is_offscreen,
RESET_CLIP | RESET_OPACITY);
gsk_transform_to_matrix (node_transform, &mat);
ops_push_modelview (builder, node_transform);
- ops_set_texture (builder, texture_id);
+ ops_set_texture (builder, region.texture_id);
ops_set_program (builder, &self->blit_program);
if (is_offscreen)
{
const GskQuadVertex offscreen_vertex_data[GL_N_VERTICES] = {
- { { min_x, min_y }, { 0, 1 }, },
- { { min_x, max_y }, { 0, 0 }, },
- { { max_x, min_y }, { 1, 1 }, },
+ { { min_x, min_y }, { region.x, region.y2 }, },
+ { { min_x, max_y }, { region.x, region.y }, },
+ { { max_x, min_y }, { region.x2, region.y2 }, },
- { { max_x, max_y }, { 1, 0 }, },
- { { min_x, max_y }, { 0, 0 }, },
- { { max_x, min_y }, { 1, 1 }, },
+ { { max_x, max_y }, { region.x2, region.y }, },
+ { { min_x, max_y }, { region.x, region.y }, },
+ { { max_x, min_y }, { region.x2, region.y2 }, },
};
ops_draw (builder, offscreen_vertex_data);
@@ -971,13 +994,13 @@ render_transform_node (GskGLRenderer *self,
else
{
const GskQuadVertex onscreen_vertex_data[GL_N_VERTICES] = {
- { { min_x, min_y }, { 0, 0 }, },
- { { min_x, max_y }, { 0, 1 }, },
- { { max_x, min_y }, { 1, 0 }, },
+ { { min_x, min_y }, { region.x, region.y }, },
+ { { min_x, max_y }, { region.x, region.y2 }, },
+ { { max_x, min_y }, { region.x2, region.y }, },
- { { max_x, max_y }, { 1, 1 }, },
- { { min_x, max_y }, { 0, 1 }, },
- { { max_x, min_y }, { 1, 0 }, },
+ { { max_x, max_y }, { region.x2, region.y2 }, },
+ { { min_x, max_y }, { region.x, region.y2 }, },
+ { { max_x, min_y }, { region.x2, region.y }, },
};
ops_draw (builder, onscreen_vertex_data);
@@ -1237,7 +1260,7 @@ render_rounded_clip_node (GskGLRenderer *self,
const float max_y = min_y + node->bounds.size.height;
graphene_matrix_t scale_matrix;
gboolean is_offscreen;
- int texture_id;
+ TextureRegion region;
/* NOTE: We are *not* transforming the clip by the current modelview here.
* We instead draw the untransformed clip to a texture and then transform
* that texture.
@@ -1258,18 +1281,18 @@ render_rounded_clip_node (GskGLRenderer *self,
ops_push_clip (builder, &child_clip);
add_offscreen_ops (self, builder, &node->bounds,
child,
- &texture_id, &is_offscreen,
+ &region, &is_offscreen,
FORCE_OFFSCREEN | RESET_OPACITY);
ops_pop_clip (builder);
ops_set_program (builder, &self->blit_program);
- ops_set_texture (builder, texture_id);
+ ops_set_texture (builder, region.texture_id);
ops_draw (builder, (GskQuadVertex[GL_N_VERTICES]) {
{ { min_x, min_y }, { 0, 1 }, },
{ { min_x, max_y }, { 0, 0 }, },
{ { max_x, min_y }, { 1, 1 }, },
-
+
{ { max_x, max_y }, { 1, 0 }, },
{ { min_x, max_y }, { 0, 0 }, },
{ { max_x, min_y }, { 1, 1 }, },
@@ -1289,13 +1312,13 @@ render_color_matrix_node (GskGLRenderer *self,
const float max_x = min_x + node->bounds.size.width;
const float max_y = min_y + node->bounds.size.height;
GskRenderNode *child = gsk_color_matrix_node_get_child (node);
- int texture_id;
+ TextureRegion region;
gboolean is_offscreen;
add_offscreen_ops (self, builder,
&node->bounds,
child,
- &texture_id, &is_offscreen,
+ &region, &is_offscreen,
RESET_CLIP | RESET_OPACITY);
ops_set_program (builder, &self->color_matrix_program);
@@ -1303,25 +1326,35 @@ render_color_matrix_node (GskGLRenderer *self,
gsk_color_matrix_node_peek_color_matrix (node),
gsk_color_matrix_node_peek_color_offset (node));
- ops_set_texture (builder, texture_id);
+ ops_set_texture (builder, region.texture_id);
if (is_offscreen)
{
GskQuadVertex offscreen_vertex_data[GL_N_VERTICES] = {
- { { min_x, min_y }, { 0, 1 }, },
- { { min_x, max_y }, { 0, 0 }, },
- { { max_x, min_y }, { 1, 1 }, },
+ { { min_x, min_y }, { region.x, region.y2 }, },
+ { { min_x, max_y }, { region.x, region.y }, },
+ { { max_x, min_y }, { region.x2, region.y2 }, },
- { { max_x, max_y }, { 1, 0 }, },
- { { min_x, max_y }, { 0, 0 }, },
- { { max_x, min_y }, { 1, 1 }, },
+ { { max_x, max_y }, { region.x2, region.y }, },
+ { { min_x, max_y }, { region.x, region.y }, },
+ { { max_x, min_y }, { region.x2, region.y2 }, },
};
ops_draw (builder, offscreen_vertex_data);
}
else
{
- ops_draw (builder, vertex_data);
+ const GskQuadVertex onscreen_vertex_data[GL_N_VERTICES] = {
+ { { min_x, min_y }, { region.x, region.y }, },
+ { { min_x, max_y }, { region.x, region.y2 }, },
+ { { max_x, min_y }, { region.x2, region.y }, },
+
+ { { max_x, max_y }, { region.x2, region.y2 }, },
+ { { min_x, max_y }, { region.x, region.y2 }, },
+ { { max_x, min_y }, { region.x2, region.y }, },
+ };
+
+ ops_draw (builder, onscreen_vertex_data);
}
}
@@ -1336,7 +1369,7 @@ render_blur_node (GskGLRenderer *self,
const float max_x = min_x + node->bounds.size.width;
const float max_y = min_y + node->bounds.size.height;
const float blur_radius = gsk_blur_node_get_radius (node);
- int texture_id;
+ TextureRegion region;
gboolean is_offscreen;
RenderOp op;
@@ -1354,7 +1387,7 @@ render_blur_node (GskGLRenderer *self,
add_offscreen_ops (self, builder,
&node->bounds,
gsk_blur_node_get_child (node),
- &texture_id, &is_offscreen,
+ &region, &is_offscreen,
RESET_CLIP | FORCE_OFFSCREEN | RESET_OPACITY);
ops_set_program (builder, &self->blur_program);
@@ -1363,7 +1396,7 @@ render_blur_node (GskGLRenderer *self,
op.blur.radius = gsk_blur_node_get_radius (node);
ops_add (builder, &op);
- ops_set_texture (builder, texture_id);
+ ops_set_texture (builder, region.texture_id);
if (is_offscreen)
{
@@ -1371,7 +1404,7 @@ render_blur_node (GskGLRenderer *self,
{ { min_x, min_y }, { 0, 1 }, },
{ { min_x, max_y }, { 0, 0 }, },
{ { max_x, min_y }, { 1, 1 }, },
-
+
{ { max_x, max_y }, { 1, 0 }, },
{ { min_x, max_y }, { 0, 0 }, },
{ { max_x, min_y }, { 1, 1 }, },
@@ -1856,7 +1889,7 @@ render_shadow_node (GskGLRenderer *self,
const GskShadow *shadow = gsk_shadow_node_peek_shadow (node, i);
const float dx = shadow->dx;
const float dy = shadow->dy;
- int texture_id;
+ TextureRegion region;
gboolean is_offscreen;
g_assert (shadow->radius <= 0);
@@ -1880,22 +1913,22 @@ render_shadow_node (GskGLRenderer *self,
/* Draw the child offscreen, without the offset. */
add_offscreen_ops (self, builder,
&shadow_child->bounds,
- shadow_child, &texture_id, &is_offscreen,
+ shadow_child, &region, &is_offscreen,
RESET_CLIP | RESET_OPACITY);
ops_set_program (builder, &self->coloring_program);
ops_set_color (builder, &shadow->color);
- ops_set_texture (builder, texture_id);
+ ops_set_texture (builder, region.texture_id);
if (is_offscreen)
{
const GskQuadVertex offscreen_vertex_data[GL_N_VERTICES] = {
- { { dx + min_x, dy + min_y }, { 0, 1 }, },
- { { dx + min_x, dy + max_y }, { 0, 0 }, },
- { { dx + max_x, dy + min_y }, { 1, 1 }, },
+ { { dx + min_x, dy + min_y }, { region.x, region.y2 }, },
+ { { dx + min_x, dy + max_y }, { region.x, region.y }, },
+ { { dx + max_x, dy + min_y }, { region.x2, region.y2 }, },
- { { dx + max_x, dy + max_y }, { 1, 0 }, },
- { { dx + min_x, dy + max_y }, { 0, 0 }, },
- { { dx + max_x, dy + min_y }, { 1, 1 }, },
+ { { dx + max_x, dy + max_y }, { region.x2, region.y }, },
+ { { dx + min_x, dy + max_y }, { region.x, region.y }, },
+ { { dx + max_x, dy + min_y }, { region.x2, region.y2 }, },
};
ops_draw (builder, offscreen_vertex_data);
@@ -1903,13 +1936,13 @@ render_shadow_node (GskGLRenderer *self,
else
{
const GskQuadVertex onscreen_vertex_data[GL_N_VERTICES] = {
- { { dx + min_x, dy + min_y }, { 0, 0 }, },
- { { dx + min_x, dy + max_y }, { 0, 1 }, },
- { { dx + max_x, dy + min_y }, { 1, 0 }, },
+ { { dx + min_x, dy + min_y }, { region.x, region.y }, },
+ { { dx + min_x, dy + max_y }, { region.x, region.y2 }, },
+ { { dx + max_x, dy + min_y }, { region.x2, region.y }, },
- { { dx + max_x, dy + max_y }, { 1, 1 }, },
- { { dx + min_x, dy + max_y }, { 0, 1 }, },
- { { dx + max_x, dy + min_y }, { 1, 0 }, },
+ { { dx + max_x, dy + max_y }, { region.x2, region.y2 }, },
+ { { dx + min_x, dy + max_y }, { region.x, region.y2 }, },
+ { { dx + max_x, dy + min_y }, { region.x2, region.y }, },
};
ops_draw (builder, onscreen_vertex_data);
@@ -1932,8 +1965,8 @@ render_cross_fade_node (GskGLRenderer *self,
GskRenderNode *start_node = gsk_cross_fade_node_get_start_child (node);
GskRenderNode *end_node = gsk_cross_fade_node_get_end_child (node);
float progress = gsk_cross_fade_node_get_progress (node);
- int start_texture_id;
- int end_texture_id;
+ TextureRegion start_region;
+ TextureRegion end_region;
gboolean is_offscreen1, is_offscreen2;
RenderOp op;
const GskQuadVertex vertex_data[GL_N_VERTICES] = {
@@ -1952,21 +1985,21 @@ render_cross_fade_node (GskGLRenderer *self,
add_offscreen_ops (self, builder,
&node->bounds,
start_node,
- &start_texture_id, &is_offscreen1,
+ &start_region, &is_offscreen1,
FORCE_OFFSCREEN | RESET_CLIP | RESET_OPACITY);
add_offscreen_ops (self, builder,
&node->bounds,
end_node,
- &end_texture_id, &is_offscreen2,
+ &end_region, &is_offscreen2,
FORCE_OFFSCREEN | RESET_CLIP | RESET_OPACITY);
ops_set_program (builder, &self->cross_fade_program);
op.op = OP_CHANGE_CROSS_FADE;
op.cross_fade.progress = progress;
- op.cross_fade.source2 = end_texture_id;
+ op.cross_fade.source2 = end_region.texture_id;
ops_add (builder, &op);
- ops_set_texture (builder, start_texture_id);
+ ops_set_texture (builder, start_region.texture_id);
ops_draw (builder, vertex_data);
}
@@ -1982,8 +2015,8 @@ render_blend_node (GskGLRenderer *self,
const float min_y = builder->dy + node->bounds.origin.y;
const float max_x = min_x + node->bounds.size.width;
const float max_y = min_y + node->bounds.size.height;
- int top_texture_id;
- int bottom_texture_id;
+ TextureRegion top_region;
+ TextureRegion bottom_region;
gboolean is_offscreen1, is_offscreen2;
RenderOp op;
const GskQuadVertex vertex_data[GL_N_VERTICES] = {
@@ -2001,19 +2034,19 @@ render_blend_node (GskGLRenderer *self,
add_offscreen_ops (self, builder,
&node->bounds,
bottom_child,
- &bottom_texture_id, &is_offscreen1,
+ &bottom_region, &is_offscreen1,
FORCE_OFFSCREEN | RESET_CLIP);
add_offscreen_ops (self, builder,
&node->bounds,
top_child,
- &top_texture_id, &is_offscreen2,
+ &top_region, &is_offscreen2,
FORCE_OFFSCREEN | RESET_CLIP);
ops_set_program (builder, &self->blend_program);
- ops_set_texture (builder, bottom_texture_id);
+ ops_set_texture (builder, bottom_region.texture_id);
op.op = OP_CHANGE_BLEND;
- op.blend.source2 = top_texture_id;
+ op.blend.source2 = top_region.texture_id;
op.blend.mode = gsk_blend_node_get_blend_mode (node);
ops_add (builder, &op);
ops_draw (builder, vertex_data);
@@ -2814,7 +2847,7 @@ add_offscreen_ops (GskGLRenderer *self,
RenderOpBuilder *builder,
const graphene_rect_t *bounds,
GskRenderNode *child_node,
- int *texture_id_out,
+ TextureRegion *texture_region_out,
gboolean *is_offscreen,
guint flags)
{
@@ -2839,14 +2872,8 @@ add_offscreen_ops (GskGLRenderer *self,
(flags & FORCE_OFFSCREEN) == 0)
{
GdkTexture *texture = gsk_texture_node_get_texture (child_node);
- int gl_min_filter = GL_NEAREST, gl_mag_filter = GL_NEAREST;
-
- get_gl_scaling_filters (child_node, &gl_min_filter, &gl_mag_filter);
- *texture_id_out = gsk_gl_driver_get_texture_for_texture (self->gl_driver,
- texture,
- gl_min_filter,
- gl_mag_filter);
+ upload_texture (self, texture, texture_region_out);
*is_offscreen = FALSE;
return;
}
@@ -2857,7 +2884,7 @@ add_offscreen_ops (GskGLRenderer *self,
if (cached_id != 0)
{
- *texture_id_out = cached_id;
+ init_full_texture_region (texture_region_out, cached_id);
/* We didn't render it offscreen, but hand out an offscreen texture id */
*is_offscreen = TRUE;
return;
@@ -2929,7 +2956,7 @@ add_offscreen_ops (GskGLRenderer *self,
ops_set_render_target (builder, prev_render_target);
*is_offscreen = TRUE;
- *texture_id_out = texture_id;
+ init_full_texture_region (texture_region_out, texture_id);
gsk_gl_driver_set_texture_for_pointer (self->gl_driver, child_node, texture_id);
}