[RFC PATCH 4/6] gl-renderer: Add necessary shaders for color correction

Niels Ole Salscheider niels_ole at salscheider-online.de
Sun Mar 30 04:36:35 PDT 2014


This patch ignores the YUV variants for now.

Signed-off-by: Niels Ole Salscheider <niels_ole at salscheider-online.de>
---
 src/gl-renderer.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 104 insertions(+)

diff --git a/src/gl-renderer.c b/src/gl-renderer.c
index 29d96f3..b2dfbac 100644
--- a/src/gl-renderer.c
+++ b/src/gl-renderer.c
@@ -43,6 +43,7 @@ struct gl_shader {
 	GLuint vertex_shader, fragment_shader;
 	GLint proj_uniform;
 	GLint tex_uniforms[3];
+	GLint lut_uniform;
 	GLint alpha_uniform;
 	GLint color_uniform;
 	const char *vertex_source, *fragment_source;
@@ -121,6 +122,7 @@ struct gl_renderer {
 	struct wl_array vtxcnt;
 
 	PFNGLEGLIMAGETARGETTEXTURE2DOESPROC image_target_texture_2d;
+	PFNGLTEXIMAGE3DOESPROC teximage3d;
 	PFNEGLCREATEIMAGEKHRPROC create_image;
 	PFNEGLDESTROYIMAGEKHRPROC destroy_image;
 
@@ -139,16 +141,22 @@ struct gl_renderer {
 
 	int has_egl_buffer_age;
 
+	int has_texture_3d;
+
 	int has_configless_context;
 
 	struct gl_shader texture_shader_rgba;
+	struct gl_shader texture_shader_rgba_lut;
 	struct gl_shader texture_shader_rgbx;
+	struct gl_shader texture_shader_rgbx_lut;
 	struct gl_shader texture_shader_egl_external;
+	struct gl_shader texture_shader_egl_external_lut;
 	struct gl_shader texture_shader_y_uv;
 	struct gl_shader texture_shader_y_u_v;
 	struct gl_shader texture_shader_y_xuxv;
 	struct gl_shader invert_color_shader;
 	struct gl_shader solid_shader;
+	struct gl_shader fb_shader;
 	struct gl_shader *current_shader;
 
 	struct wl_signal destroy_signal;
@@ -512,6 +520,8 @@ shader_uniforms(struct gl_shader *shader,
 
 	for (i = 0; i < gs->num_textures; i++)
 		glUniform1i(shader->tex_uniforms[i], i);
+
+	glUniform1i(shader->lut_uniform, i);
 }
 
 static void
@@ -1411,6 +1421,16 @@ static const char vertex_shader[] =
 	"  gl_FragColor.b = y + 2.01723214 * u;\n"			\
 	"  gl_FragColor.a = alpha;\n"
 
+#define FRAGMENT_LUT_ENABLE						\
+	"#extension GL_OES_texture_3D : enable\n"
+
+#define FRAGMENT_LUT_VARS						\
+	"uniform sampler3D lut;\n"
+
+#define FRAGMENT_LUT_APPLY						\
+	"  gl_FragColor.rgb = texture3D(lut,\n"				\
+	"    gl_FragColor.rgb / gl_FragColor.a).rgb * gl_FragColor.a;\n"
+
 static const char fragment_debug[] =
 	"  gl_FragColor = vec4(0.0, 0.3, 0.0, 0.2) + gl_FragColor * 0.8;\n";
 
@@ -1427,6 +1447,19 @@ static const char texture_fragment_shader_rgba[] =
 	"   gl_FragColor = alpha * texture2D(tex, v_texcoord)\n;"
 	;
 
+static const char texture_fragment_shader_rgba_lut[] =
+	FRAGMENT_LUT_ENABLE
+	"precision mediump float;\n"
+	"varying vec2 v_texcoord;\n"
+	"uniform sampler2D tex;\n"
+	"uniform float alpha;\n"
+	FRAGMENT_LUT_VARS
+	"void main()\n"
+	"{\n"
+	"   gl_FragColor = alpha * texture2D(tex, v_texcoord)\n;"
+	FRAGMENT_LUT_APPLY
+	;
+
 static const char texture_fragment_shader_rgbx[] =
 	"precision mediump float;\n"
 	"varying vec2 v_texcoord;\n"
@@ -1438,6 +1471,20 @@ static const char texture_fragment_shader_rgbx[] =
 	"   gl_FragColor.a = alpha;\n"
 	;
 
+static const char texture_fragment_shader_rgbx_lut[] =
+	FRAGMENT_LUT_ENABLE
+	"precision mediump float;\n"
+	"varying vec2 v_texcoord;\n"
+	"uniform sampler2D tex;\n"
+	"uniform float alpha;\n"
+	FRAGMENT_LUT_VARS
+	"void main()\n"
+	"{\n"
+	"   gl_FragColor.rgb = alpha * texture2D(tex, v_texcoord).rgb\n;"
+	"   gl_FragColor.a = alpha;\n"
+	FRAGMENT_LUT_APPLY
+	;
+
 static const char texture_fragment_shader_egl_external[] =
 	"#extension GL_OES_EGL_image_external : require\n"
 	"precision mediump float;\n"
@@ -1449,6 +1496,20 @@ static const char texture_fragment_shader_egl_external[] =
 	"   gl_FragColor = alpha * texture2D(tex, v_texcoord)\n;"
 	;
 
+static const char texture_fragment_shader_egl_external_lut[] =
+	FRAGMENT_LUT_ENABLE
+	"#extension GL_OES_EGL_image_external : require\n"
+	"precision mediump float;\n"
+	"varying vec2 v_texcoord;\n"
+	"uniform samplerExternalOES tex;\n"
+	"uniform float alpha;\n"
+	FRAGMENT_LUT_VARS
+	"void main()\n"
+	"{\n"
+	"   gl_FragColor = alpha * texture2D(tex, v_texcoord)\n;"
+	FRAGMENT_LUT_APPLY
+	;
+
 static const char texture_fragment_shader_y_uv[] =
 	"precision mediump float;\n"
 	"uniform sampler2D tex;\n"
@@ -1498,6 +1559,20 @@ static const char solid_fragment_shader[] =
 	"   gl_FragColor = alpha * color\n;"
 	;
 
+static const char fb_fragment_shader[] =
+	FRAGMENT_LUT_ENABLE
+	"precision mediump float;\n"
+	"uniform sampler2D tex;\n"
+	"uniform sampler2D tex1;\n"
+	"varying vec2 v_texcoord;\n"
+	FRAGMENT_LUT_VARS
+	"void main()\n"
+	"{\n"
+	"   gl_FragColor = texture2D(tex, v_texcoord);\n"
+	"if (texture2D(tex1, v_texcoord).r == 0.0)\n"
+	FRAGMENT_LUT_APPLY
+	;
+
 static int
 compile_shader(GLenum type, int count, const char **sources)
 {
@@ -1562,6 +1637,7 @@ shader_init(struct gl_shader *shader, struct gl_renderer *renderer,
 	shader->tex_uniforms[0] = glGetUniformLocation(shader->program, "tex");
 	shader->tex_uniforms[1] = glGetUniformLocation(shader->program, "tex1");
 	shader->tex_uniforms[2] = glGetUniformLocation(shader->program, "tex2");
+	shader->lut_uniform = glGetUniformLocation(shader->program, "lut");
 	shader->alpha_uniform = glGetUniformLocation(shader->program, "alpha");
 	shader->color_uniform = glGetUniformLocation(shader->program, "color");
 
@@ -1983,13 +2059,25 @@ compile_shaders(struct weston_compositor *ec)
 	gr->texture_shader_rgba.vertex_source = vertex_shader;
 	gr->texture_shader_rgba.fragment_source = texture_fragment_shader_rgba;
 
+	gr->texture_shader_rgba_lut.vertex_source = vertex_shader;
+	gr->texture_shader_rgba_lut.fragment_source =
+		texture_fragment_shader_rgba_lut;
+
 	gr->texture_shader_rgbx.vertex_source = vertex_shader;
 	gr->texture_shader_rgbx.fragment_source = texture_fragment_shader_rgbx;
 
+	gr->texture_shader_rgbx_lut.vertex_source = vertex_shader;
+	gr->texture_shader_rgbx_lut.fragment_source =
+		texture_fragment_shader_rgbx_lut;
+
 	gr->texture_shader_egl_external.vertex_source = vertex_shader;
 	gr->texture_shader_egl_external.fragment_source =
 		texture_fragment_shader_egl_external;
 
+	gr->texture_shader_egl_external_lut.vertex_source = vertex_shader;
+	gr->texture_shader_egl_external_lut.fragment_source =
+		texture_fragment_shader_egl_external_lut;
+
 	gr->texture_shader_y_uv.vertex_source = vertex_shader;
 	gr->texture_shader_y_uv.fragment_source = texture_fragment_shader_y_uv;
 
@@ -2004,6 +2092,9 @@ compile_shaders(struct weston_compositor *ec)
 	gr->solid_shader.vertex_source = vertex_shader;
 	gr->solid_shader.fragment_source = solid_fragment_shader;
 
+	gr->fb_shader.vertex_source = vertex_shader;
+	gr->fb_shader.fragment_source = fb_fragment_shader;
+
 	return 0;
 }
 
@@ -2018,12 +2109,16 @@ fragment_debug_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
 	gr->fragment_shader_debug ^= 1;
 
 	shader_release(&gr->texture_shader_rgba);
+	shader_release(&gr->texture_shader_rgba_lut);
 	shader_release(&gr->texture_shader_rgbx);
+	shader_release(&gr->texture_shader_rgbx_lut);
 	shader_release(&gr->texture_shader_egl_external);
+	shader_release(&gr->texture_shader_egl_external_lut);
 	shader_release(&gr->texture_shader_y_uv);
 	shader_release(&gr->texture_shader_y_u_v);
 	shader_release(&gr->texture_shader_y_xuxv);
 	shader_release(&gr->solid_shader);
+	shader_release(&gr->fb_shader);
 
 	/* Force use_shader() to call glUseProgram(), since we need to use
 	 * the recompiled version of the shader. */
@@ -2091,6 +2186,9 @@ gl_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
 	gr->image_target_texture_2d =
 		(void *) eglGetProcAddress("glEGLImageTargetTexture2DOES");
 
+	gr->teximage3d =
+		(void *) eglGetProcAddress("glTexImage3DOES");
+
 	extensions = (const char *) glGetString(GL_EXTENSIONS);
 	if (!extensions) {
 		weston_log("Retrieving GL extension string failed.\n");
@@ -2115,6 +2213,12 @@ gl_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
 	if (strstr(extensions, "GL_OES_EGL_image_external"))
 		gr->has_egl_image_external = 1;
 
+	if (strstr(extensions, "GL_OES_texture_3D"))
+		gr->has_texture_3d = 1;
+	else
+		weston_log("warning: GL_OES_texture_3D not supported. "
+			   "Color correction will be disabled.\n");
+
 	glActiveTexture(GL_TEXTURE0);
 
 	if (compile_shaders(ec))
-- 
1.9.1



More information about the wayland-devel mailing list