[gtk+/wip/baedert/gl: 205/216] gl renderer: Don't draw texture nodes to a framebuffer
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/baedert/gl: 205/216] gl renderer: Don't draw texture nodes to a framebuffer
- Date: Fri, 1 Dec 2017 10:20:19 +0000 (UTC)
commit 23a4dedda185047edbab5b1c2d63af9b8e22a1e9
Author: Timm Bäder <mail baedert org>
Date: Fri Nov 24 10:43:17 2017 +0100
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.
gsk/gl/gskglrenderer.c | 112 ++++++++++++++++++++++++++++++++----------------
1 files changed, 75 insertions(+), 37 deletions(-)
---
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index f549f65..c20d95c 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -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
@@ -750,25 +750,36 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
case GSK_OPACITY_NODE:
{
int texture_id;
+ gboolean is_offscreen;
float prev_opacity;
- GskQuadVertex vertex_data[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 }, },
- };
- texture_id = add_offscreen_ops (self, builder, min_x, max_x, min_y, max_y,
- gsk_opacity_node_get_child (node));
+ 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);
- ops_draw (builder, vertex_data);
+
+ if (is_offscreen)
+ {
+ GskQuadVertex vertex_data[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 }, },
+ };
+ ops_draw (builder, vertex_data);
+ }
+ else
+ {
+ ops_draw (builder, vertex_data);
+ }
ops_set_opacity (builder, prev_opacity);
}
break;
@@ -942,23 +953,14 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
}
break;
-
case GSK_COLOR_MATRIX_NODE:
{
int texture_id;
+ gboolean is_offscreen;
RenderOp op;
- GskQuadVertex vertex_data[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 }, },
- };
-
- texture_id = add_offscreen_ops (self, builder, min_x, max_x, min_y, max_y,
- gsk_color_matrix_node_get_child (node));
+ 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;
@@ -967,7 +969,26 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
ops_add (builder, &op);
ops_set_texture (builder, texture_id);
- ops_draw (builder, vertex_data);
+
+ if (is_offscreen)
+ {
+ GskQuadVertex vertex_data[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 }, },
+ };
+
+ ops_draw (builder, vertex_data);
+ }
+ else
+ {
+ ops_draw (builder, vertex_data);
+ }
+
}
break;
@@ -1025,16 +1046,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;
@@ -1044,11 +1066,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;
+
+ 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);
+ *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,
@@ -1072,7 +1110,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
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]