This moves all shader functions into it's own file in preparation of a more flexible shader generation. It adds gl-internal.h for shared definitions between the files. --- src/Makefile.am | 2 + src/gl-internal.h | 144 ++++++++++++++++++++ src/gl-renderer.c | 382 ++---------------------------------------------------- src/gl-shaders.c | 284 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 443 insertions(+), 369 deletions(-) create mode 100644 src/gl-internal.h create mode 100644 src/gl-shaders.c
diff --git a/src/Makefile.am b/src/Makefile.am index 7da2c01..978a21d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -46,6 +46,8 @@ weston_SOURCES = \ if ENABLE_EGL weston_SOURCES += \ + gl-shaders.c \ + gl-internal.h \ gl-renderer.c endif diff --git a/src/gl-internal.h b/src/gl-internal.h new file mode 100644 index 0000000..2e55313 --- /dev/null +++ b/src/gl-internal.h @@ -0,0 +1,144 @@ +/* + * Copyright © 2012 Intel Corporation + * Copyright © 2012 John Kåre Alsaker + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _GL_INTERNAL_H_ +#define _GL_INTERNAL_H_ + +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <float.h> +#include <assert.h> +#include <linux/input.h> + +#include "gl-renderer.h" + +#include <EGL/eglext.h> +#include "weston-egl-ext.h" + +struct gl_shader { + GLuint program; + GLuint vertex_shader, fragment_shader; + GLint proj_uniform; + GLint tex_uniforms[3]; + GLint alpha_uniform; + GLint color_uniform; +}; + +struct gl_output_state { + EGLSurface egl_surface; + int current_buffer; + pixman_region32_t buffer_damage[2]; +}; + +struct gl_surface_state { + GLfloat color[4]; + struct gl_shader *shader; + + GLuint textures[3]; + int num_textures; + pixman_region32_t texture_damage; + + EGLImageKHR images[3]; + GLenum target; + int num_images; + + struct weston_buffer_reference buffer_ref; + int pitch; /* in pixels */ +}; + +struct gl_renderer { + struct weston_renderer base; + int fragment_shader_debug; + + EGLDisplay egl_display; + EGLContext egl_context; + EGLConfig egl_config; + + struct { + int32_t top, bottom, left, right; + GLuint texture; + int32_t width, height; + } border; + + PFNGLEGLIMAGETARGETTEXTURE2DOESPROC image_target_texture_2d; + PFNEGLCREATEIMAGEKHRPROC create_image; + PFNEGLDESTROYIMAGEKHRPROC destroy_image; + + int has_unpack_subimage; + + PFNEGLBINDWAYLANDDISPLAYWL bind_display; + PFNEGLUNBINDWAYLANDDISPLAYWL unbind_display; + PFNEGLQUERYWAYLANDBUFFERWL query_buffer; + int has_bind_display; + + int has_egl_image_external; + + struct gl_shader texture_shader_rgba; + struct gl_shader texture_shader_rgbx; + struct gl_shader texture_shader_egl_external; + 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 *current_shader; +}; + +static inline struct gl_output_state * +get_output_state(struct weston_output *output) +{ + return (struct gl_output_state *)output->renderer_state; +} + +static inline struct gl_surface_state * +get_surface_state(struct weston_surface *surface) +{ + return (struct gl_surface_state *)surface->renderer_state; +} + +static inline struct gl_renderer * +get_renderer(struct weston_compositor *ec) +{ + return (struct gl_renderer *)ec->renderer; +} + +int +gl_init_shaders(struct gl_renderer *gr); + +void +gl_destroy_shaders(struct gl_renderer *gr); + +void +gl_use_shader(struct gl_renderer *gr, + struct gl_shader *shader); + +void +gl_shader_uniforms(struct gl_shader *shader, + struct weston_surface *surface, + struct weston_output *output); + +#endif diff --git a/src/gl-renderer.c b/src/gl-renderer.c index a5dc2f3..495d5db 100644 --- a/src/gl-renderer.c +++ b/src/gl-renderer.c @@ -1,5 +1,6 @@ /* * Copyright © 2012 Intel Corporation + * Copyright © 2012 John Kåre Alsaker * * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided @@ -22,107 +23,7 @@ #define _GNU_SOURCE -#include <GLES2/gl2.h> -#include <GLES2/gl2ext.h> - -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <float.h> -#include <assert.h> -#include <linux/input.h> - -#include "gl-renderer.h" - -#include <EGL/eglext.h> -#include "weston-egl-ext.h" - -struct gl_shader { - GLuint program; - GLuint vertex_shader, fragment_shader; - GLint proj_uniform; - GLint tex_uniforms[3]; - GLint alpha_uniform; - GLint color_uniform; -}; - -struct gl_output_state { - EGLSurface egl_surface; - int current_buffer; - pixman_region32_t buffer_damage[2]; -}; - -struct gl_surface_state { - GLfloat color[4]; - struct gl_shader *shader; - - GLuint textures[3]; - int num_textures; - pixman_region32_t texture_damage; - - EGLImageKHR images[3]; - GLenum target; - int num_images; - - struct weston_buffer_reference buffer_ref; - int pitch; /* in pixels */ -}; - -struct gl_renderer { - struct weston_renderer base; - int fragment_shader_debug; - - EGLDisplay egl_display; - EGLContext egl_context; - EGLConfig egl_config; - - struct { - int32_t top, bottom, left, right; - GLuint texture; - int32_t width, height; - } border; - - PFNGLEGLIMAGETARGETTEXTURE2DOESPROC image_target_texture_2d; - PFNEGLCREATEIMAGEKHRPROC create_image; - PFNEGLDESTROYIMAGEKHRPROC destroy_image; - - int has_unpack_subimage; - - PFNEGLBINDWAYLANDDISPLAYWL bind_display; - PFNEGLUNBINDWAYLANDDISPLAYWL unbind_display; - PFNEGLQUERYWAYLANDBUFFERWL query_buffer; - int has_bind_display; - - int has_egl_image_external; - - struct gl_shader texture_shader_rgba; - struct gl_shader texture_shader_rgbx; - struct gl_shader texture_shader_egl_external; - 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 *current_shader; -}; - -static inline struct gl_output_state * -get_output_state(struct weston_output *output) -{ - return (struct gl_output_state *)output->renderer_state; -} - -static inline struct gl_surface_state * -get_surface_state(struct weston_surface *surface) -{ - return (struct gl_surface_state *)surface->renderer_state; -} - -static inline struct gl_renderer * -get_renderer(struct weston_compositor *ec) -{ - return (struct gl_renderer *)ec->renderer; -} +#include "gl-internal.h" static const char * egl_error_string(EGLint code) @@ -708,34 +609,6 @@ use_output(struct weston_output *output) } static void -use_shader(struct gl_renderer *gr, - struct gl_shader *shader) -{ - if (gr->current_shader == shader) - return; - - glUseProgram(shader->program); - gr->current_shader = shader; -} - -static void -shader_uniforms(struct gl_shader *shader, - struct weston_surface *surface, - struct weston_output *output) -{ - int i; - struct gl_surface_state *gs = get_surface_state(surface); - - glUniformMatrix4fv(shader->proj_uniform, - 1, GL_FALSE, output->matrix.d); - glUniform4fv(shader->color_uniform, 1, gs->color); - glUniform1f(shader->alpha_uniform, surface->alpha); - - for (i = 0; i < gs->num_textures; i++) - glUniform1i(shader->tex_uniforms[i], i); -} - -static void draw_surface(struct weston_surface *es, struct weston_output *output, pixman_region32_t *damage) /* in global coordinates */ { @@ -765,12 +638,12 @@ draw_surface(struct weston_surface *es, struct weston_output *output, glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); if (ec->fan_debug) { - use_shader(gr, &gr->solid_shader); - shader_uniforms(&gr->solid_shader, es, output); + gl_use_shader(gr, &gr->solid_shader); + gl_shader_uniforms(&gr->solid_shader, es, output); } - use_shader(gr, gs->shader); - shader_uniforms(gs->shader, es, output); + gl_use_shader(gr, gs->shader); + gl_shader_uniforms(gs->shader, es, output); if (es->transform.enabled || output->zoom.active) filter = GL_LINEAR; @@ -796,8 +669,8 @@ draw_surface(struct weston_surface *es, struct weston_output *output, * that forces texture alpha = 1.0. * Xwayland surfaces need this. */ - use_shader(gr, &gr->texture_shader_rgbx); - shader_uniforms(&gr->texture_shader_rgbx, es, output); + gl_use_shader(gr, &gr->texture_shader_rgbx); + gl_shader_uniforms(&gr->texture_shader_rgbx, es, output); } if (es->alpha < 1.0) @@ -809,7 +682,7 @@ draw_surface(struct weston_surface *es, struct weston_output *output, } if (pixman_region32_not_empty(&surface_blend)) { - use_shader(gr, gs->shader); + gl_use_shader(gr, gs->shader); glEnable(GL_BLEND); repaint_region(es, &repaint, &surface_blend); } @@ -918,7 +791,7 @@ draw_border(struct weston_output *output) int n; glDisable(GL_BLEND); - use_shader(gr, shader); + gl_use_shader(gr, shader); glUniformMatrix4fv(shader->proj_uniform, 1, GL_FALSE, output->matrix.d); @@ -1272,197 +1145,6 @@ gl_renderer_destroy_surface(struct weston_surface *surface) free(gs); } -static const char vertex_shader[] = - "uniform mat4 proj;\n" - "attribute vec2 position;\n" - "attribute vec2 texcoord;\n" - "varying vec2 v_texcoord;\n" - "void main()\n" - "{\n" - " gl_Position = proj * vec4(position, 0.0, 1.0);\n" - " v_texcoord = texcoord;\n" - "}\n"; - -/* Declare common fragment shader uniforms */ -#define FRAGMENT_CONVERT_YUV \ - " y *= alpha;\n" \ - " u *= alpha;\n" \ - " v *= alpha;\n" \ - " gl_FragColor.r = y + 1.59602678 * v;\n" \ - " gl_FragColor.g = y - 0.39176229 * u - 0.81296764 * v;\n" \ - " 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" - "uniform sampler2D tex;\n" - "uniform float alpha;\n" - "void main()\n" - "{\n" - " gl_FragColor = alpha * texture2D(tex, v_texcoord)\n;" - ; - -static const char texture_fragment_shader_rgbx[] = - "precision mediump float;\n" - "varying vec2 v_texcoord;\n" - "uniform sampler2D tex;\n" - "uniform float alpha;\n" - "void main()\n" - "{\n" - " gl_FragColor.rgb = alpha * texture2D(tex, v_texcoord).rgb\n;" - " gl_FragColor.a = alpha;\n" - ; - -static const char texture_fragment_shader_egl_external[] = - "#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" - "void main()\n" - "{\n" - " gl_FragColor = alpha * texture2D(tex, v_texcoord)\n;" - ; - -static const char texture_fragment_shader_y_uv[] = - "precision mediump float;\n" - "uniform sampler2D tex;\n" - "uniform sampler2D tex1;\n" - "varying vec2 v_texcoord;\n" - "uniform float alpha;\n" - "void main() {\n" - " float y = 1.16438356 * (texture2D(tex, v_texcoord).x - 0.0625);\n" - " float u = texture2D(tex1, v_texcoord).r - 0.5;\n" - " float v = texture2D(tex1, v_texcoord).g - 0.5;\n" - FRAGMENT_CONVERT_YUV - ; - -static const char texture_fragment_shader_y_u_v[] = - "precision mediump float;\n" - "uniform sampler2D tex;\n" - "uniform sampler2D tex1;\n" - "uniform sampler2D tex2;\n" - "varying vec2 v_texcoord;\n" - "uniform float alpha;\n" - "void main() {\n" - " float y = 1.16438356 * (texture2D(tex, v_texcoord).x - 0.0625);\n" - " float u = texture2D(tex1, v_texcoord).x - 0.5;\n" - " float v = texture2D(tex2, v_texcoord).x - 0.5;\n" - FRAGMENT_CONVERT_YUV - ; - -static const char texture_fragment_shader_y_xuxv[] = - "precision mediump float;\n" - "uniform sampler2D tex;\n" - "uniform sampler2D tex1;\n" - "varying vec2 v_texcoord;\n" - "uniform float alpha;\n" - "void main() {\n" - " float y = 1.16438356 * (texture2D(tex, v_texcoord).x - 0.0625);\n" - " float u = texture2D(tex1, v_texcoord).g - 0.5;\n" - " float v = texture2D(tex1, v_texcoord).a - 0.5;\n" - FRAGMENT_CONVERT_YUV - ; - -static const char solid_fragment_shader[] = - "precision mediump float;\n" - "uniform vec4 color;\n" - "uniform float alpha;\n" - "void main()\n" - "{\n" - " gl_FragColor = alpha * color\n;" - ; - -static int -compile_shader(GLenum type, int count, const char **sources) -{ - GLuint s; - char msg[512]; - GLint status; - - s = glCreateShader(type); - glShaderSource(s, count, sources, NULL); - glCompileShader(s); - glGetShaderiv(s, GL_COMPILE_STATUS, &status); - if (!status) { - glGetShaderInfoLog(s, sizeof msg, NULL, msg); - weston_log("shader info: %s\n", msg); - return GL_NONE; - } - - return s; -} - -static int -shader_init(struct gl_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 gl_renderer *renderer = get_renderer(ec); - - shader->vertex_shader = - 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, count, sources); - - shader->program = glCreateProgram(); - glAttachShader(shader->program, shader->vertex_shader); - glAttachShader(shader->program, shader->fragment_shader); - glBindAttribLocation(shader->program, 0, "position"); - glBindAttribLocation(shader->program, 1, "texcoord"); - - glLinkProgram(shader->program); - glGetProgramiv(shader->program, GL_LINK_STATUS, &status); - if (!status) { - glGetProgramInfoLog(shader->program, sizeof msg, NULL, msg); - weston_log("link info: %s\n", msg); - return -1; - } - - shader->proj_uniform = glGetUniformLocation(shader->program, "proj"); - 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->alpha_uniform = glGetUniformLocation(shader->program, "alpha"); - shader->color_uniform = glGetUniformLocation(shader->program, "color"); - - return 0; -} - -static void -shader_release(struct gl_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) { @@ -1782,37 +1464,6 @@ gl_renderer_display(struct weston_compositor *ec) return get_renderer(ec)->egl_display; } -static int -compile_shaders(struct weston_compositor *ec) -{ - struct gl_renderer *gr = get_renderer(ec); - - if (shader_init(&gr->texture_shader_rgba, ec, - vertex_shader, texture_fragment_shader_rgba) < 0) - return -1; - if (shader_init(&gr->texture_shader_rgbx, ec, - vertex_shader, texture_fragment_shader_rgbx) < 0) - return -1; - if (gr->has_egl_image_external && - shader_init(&gr->texture_shader_egl_external, ec, - vertex_shader, texture_fragment_shader_egl_external) < 0) - return -1; - if (shader_init(&gr->texture_shader_y_uv, ec, - vertex_shader, texture_fragment_shader_y_uv) < 0) - return -1; - if (shader_init(&gr->texture_shader_y_u_v, ec, - vertex_shader, texture_fragment_shader_y_u_v) < 0) - return -1; - if (shader_init(&gr->texture_shader_y_xuxv, ec, - vertex_shader, texture_fragment_shader_y_xuxv) < 0) - return -1; - if (shader_init(&gr->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) @@ -1823,15 +1474,8 @@ fragment_debug_binding(struct wl_seat *seat, uint32_t time, uint32_t key, gr->fragment_shader_debug ^= 1; - shader_release(&gr->texture_shader_rgba); - shader_release(&gr->texture_shader_rgbx); - shader_release(&gr->texture_shader_egl_external); - 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); - - compile_shaders(ec); + gl_destroy_shaders(gr); + gl_init_shaders(gr); /* Force use_shader() to call glUseProgram(), since we need to use * the recompiled version of the shader. */ @@ -1929,7 +1573,7 @@ gl_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface) glActiveTexture(GL_TEXTURE0); - if (compile_shaders(ec)) + if (gl_init_shaders(gr) < 0) return -1; weston_compositor_add_debug_binding(ec, KEY_S, diff --git a/src/gl-shaders.c b/src/gl-shaders.c new file mode 100644 index 0000000..35275ca --- /dev/null +++ b/src/gl-shaders.c @@ -0,0 +1,284 @@ +/* + * Copyright © 2012 John Kåre Alsaker + * Copyright © 2012 Intel Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "gl-internal.h" + +void +gl_use_shader(struct gl_renderer *gr, + struct gl_shader *shader) +{ + if (gr->current_shader == shader) + return; + + glUseProgram(shader->program); + gr->current_shader = shader; +} + +void +gl_shader_uniforms(struct gl_shader *shader, + struct weston_surface *surface, + struct weston_output *output) +{ + int i; + struct gl_surface_state *gs = get_surface_state(surface); + + glUniformMatrix4fv(shader->proj_uniform, + 1, GL_FALSE, output->matrix.d); + glUniform4fv(shader->color_uniform, 1, gs->color); + glUniform1f(shader->alpha_uniform, surface->alpha); + + for (i = 0; i < gs->num_textures; i++) + glUniform1i(shader->tex_uniforms[i], i); +} + +static const char vertex_shader[] = + "uniform mat4 proj;\n" + "attribute vec2 position;\n" + "attribute vec2 texcoord;\n" + "varying vec2 v_texcoord;\n" + "void main()\n" + "{\n" + " gl_Position = proj * vec4(position, 0.0, 1.0);\n" + " v_texcoord = texcoord;\n" + "}\n"; + +/* Declare common fragment shader uniforms */ +#define FRAGMENT_CONVERT_YUV \ + " y *= alpha;\n" \ + " u *= alpha;\n" \ + " v *= alpha;\n" \ + " gl_FragColor.r = y + 1.59602678 * v;\n" \ + " gl_FragColor.g = y - 0.39176229 * u - 0.81296764 * v;\n" \ + " 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" + "uniform sampler2D tex;\n" + "uniform float alpha;\n" + "void main()\n" + "{\n" + " gl_FragColor = alpha * texture2D(tex, v_texcoord)\n;" + ; + +static const char texture_fragment_shader_rgbx[] = + "precision mediump float;\n" + "varying vec2 v_texcoord;\n" + "uniform sampler2D tex;\n" + "uniform float alpha;\n" + "void main()\n" + "{\n" + " gl_FragColor.rgb = alpha * texture2D(tex, v_texcoord).rgb\n;" + " gl_FragColor.a = alpha;\n" + ; + +static const char texture_fragment_shader_egl_external[] = + "#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" + "void main()\n" + "{\n" + " gl_FragColor = alpha * texture2D(tex, v_texcoord)\n;" + ; + +static const char texture_fragment_shader_y_uv[] = + "precision mediump float;\n" + "uniform sampler2D tex;\n" + "uniform sampler2D tex1;\n" + "varying vec2 v_texcoord;\n" + "uniform float alpha;\n" + "void main() {\n" + " float y = 1.16438356 * (texture2D(tex, v_texcoord).x - 0.0625);\n" + " float u = texture2D(tex1, v_texcoord).r - 0.5;\n" + " float v = texture2D(tex1, v_texcoord).g - 0.5;\n" + FRAGMENT_CONVERT_YUV + ; + +static const char texture_fragment_shader_y_u_v[] = + "precision mediump float;\n" + "uniform sampler2D tex;\n" + "uniform sampler2D tex1;\n" + "uniform sampler2D tex2;\n" + "varying vec2 v_texcoord;\n" + "uniform float alpha;\n" + "void main() {\n" + " float y = 1.16438356 * (texture2D(tex, v_texcoord).x - 0.0625);\n" + " float u = texture2D(tex1, v_texcoord).x - 0.5;\n" + " float v = texture2D(tex2, v_texcoord).x - 0.5;\n" + FRAGMENT_CONVERT_YUV + ; + +static const char texture_fragment_shader_y_xuxv[] = + "precision mediump float;\n" + "uniform sampler2D tex;\n" + "uniform sampler2D tex1;\n" + "varying vec2 v_texcoord;\n" + "uniform float alpha;\n" + "void main() {\n" + " float y = 1.16438356 * (texture2D(tex, v_texcoord).x - 0.0625);\n" + " float u = texture2D(tex1, v_texcoord).g - 0.5;\n" + " float v = texture2D(tex1, v_texcoord).a - 0.5;\n" + FRAGMENT_CONVERT_YUV + ; + +static const char solid_fragment_shader[] = + "precision mediump float;\n" + "uniform vec4 color;\n" + "uniform float alpha;\n" + "void main()\n" + "{\n" + " gl_FragColor = alpha * color\n;" + ; + +static int +compile_shader(GLenum type, int count, const char **sources) +{ + GLuint s; + char msg[512]; + GLint status; + + s = glCreateShader(type); + glShaderSource(s, count, sources, NULL); + glCompileShader(s); + glGetShaderiv(s, GL_COMPILE_STATUS, &status); + if (!status) { + glGetShaderInfoLog(s, sizeof msg, NULL, msg); + weston_log("shader info: %s\n", msg); + return GL_NONE; + } + + return s; +} + +static int +shader_init(struct gl_renderer *renderer, struct gl_shader *shader, + const char *vertex_source, const char *fragment_source) +{ + char msg[512]; + GLint status; + int count; + const char *sources[3]; + + shader->vertex_shader = + 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, count, sources); + + shader->program = glCreateProgram(); + glAttachShader(shader->program, shader->vertex_shader); + glAttachShader(shader->program, shader->fragment_shader); + glBindAttribLocation(shader->program, 0, "position"); + glBindAttribLocation(shader->program, 1, "texcoord"); + + glLinkProgram(shader->program); + glGetProgramiv(shader->program, GL_LINK_STATUS, &status); + if (!status) { + glGetProgramInfoLog(shader->program, sizeof msg, NULL, msg); + weston_log("link info: %s\n", msg); + return -1; + } + + shader->proj_uniform = glGetUniformLocation(shader->program, "proj"); + 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->alpha_uniform = glGetUniformLocation(shader->program, "alpha"); + shader->color_uniform = glGetUniformLocation(shader->program, "color"); + + return 0; +} + +static void +shader_release(struct gl_shader *shader) +{ + glDeleteShader(shader->vertex_shader); + glDeleteShader(shader->fragment_shader); + glDeleteProgram(shader->program); + + shader->vertex_shader = 0; + shader->fragment_shader = 0; + shader->program = 0; +} + +int +gl_init_shaders(struct gl_renderer *gr) +{ + if (shader_init(gr, &gr->texture_shader_rgba, + vertex_shader, texture_fragment_shader_rgba) < 0) + return -1; + if (shader_init(gr, &gr->texture_shader_rgbx, + vertex_shader, texture_fragment_shader_rgbx) < 0) + return -1; + if (gr->has_egl_image_external && + shader_init(gr, &gr->texture_shader_egl_external, + vertex_shader, texture_fragment_shader_egl_external) < 0) + return -1; + if (shader_init(gr, &gr->texture_shader_y_uv, + vertex_shader, texture_fragment_shader_y_uv) < 0) + return -1; + if (shader_init(gr, &gr->texture_shader_y_u_v, + vertex_shader, texture_fragment_shader_y_u_v) < 0) + return -1; + if (shader_init(gr, &gr->texture_shader_y_xuxv, + vertex_shader, texture_fragment_shader_y_xuxv) < 0) + return -1; + if (shader_init(gr, &gr->solid_shader, + vertex_shader, solid_fragment_shader) < 0) + return -1; + + return 0; +} + +void +gl_destroy_shaders(struct gl_renderer *gr) +{ + shader_release(&gr->texture_shader_rgba); + shader_release(&gr->texture_shader_rgbx); + shader_release(&gr->texture_shader_egl_external); + 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); + +} -- 1.8.1.3 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel