static void _compile_shader (GstGLContext * context, struct _compile_shader *data) { GstGLShader *shader; GstGLSLStage *vert, *frag; GError *error = NULL; shader = gst_gl_shader_new (context); if (data->vertex_src) { vert = gst_glsl_stage_new_with_string (context, GL_VERTEX_SHADER, GST_GLSL_VERSION_NONE, GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY, data->vertex_src); if (!gst_glsl_stage_compile (vert, &error)) { GST_ERROR_OBJECT (vert, "%s", error->message); gst_object_unref (vert); gst_object_unref (shader); return; } if (!gst_gl_shader_attach (shader, vert)) { gst_object_unref (shader); return; } } if (data->fragment_src) { frag = gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER, GST_GLSL_VERSION_NONE, GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY, data->fragment_src); if (!gst_glsl_stage_compile (frag, &error)) { GST_ERROR_OBJECT (frag, "%s", error->message); gst_object_unref (frag); gst_object_unref (shader); return; } if (!gst_gl_shader_attach (shader, frag)) { gst_object_unref (shader); return; } } if (!gst_gl_shader_link (shader, &error)) { GST_ERROR_OBJECT (shader, "%s", error->message); g_error_free (error); error = NULL; gst_gl_context_clear_shader (context); gst_object_unref (shader); return; } *data->shader = shader; }
static void _test_link_gl (GstGLContext * context, gpointer data) { GstGLShader *shader; GstGLSLStage *vert, *frag; GError *error = NULL; shader = gst_gl_shader_new (context); vert = gst_glsl_stage_new_default_vertex (context); frag = gst_glsl_stage_new_default_fragment (context); fail_unless (gst_gl_shader_compile_attach_stage (shader, vert, &error)); fail_unless (gst_gl_shader_compile_attach_stage (shader, frag, &error)); fail_unless (gst_gl_shader_link (shader, &error)); fail_unless (gst_gl_shader_is_linked (shader)); gst_object_unref (shader); }
/** * gst_gl_shader_new_link_with_stages: * @context: a #GstGLContext * @error: a #GError * @...: a NULL terminated list of #GstGLSLStage's * * Each stage will attempt to be compiled and attached to @shader. Then * the shader will be linked. On error, %NULL will be returned and @error will * contain the details of the error. * * Note: must be called in the GL thread * * Returns: (transfer full): a new @shader with the specified stages. * * Since: 1.8 */ GstGLShader * gst_gl_shader_new_link_with_stages (GstGLContext * context, GError ** error, ...) { GstGLShader *shader; va_list varargs; va_start (varargs, error); shader = _new_with_stages_va_list (context, error, varargs); va_end (varargs); if (!shader) return NULL; if (!gst_gl_shader_link (shader, error)) return NULL; return shader; }
static GstGLShader * _maybe_recompile_shader (GstGLFilterShader * filtershader) { GstGLContext *context = GST_GL_BASE_FILTER (filtershader)->context; GstGLShader *shader; GError *error = NULL; GST_OBJECT_LOCK (filtershader); if (!filtershader->shader || filtershader->update_shader) { filtershader->update_shader = FALSE; GST_OBJECT_UNLOCK (filtershader); g_signal_emit (filtershader, gst_gl_shader_signals[SIGNAL_CREATE_SHADER], 0, &shader); GST_OBJECT_LOCK (filtershader); if (shader) { if (filtershader->shader) gst_object_unref (filtershader->shader); filtershader->new_source = FALSE; filtershader->shader = gst_object_ref (shader); filtershader->new_uniforms = TRUE; _update_uniforms (filtershader); GST_OBJECT_UNLOCK (filtershader); return shader; } } if (filtershader->shader) { shader = gst_object_ref (filtershader->shader); _update_uniforms (filtershader); GST_OBJECT_UNLOCK (filtershader); return shader; } if (filtershader->new_source) { GstGLSLStage *stage; shader = gst_gl_shader_new (context); if (filtershader->vertex) { if (!(stage = gst_glsl_stage_new_with_string (context, GL_VERTEX_SHADER, GST_GLSL_VERSION_NONE, GST_GLSL_PROFILE_NONE, filtershader->vertex))) { g_set_error (&error, GST_GLSL_ERROR, GST_GLSL_ERROR_COMPILE, "Failed to create shader vertex stage"); goto print_error; } } else { stage = gst_glsl_stage_new_default_vertex (context); } if (!gst_gl_shader_compile_attach_stage (shader, stage, &error)) { gst_object_unref (stage); goto print_error; } if (filtershader->fragment) { if (!(stage = gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER, GST_GLSL_VERSION_NONE, GST_GLSL_PROFILE_NONE, filtershader->fragment))) { g_set_error (&error, GST_GLSL_ERROR, GST_GLSL_ERROR_COMPILE, "Failed to create shader fragment stage"); goto print_error; } } else { stage = gst_glsl_stage_new_default_fragment (context); } if (!gst_gl_shader_compile_attach_stage (shader, stage, &error)) { gst_object_unref (stage); goto print_error; } if (!gst_gl_shader_link (shader, &error)) { goto print_error; } if (filtershader->shader) gst_object_unref (filtershader->shader); filtershader->shader = gst_object_ref (shader); filtershader->new_source = FALSE; filtershader->new_uniforms = TRUE; _update_uniforms (filtershader); GST_OBJECT_UNLOCK (filtershader); return shader; } else if (filtershader->shader) { _update_uniforms (filtershader); shader = gst_object_ref (filtershader->shader); GST_OBJECT_UNLOCK (filtershader); return shader; } return NULL; print_error: if (shader) { gst_object_unref (shader); shader = NULL; } GST_OBJECT_UNLOCK (filtershader); GST_ELEMENT_ERROR (filtershader, RESOURCE, NOT_FOUND, ("%s", error->message), (NULL)); return NULL; }