glutils: Export affine transformation functions for gtkglsink
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-base / ext / gl / gstglutils.c
1 /* 
2  * GStreamer
3  * Copyright (C) 2016 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 <gst/gl/gstglfuncs.h>
26
27 #include "gstglutils.h"
28
29 struct _compile_shader
30 {
31   GstGLShader **shader;
32   const gchar *vertex_src;
33   const gchar *fragment_src;
34 };
35
36 static void
37 _compile_shader (GstGLContext * context, struct _compile_shader *data)
38 {
39   GstGLShader *shader;
40   GstGLSLStage *vert, *frag;
41   GError *error = NULL;
42
43   shader = gst_gl_shader_new (context);
44
45   if (data->vertex_src) {
46     vert = gst_glsl_stage_new_with_string (context, GL_VERTEX_SHADER,
47         GST_GLSL_VERSION_NONE,
48         GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY, data->vertex_src);
49     if (!gst_glsl_stage_compile (vert, &error)) {
50       GST_ERROR_OBJECT (vert, "%s", error->message);
51       gst_object_unref (vert);
52       gst_object_unref (shader);
53       return;
54     }
55     if (!gst_gl_shader_attach (shader, vert)) {
56       gst_object_unref (shader);
57       return;
58     }
59   }
60
61   if (data->fragment_src) {
62     frag = gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
63         GST_GLSL_VERSION_NONE,
64         GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
65         data->fragment_src);
66     if (!gst_glsl_stage_compile (frag, &error)) {
67       GST_ERROR_OBJECT (frag, "%s", error->message);
68       gst_object_unref (frag);
69       gst_object_unref (shader);
70       return;
71     }
72     if (!gst_gl_shader_attach (shader, frag)) {
73       gst_object_unref (shader);
74       return;
75     }
76   }
77
78   if (!gst_gl_shader_link (shader, &error)) {
79     GST_ERROR_OBJECT (shader, "%s", error->message);
80     g_error_free (error);
81     error = NULL;
82     gst_gl_context_clear_shader (context);
83     gst_object_unref (shader);
84     return;
85   }
86
87   *data->shader = shader;
88 }
89
90 /* Called by glfilter */
91 gboolean
92 gst_gl_context_gen_shader (GstGLContext * context, const gchar * vert_src,
93     const gchar * frag_src, GstGLShader ** shader)
94 {
95   struct _compile_shader data;
96
97   g_return_val_if_fail (frag_src != NULL || vert_src != NULL, FALSE);
98   g_return_val_if_fail (shader != NULL, FALSE);
99
100   data.shader = shader;
101   data.vertex_src = vert_src;
102   data.fragment_src = frag_src;
103
104   gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _compile_shader,
105       &data);
106
107   return *shader != NULL;
108 }