mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-27 06:00:22 +00:00
gl renderer: Don't draw texture nodes to a framebuffer
We don't need to create a texture from a texture node. We can simply use its texture instead and draw it however we want.
This commit is contained in:
parent
e3264d5fd3
commit
2865ab84a9
@ -42,8 +42,6 @@
|
||||
g_assert (self->program_name.location_name != 0); \
|
||||
}G_STMT_END
|
||||
|
||||
|
||||
|
||||
static void G_GNUC_UNUSED
|
||||
dump_framebuffer (const char *filename, int w, int h)
|
||||
{
|
||||
@ -77,13 +75,15 @@ font_has_color_glyphs (const PangoFont *font)
|
||||
}
|
||||
|
||||
static void gsk_gl_renderer_setup_render_mode (GskGLRenderer *self);
|
||||
static int add_offscreen_ops (GskGLRenderer *self,
|
||||
static void add_offscreen_ops (GskGLRenderer *self,
|
||||
RenderOpBuilder *builder,
|
||||
float min_x,
|
||||
float max_x,
|
||||
float min_y,
|
||||
float max_y,
|
||||
GskRenderNode *child_node);
|
||||
GskRenderNode *child_node,
|
||||
int *texture_id,
|
||||
gboolean *is_offscreen);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
typedef struct
|
||||
@ -719,7 +719,21 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
|
||||
case GSK_OPACITY_NODE:
|
||||
{
|
||||
int texture_id;
|
||||
gboolean is_offscreen;
|
||||
float prev_opacity;
|
||||
|
||||
|
||||
add_offscreen_ops (self, builder, min_x, max_x, min_y, max_y,
|
||||
gsk_opacity_node_get_child (node),
|
||||
&texture_id, &is_offscreen);
|
||||
|
||||
/* Now draw the texture with the node's opacity */
|
||||
ops_set_program (builder, &self->blit_program);
|
||||
prev_opacity = ops_set_opacity (builder, gsk_opacity_node_get_opacity (node));
|
||||
ops_set_texture (builder, texture_id);
|
||||
|
||||
if (is_offscreen)
|
||||
{
|
||||
GskQuadVertex vertex_data[GL_N_VERTICES] = {
|
||||
{ { min_x, min_y }, { 0, 1 }, },
|
||||
{ { min_x, max_y }, { 0, 0 }, },
|
||||
@ -729,15 +743,12 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
|
||||
{ { min_x, max_y }, { 0, 0 }, },
|
||||
{ { max_x, min_y }, { 1, 1 }, },
|
||||
};
|
||||
|
||||
texture_id = add_offscreen_ops (self, builder, min_x, max_x, min_y, max_y,
|
||||
gsk_opacity_node_get_child (node));
|
||||
|
||||
/* Now draw the texture with the node's opacity */
|
||||
ops_set_program (builder, &self->blit_program);
|
||||
prev_opacity = ops_set_opacity (builder, gsk_opacity_node_get_opacity (node));
|
||||
ops_set_texture (builder, texture_id);
|
||||
ops_draw (builder, vertex_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
ops_draw (builder, vertex_data);
|
||||
}
|
||||
ops_set_opacity (builder, prev_opacity);
|
||||
}
|
||||
break;
|
||||
@ -911,11 +922,25 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_COLOR_MATRIX_NODE:
|
||||
{
|
||||
int texture_id;
|
||||
gboolean is_offscreen;
|
||||
RenderOp op;
|
||||
add_offscreen_ops (self, builder, min_x, max_x, min_y, max_y,
|
||||
gsk_color_matrix_node_get_child (node),
|
||||
&texture_id, &is_offscreen);
|
||||
|
||||
ops_set_program (builder, &self->color_matrix_program);
|
||||
op.op = OP_CHANGE_COLOR_MATRIX;
|
||||
op.color_matrix.matrix = *gsk_color_matrix_node_peek_color_matrix (node);
|
||||
op.color_matrix.offset = *gsk_color_matrix_node_peek_color_offset (node);
|
||||
ops_add (builder, &op);
|
||||
|
||||
ops_set_texture (builder, texture_id);
|
||||
|
||||
if (is_offscreen)
|
||||
{
|
||||
GskQuadVertex vertex_data[GL_N_VERTICES] = {
|
||||
{ { min_x, min_y }, { 0, 1 }, },
|
||||
{ { min_x, max_y }, { 0, 0 }, },
|
||||
@ -926,18 +951,14 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
|
||||
{ { max_x, min_y }, { 1, 1 }, },
|
||||
};
|
||||
|
||||
texture_id = add_offscreen_ops (self, builder, min_x, max_x, min_y, max_y,
|
||||
gsk_color_matrix_node_get_child (node));
|
||||
|
||||
ops_set_program (builder, &self->color_matrix_program);
|
||||
op.op = OP_CHANGE_COLOR_MATRIX;
|
||||
op.color_matrix.matrix = *gsk_color_matrix_node_peek_color_matrix (node);
|
||||
op.color_matrix.offset = *gsk_color_matrix_node_peek_color_offset (node);
|
||||
ops_add (builder, &op);
|
||||
|
||||
ops_set_texture (builder, texture_id);
|
||||
ops_draw (builder, vertex_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
ops_draw (builder, vertex_data);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
|
||||
@ -994,16 +1015,17 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
add_offscreen_ops (GskGLRenderer *self,
|
||||
RenderOpBuilder *builder,
|
||||
float min_x,
|
||||
float max_x,
|
||||
float min_y,
|
||||
float max_y,
|
||||
GskRenderNode *child_node)
|
||||
GskRenderNode *child_node,
|
||||
int *texture_id,
|
||||
gboolean *is_offscreen)
|
||||
{
|
||||
int texture_id;
|
||||
int render_target;
|
||||
int prev_render_target;
|
||||
RenderOp op;
|
||||
@ -1013,11 +1035,27 @@ add_offscreen_ops (GskGLRenderer *self,
|
||||
graphene_rect_t prev_viewport;
|
||||
graphene_matrix_t item_proj;
|
||||
|
||||
/* We need the child node as a texture. If it already is one, we don't need to draw
|
||||
* it on a framebuffer of course. */
|
||||
if (gsk_render_node_get_node_type (child_node) == GSK_TEXTURE_NODE)
|
||||
{
|
||||
GdkTexture *texture = gsk_texture_node_get_texture (child_node);
|
||||
int gl_min_filter = GL_NEAREST, gl_mag_filter = GL_NEAREST;
|
||||
|
||||
texture_id = gsk_gl_driver_create_texture (self->gl_driver, max_x - min_x, max_y - min_y);
|
||||
gsk_gl_driver_bind_source_texture (self->gl_driver, texture_id);
|
||||
gsk_gl_driver_init_texture_empty (self->gl_driver, texture_id);
|
||||
render_target = gsk_gl_driver_create_render_target (self->gl_driver, texture_id, TRUE, TRUE);
|
||||
get_gl_scaling_filters (child_node, &gl_min_filter, &gl_mag_filter);
|
||||
|
||||
*texture_id = gsk_gl_driver_get_texture_for_texture (self->gl_driver,
|
||||
texture,
|
||||
gl_min_filter,
|
||||
gl_mag_filter);
|
||||
*is_offscreen = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
*texture_id = gsk_gl_driver_create_texture (self->gl_driver, max_x - min_x, max_y - min_y);
|
||||
gsk_gl_driver_bind_source_texture (self->gl_driver, *texture_id);
|
||||
gsk_gl_driver_init_texture_empty (self->gl_driver, *texture_id);
|
||||
render_target = gsk_gl_driver_create_render_target (self->gl_driver, *texture_id, TRUE, TRUE);
|
||||
|
||||
graphene_matrix_init_ortho (&item_proj,
|
||||
min_x, max_x,
|
||||
@ -1041,7 +1079,7 @@ add_offscreen_ops (GskGLRenderer *self,
|
||||
ops_set_projection (builder, &prev_projection);
|
||||
ops_set_render_target (builder, prev_render_target);
|
||||
|
||||
return texture_id;
|
||||
*is_offscreen = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user