3 * Copyright (C) 2008 Filippo Argiolas <filippo.argiolas@gmail.com>
4 * Copyright (C) 2014 Julien Isorce <julien.isorce@collabora.co.uk>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
27 #include "gstglshader.h"
28 #include "gstglsl_private.h"
33 * @short_description: object representing an OpenGL shader program
34 * @see_also: #GstGLSLStage
38 #define GLhandleARB GLuint
41 #define USING_OPENGL(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 1, 0))
42 #define USING_OPENGL3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 1))
43 #define USING_GLES(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES, 1, 0))
44 #define USING_GLES2(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 2, 0))
45 #define USING_GLES3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0))
47 typedef struct _GstGLShaderVTable
49 GLuint (GSTGLAPI * CreateProgram) (void);
50 void (GSTGLAPI * DeleteProgram) (GLuint program);
51 void (GSTGLAPI * UseProgram) (GLuint program);
52 void (GSTGLAPI * GetAttachedShaders) (GLuint program, GLsizei maxcount,
53 GLsizei * count, GLuint * shaders);
55 GLuint (GSTGLAPI * CreateShader) (GLenum shaderType);
56 void (GSTGLAPI * DeleteShader) (GLuint shader);
57 void (GSTGLAPI * AttachShader) (GLuint program, GLuint shader);
58 void (GSTGLAPI * DetachShader) (GLuint program, GLuint shader);
60 void (GSTGLAPI * GetShaderiv) (GLuint program, GLenum pname, GLint * params);
61 void (GSTGLAPI * GetProgramiv) (GLuint program, GLenum pname, GLint * params);
62 void (GSTGLAPI * GetShaderInfoLog) (GLuint shader, GLsizei maxLength,
63 GLsizei * length, char *log);
64 void (GSTGLAPI * GetProgramInfoLog) (GLuint shader, GLsizei maxLength,
65 GLsizei * length, char *log);
74 struct _GstGLShaderPrivate
76 GLhandleARB program_handle;
80 GHashTable *uniform_locations;
85 GST_DEBUG_CATEGORY_STATIC (gst_gl_shader_debug);
86 #define GST_CAT_DEFAULT gst_gl_shader_debug
89 GST_DEBUG_CATEGORY_INIT (gst_gl_shader_debug, "glshader", 0, "shader");
90 G_DEFINE_TYPE_WITH_CODE (GstGLShader, gst_gl_shader, GST_TYPE_OBJECT,
91 G_ADD_PRIVATE (GstGLShader) DEBUG_INIT);
94 _cleanup_shader (GstGLContext * context, GstGLShader * shader)
96 GstGLShaderPrivate *priv = shader->priv;
98 GST_OBJECT_LOCK (shader);
100 /* release shader objects */
101 gst_gl_shader_release_unlocked (shader);
104 if (priv->program_handle) {
105 GST_TRACE ("finalizing program shader %u", priv->program_handle);
107 priv->vtable.DeleteProgram (priv->program_handle);
110 GST_DEBUG ("shader deleted %u", priv->program_handle);
112 GST_OBJECT_UNLOCK (shader);
116 gst_gl_shader_finalize (GObject * object)
119 GstGLShaderPrivate *priv;
121 shader = GST_GL_SHADER (object);
124 GST_TRACE_OBJECT (shader, "finalizing shader %u", priv->program_handle);
126 gst_gl_context_thread_add (shader->context,
127 (GstGLContextThreadFunc) _cleanup_shader, shader);
129 priv->program_handle = 0;
130 g_hash_table_destroy (priv->uniform_locations);
132 if (shader->context) {
133 gst_object_unref (shader->context);
134 shader->context = NULL;
137 G_OBJECT_CLASS (gst_gl_shader_parent_class)->finalize (object);
141 gst_gl_shader_set_property (GObject * object,
142 guint prop_id, const GValue * value, GParamSpec * pspec)
146 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
152 gst_gl_shader_get_property (GObject * object,
153 guint prop_id, GValue * value, GParamSpec * pspec)
155 GstGLShader *shader = GST_GL_SHADER (object);
156 GstGLShaderPrivate *priv = shader->priv;
160 g_value_set_boolean (value, priv->linked);
163 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
169 gst_gl_shader_class_init (GstGLShaderClass * klass)
171 /* bind class methods .. */
172 GObjectClass *obj_class = G_OBJECT_CLASS (klass);
174 obj_class->finalize = gst_gl_shader_finalize;
175 obj_class->set_property = gst_gl_shader_set_property;
176 obj_class->get_property = gst_gl_shader_get_property;
178 /* .. and install properties */
179 g_object_class_install_property (obj_class,
181 g_param_spec_boolean ("linked",
183 "Shader link status", FALSE,
184 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
188 gst_gl_shader_init (GstGLShader * self)
190 /* initialize sources and create program object */
191 GstGLShaderPrivate *priv;
193 priv = self->priv = gst_gl_shader_get_instance_private (self);
195 priv->linked = FALSE;
196 priv->uniform_locations =
197 g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
201 _get_uniform_location (GstGLShader * shader, const gchar * name)
203 GstGLShaderPrivate *priv = shader->priv;
207 g_return_val_if_fail (priv->linked, 0);
209 if (!g_hash_table_lookup_extended (priv->uniform_locations, name, NULL,
211 const GstGLFuncs *gl = shader->context->gl_vtable;
212 location = gl->GetUniformLocation (priv->program_handle, name);
213 g_hash_table_insert (priv->uniform_locations, g_strdup (name),
214 GINT_TO_POINTER (location));
216 location = GPOINTER_TO_INT (value);
219 GST_TRACE_OBJECT (shader, "Retrieved uniform \'%s\' location %i", name,
226 _new_with_stages_va_list (GstGLContext * context, GError ** error,
231 gboolean to_unref_and_out = FALSE;
233 g_return_val_if_fail (GST_IS_GL_CONTEXT (context), NULL);
235 shader = g_object_new (GST_TYPE_GL_SHADER, NULL);
236 gst_object_ref_sink (shader);
237 shader->context = gst_object_ref (context);
239 while ((stage = va_arg (varargs, GstGLSLStage *))) {
240 if (to_unref_and_out) {
241 gst_object_unref (stage);
245 if (!gst_glsl_stage_compile (stage, error)) {
246 gst_object_unref (stage);
247 to_unref_and_out = TRUE;
250 if (!gst_gl_shader_attach (shader, stage)) {
251 g_set_error (error, GST_GLSL_ERROR, GST_GLSL_ERROR_PROGRAM,
252 "Failed to attach stage to program");
253 to_unref_and_out = TRUE;
258 if (to_unref_and_out) {
259 gst_object_unref (shader);
267 * gst_gl_shader_new_link_with_stages:
268 * @context: a #GstGLContext
269 * @error: (optional): a #GError
270 * @...: a NULL terminated list of #GstGLSLStage's
272 * Each stage will attempt to be compiled and attached to @shader. Then
273 * the shader will be linked. On error, %NULL will be returned and @error will
274 * contain the details of the error.
276 * Note: must be called in the GL thread
278 * Returns: (transfer full): a new @shader with the specified stages.
283 gst_gl_shader_new_link_with_stages (GstGLContext * context, GError ** error,
289 va_start (varargs, error);
290 shader = _new_with_stages_va_list (context, error, varargs);
296 if (!gst_gl_shader_link (shader, error))
303 * gst_gl_shader_new_with_stages:
304 * @context: a #GstGLContext
305 * @error: (optional): a #GError
306 * @...: a NULL terminated list of #GstGLSLStage's
308 * Each stage will attempt to be compiled and attached to @shader. On error,
309 * %NULL will be returned and @error will contain the details of the error.
311 * Note: must be called in the GL thread
313 * Returns: (transfer full): a new @shader with the specified stages.
318 gst_gl_shader_new_with_stages (GstGLContext * context, GError ** error, ...)
323 va_start (varargs, error);
324 shader = _new_with_stages_va_list (context, error, varargs);
332 * @context: a #GstGLContext
334 * Note: must be called in the GL thread
336 * Returns: (transfer full): a new empty @shader
339 gst_gl_shader_new (GstGLContext * context)
341 return gst_gl_shader_new_with_stages (context, NULL, NULL);
345 * gst_gl_shader_new_default:
346 * @context: a #GstGLContext
347 * @error: (optional): a #GError that is filled on failure
349 * Note: must be called in the GL thread
351 * Returns: (transfer full): a default @shader or %NULL on failure
356 gst_gl_shader_new_default (GstGLContext * context, GError ** error)
358 return gst_gl_shader_new_link_with_stages (context, error,
359 gst_glsl_stage_new_default_vertex (context),
360 gst_glsl_stage_new_default_fragment (context), NULL);
364 * gst_gl_shader_is_linked:
365 * @shader: a #GstGLShader
367 * Note: must be called in the GL thread
369 * Returns: whether @shader has been successfully linked
374 gst_gl_shader_is_linked (GstGLShader * shader)
378 g_return_val_if_fail (GST_IS_GL_SHADER (shader), FALSE);
380 GST_OBJECT_LOCK (shader);
381 ret = shader->priv->linked;
382 GST_OBJECT_UNLOCK (shader);
388 _ensure_program (GstGLShader * shader)
390 if (shader->priv->program_handle)
393 shader->priv->program_handle = shader->priv->vtable.CreateProgram ();
394 return shader->priv->program_handle != 0;
398 * gst_gl_shader_get_program_handle:
399 * @shader: a #GstGLShader
401 * Returns: the GL program handle for this shader
406 gst_gl_shader_get_program_handle (GstGLShader * shader)
410 g_return_val_if_fail (GST_IS_GL_SHADER (shader), 0);
412 GST_OBJECT_LOCK (shader);
413 ret = (int) shader->priv->program_handle;
414 GST_OBJECT_UNLOCK (shader);
420 * gst_gl_shader_detach_unlocked:
421 * @shader: a #GstGLShader
422 * @stage: a #GstGLSLStage to attach
424 * Detaches @stage from @shader. @stage must have been successfully attached
425 * to @shader with gst_gl_shader_attach() or gst_gl_shader_attach_unlocked().
427 * Note: must be called in the GL thread
432 gst_gl_shader_detach_unlocked (GstGLShader * shader, GstGLSLStage * stage)
437 g_return_if_fail (GST_IS_GL_SHADER (shader));
438 g_return_if_fail (GST_IS_GLSL_STAGE (stage));
440 if (!_gst_glsl_funcs_fill (&shader->priv->vtable, shader->context)) {
441 GST_WARNING_OBJECT (shader, "Failed to retrieve required GLSL functions");
445 if (!shader->priv->program_handle)
448 elem = g_list_find (shader->priv->stages, stage);
450 GST_FIXME_OBJECT (shader, "Could not find stage %p in shader %p", stage,
455 stage_handle = gst_glsl_stage_get_handle (stage);
457 GST_FIXME_OBJECT (shader, "Stage %p doesn't have a GL handle", stage);
461 if (shader->context->gl_vtable->IsProgram)
462 g_assert (shader->context->gl_vtable->IsProgram (shader->
463 priv->program_handle));
464 if (shader->context->gl_vtable->IsShader)
465 g_assert (shader->context->gl_vtable->IsShader (stage_handle));
467 GST_LOG_OBJECT (shader, "detaching shader %i from program %i", stage_handle,
468 (int) shader->priv->program_handle);
469 shader->priv->vtable.DetachShader (shader->priv->program_handle,
472 shader->priv->stages = g_list_delete_link (shader->priv->stages, elem);
473 gst_object_unref (stage);
477 * gst_gl_shader_detach:
478 * @shader: a #GstGLShader
479 * @stage: a #GstGLSLStage to attach
481 * Detaches @stage from @shader. @stage must have been successfully attached
482 * to @shader with gst_gl_shader_attach() or gst_gl_shader_attach_unlocked().
484 * Note: must be called in the GL thread
489 gst_gl_shader_detach (GstGLShader * shader, GstGLSLStage * stage)
491 g_return_if_fail (GST_IS_GL_SHADER (shader));
492 g_return_if_fail (GST_IS_GLSL_STAGE (stage));
494 GST_OBJECT_LOCK (shader);
495 gst_gl_shader_detach_unlocked (shader, stage);
496 GST_OBJECT_UNLOCK (shader);
500 * gst_gl_shader_attach_unlocked:
501 * @shader: a #GstGLShader
502 * @stage: (transfer floating): a #GstGLSLStage to attach
504 * Attaches @stage to @shader. @stage must have been successfully compiled
505 * with gst_glsl_stage_compile().
507 * Note: must be called in the GL thread
509 * Returns: whether @stage could be attached to @shader
514 gst_gl_shader_attach_unlocked (GstGLShader * shader, GstGLSLStage * stage)
518 g_return_val_if_fail (GST_IS_GL_SHADER (shader), FALSE);
519 g_return_val_if_fail (GST_IS_GLSL_STAGE (stage), FALSE);
521 if (!_gst_glsl_funcs_fill (&shader->priv->vtable, shader->context)) {
522 GST_WARNING_OBJECT (shader, "Failed to retrieve required GLSL functions");
523 gst_object_ref_sink (stage);
524 gst_object_unref (stage);
528 if (!_ensure_program (shader)) {
529 gst_object_ref_sink (stage);
530 gst_object_unref (stage);
534 /* already attached? */
535 if (g_list_find (shader->priv->stages, stage)) {
536 gst_object_ref_sink (stage);
537 gst_object_unref (stage);
541 stage_handle = gst_glsl_stage_get_handle (stage);
543 gst_object_ref_sink (stage);
544 gst_object_unref (stage);
548 if (shader->context->gl_vtable->IsProgram)
549 g_assert (shader->context->gl_vtable->IsProgram (shader->
550 priv->program_handle));
551 if (shader->context->gl_vtable->IsShader)
552 g_assert (shader->context->gl_vtable->IsShader (stage_handle));
554 shader->priv->stages =
555 g_list_prepend (shader->priv->stages, gst_object_ref_sink (stage));
556 GST_LOG_OBJECT (shader, "attaching shader %i to program %i", stage_handle,
557 (int) shader->priv->program_handle);
558 shader->priv->vtable.AttachShader (shader->priv->program_handle,
565 * gst_gl_shader_attach:
566 * @shader: a #GstGLShader
567 * @stage: (transfer floating): a #GstGLSLStage to attach
569 * Attaches @stage to @shader. @stage must have been successfully compiled
570 * with gst_glsl_stage_compile().
572 * Note: must be called in the GL thread
574 * Returns: whether @stage could be attached to @shader
579 gst_gl_shader_attach (GstGLShader * shader, GstGLSLStage * stage)
583 g_return_val_if_fail (GST_IS_GL_SHADER (shader), FALSE);
584 g_return_val_if_fail (GST_IS_GLSL_STAGE (stage), FALSE);
586 GST_OBJECT_LOCK (shader);
587 ret = gst_gl_shader_attach_unlocked (shader, stage);
588 GST_OBJECT_UNLOCK (shader);
594 * gst_gl_shader_compile_attach_stage:
595 * @shader: a #GstGLShader
596 * @stage: a #GstGLSLStage to attach
597 * @error: (optional): a #GError
599 * Compiles @stage and attaches it to @shader.
601 * Note: must be called in the GL thread
603 * Returns: whether @stage could be compiled and attached to @shader
608 gst_gl_shader_compile_attach_stage (GstGLShader * shader, GstGLSLStage * stage,
611 g_return_val_if_fail (GST_IS_GLSL_STAGE (stage), FALSE);
613 if (!gst_glsl_stage_compile (stage, error)) {
617 if (!gst_gl_shader_attach (shader, stage)) {
618 g_set_error (error, GST_GLSL_ERROR, GST_GLSL_ERROR_COMPILE,
619 "Failed to attach stage to shader");
627 * gst_gl_shader_link:
628 * @shader: a #GstGLShader
629 * @error: (optional): a #GError
631 * Links the current list of #GstGLSLStage's in @shader.
633 * Note: must be called in the GL thread
635 * Returns: whether @shader could be linked together.
640 gst_gl_shader_link (GstGLShader * shader, GError ** error)
642 GstGLShaderPrivate *priv;
643 const GstGLFuncs *gl;
644 gchar info_buffer[2048];
645 GLint status = GL_FALSE;
650 g_return_val_if_fail (GST_IS_GL_SHADER (shader), FALSE);
652 GST_OBJECT_LOCK (shader);
655 gl = shader->context->gl_vtable;
658 GST_OBJECT_UNLOCK (shader);
662 if (!_gst_glsl_funcs_fill (&shader->priv->vtable, shader->context)) {
663 g_set_error (error, GST_GLSL_ERROR, GST_GLSL_ERROR_PROGRAM,
664 "Failed to retrieve required GLSL functions");
665 GST_OBJECT_UNLOCK (shader);
669 if (!_ensure_program (shader)) {
670 g_set_error (error, GST_GLSL_ERROR, GST_GLSL_ERROR_PROGRAM,
671 "Failed to create GL program object");
672 GST_OBJECT_UNLOCK (shader);
676 GST_TRACE ("shader created %u", shader->priv->program_handle);
678 for (elem = shader->priv->stages; elem; elem = elem->next) {
679 GstGLSLStage *stage = elem->data;
681 if (!gst_glsl_stage_compile (stage, error)) {
682 GST_OBJECT_UNLOCK (shader);
686 if (!gst_gl_shader_attach_unlocked (shader, stage)) {
687 g_set_error (error, GST_GLSL_ERROR, GST_GLSL_ERROR_COMPILE,
688 "Failed to attach shader %" GST_PTR_FORMAT "to program %"
689 GST_PTR_FORMAT, stage, shader);
690 GST_OBJECT_UNLOCK (shader);
695 /* if nothing failed link shaders */
696 gl->LinkProgram (priv->program_handle);
698 priv->vtable.GetProgramiv (priv->program_handle, GL_LINK_STATUS, &status);
700 priv->vtable.GetProgramInfoLog (priv->program_handle,
701 sizeof (info_buffer) - 1, &len, info_buffer);
702 info_buffer[len] = '\0';
704 if (status != GL_TRUE) {
705 GST_ERROR ("Shader linking failed:\n%s", info_buffer);
707 g_set_error (error, GST_GLSL_ERROR, GST_GLSL_ERROR_LINK,
708 "Shader Linking failed:\n%s", info_buffer);
709 ret = priv->linked = FALSE;
710 GST_OBJECT_UNLOCK (shader);
712 } else if (len > 1) {
713 GST_FIXME ("shader link log:\n%s", info_buffer);
716 ret = priv->linked = TRUE;
717 GST_OBJECT_UNLOCK (shader);
719 g_object_notify (G_OBJECT (shader), "linked");
725 * gst_gl_shader_release_unlocked:
726 * @shader: a #GstGLShader
728 * Releases the shader and stages.
730 * Note: must be called in the GL thread
735 gst_gl_shader_release_unlocked (GstGLShader * shader)
737 GstGLShaderPrivate *priv;
740 g_return_if_fail (GST_IS_GL_SHADER (shader));
744 for (elem = shader->priv->stages; elem;) {
745 GstGLSLStage *stage = elem->data;
746 GList *next = elem->next;
748 gst_gl_shader_detach_unlocked (shader, stage);
752 g_list_free_full (shader->priv->stages, (GDestroyNotify) gst_object_unref);
753 shader->priv->stages = NULL;
755 priv->linked = FALSE;
756 g_hash_table_remove_all (priv->uniform_locations);
758 g_object_notify (G_OBJECT (shader), "linked");
762 * gst_gl_shader_release:
763 * @shader: a #GstGLShader
765 * Releases the shader and stages.
767 * Note: must be called in the GL thread
772 gst_gl_shader_release (GstGLShader * shader)
774 g_return_if_fail (GST_IS_GL_SHADER (shader));
776 GST_OBJECT_LOCK (shader);
777 gst_gl_shader_release_unlocked (shader);
778 GST_OBJECT_UNLOCK (shader);
783 * @shader: a #GstGLShader
785 * Mark's @shader as being used for the next GL draw command.
787 * Note: must be called in the GL thread and @shader must have been linked.
790 gst_gl_shader_use (GstGLShader * shader)
792 GstGLShaderPrivate *priv;
794 g_return_if_fail (GST_IS_GL_SHADER (shader));
798 g_return_if_fail (priv->program_handle);
800 priv->vtable.UseProgram (priv->program_handle);
806 * gst_gl_context_clear_shader:
807 * @context: a #GstGLContext
809 * Clear's the currently set shader from the GL state machine.
811 * Note: must be called in the GL thread.
814 gst_gl_context_clear_shader (GstGLContext * context)
818 g_return_if_fail (GST_IS_GL_CONTEXT (context));
820 gl = context->gl_vtable;
822 if (gl->CreateProgram)
824 else if (gl->CreateProgramObject)
825 gl->UseProgramObject (0);
828 #define set_uniform_pre_check(shader, name) \
829 GLint location = -1; \
830 g_return_if_fail (shader != NULL); \
831 g_return_if_fail (shader->priv->program_handle != 0); \
832 location = _get_uniform_location (shader, name);
834 #ifdef G_HAVE_ISO_VARARGS
836 #define set_uniform_v(gl_suffix, c_type, debug_stride, debug_str, ...) \
838 G_PASTE(gst_gl_shader_set_uniform_,gl_suffix) (GstGLShader * shader, \
839 const gchar * name, guint count, const c_type * value) \
842 set_uniform_pre_check(shader, name) \
843 for (i = 0; i < count; i++) { \
844 const c_type * item = &value[i * debug_stride]; \
845 GST_TRACE_OBJECT (shader, "Setting uniform %s (%i) index %i to " \
846 debug_str, name, location, i, __VA_ARGS__); \
848 shader->context->gl_vtable->G_PASTE(Uniform,gl_suffix) (location, count, value); \
851 #define set_uniform_func_decl(gl_suffix, ...) \
853 G_PASTE(gst_gl_shader_set_uniform_,gl_suffix) (GstGLShader * shader, \
854 const gchar * name, __VA_ARGS__)
856 #define set_uniform_body(gl_suffix, debug_str, ...) \
858 set_uniform_pre_check(shader, name) \
859 GST_TRACE_OBJECT (shader, "Setting uniform %s (%i) = " debug_str, \
860 name, location, __VA_ARGS__); \
861 shader->context->gl_vtable->G_PASTE(Uniform,gl_suffix) (location, __VA_ARGS__); \
864 #else /* G_HAVE_ISO_VARARGS */
865 #if G_HAVE_GNUC_VARARGS
867 #define set_uniform_v(gl_suffix, c_type, debug_stride, debug_str, args...) \
869 G_PASTE(gst_gl_shader_set_uniform_,gl_suffix) (GstGLShader * shader, \
870 const gchar * name, guint count, const c_type * value) \
873 set_uniform_pre_check(shader, name) \
874 for (i = 0; i < count; i++) { \
875 const c_type * item = &value[i * debug_stride]; \
876 GST_TRACE_OBJECT (shader, "Setting uniform %s (%i) index %i to " \
877 debug_str, name, location, i, ##args); \
879 shader->context->gl_vtable->G_PASTE(Uniform,gl_suffix) (location, count, value); \
882 #define set_uniform_func_decl(gl_suffix, args...) \
884 G_PASTE(gst_gl_shader_set_uniform_,gl_suffix) (GstGLShader * shader, \
885 const gchar * name, ##args)
887 #define set_uniform_body(gl_suffix, debug_str, args...) \
889 set_uniform_pre_check(shader, name) \
890 GST_TRACE_OBJECT (shader, "Setting uniform %s (%i) = " debug_str, \
891 name, location, ##args); \
892 shader->context->gl_vtable->G_PASTE(Uniform,gl_suffix) (location, ##args); \
897 #error "No vararg support in C macros. What kind of C compiler is this?!"
899 #endif /* G_HAVE_GNUC_VARARGS */
900 #endif /* G_HAVE_ISO_VARARGS */
904 * gst_gl_shader_set_uniform_1f:
905 * @shader: a #GstGLShader
906 * @name: name of the uniform
907 * @value: value to set
909 * Perform `glUniform1f()` for @name on @shader
911 set_uniform_func_decl(1f, float value)
912 set_uniform_body(1f, "%f", value);
915 * gst_gl_shader_set_uniform_1fv:
916 * @shader: a #GstGLShader
917 * @name: name of the uniform
918 * @count: number of values to set
919 * @value: (array length=count): values to set
921 * Perform `glUniform1fv()` for @name on @shader
923 set_uniform_v(1fv, float, 1, "%f", item[0]);
926 * gst_gl_shader_set_uniform_1i:
927 * @shader: a #GstGLShader
928 * @name: name of the uniform
929 * @value: value to set
931 * Perform `glUniform1i()` for @name on @shader
933 set_uniform_func_decl(1i, int value)
934 set_uniform_body(1i, "%i", value);
937 * gst_gl_shader_set_uniform_1iv:
938 * @shader: a #GstGLShader
939 * @name: name of the uniform
940 * @count: number of values to set
941 * @value: (array length=count): values to set
943 * Perform `glUniform1iv()` for @name on @shader
945 set_uniform_v(1iv, int, 1, "%i", item[0]);
948 * gst_gl_shader_set_uniform_2f:
949 * @shader: a #GstGLShader
950 * @name: name of the uniform
951 * @v0: first value to set
952 * @v1: second value to set
954 * Perform `glUniform2f()` for @name on @shader
956 set_uniform_func_decl(2f, float v0, float v1)
957 set_uniform_body(2f, "%f, %f", v0, v1);
960 * gst_gl_shader_set_uniform_2fv:
961 * @shader: a #GstGLShader
962 * @name: name of the uniform
963 * @count: number of values to set
964 * @value: (array length=count): values to set
966 * Perform `glUniform2fv()` for @name on @shader
968 set_uniform_v(2fv, float, 2, "%f, %f", item[0], item[1]);
971 * gst_gl_shader_set_uniform_2i:
972 * @shader: a #GstGLShader
973 * @name: name of the uniform
974 * @v0: first value to set
975 * @v1: second value to set
977 * Perform `glUniform2i()` for @name on @shader
979 set_uniform_func_decl(2i, int v0, int v1)
980 set_uniform_body(2i, "%i, %i", v0, v1);
983 * gst_gl_shader_set_uniform_2iv:
984 * @shader: a #GstGLShader
985 * @name: name of the uniform
986 * @count: number of values to set
987 * @value: (array length=count): values to set
989 * Perform `glUniform2iv()` for @name on @shader
991 set_uniform_v(2iv, int, 2, "%i, %i", item[0], item[1]);
994 * gst_gl_shader_set_uniform_3f:
995 * @shader: a #GstGLShader
996 * @name: name of the uniform
997 * @v0: first value to set
998 * @v1: second value to set
999 * @v2: third value to set
1001 * Perform `glUniform3f()` for @name on @shader
1003 set_uniform_func_decl(3f, float v0, float v1, float v2)
1004 set_uniform_body(3f, "%f, %f, %f", v0, v1, v2);
1007 * gst_gl_shader_set_uniform_3fv:
1008 * @shader: a #GstGLShader
1009 * @name: name of the uniform
1010 * @count: number of values to set
1011 * @value: (array length=count): values to set
1013 * Perform `glUniform3fv()` for @name on @shader
1015 set_uniform_v(3fv, float, 3, "%f, %f, %f", item[0], item[1], item[2]);
1018 * gst_gl_shader_set_uniform_3i:
1019 * @shader: a #GstGLShader
1020 * @name: name of the uniform
1021 * @v0: first value to set
1022 * @v1: second value to set
1023 * @v2: third value to set
1025 * Perform `glUniform3i()` for @name on @shader
1027 set_uniform_func_decl(3i, int v0, int v1, int v2)
1028 set_uniform_body(3i, "%i, %i, %i", v0, v1, v2);
1031 * gst_gl_shader_set_uniform_3iv:
1032 * @shader: a #GstGLShader
1033 * @name: name of the uniform
1034 * @count: number of values to set
1035 * @value: (array length=count): values to set
1037 * Perform `glUniform3iv()` for @name on @shader
1039 set_uniform_v(3iv, int, 3, "%i, %i, %i", item[0], item[1], item[2]);
1042 * gst_gl_shader_set_uniform_4f:
1043 * @shader: a #GstGLShader
1044 * @name: name of the uniform
1045 * @v0: first value to set
1046 * @v1: second value to set
1047 * @v2: third value to set
1048 * @v3: fourth value to set
1050 * Perform `glUniform4f()` for @name on @shader
1052 set_uniform_func_decl(4f, float v0, float v1, float v2, float v3)
1053 set_uniform_body(4f, "%f, %f, %f, %f", v0, v1, v2, v3);
1056 * gst_gl_shader_set_uniform_4fv:
1057 * @shader: a #GstGLShader
1058 * @name: name of the uniform
1059 * @count: number of values to set
1060 * @value: (array length=count): values to set
1062 * Perform `glUniform4fv()` for @name on @shader
1064 set_uniform_v(4fv, float, 4, "%f, %f, %f, %f", item[0], item[1], item[2], item[3]);
1067 * gst_gl_shader_set_uniform_4i:
1068 * @shader: a #GstGLShader
1069 * @name: name of the uniform
1070 * @v0: first value to set
1071 * @v1: second value to set
1072 * @v2: third value to set
1073 * @v3: fourth value to set
1075 * Perform `glUniform4i()` for @name on @shader
1077 set_uniform_func_decl(4i, int v0, int v1, int v2, int v3)
1078 set_uniform_body(4i, "%i, %i, %i, %i", v0, v1, v2, v3);
1081 * gst_gl_shader_set_uniform_4iv:
1082 * @shader: a #GstGLShader
1083 * @name: name of the uniform
1084 * @count: number of values to set
1085 * @value: (array length=count): values to set
1087 * Perform `glUniform4iv()` for @name on @shader
1089 set_uniform_v(4iv, int, 4, "%i, %i, %i, %i", item[0], item[1], item[2], item[3]);
1093 * gst_gl_shader_set_uniform_matrix_2fv:
1094 * @shader: a #GstGLShader
1095 * @name: name of the uniform
1096 * @count: number of 2x2 matrices to set
1097 * @transpose: transpose the matrix
1098 * @value: matrix to set
1100 * Perform `glUniformMatrix2fv()` for @name on @shader
1103 gst_gl_shader_set_uniform_matrix_2fv (GstGLShader * shader, const gchar * name,
1104 gint count, gboolean transpose, const gfloat * value)
1106 set_uniform_pre_check (shader, name);
1107 shader->context->gl_vtable->UniformMatrix2fv (location, count, transpose,
1112 * gst_gl_shader_set_uniform_matrix_3fv:
1113 * @shader: a #GstGLShader
1114 * @name: name of the uniform
1115 * @count: number of 3x3 matrices to set
1116 * @transpose: transpose the matrix
1117 * @value: values to set
1119 * Perform `glUniformMatrix3fv()` for @name on @shader
1122 gst_gl_shader_set_uniform_matrix_3fv (GstGLShader * shader, const gchar * name,
1123 gint count, gboolean transpose, const gfloat * value)
1125 set_uniform_pre_check (shader, name);
1126 shader->context->gl_vtable->UniformMatrix3fv (location, count, transpose,
1131 * gst_gl_shader_set_uniform_matrix_4fv:
1132 * @shader: a #GstGLShader
1133 * @name: name of the uniform
1134 * @count: number of 4x4 matrices to set
1135 * @transpose: transpose the matrix
1136 * @value: values to set
1138 * Perform `glUniformMatrix4fv()` for @name on @shader
1141 gst_gl_shader_set_uniform_matrix_4fv (GstGLShader * shader, const gchar * name,
1142 gint count, gboolean transpose, const gfloat * value)
1144 set_uniform_pre_check (shader, name);
1145 shader->context->gl_vtable->UniformMatrix4fv (location, count, transpose,
1150 * gst_gl_shader_set_uniform_matrix_2x3fv:
1151 * @shader: a #GstGLShader
1152 * @name: name of the uniform
1153 * @count: number of 2x3 matrices to set
1154 * @transpose: transpose the matrix
1155 * @value: values to set
1157 * Perform `glUniformMatrix2x3fv()` for @name on @shader
1160 gst_gl_shader_set_uniform_matrix_2x3fv (GstGLShader * shader,
1161 const gchar * name, gint count, gboolean transpose, const gfloat * value)
1163 set_uniform_pre_check (shader, name);
1164 shader->context->gl_vtable->UniformMatrix2x3fv (location, count, transpose,
1169 * gst_gl_shader_set_uniform_matrix_2x4fv:
1170 * @shader: a #GstGLShader
1171 * @name: name of the uniform
1172 * @count: number of 2x4 matrices to set
1173 * @transpose: transpose the matrix
1174 * @value: values to set
1176 * Perform `glUniformMatrix2x4fv()` for @name on @shader
1179 gst_gl_shader_set_uniform_matrix_2x4fv (GstGLShader * shader,
1180 const gchar * name, gint count, gboolean transpose, const gfloat * value)
1182 set_uniform_pre_check (shader, name);
1183 shader->context->gl_vtable->UniformMatrix2x4fv (location, count, transpose,
1188 * gst_gl_shader_set_uniform_matrix_3x2fv:
1189 * @shader: a #GstGLShader
1190 * @name: name of the uniform
1191 * @count: number of 3x2 matrices to set
1192 * @transpose: transpose the matrix
1193 * @value: values to set
1195 * Perform `glUniformMatrix3x2fv()` for @name on @shader
1198 gst_gl_shader_set_uniform_matrix_3x2fv (GstGLShader * shader,
1199 const gchar * name, gint count, gboolean transpose, const gfloat * value)
1201 set_uniform_pre_check (shader, name);
1202 shader->context->gl_vtable->UniformMatrix3x2fv (location, count, transpose,
1207 * gst_gl_shader_set_uniform_matrix_3x4fv:
1208 * @shader: a #GstGLShader
1209 * @name: name of the uniform
1210 * @count: number of 3x4 matrices to set
1211 * @transpose: transpose the matrix
1212 * @value: values to set
1214 * Perform `glUniformMatrix3x4fv()` for @name on @shader
1217 gst_gl_shader_set_uniform_matrix_3x4fv (GstGLShader * shader,
1218 const gchar * name, gint count, gboolean transpose, const gfloat * value)
1220 set_uniform_pre_check (shader, name);
1221 shader->context->gl_vtable->UniformMatrix3x4fv (location, count, transpose,
1226 * gst_gl_shader_set_uniform_matrix_4x2fv:
1227 * @shader: a #GstGLShader
1228 * @name: name of the uniform
1229 * @count: number of 4x2 matrices to set
1230 * @transpose: transpose the matrix
1231 * @value: values to set
1233 * Perform `glUniformMatrix4x2fv()` for @name on @shader
1236 gst_gl_shader_set_uniform_matrix_4x2fv (GstGLShader * shader,
1237 const gchar * name, gint count, gboolean transpose, const gfloat * value)
1239 set_uniform_pre_check (shader, name);
1240 shader->context->gl_vtable->UniformMatrix4x2fv (location, count, transpose,
1245 * gst_gl_shader_set_uniform_matrix_4x3fv:
1246 * @shader: a #GstGLShader
1247 * @name: name of the uniform
1248 * @count: number of 4x3 matrices to set
1249 * @transpose: transpose the matrix
1250 * @value: values to set
1252 * Perform `glUniformMatrix4x3fv()` for @name on @shader
1255 gst_gl_shader_set_uniform_matrix_4x3fv (GstGLShader * shader,
1256 const gchar * name, gint count, gboolean transpose, const gfloat * value)
1258 set_uniform_pre_check (shader, name);
1259 shader->context->gl_vtable->UniformMatrix4x3fv (location, count, transpose,
1264 * gst_gl_shader_get_attribute_location:
1265 * @shader: a #GstGLShader
1266 * @name: name of the attribute
1268 * Returns: the attribute index for @name in @shader or -1 on failure
1271 gst_gl_shader_get_attribute_location (GstGLShader * shader, const gchar * name)
1275 g_return_val_if_fail (shader != NULL, -1);
1276 g_return_val_if_fail (shader->priv->program_handle != 0, -1);
1279 shader->context->gl_vtable->GetAttribLocation (shader->priv->
1280 program_handle, name);
1282 GST_TRACE_OBJECT (shader, "retrieved program %i attribute \'%s\' location %i",
1283 (int) shader->priv->program_handle, name, ret);
1289 * gst_gl_shader_bind_attribute_location:
1290 * @shader: a #GstGLShader
1291 * @index: attribute index to set
1292 * @name: name of the attribute
1294 * Bind attribute @name to the specified location @index using
1295 * `glBindAttributeLocation()`.
1298 gst_gl_shader_bind_attribute_location (GstGLShader * shader, GLuint index,
1301 g_return_if_fail (shader != NULL);
1302 g_return_if_fail (shader->priv->program_handle != 0);
1304 GST_TRACE_OBJECT (shader, "binding program %i attribute \'%s\' location %i",
1305 (int) shader->priv->program_handle, name, index);
1307 shader->context->gl_vtable->BindAttribLocation (shader->priv->program_handle,
1312 * gst_gl_shader_bind_frag_data_location:
1313 * @shader: a #GstGLShader
1314 * @index: attribute index to set
1315 * @name: name of the attribute
1317 * Bind attribute @name to the specified location @index using
1318 * `glBindFragDataLocation()`.
1321 gst_gl_shader_bind_frag_data_location (GstGLShader * shader,
1322 guint index, const gchar * name)
1324 g_return_if_fail (shader != NULL);
1325 if (!_ensure_program (shader))
1326 g_return_if_fail (shader->priv->program_handle);
1327 g_return_if_fail (shader->context->gl_vtable->BindFragDataLocation);
1329 GST_TRACE_OBJECT (shader, "binding program %i frag data \'%s\' location %i",
1330 (int) shader->priv->program_handle, name, index);
1332 shader->context->gl_vtable->BindFragDataLocation (shader->priv->
1333 program_handle, index, name);