gl renderer: Implement cross fade nodes

This commit is contained in:
Timm Bäder 2017-12-11 08:22:28 +01:00
parent bed03aa319
commit a83037c440
4 changed files with 90 additions and 4 deletions

View File

@ -199,6 +199,7 @@ struct _GskGLRenderer
Program outset_shadow_program;
Program shadow_program;
Program border_program;
Program cross_fade_program;
};
};
@ -992,6 +993,51 @@ render_shadow_node (GskGLRenderer *self,
gsk_gl_renderer_add_render_ops (self, original_child, builder);
}
static inline void
render_cross_fade_node (GskGLRenderer *self,
GskRenderNode *node,
RenderOpBuilder *builder)
{
const float min_x = node->bounds.origin.x;
const float min_y = node->bounds.origin.y;
const float max_x = min_x + node->bounds.size.width;
const float max_y = min_y + node->bounds.size.height;
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;
gboolean is_offscreen;
RenderOp op;
const 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 }, },
};
/* TODO: We create 2 textures here as big as the cross-fade node, but both the
* start and the end node might be a lot smaller than that. */
add_offscreen_ops (self, builder, min_x, max_x, min_y, max_y, start_node,
&start_texture_id, &is_offscreen);
add_offscreen_ops (self, builder, min_x, max_x, min_y, max_y, end_node,
&end_texture_id, &is_offscreen);
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;
ops_add (builder, &op);
ops_set_texture (builder, start_texture_id);
ops_draw (builder, vertex_data);
}
static void
gsk_gl_renderer_dispose (GObject *gobject)
{
@ -1073,6 +1119,7 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
{ "outset shadow", "blit.vs.glsl", "outset_shadow.fs.glsl" },
{ "shadow", "blit.vs.glsl", "shadow.fs.glsl" },
{ "border", "blit.vs.glsl", "border.fs.glsl" },
{ "cross fade", "blit.vs.glsl", "cross_fade.fs.glsl" },
};
builder = gsk_shader_builder_new ();
@ -1190,6 +1237,10 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
INIT_PROGRAM_UNIFORM_LOCATION (border, color);
INIT_PROGRAM_UNIFORM_LOCATION (border, widths);
/* cross fade */
INIT_PROGRAM_UNIFORM_LOCATION (cross_fade, progress);
INIT_PROGRAM_UNIFORM_LOCATION (cross_fade, source2);
g_object_unref (builder);
return TRUE;
}
@ -1510,8 +1561,11 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
render_border_node (self, node, builder);
break;
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
case GSK_CROSS_FADE_NODE:
render_cross_fade_node (self, node, builder);
break;
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
case GSK_BLEND_NODE:
case GSK_REPEAT_NODE:
default:
@ -1770,6 +1824,16 @@ gsk_gl_renderer_render_ops (GskGLRenderer *self,
break;
case OP_CHANGE_CROSS_FADE:
g_assert (program == &self->cross_fade_program);
/* End texture id */
glUniform1i (program->cross_fade.source2_location, 1);
glActiveTexture (GL_TEXTURE0 + 1);
glBindTexture (GL_TEXTURE_2D, op->cross_fade.source2);
/* progress */
glUniform1f (program->cross_fade.progress_location, op->cross_fade.progress);
break;
case OP_CHANGE_LINEAR_GRADIENT:
OP_PRINT (" -> Linear gradient");
glUniform1i (program->linear_gradient.num_color_stops_location,

View File

@ -10,7 +10,7 @@
#include "gskglrendererprivate.h"
#define GL_N_VERTICES 6
#define GL_N_PROGRAMS 11
#define GL_N_PROGRAMS 12
enum {
OP_NONE,
@ -31,8 +31,9 @@ enum {
OP_CHANGE_OUTSET_SHADOW = 15,
OP_CHANGE_BORDER = 16,
OP_CHANGE_BORDER_COLOR = 17,
OP_CLEAR = 18,
OP_DRAW = 19,
OP_CHANGE_CROSS_FADE = 18,
OP_CLEAR = 19,
OP_DRAW = 20,
};
typedef struct
@ -99,6 +100,10 @@ typedef struct
int color_location;
int widths_location;
} border;
struct {
int source2_location;
int progress_location;
} cross_fade;
};
} Program;
@ -162,6 +167,10 @@ typedef struct
float widths[4];
float color[4];
} border;
struct {
float progress;
int source2;
} cross_fade;
};
} RenderOp;

View File

@ -13,6 +13,7 @@ gsk_private_source_shaders = [
'resources/glsl/outset_shadow.fs.glsl',
'resources/glsl/shadow.fs.glsl',
'resources/glsl/border.fs.glsl',
'resources/glsl/cross_fade.fs.glsl',
'resources/glsl/es2_common.fs.glsl',
'resources/glsl/es2_common.vs.glsl',
'resources/glsl/gl3_common.fs.glsl',

View File

@ -0,0 +1,12 @@
uniform float u_progress;
uniform sampler2D u_source2;
void main() {
vec4 source1 = Texture(u_source, vUv); // start child
vec4 source2 = Texture(u_source2, vUv); // end child
float p = u_progress;
vec4 color = ((1 - p) * source1) + (p * source2);
setOutputColor(color);
}