[PATCH weston 2/3] gles2: Add a debug binding for highlighting shaded content

Ander Conselvan de Oliveira ander.conselvan.de.oliveira at intel.com
Thu Nov 8 07:20:46 PST 2012


Pressing mode-shift-space s will cause the fragment shaders to be
recompiled, adding a green tint to all composited content.
---
 src/compositor.h     |    2 +
 src/gles2-renderer.c |  156 ++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 116 insertions(+), 42 deletions(-)

diff --git a/src/compositor.h b/src/compositor.h
index 9bd2b08..8c7117f 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -358,6 +358,8 @@ struct weston_compositor {
 	PFNEGLQUERYWAYLANDBUFFERWL query_buffer;
 	int has_bind_display;
 
+	int has_egl_image_external;
+
 	void (*destroy)(struct weston_compositor *ec);
 	void (*restore)(struct weston_compositor *ec);
 	int (*authenticate)(struct weston_compositor *c, uint32_t id);
diff --git a/src/gles2-renderer.c b/src/gles2-renderer.c
index 544cc15..05647b7 100644
--- a/src/gles2-renderer.c
+++ b/src/gles2-renderer.c
@@ -27,9 +27,15 @@
 #include <ctype.h>
 #include <float.h>
 #include <assert.h>
+#include <linux/input.h>
 
 #include "compositor.h"
 
+struct gles2_renderer {
+	struct weston_renderer base;
+	int fragment_shader_debug;
+};
+
 static const char *
 egl_error_string(EGLint code)
 {
@@ -940,6 +946,12 @@ static const char vertex_shader[] =
 	"  gl_FragColor.b = y + 2.01723214 * u;\n"			\
 	"  gl_FragColor.a = alpha;\n"
 
+static const char fragment_debug[] =
+	"  gl_FragColor = vec4(0.0, 0.3, 0.0, 0.2) + gl_FragColor * 0.8;\n";
+
+static const char fragment_brace[] =
+	"}\n";
+
 static const char texture_fragment_shader_rgba[] =
 	"precision mediump float;\n"
 	"varying vec2 v_texcoord;\n"
@@ -948,7 +960,7 @@ static const char texture_fragment_shader_rgba[] =
 	"void main()\n"
 	"{\n"
 	"   gl_FragColor = alpha * texture2D(tex, v_texcoord)\n;"
-	"}\n";
+	;
 
 static const char texture_fragment_shader_rgbx[] =
 	"precision mediump float;\n"
@@ -959,7 +971,7 @@ static const char texture_fragment_shader_rgbx[] =
 	"{\n"
 	"   gl_FragColor.rgb = alpha * texture2D(tex, v_texcoord).rgb\n;"
 	"   gl_FragColor.a = alpha;\n"
-	"}\n";
+	;
 
 static const char texture_fragment_shader_egl_external[] =
 	"#extension GL_OES_EGL_image_external : require\n"
@@ -970,7 +982,7 @@ static const char texture_fragment_shader_egl_external[] =
 	"void main()\n"
 	"{\n"
 	"   gl_FragColor = alpha * texture2D(tex, v_texcoord)\n;"
-	"}\n";
+	;
 
 static const char texture_fragment_shader_y_uv[] =
 	"precision mediump float;\n"
@@ -983,7 +995,7 @@ static const char texture_fragment_shader_y_uv[] =
 	"  float u = texture2D(tex1, v_texcoord).r - 0.5;\n"
 	"  float v = texture2D(tex1, v_texcoord).g - 0.5;\n"
 	FRAGMENT_CONVERT_YUV
-	"}\n";
+	;
 
 static const char texture_fragment_shader_y_u_v[] =
 	"precision mediump float;\n"
@@ -997,7 +1009,7 @@ static const char texture_fragment_shader_y_u_v[] =
 	"  float u = texture2D(tex1, v_texcoord).x - 0.5;\n"
 	"  float v = texture2D(tex2, v_texcoord).x - 0.5;\n"
 	FRAGMENT_CONVERT_YUV
-	"}\n";
+	;
 
 static const char texture_fragment_shader_y_xuxv[] =
 	"precision mediump float;\n"
@@ -1010,7 +1022,7 @@ static const char texture_fragment_shader_y_xuxv[] =
 	"  float u = texture2D(tex1, v_texcoord).g - 0.5;\n"
 	"  float v = texture2D(tex1, v_texcoord).a - 0.5;\n"
 	FRAGMENT_CONVERT_YUV
-	"}\n";
+	;
 
 static const char solid_fragment_shader[] =
 	"precision mediump float;\n"
@@ -1019,17 +1031,17 @@ static const char solid_fragment_shader[] =
 	"void main()\n"
 	"{\n"
 	"   gl_FragColor = alpha * color\n;"
-	"}\n";
+	;
 
 static int
-compile_shader(GLenum type, const char *source)
+compile_shader(GLenum type, int count, const char **sources)
 {
 	GLuint s;
 	char msg[512];
 	GLint status;
 
 	s = glCreateShader(type);
-	glShaderSource(s, 1, &source, NULL);
+	glShaderSource(s, count, sources, NULL);
 	glCompileShader(s);
 	glGetShaderiv(s, GL_COMPILE_STATUS, &status);
 	if (!status) {
@@ -1042,16 +1054,32 @@ compile_shader(GLenum type, const char *source)
 }
 
 static int
-weston_shader_init(struct weston_shader *shader,
+weston_shader_init(struct weston_shader *shader, struct weston_compositor *ec,
 		   const char *vertex_source, const char *fragment_source)
 {
 	char msg[512];
 	GLint status;
+	int count;
+	const char *sources[3];
+	struct gles2_renderer *renderer =
+		(struct gles2_renderer *) ec->renderer;
 
 	shader->vertex_shader =
-		compile_shader(GL_VERTEX_SHADER, vertex_source);
+		compile_shader(GL_VERTEX_SHADER, 1, &vertex_source);
+
+	if (renderer->fragment_shader_debug) {
+		sources[0] = fragment_source;
+		sources[1] = fragment_debug;
+		sources[2] = fragment_brace;
+		count = 3;
+	} else {
+		sources[0] = fragment_source;
+		sources[1] = fragment_brace;
+		count = 2;
+	}
+
 	shader->fragment_shader =
-		compile_shader(GL_FRAGMENT_SHADER, fragment_source);
+		compile_shader(GL_FRAGMENT_SHADER, count, sources);
 
 	shader->program = glCreateProgram();
 	glAttachShader(shader->program, shader->vertex_shader);
@@ -1078,6 +1106,18 @@ weston_shader_init(struct weston_shader *shader,
 }
 
 static void
+weston_shader_release(struct weston_shader *shader)
+{
+	glDeleteShader(shader->vertex_shader);
+	glDeleteShader(shader->fragment_shader);
+	glDeleteProgram(shader->program);
+
+	shader->vertex_shader = 0;
+	shader->fragment_shader = 0;
+	shader->program = 0;
+}
+
+static void
 log_extensions(const char *name, const char *extensions)
 {
 	const char *p, *end;
@@ -1157,10 +1197,6 @@ log_egl_config_info(EGLDisplay egldpy, EGLConfig eglconfig)
 		weston_log_continue(" unknown\n");
 }
 
-struct gles2_renderer {
-	struct weston_renderer base;
-};
-
 WL_EXPORT void
 gles2_renderer_destroy(struct weston_compositor *ec)
 {
@@ -1168,12 +1204,65 @@ gles2_renderer_destroy(struct weston_compositor *ec)
 		ec->unbind_display(ec->egl_display, ec->wl_display);
 }
 
+static int
+compile_shaders(struct weston_compositor *ec)
+{
+	if (weston_shader_init(&ec->texture_shader_rgba, ec,
+			     vertex_shader, texture_fragment_shader_rgba) < 0)
+		return -1;
+	if (weston_shader_init(&ec->texture_shader_rgbx, ec,
+			     vertex_shader, texture_fragment_shader_rgbx) < 0)
+		return -1;
+	if (ec->has_egl_image_external &&
+			weston_shader_init(&ec->texture_shader_egl_external, ec,
+				vertex_shader, texture_fragment_shader_egl_external) < 0)
+		return -1;
+	if (weston_shader_init(&ec->texture_shader_y_uv, ec,
+			       vertex_shader, texture_fragment_shader_y_uv) < 0)
+		return -1;
+	if (weston_shader_init(&ec->texture_shader_y_u_v, ec,
+			       vertex_shader, texture_fragment_shader_y_u_v) < 0)
+		return -1;
+	if (weston_shader_init(&ec->texture_shader_y_xuxv, ec,
+			       vertex_shader, texture_fragment_shader_y_xuxv) < 0)
+		return -1;
+	if (weston_shader_init(&ec->solid_shader, ec,
+			     vertex_shader, solid_fragment_shader) < 0)
+		return -1;
+
+	return 0;
+}
+
+static void
+fragment_debug_binding(struct wl_seat *seat, uint32_t time, uint32_t key,
+		       void *data)
+{
+	struct weston_compositor *ec = data;
+	struct gles2_renderer *renderer =
+		(struct gles2_renderer *) ec->renderer;
+	struct weston_output *output;
+
+	renderer->fragment_shader_debug ^= 1;
+
+	weston_shader_release(&ec->texture_shader_rgba);
+	weston_shader_release(&ec->texture_shader_rgbx);
+	weston_shader_release(&ec->texture_shader_egl_external);
+	weston_shader_release(&ec->texture_shader_y_uv);
+	weston_shader_release(&ec->texture_shader_y_u_v);
+	weston_shader_release(&ec->texture_shader_y_xuxv);
+	weston_shader_release(&ec->solid_shader);
+
+	compile_shaders(ec);
+
+	wl_list_for_each(output, &ec->output_list, link)
+		weston_output_damage(output);
+}
+
 WL_EXPORT int
 gles2_renderer_init(struct weston_compositor *ec)
 {
 	struct gles2_renderer *renderer;
 	const char *extensions;
-	int has_egl_image_external = 0;
 	struct weston_output *output;
 	EGLBoolean ret;
 
@@ -1182,7 +1271,7 @@ gles2_renderer_init(struct weston_compositor *ec)
 		EGL_NONE
 	};
 
-	renderer = malloc(sizeof *renderer);
+	renderer = calloc(1, sizeof *renderer);
 	if (renderer == NULL)
 		return -1;
 
@@ -1247,7 +1336,7 @@ gles2_renderer_init(struct weston_compositor *ec)
 		ec->has_unpack_subimage = 1;
 
 	if (strstr(extensions, "GL_OES_EGL_image_external"))
-		has_egl_image_external = 1;
+		ec->has_egl_image_external = 1;
 
 	extensions =
 		(const char *) eglQueryString(ec->egl_display, EGL_EXTENSIONS);
@@ -1266,35 +1355,18 @@ gles2_renderer_init(struct weston_compositor *ec)
 
 	glActiveTexture(GL_TEXTURE0);
 
-	if (weston_shader_init(&ec->texture_shader_rgba,
-			     vertex_shader, texture_fragment_shader_rgba) < 0)
-		return -1;
-	if (weston_shader_init(&ec->texture_shader_rgbx,
-			     vertex_shader, texture_fragment_shader_rgbx) < 0)
-		return -1;
-	if (has_egl_image_external &&
-			weston_shader_init(&ec->texture_shader_egl_external,
-				vertex_shader, texture_fragment_shader_egl_external) < 0)
-		return -1;
-	if (weston_shader_init(&ec->texture_shader_y_uv,
-			       vertex_shader, texture_fragment_shader_y_uv) < 0)
-		return -1;
-	if (weston_shader_init(&ec->texture_shader_y_u_v,
-			       vertex_shader, texture_fragment_shader_y_u_v) < 0)
-		return -1;
-	if (weston_shader_init(&ec->texture_shader_y_xuxv,
-			       vertex_shader, texture_fragment_shader_y_xuxv) < 0)
-		return -1;
-	if (weston_shader_init(&ec->solid_shader,
-			     vertex_shader, solid_fragment_shader) < 0)
-		return -1;
-
 	renderer->base.repaint_output = gles2_renderer_repaint_output;
 	renderer->base.flush_damage = gles2_renderer_flush_damage;
 	renderer->base.attach = gles2_renderer_attach;
 	renderer->base.destroy_surface = gles2_renderer_destroy_surface;
 	ec->renderer = &renderer->base;
 
+	if (compile_shaders(ec))
+		return -1;
+
+	weston_compositor_add_debug_binding(ec, KEY_S,
+					    fragment_debug_binding, ec);
+
 	weston_log("GL ES 2 renderer features:\n");
 	weston_log_continue(STAMP_SPACE "read-back format: %s\n",
 			    ec->read_format == GL_BGRA_EXT ? "BGRA" : "RGBA");
-- 
1.7.10.4



More information about the wayland-devel mailing list