1 /*
2  * GStreamer
3  * Copyright (C) 2015 Matthew Waters <matthew@centricular.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20 
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #include "gstglshaderstrings.h"
26 
27 #define MEDIUMP_PRECISION \
28    "#ifdef GL_ES\n" \
29    "precision mediump float;\n" \
30    "#endif\n"
31 
32 #define HIGHP_PRECISION \
33    "#ifdef GL_ES\n" \
34    "precision highp float;\n" \
35    "#endif\n"
36 
37 /* *INDENT-OFF* */
38 const gchar *gst_gl_shader_string_fragment_mediump_precision =
39     MEDIUMP_PRECISION;
40 
41 const gchar *gst_gl_shader_string_fragment_highp_precision =
42     HIGHP_PRECISION;
43 
44 const gchar *gst_gl_shader_string_vertex_default =
45     "attribute vec4 a_position;\n"
46     "attribute vec2 a_texcoord;\n"
47     "varying vec2 v_texcoord;\n"
48     "void main()\n"
49     "{\n"
50     "   gl_Position = a_position;\n"
51     "   v_texcoord = a_texcoord;\n"
52     "}\n";
53 
54 const gchar *gst_gl_shader_string_vertex_mat4_texture_transform =
55     "uniform mat4 u_transformation;\n"
56     "attribute vec4 a_position;\n"
57     "attribute vec2 a_texcoord;\n"
58     "varying vec2 v_texcoord;\n"
59     "void main()\n"
60     "{\n"
61     "   gl_Position = a_position;\n"
62     "   v_texcoord = (u_transformation * vec4(a_texcoord, 0, 1)).xy;\n"
63     "}\n";
64 
65 const gchar *gst_gl_shader_string_vertex_mat4_vertex_transform =
66     "uniform mat4 u_transformation;\n"
67     "attribute vec4 a_position;\n"
68     "attribute vec2 a_texcoord;\n"
69     "varying vec2 v_texcoord;\n"
70     "void main()\n"
71     "{\n"
72     "   gl_Position = u_transformation * a_position;\n"
73     "   v_texcoord = a_texcoord;\n"
74     "}\n";
75 
76 #define DEFAULT_FRAGMENT_BODY \
77     "varying vec2 v_texcoord;\n" \
78     "uniform sampler2D tex;\n" \
79     "void main()\n" \
80     "{\n" \
81     "  gl_FragColor = texture2D(tex, v_texcoord);\n" \
82     "}"
83 const gchar *gst_gl_shader_string_fragment_default =
84     MEDIUMP_PRECISION
85     DEFAULT_FRAGMENT_BODY;
86 
87 #define EXTERNAL_FRAGMENT_HEADER \
88     "#extension GL_OES_EGL_image_external : require\n"
89 
90 #define EXTERNAL_FRAGMENT_BODY \
91     "varying vec2 v_texcoord;\n" \
92     "uniform samplerExternalOES tex;\n" \
93     "void main()\n" \
94     "{\n" \
95     "  gl_FragColor = texture2D(tex, v_texcoord);\n" \
96     "}"
97 const gchar *gst_gl_shader_string_fragment_external_oes_default =
98     EXTERNAL_FRAGMENT_HEADER
99     MEDIUMP_PRECISION
100     EXTERNAL_FRAGMENT_BODY;
101 /* *INDENT-ON* */
102 
103 /**
104  * gst_gl_shader_string_get_highest_precision:
105  * @context: a #GstGLContext
106  * @version: a #GstGLSLVersion
107  * @profile: a #GstGLSLProfile
108  *
109  * Generates a shader string that defines the precision of float types in
110  * GLSL shaders.  This is particularly needed for fragment shaders in a
111  * GLSL ES context where there is no default precision specified.
112  *
113  * Practically, this will return the string 'precision mediump float'
114  * or 'precision highp float' depending on if high precision floats are
115  * determined to be supported.
116  *
117  * Returns: a shader string defining the precision of float types based on
118  *      @context, @version and @profile
119  *
120  * Since: 1.16
121  */
122 const gchar *
gst_gl_shader_string_get_highest_precision(GstGLContext * context,GstGLSLVersion version,GstGLSLProfile profile)123 gst_gl_shader_string_get_highest_precision (GstGLContext * context,
124     GstGLSLVersion version, GstGLSLProfile profile)
125 {
126   if (gst_gl_context_supports_precision (context, version, profile)) {
127     if (gst_gl_context_supports_precision_highp (context, version, profile))
128       return gst_gl_shader_string_fragment_highp_precision;
129     else
130       return gst_gl_shader_string_fragment_mediump_precision;
131   }
132   return "";
133 }
134 
135 /**
136  * gst_gl_shader_string_fragment_get_default:
137  * @context: a #GstGLContext
138  * @version: a #GstGLSLVersion
139  * @profile: a #GstGLSLProfile
140  *
141  * Returns: a passthrough shader string for copying an input texture to
142  *          the output
143  *
144  * Since: 1.16
145  */
146 gchar *
gst_gl_shader_string_fragment_get_default(GstGLContext * context,GstGLSLVersion version,GstGLSLProfile profile)147 gst_gl_shader_string_fragment_get_default (GstGLContext * context,
148     GstGLSLVersion version, GstGLSLProfile profile)
149 {
150   const gchar *precision =
151       gst_gl_shader_string_get_highest_precision (context, version, profile);
152 
153   return g_strdup_printf ("%s%s", precision, DEFAULT_FRAGMENT_BODY);
154 }
155 
156 /**
157  * gst_gl_shader_string_fragment_external_oes_get_default:
158  * @context: a #GstGLContext
159  * @version: a #GstGLSLVersion
160  * @profile: a #GstGLSLProfile
161  *
162  * Returns: a passthrough shader string for copying an input external-oes
163  *          texture to the output
164  *
165  * Since: 1.16
166  */
167 gchar *
gst_gl_shader_string_fragment_external_oes_get_default(GstGLContext * context,GstGLSLVersion version,GstGLSLProfile profile)168 gst_gl_shader_string_fragment_external_oes_get_default (GstGLContext * context,
169     GstGLSLVersion version, GstGLSLProfile profile)
170 {
171   const gchar *precision =
172       gst_gl_shader_string_get_highest_precision (context, version, profile);
173 
174   return g_strdup_printf ("%s%s%s", EXTERNAL_FRAGMENT_HEADER, precision,
175       EXTERNAL_FRAGMENT_BODY);
176 }
177