diff --git a/libweston/renderer-gl/gl-renderer-internal.h b/libweston/renderer-gl/gl-renderer-internal.h index 01e8b944..b208a770 100644 --- a/libweston/renderer-gl/gl-renderer-internal.h +++ b/libweston/renderer-gl/gl-renderer-internal.h @@ -149,4 +149,14 @@ gl_renderer_setup_egl_client_extensions(struct gl_renderer *gr); int gl_renderer_setup_egl_extensions(struct weston_compositor *ec); +int +shader_init(struct gl_shader *shader, struct gl_renderer *renderer, + const char *vertex_source, const char *fragment_source); + +void +shader_release(struct gl_shader *shader); + +int +compile_shaders(struct weston_compositor *ec); + #endif /* GL_RENDERER_INTERNAL_H */ diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c index be317120..10372138 100644 --- a/libweston/renderer-gl/gl-renderer.c +++ b/libweston/renderer-gl/gl-renderer.c @@ -733,10 +733,6 @@ use_output(struct weston_output *output) return 0; } -static int -shader_init(struct gl_shader *shader, struct gl_renderer *gr, - const char *vertex_source, const char *fragment_source); - static void use_shader(struct gl_renderer *gr, struct gl_shader *shader) { @@ -2909,212 +2905,6 @@ gl_renderer_create_surface(struct weston_surface *surface) return 0; } -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 texture_fragment_shader_xyuv[] = - "precision mediump float;\n" - "uniform sampler2D tex;\n" - "varying vec2 v_texcoord;\n" - "uniform float alpha;\n" - "void main() {\n" - " float y = 1.16438356 * (texture2D(tex, v_texcoord).b - 0.0625);\n" - " float u = texture2D(tex, v_texcoord).g - 0.5;\n" - " float v = texture2D(tex, v_texcoord).r - 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 gl_renderer *renderer, - 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 (shader->vertex_shader == GL_NONE) - return -1; - - 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); - if (shader->fragment_shader == GL_NONE) - return -1; - - 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; -} - void gl_renderer_log_extensions(const char *name, const char *extensions) { @@ -3586,41 +3376,6 @@ fail: return -1; } -static int -compile_shaders(struct weston_compositor *ec) -{ - struct gl_renderer *gr = get_renderer(ec); - - gr->texture_shader_rgba.vertex_source = vertex_shader; - gr->texture_shader_rgba.fragment_source = texture_fragment_shader_rgba; - - gr->texture_shader_rgbx.vertex_source = vertex_shader; - gr->texture_shader_rgbx.fragment_source = texture_fragment_shader_rgbx; - - gr->texture_shader_egl_external.vertex_source = vertex_shader; - gr->texture_shader_egl_external.fragment_source = - texture_fragment_shader_egl_external; - - gr->texture_shader_y_uv.vertex_source = vertex_shader; - gr->texture_shader_y_uv.fragment_source = texture_fragment_shader_y_uv; - - gr->texture_shader_y_u_v.vertex_source = vertex_shader; - gr->texture_shader_y_u_v.fragment_source = - texture_fragment_shader_y_u_v; - - gr->texture_shader_y_xuxv.vertex_source = vertex_shader; - gr->texture_shader_y_xuxv.fragment_source = - texture_fragment_shader_y_xuxv; - - gr->texture_shader_xyuv.vertex_source = vertex_shader; - gr->texture_shader_xyuv.fragment_source = texture_fragment_shader_xyuv; - - gr->solid_shader.vertex_source = vertex_shader; - gr->solid_shader.fragment_source = solid_fragment_shader; - - return 0; -} - static void fragment_debug_binding(struct weston_keyboard *keyboard, const struct timespec *time, diff --git a/libweston/renderer-gl/gl-shaders.c b/libweston/renderer-gl/gl-shaders.c new file mode 100644 index 00000000..c1f454e3 --- /dev/null +++ b/libweston/renderer-gl/gl-shaders.c @@ -0,0 +1,274 @@ +/* + * Copyright 2012 Intel Corporation + * Copyright 2015,2019 Collabora, Ltd. + * Copyright 2016 NVIDIA Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "config.h" + +#include + +#include "gl-renderer.h" +#include "gl-renderer-internal.h" + +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 texture_fragment_shader_xyuv[] = + "precision mediump float;\n" + "uniform sampler2D tex;\n" + "varying vec2 v_texcoord;\n" + "uniform float alpha;\n" + "void main() {\n" + " float y = 1.16438356 * (texture2D(tex, v_texcoord).b - 0.0625);\n" + " float u = texture2D(tex, v_texcoord).g - 0.5;\n" + " float v = texture2D(tex, v_texcoord).r - 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; +} + +int +shader_init(struct gl_shader *shader, struct gl_renderer *renderer, + 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 (shader->vertex_shader == GL_NONE) + return -1; + + 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); + if (shader->fragment_shader == GL_NONE) + return -1; + + 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; +} + +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 +compile_shaders(struct weston_compositor *ec) +{ + struct gl_renderer *gr = get_renderer(ec); + + gr->texture_shader_rgba.vertex_source = vertex_shader; + gr->texture_shader_rgba.fragment_source = texture_fragment_shader_rgba; + + gr->texture_shader_rgbx.vertex_source = vertex_shader; + gr->texture_shader_rgbx.fragment_source = texture_fragment_shader_rgbx; + + gr->texture_shader_egl_external.vertex_source = vertex_shader; + gr->texture_shader_egl_external.fragment_source = + texture_fragment_shader_egl_external; + + gr->texture_shader_y_uv.vertex_source = vertex_shader; + gr->texture_shader_y_uv.fragment_source = texture_fragment_shader_y_uv; + + gr->texture_shader_y_u_v.vertex_source = vertex_shader; + gr->texture_shader_y_u_v.fragment_source = + texture_fragment_shader_y_u_v; + + gr->texture_shader_y_xuxv.vertex_source = vertex_shader; + gr->texture_shader_y_xuxv.fragment_source = + texture_fragment_shader_y_xuxv; + + gr->texture_shader_xyuv.vertex_source = vertex_shader; + gr->texture_shader_xyuv.fragment_source = texture_fragment_shader_xyuv; + + gr->solid_shader.vertex_source = vertex_shader; + gr->solid_shader.fragment_source = solid_fragment_shader; + + return 0; +} diff --git a/libweston/renderer-gl/meson.build b/libweston/renderer-gl/meson.build index 374e65ba..f2f58fac 100644 --- a/libweston/renderer-gl/meson.build +++ b/libweston/renderer-gl/meson.build @@ -7,6 +7,7 @@ config_h.set('ENABLE_EGL', '1') srcs_renderer_gl = [ 'egl-glue.c', 'gl-renderer.c', + 'gl-shaders.c', linux_dmabuf_unstable_v1_protocol_c, linux_dmabuf_unstable_v1_server_protocol_h, ]