summaryrefslogtreecommitdiff
path: root/gsk
diff options
context:
space:
mode:
authorTimm Bäder <mail@baedert.org>2017-01-06 20:53:12 +0100
committerTimm Bäder <mail@baedert.org>2017-03-31 09:50:39 +0200
commitfbada8e7583f0cc21a68d60c16f7af0468d24b33 (patch)
tree52a84c83bef9c8c2c4c05fc7580ee06733d789c4 /gsk
parenta33e90a02944cee362c32022b1358b06929cfda1 (diff)
downloadgtk+-fbada8e7583f0cc21a68d60c16f7af0468d24b33.tar.gz
glrenderer: Handle color nodes
Diffstat (limited to 'gsk')
-rw-r--r--gsk/gskglrenderer.c92
-rw-r--r--gsk/resources/glsl/color.fs.glsl5
-rw-r--r--gsk/resources/glsl/color.vs.glsl6
3 files changed, 88 insertions, 15 deletions
diff --git a/gsk/gskglrenderer.c b/gsk/gskglrenderer.c
index 337aaba7f3..4412084ef9 100644
--- a/gsk/gskglrenderer.c
+++ b/gsk/gskglrenderer.c
@@ -34,6 +34,9 @@ typedef struct {
/* Shader-specific locations */
union {
+ struct {
+ int color_location;
+ };
};
} Program;
@@ -47,7 +50,14 @@ typedef struct {
Program *program;
} RenderData;
+enum {
+ MODE_COLOR = 1,
+ MODE_TEXTURE,
+ N_MODES
+};
+
typedef struct {
+ int mode;
/* Back pointer to the node, only meant for comparison */
GskRenderNode *node;
@@ -61,8 +71,13 @@ typedef struct {
float opacity;
float z;
- /* mode-specific data for shaders */
union {
+ struct {
+ GdkRGBA color;
+ } color_data;
+ struct {
+ int a,b;
+ } texture_data;
};
const char *name;
@@ -109,7 +124,7 @@ typedef enum {
RENDER_SCISSOR
} RenderMode;
-#define NUM_PROGRAMS 2
+#define NUM_PROGRAMS 3
struct _GskGLRenderer
{
@@ -134,6 +149,7 @@ struct _GskGLRenderer
struct {
Program blend_program;
Program blit_program;
+ Program color_program;
};
struct {
Program programs[NUM_PROGRAMS];
@@ -320,7 +336,22 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
}
init_common_locations (self, &self->blit_program);
-
+ self->color_program.id =
+ gsk_shader_builder_create_program (builder, "color.vs.glsl", "color.fs.glsl", &shader_error);
+ if (shader_error != NULL)
+ {
+ g_propagate_prefixed_error (error,
+ shader_error,
+ "Unable to create 'color' program: ");
+ g_object_unref (builder);
+ goto out;
+ }
+ init_common_locations (self, &self->color_program);
+ self->color_program.color_location = gsk_shader_builder_get_uniform_location (self->shader_builder,
+ self->color_program.id,
+ g_quark_from_string("uColor"));
+ self->color_program.color_location = glGetUniformLocation(self->color_program.id, "uColor");
+ g_assert(self->color_program.color_location >= 0);
res = TRUE;
@@ -492,25 +523,43 @@ render_item (GskGLRenderer *self,
gsk_gl_driver_bind_vao (self->gl_driver, item->render_data.vao_id);
- glUseProgram (item->render_data.program_id);
+ glUseProgram (item->render_data.program->id);
- if (item->render_data.texture_id != 0)
+ switch(item->mode)
{
- /* Use texture unit 0 for the source */
- glUniform1i (item->render_data.program->source_location, 0);
- gsk_gl_driver_bind_source_texture (self->gl_driver, item->render_data.texture_id);
+ case MODE_COLOR:
+ {
+ glUniform4f (item->render_data.program->color_location,
+ item->color_data.color.red,
+ item->color_data.color.green,
+ item->color_data.color.blue,
+ item->color_data.color.alpha);
+ }
+ break;
- if (item->parent_data != NULL)
+ case MODE_TEXTURE:
{
- glUniform1i (item->render_data.program->blendMode_location, item->blend_mode);
+ g_assert(item->render_data.texture_id != 0);
+ /* Use texture unit 0 for the source */
+ glUniform1i (item->render_data.program->source_location, 0);
+ gsk_gl_driver_bind_source_texture (self->gl_driver, item->render_data.texture_id);
- /* Use texture unit 1 for the mask */
- if (item->parent_data->texture_id != 0)
+ if (item->parent_data != NULL)
{
- glUniform1i (item->render_data.program->mask_location, 1);
- gsk_gl_driver_bind_mask_texture (self->gl_driver, item->parent_data->texture_id);
+ glUniform1i (item->render_data.program->blendMode_location, item->blend_mode);
+
+ /* Use texture unit 1 for the mask */
+ if (item->parent_data->texture_id != 0)
+ {
+ glUniform1i (item->render_data.program->mask_location, 1);
+ gsk_gl_driver_bind_mask_texture (self->gl_driver, item->parent_data->texture_id);
+ }
}
}
+ break;
+
+ default:
+ g_assert_not_reached ();
}
/* Pass the opacity component */
@@ -753,6 +802,7 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self,
texture,
gl_min_filter,
gl_mag_filter);
+ item.mode = MODE_TEXTURE;
}
break;
@@ -776,6 +826,17 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self,
surface,
gl_min_filter,
gl_mag_filter);
+ item.mode = MODE_TEXTURE;
+ }
+ break;
+
+ case GSK_COLOR_NODE:
+ {
+ const GdkRGBA *c = gsk_color_node_peek_color(node);
+ program_id = self->color_program.id;
+ item.render_data.program = &self->color_program;
+ item.mode = MODE_COLOR;
+ item.color_data.color= *c;
}
break;
@@ -822,7 +883,7 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self,
cairo_translate (cr, -node->bounds.origin.x, -node->bounds.origin.y);
gsk_render_node_draw (node, cr);
-
+
cairo_destroy (cr);
/* Upload the Cairo surface to a GL texture */
@@ -836,6 +897,7 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self,
GL_NEAREST, GL_NEAREST);
cairo_surface_destroy (surface);
+ item.mode = MODE_TEXTURE;
}
break;
}
diff --git a/gsk/resources/glsl/color.fs.glsl b/gsk/resources/glsl/color.fs.glsl
new file mode 100644
index 0000000000..62d4ba05de
--- /dev/null
+++ b/gsk/resources/glsl/color.fs.glsl
@@ -0,0 +1,5 @@
+uniform vec4 uColor;
+
+void main() {
+ setOutputColor(uColor);
+}
diff --git a/gsk/resources/glsl/color.vs.glsl b/gsk/resources/glsl/color.vs.glsl
new file mode 100644
index 0000000000..1208513f33
--- /dev/null
+++ b/gsk/resources/glsl/color.vs.glsl
@@ -0,0 +1,6 @@
+void main() {
+ gl_Position = uMVP * vec4(aPosition, 0.0, 1.0);
+
+ // Flip the sampling
+ vUv = vec2(aUv.x, aUv.y);
+}