gst_gl_shader_string_vertex_default
gst_gl_shader_string_vertex_mat4_texture_transform
gst_gl_shader_string_vertex_mat4_vertex_transform
+gst_gl_shader_string_get_highest_precision
+gst_gl_shader_string_fragment_get_default
+gst_gl_shader_string_fragment_external_oes_get_default
<SUBSECTION Standard>
GstGLShaderPrivate
GST_GL_SHADER
gst_glsl_string_get_version_profile
gst_gl_context_supports_glsl_profile_version
gst_gl_version_to_glsl_version
+gst_gl_context_supports_precision
+gst_gl_context_supports_precision_highp
<SUBSECTION Standard>
gst_glsl_error_quark
</SECTION>
"}";
const gchar *mirror_fragment_source_gles2 =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;"
"uniform sampler2D tex;"
"void main () {"
"}";
const gchar *squeeze_fragment_source_gles2 =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;"
"uniform sampler2D tex;"
"void main () {"
"}";
const gchar *stretch_fragment_source_gles2 =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;"
"uniform sampler2D tex;"
"void main () {"
"}";
const gchar *tunnel_fragment_source_gles2 =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;"
"uniform sampler2D tex;"
"void main () {"
"}";
const gchar *fisheye_fragment_source_gles2 =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;"
"uniform sampler2D tex;"
"void main () {"
"}";
const gchar *twirl_fragment_source_gles2 =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;"
- "uniform sampler2D tex;"
+ "uniform sampler2D tex;"
"void main () {"
" vec2 texturecoord = v_texcoord.xy;"
" vec2 normcoord;"
"}";
const gchar *bulge_fragment_source_gles2 =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;"
"uniform sampler2D tex;"
"void main () {"
"}";
const gchar *square_fragment_source_gles2 =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;"
"uniform sampler2D tex;"
"void main () {"
"}";
const gchar *luma_threshold_fragment_source_gles2 =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;"
"uniform sampler2D tex;"
"void main () {"
"}";
const gchar *sep_sobel_length_fragment_source_gles2 =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;"
"uniform sampler2D tex;"
"uniform bool invert;"
"}";
const gchar *desaturate_fragment_source_gles2 =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;"
"uniform sampler2D tex;"
"void main () {"
"}";
const gchar *sep_sobel_hconv3_fragment_source_gles2 =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;"
"uniform sampler2D tex;"
"uniform float width;"
"}";
const gchar *sep_sobel_vconv3_fragment_source_gles2 =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;"
"uniform sampler2D tex;"
"uniform float height;"
"}";
const gchar *hconv7_fragment_source_gles2 =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;"
"uniform sampler2D tex;"
"uniform float kernel[7];"
/* vertical convolution 7x7 */
const gchar *vconv7_fragment_source_gles2 =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;"
"uniform sampler2D tex;"
"uniform float kernel[7];"
/* TODO: support several blend modes */
const gchar *sum_fragment_source_gles2 =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;"
"uniform sampler2D base;"
"uniform sampler2D blend;"
"}";
const gchar *multiply_fragment_source_gles2 =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;"
"uniform sampler2D base;"
"uniform sampler2D blend;"
/* lut operations, map luma to tex1d, see orange book (chapter 19) */
const gchar *luma_to_curve_fragment_source_gles2 =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;"
"uniform sampler2D tex;"
"uniform sampler2D curve;"
/* lut operations, map rgb to tex1d, see orange book (chapter 19) */
const gchar *rgb_to_curve_fragment_source_gles2 =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;"
"uniform sampler2D tex;"
"uniform sampler2D curve;"
"}";
const gchar *sin_fragment_source_gles2 =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;"
"uniform sampler2D tex;"
"void main () {"
"}";
const gchar *interpolate_fragment_source =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;"
"uniform sampler2D base;"
"uniform sampler2D blend;"
"}";
const gchar *texture_interp_fragment_source =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;"
"uniform sampler2D base;"
"uniform sampler2D blend;"
"}";
const gchar *difference_fragment_source =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;"
"uniform sampler2D saved;"
"uniform sampler2D current;"
kernel into the shader and remove unneeded zero multiplications in
the convolution */
const gchar *conv9_fragment_source_gles2 =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;"
"uniform sampler2D tex;"
"uniform float kernel[9];"
"}";
static const gchar *smpte_fragment_src =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec4 color;\n"
"void main()\n"
"{\n"
"}";
static const gchar *snow_fragment_src =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"uniform float time;\n"
"varying vec2 out_uv;\n"
"\n"
gushort *plane_indices;
GError *error = NULL;
int color_idx = 0;
+ const gchar *frags[2];
int i;
src->base.base.context = context;
if (src->color_shader)
gst_object_unref (src->color_shader);
+
+ frags[0] =
+ gst_gl_shader_string_get_highest_precision (context,
+ GST_GLSL_VERSION_NONE,
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY);
+ frags[1] = smpte_fragment_src;
+
src->color_shader = gst_gl_shader_new_link_with_stages (context, &error,
gst_glsl_stage_new_with_string (context, GL_VERTEX_SHADER,
GST_GLSL_VERSION_NONE,
GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
smpte_vertex_src),
- gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
+ gst_glsl_stage_new_with_strings (context, GL_FRAGMENT_SHADER,
GST_GLSL_VERSION_NONE,
- GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
- smpte_fragment_src), NULL);
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY, 2,
+ frags), NULL);
if (!src->color_shader) {
GST_ERROR_OBJECT (src->base.base.src, "%s", error->message);
return FALSE;
}
+ frags[1] = snow_fragment_src;
+
if (src->snow_shader)
gst_object_unref (src->snow_shader);
src->snow_shader = gst_gl_shader_new_link_with_stages (context, &error,
GST_GLSL_VERSION_NONE,
GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
snow_vertex_src),
- gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
+ gst_glsl_stage_new_with_strings (context, GL_FRAGMENT_SHADER,
GST_GLSL_VERSION_NONE,
- GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
- snow_fragment_src), NULL);
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY, 2,
+ frags), NULL);
if (!src->snow_shader) {
GST_ERROR_OBJECT (src->base.base.src, "%s", error->message);
return FALSE;
"}";
static const gchar *checkers_fragment_src =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"uniform float checker_width;\n"
"uniform float width;\n"
"uniform float height;\n"
{
struct SrcCheckers *src = impl;
GError *error = NULL;
+ const gchar *frags[2];
src->base.base.context = context;
+ frags[0] =
+ gst_gl_shader_string_get_highest_precision (context,
+ GST_GLSL_VERSION_NONE,
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY);
+ frags[1] = checkers_fragment_src;
+
if (src->base.shader)
gst_object_unref (src->base.shader);
src->base.shader = gst_gl_shader_new_link_with_stages (context, &error,
GST_GLSL_VERSION_NONE,
GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
checkers_vertex_src),
- gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
+ gst_glsl_stage_new_with_strings (context, GL_FRAGMENT_SHADER,
GST_GLSL_VERSION_NONE,
- GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
- checkers_fragment_src), NULL);
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY, 2,
+ frags), NULL);
if (!src->base.shader) {
GST_ERROR_OBJECT (src->base.base.src, "%s", error->message);
return FALSE;
{
struct SrcShader *src = impl;
GError *error = NULL;
+ const gchar *frags[2];
src->base.context = context;
+ frags[0] =
+ gst_gl_shader_string_get_highest_precision (context,
+ GST_GLSL_VERSION_NONE,
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY);
+ frags[1] = snow_fragment_src;
+
if (src->shader)
gst_object_unref (src->shader);
src->shader = gst_gl_shader_new_link_with_stages (context, &error,
GST_GLSL_VERSION_NONE,
GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
snow_vertex_src),
- gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
+ gst_glsl_stage_new_with_strings (context, GL_FRAGMENT_SHADER,
GST_GLSL_VERSION_NONE,
- GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
- snow_fragment_src), NULL);
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY, 2,
+ frags), NULL);
if (!src->shader) {
GST_ERROR_OBJECT (src->base.src, "%s", error->message);
return FALSE;
"}";
static const gchar *mandelbrot_fragment_src =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"uniform float time;\n"
"varying vec2 fractal_position;\n"
"const vec4 K = vec4(1.0, 0.66, 0.33, 3.0);\n"
{
struct SrcShader *src = impl;
GError *error = NULL;
+ const gchar *frags[2];
src->base.context = context;
+ frags[0] =
+ gst_gl_shader_string_get_highest_precision (context,
+ GST_GLSL_VERSION_NONE,
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY);
+ frags[1] = mandelbrot_fragment_src;
+
if (src->shader)
gst_object_unref (src->shader);
src->shader = gst_gl_shader_new_link_with_stages (context, &error,
GST_GLSL_VERSION_NONE,
GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
mandelbrot_vertex_src),
- gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
+ gst_glsl_stage_new_with_strings (context, GL_FRAGMENT_SHADER,
GST_GLSL_VERSION_NONE,
- GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
- mandelbrot_fragment_src), NULL);
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY, 2,
+ frags), NULL);
if (!src->shader) {
GST_ERROR_OBJECT (src->base.src, "%s", error->message);
return FALSE;
"}";
static const gchar *circular_fragment_src =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"uniform float aspect_ratio;\n"
"varying vec2 uv;\n"
"#define PI 3.14159265\n"
{
struct SrcShader *src = impl;
GError *error = NULL;
+ const gchar *frags[2];
src->base.context = context;
+ frags[0] =
+ gst_gl_shader_string_get_highest_precision (context,
+ GST_GLSL_VERSION_NONE,
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY);
+ frags[1] = circular_fragment_src;
+
if (src->shader)
gst_object_unref (src->shader);
src->shader = gst_gl_shader_new_link_with_stages (context, &error,
GST_GLSL_VERSION_NONE,
GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
circular_vertex_src),
- gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
+ gst_glsl_stage_new_with_strings (context, GL_FRAGMENT_SHADER,
GST_GLSL_VERSION_NONE,
- GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
- circular_fragment_src), NULL);
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY, 2,
+ frags), NULL);
if (!src->shader) {
GST_ERROR_OBJECT (src->base.src, "%s", error->message);
return FALSE;
/* *INDENT-OFF* */
static const gchar *alpha_frag =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;\n"
"uniform sampler2D tex;\n"
"uniform float alpha;\n"
"}\n";
static const gchar *chroma_key_frag =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;\n"
"uniform sampler2D tex;\n"
"uniform float cb;\n"
GstGLBaseFilter *base_filter = GST_GL_BASE_FILTER (alpha);
GstGLFilter *filter = GST_GL_FILTER (alpha);
GError *error = NULL;
+ const gchar *frags[2];
if (alpha->alpha_shader)
gst_object_unref (alpha->alpha_shader);
+ frags[0] =
+ gst_gl_shader_string_get_highest_precision (base_filter->context,
+ GST_GLSL_VERSION_NONE,
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY);
+ frags[1] = alpha_frag;
+
if (!(alpha->alpha_shader =
gst_gl_shader_new_link_with_stages (base_filter->context, &error,
gst_glsl_stage_new_default_vertex (base_filter->context),
- gst_glsl_stage_new_with_string (base_filter->context,
+ gst_glsl_stage_new_with_strings (base_filter->context,
GL_FRAGMENT_SHADER, GST_GLSL_VERSION_NONE,
- GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
- alpha_frag), NULL))) {
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY, 2,
+ frags), NULL))) {
GST_ELEMENT_ERROR (alpha, RESOURCE, NOT_FOUND, ("%s",
"Failed to initialize alpha shader"), ("%s",
error ? error->message : "Unknown error"));
if (alpha->chroma_key_shader)
gst_object_unref (alpha->chroma_key_shader);
+ frags[1] = chroma_key_frag;
+
if (!(alpha->chroma_key_shader =
gst_gl_shader_new_link_with_stages (base_filter->context, &error,
gst_glsl_stage_new_default_vertex (base_filter->context),
- gst_glsl_stage_new_with_string (base_filter->context,
+ gst_glsl_stage_new_with_strings (base_filter->context,
GL_FRAGMENT_SHADER, GST_GLSL_VERSION_NONE,
- GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
- chroma_key_frag), NULL))) {
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY, 2,
+ frags), NULL))) {
GST_ELEMENT_ERROR (alpha, RESOURCE, NOT_FOUND, ("%s",
"Failed to initialize chroma key shader"), ("%s",
error ? error->message : "Unknown error"));
GST_STATIC_CAPS (GST_GL_COLOR_BALANCE_VIDEO_CAPS));
/* *INDENT-OFF* */
-static const gchar color_balance_frag_OES_preamble[] =
- "#extension GL_OES_EGL_image_external : require\n"
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
+static const gchar glsl_external_image_extension[] =
+ "#extension GL_OES_EGL_image_external : require\n";
+
+static const gchar glsl_external_image_sampler[] =
"uniform samplerExternalOES tex;\n";
-static const gchar color_balance_frag_2D_preamble[] =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
+static const gchar glsl_2D_image_sampler[] =
"uniform sampler2D tex;\n";
static const gchar color_balance_frag_templ[] =
- "%s\n" // Preamble
"uniform float brightness;\n"
"uniform float contrast;\n"
"uniform float saturation;\n"
GstGLBaseFilter *base_filter = GST_GL_BASE_FILTER (balance);
GstGLFilter *filter = GST_GL_FILTER (balance);
GError *error = NULL;
- gchar *frag_str;
+ gchar *frag_body;
+ const gchar *frags[4];
+ guint frag_i = 0;
if (balance->shader)
gst_object_unref (balance->shader);
+ if (filter->in_texture_target == GST_GL_TEXTURE_TARGET_EXTERNAL_OES)
+ frags[frag_i++] = glsl_external_image_extension;
+
+ frags[frag_i++] =
+ gst_gl_shader_string_get_highest_precision (base_filter->context,
+ GST_GLSL_VERSION_NONE,
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY);
+
/* Can support rectangle textures in the future if needed */
- if (filter->in_texture_target == GST_GL_TEXTURE_TARGET_2D)
- frag_str =
- g_strdup_printf (color_balance_frag_templ,
- color_balance_frag_2D_preamble, "texture2D");
- else
- frag_str =
- g_strdup_printf (color_balance_frag_templ,
- color_balance_frag_OES_preamble, "texture2D");
+ if (filter->in_texture_target == GST_GL_TEXTURE_TARGET_2D) {
+ frags[frag_i++] = glsl_2D_image_sampler;
+ frags[frag_i++] = frag_body =
+ g_strdup_printf (color_balance_frag_templ, "texture2D");
+ } else {
+ frags[frag_i++] = glsl_external_image_sampler;
+ frags[frag_i++] = frag_body =
+ g_strdup_printf (color_balance_frag_templ, "texture2D");
+ }
+
+ g_assert (frag_i <= G_N_ELEMENTS (frags));
if (!(balance->shader =
gst_gl_shader_new_link_with_stages (base_filter->context, &error,
gst_glsl_stage_new_default_vertex (base_filter->context),
- gst_glsl_stage_new_with_string (base_filter->context,
+ gst_glsl_stage_new_with_strings (base_filter->context,
GL_FRAGMENT_SHADER, GST_GLSL_VERSION_NONE,
- GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
- frag_str), NULL))) {
- g_free (frag_str);
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY, frag_i,
+ frags), NULL))) {
+ g_free (frag_body);
GST_ELEMENT_ERROR (balance, RESOURCE, NOT_FOUND, ("%s",
"Failed to initialize colorbalance shader"), ("%s",
error ? error->message : "Unknown error"));
return FALSE;
}
- g_free (frag_str);
+ g_free (frag_body);
filter->draw_attr_position_loc =
gst_gl_shader_get_attribute_location (balance->shader, "a_position");
/* *INDENT-OFF* */
static const gchar *greedyh_fragment_source =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"uniform sampler2D tex;\n"
"uniform sampler2D tex_prev;\n"
"uniform float max_comb;\n"
"}\n";
const gchar *vfir_fragment_source =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"uniform sampler2D tex;\n"
"uniform float width;\n"
"uniform float height;\n"
GstGLShader *shader = NULL;
GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (filter);
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
+ const gchar *frags[2];
shader = g_hash_table_lookup (deinterlace_filter->shaderstable, shader_name);
+ frags[0] =
+ gst_gl_shader_string_get_highest_precision (context,
+ GST_GLSL_VERSION_NONE,
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY);
+ frags[1] = shader_source;
+
if (!shader) {
GError *error = NULL;
if (!(shader = gst_gl_shader_new_link_with_stages (context, &error,
gst_glsl_stage_new_default_vertex (context),
- gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
+ gst_glsl_stage_new_with_strings (context, GL_FRAGMENT_SHADER,
GST_GLSL_VERSION_NONE,
- GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
- shader_source), NULL))) {
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY, 2,
+ frags), NULL))) {
GST_ELEMENT_ERROR (deinterlace_filter, RESOURCE, NOT_FOUND,
("Failed to initialize %s shader", shader_name), (NULL));
}
GstGLBaseMemoryAllocator *tex_alloc;
GstGLAllocationParams *params;
GError *error = NULL;
+ const gchar *frags[2];
gint i;
if (!GST_GL_BASE_FILTER_CLASS (parent_class)->gl_start (base_filter))
return FALSE;
}
+ frags[0] =
+ gst_gl_shader_string_get_highest_precision (context,
+ GST_GLSL_VERSION_NONE,
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY);
+
+ frags[1] = difference_fragment_source;
if (!(differencematte->shader[0] =
gst_gl_shader_new_link_with_stages (context, &error,
gst_glsl_stage_new_default_vertex (context),
- gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
+ gst_glsl_stage_new_with_strings (context, GL_FRAGMENT_SHADER,
GST_GLSL_VERSION_NONE,
- GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
- difference_fragment_source), NULL))) {
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY, 2,
+ frags), NULL))) {
GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s",
"Failed to compile difference shader"), ("%s", error->message));
return FALSE;
}
+ frags[1] = hconv7_fragment_source_gles2;
if (!(differencematte->shader[1] =
gst_gl_shader_new_link_with_stages (context, &error,
gst_glsl_stage_new_default_vertex (context),
- gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
+ gst_glsl_stage_new_with_strings (context, GL_FRAGMENT_SHADER,
GST_GLSL_VERSION_NONE,
- GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
- hconv7_fragment_source_gles2), NULL))) {
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY, 2,
+ frags), NULL))) {
GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s",
"Failed to compile convolution shader"), ("%s", error->message));
return FALSE;
}
+ frags[1] = vconv7_fragment_source_gles2;
if (!(differencematte->shader[2] =
gst_gl_shader_new_link_with_stages (context, &error,
gst_glsl_stage_new_default_vertex (context),
- gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
+ gst_glsl_stage_new_with_strings (context, GL_FRAGMENT_SHADER,
GST_GLSL_VERSION_NONE,
- GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
- vconv7_fragment_source_gles2), NULL))) {
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY, 2,
+ frags), NULL))) {
GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s",
"Failed to compile convolution shader"), ("%s", error->message));
return FALSE;
}
+ frags[1] = texture_interp_fragment_source;
if (!(differencematte->shader[3] =
gst_gl_shader_new_link_with_stages (context, &error,
gst_glsl_stage_new_default_vertex (context),
- gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
+ gst_glsl_stage_new_with_strings (context, GL_FRAGMENT_SHADER,
GST_GLSL_VERSION_NONE,
- GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
- texture_interp_fragment_source), NULL))) {
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY, 2,
+ frags), NULL))) {
GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s",
"Failed to compile interpolation shader"), ("%s", error->message));
return FALSE;
if (!shader) {
GError *error = NULL;
+ const gchar *frag_strs[2];
+
+ frag_strs[0] =
+ gst_gl_shader_string_get_highest_precision (context,
+ GST_GLSL_VERSION_NONE,
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY);
+ frag_strs[1] = shader_source_gles2;
if (!(shader = gst_gl_shader_new_link_with_stages (context, &error,
gst_glsl_stage_new_default_vertex (context),
- gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
+ gst_glsl_stage_new_with_strings (context, GL_FRAGMENT_SHADER,
GST_GLSL_VERSION_NONE,
- GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
- shader_source_gles2), NULL))) {
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY, 2,
+ frag_strs), NULL))) {
GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
("Failed to initialize %s shader", shader_name), (NULL));
}
/* fragment source */
static const gchar *cube_f_src =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord; \n"
"uniform sampler2D s_texture; \n"
"void main() \n"
gst_gl_filter_cube_gl_start (GstGLBaseFilter * filter)
{
GstGLFilterCube *cube_filter = GST_GL_FILTER_CUBE (filter);
+ GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
+ gchar *frag_str;
+ gboolean ret;
+
+ frag_str =
+ g_strdup_printf ("%s%s",
+ gst_gl_shader_string_get_highest_precision (context,
+ GST_GLSL_VERSION_NONE,
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY), cube_f_src);
/* blocking call, wait the opengl thread has compiled the shader */
- return gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context,
- cube_v_src, cube_f_src, &cube_filter->shader);
+ ret = gst_gl_context_gen_shader (context, cube_v_src, frag_str,
+ &cube_filter->shader);
+ g_free (frag_str);
+
+ return ret;
}
static gboolean
GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
gst_gl_shader_string_vertex_mat4_vertex_transform);
if (gl_sink->texture_target == GST_GL_TEXTURE_TARGET_EXTERNAL_OES) {
+ gchar *frag_str;
+ frag_str =
+ gst_gl_shader_string_fragment_external_oes_get_default
+ (gl_sink->context, GST_GLSL_VERSION_NONE,
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY);
+
frag_stage = gst_glsl_stage_new_with_string (gl_sink->context,
GL_FRAGMENT_SHADER, GST_GLSL_VERSION_NONE,
- GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
- gst_gl_shader_string_fragment_external_oes_default);
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY, frag_str);
+
+ g_free (frag_str);
} else {
frag_stage = gst_glsl_stage_new_default_fragment (gl_sink->context);
}
/* fragment source */
static const gchar *overlay_f_src =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"uniform sampler2D texture;\n"
"uniform float alpha;\n"
"varying vec2 v_texcoord;\n"
gst_gl_overlay_gl_start (GstGLBaseFilter * base_filter)
{
GstGLOverlay *overlay = GST_GL_OVERLAY (base_filter);
+ gchar *frag_str;
+ gboolean ret;
if (!GST_GL_BASE_FILTER_CLASS (parent_class)->gl_start (base_filter))
return FALSE;
- return gst_gl_context_gen_shader (base_filter->context, overlay_v_src,
- overlay_f_src, &overlay->shader);
+ frag_str =
+ g_strdup_printf ("%s%s",
+ gst_gl_shader_string_get_highest_precision (base_filter->context,
+ GST_GLSL_VERSION_NONE,
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY), overlay_f_src);
+
+ /* blocking call, wait the opengl thread has compiled the shader */
+ ret = gst_gl_context_gen_shader (base_filter->context, overlay_v_src,
+ frag_str, &overlay->shader);
+ g_free (frag_str);
+
+ return ret;
}
/* free resources that need a gl context */
return FALSE;
if (gst_gl_context_get_gl_api (base_filter->context)) {
+ gchar *frag_str;
+ gboolean ret;
+
+ frag_str =
+ gst_gl_shader_string_fragment_get_default (base_filter->context,
+ GST_GLSL_VERSION_NONE,
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY);
+
/* blocking call, wait until the opengl thread has compiled the shader */
- return gst_gl_context_gen_shader (base_filter->context,
+ ret = gst_gl_context_gen_shader (base_filter->context,
gst_gl_shader_string_vertex_mat4_vertex_transform,
- gst_gl_shader_string_fragment_default, &transformation->shader);
+ frag_str, &transformation->shader);
+
+ g_free (frag_str);
+
+ return ret;
}
return TRUE;
}
/* fragment source */
static const gchar *video_mixer_f_src =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"uniform sampler2D texture; \n"
"uniform float alpha;\n"
"varying vec2 v_texcoord; \n"
/* checker fragment source */
static const gchar *checker_f_src =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"const float blocksize = 8.0;\n"
"void main ()\n"
"{\n"
gst_gl_video_mixer_init_shader (GstGLMixer * mixer, GstCaps * outcaps)
{
GstGLVideoMixer *video_mixer = GST_GL_VIDEO_MIXER (mixer);
+ gchar *frag_str;
+ gboolean ret;
if (video_mixer->shader)
gst_object_unref (video_mixer->shader);
/* need reconfigure output geometry */
video_mixer->output_geo_change = TRUE;
- return gst_gl_context_gen_shader (GST_GL_BASE_MIXER (mixer)->context,
+ frag_str =
+ g_strdup_printf ("%s%s",
+ gst_gl_shader_string_get_highest_precision (GST_GL_BASE_MIXER
+ (mixer)->context, GST_GLSL_VERSION_NONE,
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY),
+ video_mixer_f_src);
+
+ ret = gst_gl_context_gen_shader (GST_GL_BASE_MIXER (mixer)->context,
gst_gl_shader_string_vertex_mat4_vertex_transform,
- video_mixer_f_src, &video_mixer->shader);
+ frag_str, &video_mixer->shader);
+ g_free (frag_str);
+ return ret;
}
static void
/* *INDENT-ON* */
if (!video_mixer->checker) {
+ gchar *frag_str;
+
+ frag_str =
+ g_strdup_printf ("%s%s",
+ gst_gl_shader_string_get_highest_precision (GST_GL_BASE_MIXER
+ (mixer)->context, GST_GLSL_VERSION_NONE,
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY),
+ checker_f_src);
+
if (!gst_gl_context_gen_shader (GST_GL_BASE_MIXER (mixer)->context,
- checker_v_src, checker_f_src, &video_mixer->checker))
+ checker_v_src, frag_str, &video_mixer->checker)) {
+ g_free (frag_str);
return FALSE;
+ }
+ g_free (frag_str);
}
gst_gl_shader_use (video_mixer->checker);
GST_GL_API_GLES2,
255, 255,
2, 0,
- "\0",
- "\0")
+ "ARB:\0",
+ "ES2_compatibility\0")
GST_GL_EXT_FUNCTION (void, ReleaseShaderCompiler, (void))
GST_GL_EXT_FUNCTION (void, GetShaderPrecisionFormat,
(GLenum shadertype,
"const vec2 compose_weight = vec2(0.996109, 0.003891);\n"
#define DEFAULT_UNIFORMS \
- "#ifdef GL_ES\n" \
- "precision mediump float;\n" \
- "#endif\n" \
"uniform vec2 tex_scale0;\n" \
"uniform vec2 tex_scale1;\n" \
"uniform vec2 tex_scale2;\n" \
convert->context = NULL;
}
+ GST_ERROR_OBJECT (convert, "finalize");
+
G_OBJECT_CLASS (gst_gl_color_convert_parent_class)->finalize (object);
}
GstGLSLVersion version;
GstGLSLProfile profile;
gchar *version_str, *tmp, *tmp1;
- const gchar *strings[2];
+ const gchar *strings[3];
GError *error = NULL;
int i;
&version, &profile);
g_free (tmp);
- strings[1] = info->frag_prog;
+ strings[1] =
+ gst_gl_shader_string_get_highest_precision (convert->context, version,
+ profile);
+ strings[2] = info->frag_prog;
if (!(stage = gst_glsl_stage_new_with_strings (convert->context,
- GL_FRAGMENT_SHADER, version, profile, 2, strings))) {
+ GL_FRAGMENT_SHADER, version, profile, 3, strings))) {
GST_ERROR_OBJECT (convert, "Failed to create fragment stage");
g_free (info->frag_prog);
info->frag_prog = NULL;
#include "gstgloverlaycompositor.h"
-#include "gstglcontext.h"
-#include "gstglfuncs.h"
-#include "gstglmemory.h"
-#include "gstglshader.h"
-#include "gstglslstage.h"
+#include <gst/gl/gl.h>
+#include <gst/gl/gstglfuncs.h>
GST_DEBUG_CATEGORY_STATIC (gst_gl_overlay_compositor_debug);
#define GST_CAT_DEFAULT gst_gl_overlay_compositor_debug
/* *INDENT-OFF* */
const gchar *fragment_shader =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"varying vec2 v_texcoord;\n"
"uniform sampler2D tex;\n"
"void main(void)\n"
#define DEFAULT_YINVERT FALSE
G_DEFINE_TYPE_WITH_CODE (GstGLOverlayCompositor, gst_gl_overlay_compositor,
- GST_TYPE_OBJECT, G_ADD_PRIVATE (GstGLOverlayCompositor); DEBUG_INIT);
+ GST_TYPE_OBJECT, G_ADD_PRIVATE (GstGLOverlayCompositor);
+ DEBUG_INIT);
static void gst_gl_overlay_compositor_finalize (GObject * object);
static void gst_gl_overlay_compositor_set_property (GObject * object,
GstGLOverlayCompositor *compositor =
(GstGLOverlayCompositor *) compositor_pointer;
GError *error = NULL;
+ const gchar *frag_strs[2];
+
+ frag_strs[0] =
+ gst_gl_shader_string_get_highest_precision (context,
+ GST_GLSL_VERSION_NONE,
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY);
+ frag_strs[1] = fragment_shader;
if (!(compositor->shader =
gst_gl_shader_new_link_with_stages (context, &error,
gst_glsl_stage_new_default_vertex (context),
- gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
+ gst_glsl_stage_new_with_strings (context, GL_FRAGMENT_SHADER,
GST_GLSL_VERSION_NONE,
- GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
- fragment_shader), NULL))) {
+ GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY, 2,
+ frag_strs), NULL))) {
GST_ERROR_OBJECT (compositor, "could not initialize shader: %s",
error->message);
return;
#include "gstglshaderstrings.h"
+#define MEDIUMP_PRECISION \
+ "#ifdef GL_ES\n" \
+ "precision mediump float;\n" \
+ "#endif\n"
+
+#define HIGHP_PRECISION \
+ "#ifdef GL_ES\n" \
+ "precision mediump float;\n" \
+ "#endif\n"
+
/* *INDENT-OFF* */
+const gchar *gst_gl_shader_string_fragment_mediump_precision =
+ MEDIUMP_PRECISION;
+
+const gchar *gst_gl_shader_string_fragment_highp_precision =
+ HIGHP_PRECISION;
+
const gchar *gst_gl_shader_string_vertex_default =
"attribute vec4 a_position;\n"
"attribute vec2 a_texcoord;\n"
" v_texcoord = a_texcoord;\n"
"}\n";
+#define DEFAULT_FRAGMENT_BODY \
+ "varying vec2 v_texcoord;\n" \
+ "uniform sampler2D tex;\n" \
+ "void main()\n" \
+ "{\n" \
+ " gl_FragColor = texture2D(tex, v_texcoord);\n" \
+ "}"
const gchar *gst_gl_shader_string_fragment_default =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
- "varying vec2 v_texcoord;\n"
- "uniform sampler2D tex;\n"
- "void main()\n"
- "{\n"
- " gl_FragColor = texture2D(tex, v_texcoord);\n"
- "}";
+ MEDIUMP_PRECISION
+ DEFAULT_FRAGMENT_BODY;
+#define EXTERNAL_FRAGMENT_BODY \
+ "#extension GL_OES_EGL_image_external : require\n" \
+ "varying vec2 v_texcoord;\n" \
+ "uniform samplerExternalOES tex;\n" \
+ "void main()\n" \
+ "{\n" \
+ " gl_FragColor = texture2D(tex, v_texcoord);\n" \
+ "}"
const gchar *gst_gl_shader_string_fragment_external_oes_default =
- "#extension GL_OES_EGL_image_external : require\n"
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
- "varying vec2 v_texcoord;\n"
- "uniform samplerExternalOES tex;\n"
- "void main()\n"
- "{\n"
- " gl_FragColor = texture2D(tex, v_texcoord);\n"
- "}";
+ MEDIUMP_PRECISION
+ EXTERNAL_FRAGMENT_BODY;
/* *INDENT-ON* */
+
+/**
+ * gst_gl_shader_string_get_highest_precision:
+ * @context: a #GstGLContext
+ * @version: a #GstGLSLVersion
+ * @profile: a #GstGLSLProfile
+ *
+ * Generates a shader string that defines the precision of float types in
+ * GLSL shaders. This is particularly needed for fragment shaders in a
+ * GLSL ES context where there is no default precision specified.
+ *
+ * Practically, this will return the string 'precision mediump float'
+ * or 'precision highp float' depending on if high precision floats are
+ * determined to be supported.
+ *
+ * Returns: a shader string defining the precision of float types based on
+ * @context, @version and @profile
+ */
+const gchar *
+gst_gl_shader_string_get_highest_precision (GstGLContext * context,
+ GstGLSLVersion version, GstGLSLProfile profile)
+{
+ if (gst_gl_context_supports_precision (context, version, profile)) {
+ if (gst_gl_context_supports_precision_highp (context, version, profile))
+ return gst_gl_shader_string_fragment_highp_precision;
+ else
+ return gst_gl_shader_string_fragment_mediump_precision;
+ }
+ return "";
+}
+
+/**
+ * gst_gl_shader_string_fragment_get_default:
+ * @context: a #GstGLContext
+ * @version: a #GstGLSLVersion
+ * @profile: a #GstGLSLProfile
+ *
+ * Returns: a passthrough shader string for copying an input texture to
+ * the output
+ */
+gchar *
+gst_gl_shader_string_fragment_get_default (GstGLContext * context,
+ GstGLSLVersion version, GstGLSLProfile profile)
+{
+ const gchar *precision =
+ gst_gl_shader_string_get_highest_precision (context, version, profile);
+
+ return g_strdup_printf ("%s%s", precision, DEFAULT_FRAGMENT_BODY);
+}
+
+/**
+ * gst_gl_shader_string_fragment_external_oes_get_default:
+ * @context: a #GstGLContext
+ * @version: a #GstGLSLVersion
+ * @profile: a #GstGLSLProfile
+ *
+ * Returns: a passthrough shader string for copying an input external-oes
+ * texture to the output
+ */
+gchar *
+gst_gl_shader_string_fragment_external_oes_get_default (GstGLContext * context,
+ GstGLSLVersion version, GstGLSLProfile profile)
+{
+ const gchar *precision =
+ gst_gl_shader_string_get_highest_precision (context, version, profile);
+
+ return g_strdup_printf ("%s%s", precision, EXTERNAL_FRAGMENT_BODY);
+}
#include <gst/gst.h>
#include <gst/gl/gl-prelude.h>
+#include <gst/gl/gl.h>
G_BEGIN_DECLS
GST_GL_API
-const gchar *gst_gl_shader_string_vertex_default;
+const gchar *gst_gl_shader_string_fragment_highp_precision;
+GST_GL_API
+const gchar *gst_gl_shader_string_fragment_mediump_precision;
+
GST_GL_API
+const gchar *gst_gl_shader_string_vertex_default;
+GST_GL_API G_DEPRECATED_FOR(gst_gl_shader_string_fragment_get_default)
const gchar *gst_gl_shader_string_fragment_default;
GST_GL_API
const gchar *gst_gl_shader_string_vertex_mat4_texture_transform;
GST_GL_API
const gchar *gst_gl_shader_string_vertex_mat4_vertex_transform;
-GST_GL_API
+GST_GL_API G_DEPRECATED_FOR(gst_gl_shader_string_fragment_external_oes_get_default)
const gchar *gst_gl_shader_string_fragment_external_oes_default;
+GST_GL_API
+const gchar * gst_gl_shader_string_get_highest_precision (GstGLContext * context,
+ GstGLSLVersion version,
+ GstGLSLProfile profile);
+
+GST_GL_API
+gchar * gst_gl_shader_string_fragment_get_default (GstGLContext * context,
+ GstGLSLVersion version,
+ GstGLSLProfile profile);
+GST_GL_API
+gchar * gst_gl_shader_string_fragment_external_oes_get_default (GstGLContext * context,
+ GstGLSLVersion version,
+ GstGLSLProfile profile);
+
G_END_DECLS
#endif /* __GST_GL_SHADER_STRINGS_H__ */
}
return tmp;
}
+
+/**
+ * gst_gl_context_supports_precision:
+ * @context: a #GstGLContext
+ * @version: a #GstGLSLVersion
+ * @profile: a #GstGLSLProfile
+ *
+ * Returns: whether @context supports the 'precision' specifier in GLSL shaders
+ */
+gboolean
+gst_gl_context_supports_precision (GstGLContext * context,
+ GstGLSLVersion version, GstGLSLProfile profile)
+{
+ gboolean es2 = FALSE;
+
+ g_return_val_if_fail (GST_IS_GL_CONTEXT (context), FALSE);
+
+ if ((profile & GST_GLSL_PROFILE_ES) == 0)
+ return FALSE;
+
+ es2 = gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 2, 0)
+ || gst_gl_context_check_feature (context, "GL_ARB_ES2_compatibility");
+
+ return es2 && context->gl_vtable->GetShaderPrecisionFormat;
+}
+
+/**
+ * gst_gl_context_supports_precision_highp:
+ * @context: a #GstGLContext
+ * @version: a #GstGLSLVersion
+ * @profile: a #GstGLSLProfile
+ *
+ * Returns: whether @context supports the 'precision highp' specifier in GLSL shaders
+ */
+gboolean
+gst_gl_context_supports_precision_highp (GstGLContext * context,
+ GstGLSLVersion version, GstGLSLProfile profile)
+{
+ gint v_range[2] = { 0, }
+ , v_precision = 0;
+ gint f_range[2] = { 0, }
+ , f_precision = 0;
+
+ g_return_val_if_fail (GST_IS_GL_CONTEXT (context), FALSE);
+
+ if (!gst_gl_context_supports_precision (context, version, profile))
+ return FALSE;
+
+ context->gl_vtable->GetShaderPrecisionFormat (GL_VERTEX_SHADER, GL_HIGH_FLOAT,
+ v_range, &v_precision);
+ context->gl_vtable->GetShaderPrecisionFormat (GL_FRAGMENT_SHADER,
+ GL_HIGH_FLOAT, f_range, &f_precision);
+
+ return v_range[0] != 0 && v_range[1] != 0 && v_precision != 0 &&
+ f_range[0] != 0 && f_range[1] != 0 && f_precision != 0;
+}
GstGLSLVersion version,
GstGLSLProfile profile);
+GST_GL_API
+gboolean gst_gl_context_supports_precision (GstGLContext * context,
+ GstGLSLVersion version,
+ GstGLSLProfile profile);
+GST_GL_API
+gboolean gst_gl_context_supports_precision_highp (GstGLContext * context,
+ GstGLSLVersion version,
+ GstGLSLProfile profile);
+
G_END_DECLS
#endif /* __GST_GLSL_H__ */
G_DEFINE_TYPE_WITH_CODE (GstGLSLStage, gst_glsl_stage, GST_TYPE_OBJECT,
G_ADD_PRIVATE (GstGLSLStage)
GST_DEBUG_CATEGORY_INIT (gst_glsl_stage_debug, "glslstage", 0,
- "GLSL Stage");
- );
+ "GLSL Stage"););
static void
gst_glsl_stage_finalize (GObject * object)
GstGLSLStage *
gst_glsl_stage_new_default_fragment (GstGLContext * context)
{
- return gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
- GST_GLSL_VERSION_NONE,
- GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
- gst_gl_shader_string_fragment_default);
+ GstGLSLProfile profile = GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY;
+ GstGLSLVersion version = GST_GLSL_VERSION_NONE;
+ gchar *frag_str;
+ GstGLSLStage *stage;
+
+ frag_str =
+ gst_gl_shader_string_fragment_get_default (context, version, profile);
+
+ stage = gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
+ version, profile, frag_str);
+
+ g_free (frag_str);
+
+ return stage;
}
/**
/* *INDENT-OFF* */
static const gchar *fragment_header =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
"uniform sampler2D tex_l;\n"
"uniform sampler2D tex_r;\n"
"uniform float width;\n"
if (viewconvert->from_texture_target == GST_GL_TEXTURE_TARGET_EXTERNAL_OES)
g_string_append (str, glsl_OES_extension_string);
+ g_string_append (str,
+ gst_gl_shader_string_get_highest_precision (viewconvert->context, version,
+ profile));
g_string_append (str, fragment_header);
/* GL 3.3+ and GL ES 3.x */