[PATCH 4/6] gl-renderer: Add necessary shaders for color correction
Niels Ole Salscheider
niels_ole at salscheider-online.de
Mon Oct 13 10:40:49 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 | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 102 insertions(+)
diff --git a/src/gl-renderer.c b/src/gl-renderer.c
index f7f29b3..470f98a 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;
@@ -127,6 +128,7 @@ struct gl_renderer {
struct wl_array vtxcnt;
PFNGLEGLIMAGETARGETTEXTURE2DOESPROC image_target_texture_2d;
+ PFNGLTEXIMAGE3DOESPROC teximage3d;
PFNEGLCREATEIMAGEKHRPROC create_image;
PFNEGLDESTROYIMAGEKHRPROC destroy_image;
@@ -145,16 +147,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;
@@ -518,6 +526,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
@@ -1410,6 +1420,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";
@@ -1426,6 +1446,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"
@@ -1437,6 +1470,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"
@@ -1448,6 +1495,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"
@@ -1497,6 +1558,18 @@ 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"
+ "varying vec2 v_texcoord;\n"
+ FRAGMENT_LUT_VARS
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = texture2D(tex, v_texcoord);\n"
+ FRAGMENT_LUT_APPLY
+ ;
+
static int
compile_shader(GLenum type, int count, const char **sources)
{
@@ -1561,6 +1634,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");
@@ -1982,13 +2056,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;
@@ -2003,6 +2089,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;
}
@@ -2017,12 +2106,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. */
@@ -2090,6 +2183,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");
@@ -2114,6 +2210,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))
--
2.1.2
More information about the wayland-devel
mailing list