glshader: port to using GstGLSLStage objects for string management

A GstGLShader is now simply a collection of stages that are
compiled and linked together into a program.  The uniform/attribute
interface has remained the same.
This commit is contained in:
Matthew Waters 2015-09-04 16:02:32 +10:00 committed by Tim-Philipp Müller
parent 8c922ca96b
commit f688a8f0b2
11 changed files with 692 additions and 829 deletions

View file

@ -42,17 +42,18 @@ gst_gl_effects_identity_callback (gint width, gint height, guint texture,
shader = g_hash_table_lookup (effects->shaderstable, "identity0"); shader = g_hash_table_lookup (effects->shaderstable, "identity0");
if (!shader) { if (!shader) {
shader = gst_gl_shader_new (context); GError *error = NULL;
g_hash_table_insert (effects->shaderstable, (gchar *) "identity0", shader);
if (!gst_gl_shader_compile_with_default_vf_and_check (shader, if (!(shader = gst_gl_shader_new_default (context, &error))) {
&filter->draw_attr_position_loc, &filter->draw_attr_texture_loc)) {
/* gst gl context error is already set */
GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
("Failed to initialize identity shader, %s", ("Failed to initialize identity shader: %s", error->message), (NULL));
gst_gl_context_get_error ()), (NULL));
return; return;
} }
filter->draw_attr_position_loc =
gst_gl_shader_get_attribute_location (shader, "a_position");
filter->draw_attr_texture_loc =
gst_gl_shader_get_attribute_location (shader, "a_texcoord");
} }
gst_gl_shader_use (shader); gst_gl_shader_use (shader);

View file

@ -142,19 +142,20 @@ gst_gl_colorscale_gl_start (GstGLBaseFilter * base_filter)
GstGLColorscale *colorscale = GST_GL_COLORSCALE (base_filter); GstGLColorscale *colorscale = GST_GL_COLORSCALE (base_filter);
GstGLFilter *filter = GST_GL_FILTER (base_filter); GstGLFilter *filter = GST_GL_FILTER (base_filter);
GstGLShader *shader; GstGLShader *shader;
GError *error = NULL;
shader = gst_gl_shader_new (base_filter->context); if (!(shader = gst_gl_shader_new_default (base_filter->context, &error))) {
GST_ERROR_OBJECT (colorscale, "Failed to initialize shader: %s",
if (!gst_gl_shader_compile_with_default_vf_and_check (shader, error->message);
&filter->draw_attr_position_loc, &filter->draw_attr_texture_loc)) {
gst_gl_context_clear_shader (base_filter->context);
gst_object_unref (shader); gst_object_unref (shader);
GST_ERROR_OBJECT (colorscale, "Failed to initialize identity shader");
GST_ELEMENT_ERROR (colorscale, RESOURCE, NOT_FOUND, ("%s",
"Failed to initialize identity shader"), (NULL));
return FALSE; return FALSE;
} }
filter->draw_attr_position_loc =
gst_gl_shader_get_attribute_location (shader, "a_position");
filter->draw_attr_texture_loc =
gst_gl_shader_get_attribute_location (shader, "a_texcoord");
colorscale->shader = shader; colorscale->shader = shader;
return GST_GL_BASE_FILTER_CLASS (parent_class)->gl_start (base_filter); return GST_GL_BASE_FILTER_CLASS (parent_class)->gl_start (base_filter);

View file

@ -78,7 +78,9 @@ static void
gst_gl_differencematte_init_gl_resources (GstGLFilter * filter) gst_gl_differencematte_init_gl_resources (GstGLFilter * filter)
{ {
GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (filter); GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (filter);
GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable; GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
const GstGLFuncs *gl = context->gl_vtable;
GError *error = NULL;
gint i; gint i;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
@ -96,45 +98,57 @@ gst_gl_differencematte_init_gl_resources (GstGLFilter * filter)
gst_gl_shader_new (GST_GL_BASE_FILTER (filter)->context); gst_gl_shader_new (GST_GL_BASE_FILTER (filter)->context);
} }
if (!gst_gl_shader_compile_with_default_v_and_check (differencematte->shader if (!(differencematte->shader[0] =
[0], difference_fragment_source, &filter->draw_attr_position_loc, gst_gl_shader_new_link_with_stages (context, &error,
&filter->draw_attr_texture_loc)) { gst_glsl_stage_new_default_vertex (context),
gst_gl_context_set_error (GST_GL_BASE_FILTER (differencematte)->context, gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
"Failed to initialize difference shader"); GST_GLSL_VERSION_NONE, GST_GLSL_PROFILE_ES,
difference_fragment_source), NULL))) {
GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s", GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s",
gst_gl_context_get_error ()), (NULL)); gst_gl_context_get_error ()), (NULL));
return; return;
} }
if (!gst_gl_shader_compile_with_default_v_and_check (differencematte->shader if (!(differencematte->shader[1] =
[1], hconv7_fragment_source_gles2, &filter->draw_attr_position_loc, gst_gl_shader_new_link_with_stages (context, &error,
&filter->draw_attr_texture_loc)) { gst_glsl_stage_new_default_vertex (context),
gst_gl_context_set_error (GST_GL_BASE_FILTER (differencematte)->context, gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
"Failed to initialize hconv7 shader"); GST_GLSL_VERSION_NONE, GST_GLSL_PROFILE_ES,
hconv7_fragment_source_gles2), NULL))) {
GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s", GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s",
gst_gl_context_get_error ()), (NULL)); gst_gl_context_get_error ()), (NULL));
return; return;
} }
if (!gst_gl_shader_compile_with_default_v_and_check (differencematte->shader if (!(differencematte->shader[2] =
[2], vconv7_fragment_source_gles2, &filter->draw_attr_position_loc, gst_gl_shader_new_link_with_stages (context, &error,
&filter->draw_attr_texture_loc)) { gst_glsl_stage_new_default_vertex (context),
gst_gl_context_set_error (GST_GL_BASE_FILTER (differencematte)->context, gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
"Failed to initialize vconv7 shader"); GST_GLSL_VERSION_NONE, GST_GLSL_PROFILE_ES,
vconv7_fragment_source_gles2), NULL))) {
GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s", GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s",
gst_gl_context_get_error ()), (NULL)); gst_gl_context_get_error ()), (NULL));
return; return;
} }
if (!gst_gl_shader_compile_with_default_v_and_check (differencematte->shader if (!(differencematte->shader[3] =
[3], texture_interp_fragment_source, &filter->draw_attr_position_loc, gst_gl_shader_new_link_with_stages (context, &error,
&filter->draw_attr_texture_loc)) { gst_glsl_stage_new_default_vertex (context),
gst_gl_context_set_error (GST_GL_BASE_FILTER (differencematte)->context, gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
"Failed to initialize interp shader"); GST_GLSL_VERSION_NONE, GST_GLSL_PROFILE_ES,
texture_interp_fragment_source), NULL))) {
GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s", GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s",
gst_gl_context_get_error ()), (NULL)); gst_gl_context_get_error ()), (NULL));
return; return;
} }
/* FIXME: this should really be per shader */
filter->draw_attr_position_loc =
gst_gl_shader_get_attribute_location (differencematte->shader[3],
"a_position");
filter->draw_attr_texture_loc =
gst_gl_shader_get_attribute_location (differencematte->shader[3],
"a_texcoord");
} }
/* free resources that need a gl context */ /* free resources that need a gl context */

View file

@ -545,21 +545,22 @@ gst_gl_effects_get_fragment_shader (GstGLEffects * effects,
shader = g_hash_table_lookup (effects->shaderstable, shader_name); shader = g_hash_table_lookup (effects->shaderstable, shader_name);
if (!shader) { if (!shader) {
shader = gst_gl_shader_new (context); GError *error = NULL;
if (!gst_gl_shader_compile_with_default_v_and_check (shader,
shader_source_gles2, &filter->draw_attr_position_loc,
&filter->draw_attr_texture_loc)) {
/* gst gl context error is already set */
GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
("Failed to initialize %s shader, %s",
shader_name, gst_gl_context_get_error ()), (NULL));
gst_object_unref (shader);
shader = NULL;
}
}
if (!shader) if (!(shader = gst_gl_shader_new_link_with_stages (context, &error,
return NULL; gst_glsl_stage_new_default_vertex (context),
gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
GST_GLSL_VERSION_NONE, GST_GLSL_PROFILE_ES,
shader_source_gles2), NULL))) {
GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
("Failed to initialize %s shader", shader_name), (NULL));
}
filter->draw_attr_position_loc =
gst_gl_shader_get_attribute_location (shader, "a_position");
filter->draw_attr_texture_loc =
gst_gl_shader_get_attribute_location (shader, "a_texcoord");
}
g_hash_table_insert (effects->shaderstable, (gchar *) shader_name, shader); g_hash_table_insert (effects->shaderstable, (gchar *) shader_name, shader);

View file

@ -1682,13 +1682,23 @@ static void
gst_glimage_sink_thread_init_redisplay (GstGLImageSink * gl_sink) gst_glimage_sink_thread_init_redisplay (GstGLImageSink * gl_sink)
{ {
const GstGLFuncs *gl = gl_sink->context->gl_vtable; const GstGLFuncs *gl = gl_sink->context->gl_vtable;
GError *error = NULL;
gl_sink->redisplay_shader = gst_gl_shader_new (gl_sink->context); if (!(gl_sink->redisplay_shader =
gst_gl_shader_new_link_with_stages (gl_sink->context, &error,
if (!gst_gl_shader_compile_with_default_vf_and_check gst_glsl_stage_new_default_vertex (gl_sink->context),
(gl_sink->redisplay_shader, &gl_sink->attr_position, gst_glsl_stage_new_default_fragment (gl_sink->context), NULL))) {
&gl_sink->attr_texture)) GST_ERROR_OBJECT (gl_sink, "Failed to link shader: %s", error->message);
gst_glimage_sink_cleanup_glthread (gl_sink); gst_glimage_sink_cleanup_glthread (gl_sink);
return;
}
gl_sink->attr_position =
gst_gl_shader_get_attribute_location (gl_sink->redisplay_shader,
"a_position");
gl_sink->attr_texture =
gst_gl_shader_get_attribute_location (gl_sink->redisplay_shader,
"a_texcoord");
if (gl->GenVertexArrays) { if (gl->GenVertexArrays) {
gl->GenVertexArrays (1, &gl_sink->vao); gl->GenVertexArrays (1, &gl_sink->vao);

View file

@ -425,12 +425,24 @@ gst_gl_overlay_compositor_init_gl (GstGLContext * context,
{ {
GstGLOverlayCompositor *compositor = GstGLOverlayCompositor *compositor =
(GstGLOverlayCompositor *) compositor_pointer; (GstGLOverlayCompositor *) compositor_pointer;
GError *error = NULL;
if (!gst_gl_shader_compile_with_default_v_and_check (compositor->shader, if (!(compositor->shader =
fragment_shader, &compositor->position_attrib, gst_gl_shader_new_link_with_stages (context, &error,
&compositor->texcoord_attrib)) { gst_glsl_stage_new_default_vertex (context),
GST_ERROR ("could not initialize shader."); gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
GST_GLSL_VERSION_NONE,
GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
fragment_shader), NULL))) {
GST_ERROR_OBJECT (compositor, "could not initialize shader: %s",
error->message);
return;
} }
compositor->position_attrib =
gst_gl_shader_get_attribute_location (compositor->shader, "a_position");
compositor->texcoord_attrib =
gst_gl_shader_get_attribute_location (compositor->shader, "a_texcoord");
} }
GstGLOverlayCompositor * GstGLOverlayCompositor *
@ -441,8 +453,6 @@ gst_gl_overlay_compositor_new (GstGLContext * context)
compositor->context = gst_object_ref (context); compositor->context = gst_object_ref (context);
compositor->shader = gst_gl_shader_new (compositor->context);
gst_gl_context_thread_add (compositor->context, gst_gl_context_thread_add (compositor->context,
gst_gl_overlay_compositor_init_gl, compositor); gst_gl_overlay_compositor_init_gl, compositor);

File diff suppressed because it is too large Load diff

View file

@ -26,6 +26,7 @@
G_BEGIN_DECLS G_BEGIN_DECLS
GType gst_gl_shader_get_type (void);
#define GST_GL_TYPE_SHADER (gst_gl_shader_get_type()) #define GST_GL_TYPE_SHADER (gst_gl_shader_get_type())
#define GST_GL_SHADER(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_GL_TYPE_SHADER, GstGLShader)) #define GST_GL_SHADER(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_GL_TYPE_SHADER, GstGLShader))
#define GST_GL_SHADER_CLASS(k) (G_TYPE_CHECK_CLASS((k), GST_GL_TYPE_SHADER, GstGLShaderClass)) #define GST_GL_SHADER_CLASS(k) (G_TYPE_CHECK_CLASS((k), GST_GL_TYPE_SHADER, GstGLShaderClass))
@ -33,19 +34,6 @@ G_BEGIN_DECLS
#define GST_GL_IS_SHADER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_GL_TYPE_SHADER)) #define GST_GL_IS_SHADER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_GL_TYPE_SHADER))
#define GST_GL_SHADER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_GL_TYPE_SHADER, GstGLShaderClass)) #define GST_GL_SHADER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_GL_TYPE_SHADER, GstGLShaderClass))
#define GST_GL_SHADER_ERROR (gst_gl_shader_error_quark ())
typedef enum {
GST_GL_SHADER_ERROR_COMPILE,
GST_GL_SHADER_ERROR_LINK,
GST_GL_SHADER_ERROR_PROGRAM
} GstGLShaderError;
typedef enum {
GST_GL_SHADER_FRAGMENT_SOURCE,
GST_GL_SHADER_VERTEX_SOURCE
} GstGLShaderSourceType;
struct _GstGLShader { struct _GstGLShader {
/*< private >*/ /*< private >*/
GstObject parent; GstObject parent;
@ -53,6 +41,8 @@ struct _GstGLShader {
GstGLContext *context; GstGLContext *context;
GstGLShaderPrivate *priv; GstGLShaderPrivate *priv;
gpointer _padding[GST_PADDING];
}; };
struct _GstGLShaderClass { struct _GstGLShaderClass {
@ -60,33 +50,29 @@ struct _GstGLShaderClass {
GstObjectClass parent_class; GstObjectClass parent_class;
}; };
/* methods */ GstGLShader * gst_gl_shader_new (GstGLContext *context);
GstGLShader * gst_gl_shader_new_with_stages (GstGLContext * context, GError ** error, ...);
GstGLShader * gst_gl_shader_new_link_with_stages (GstGLContext * context, GError ** error, ...);
GstGLShader * gst_gl_shader_new_default (GstGLContext * context, GError ** error);
GQuark gst_gl_shader_error_quark (void); gboolean gst_gl_shader_attach (GstGLShader * shader, GstGLSLStage * stage);
GType gst_gl_shader_get_type (void); gboolean gst_gl_shader_attach_unlocked (GstGLShader * shader, GstGLSLStage * stage);
GstGLShader * gst_gl_shader_new (GstGLContext *context); void gst_gl_shader_detach (GstGLShader * shader, GstGLSLStage * stage);
void gst_gl_shader_detach_unlocked (GstGLShader * shader, GstGLSLStage * stage);
int gst_gl_shader_get_program_handle(GstGLShader * shader); gboolean gst_gl_shader_compile_attach_stage (GstGLShader * shader,
GstGLSLStage *stage,
GError ** error);
gboolean gst_gl_shader_link (GstGLShader * shader, GError ** error);
gboolean gst_gl_shader_is_linked (GstGLShader *shader);
void gst_gl_shader_set_vertex_source (GstGLShader *shader, const gchar *src); int gst_gl_shader_get_program_handle (GstGLShader * shader);
void gst_gl_shader_set_fragment_source (GstGLShader *shader, const gchar *src);
const gchar * gst_gl_shader_get_vertex_source (GstGLShader *shader);
const gchar * gst_gl_shader_get_fragment_source (GstGLShader *shader);
void gst_gl_shader_set_active (GstGLShader *shader, gboolean active); void gst_gl_shader_release (GstGLShader *shader);
gboolean gst_gl_shader_is_compiled (GstGLShader *shader); void gst_gl_shader_release_unlocked (GstGLShader * shader);
gboolean gst_gl_shader_compile (GstGLShader *shader, GError **error); void gst_gl_shader_use (GstGLShader *shader);
gboolean gst_gl_shader_compile_and_check (GstGLShader *shader, const gchar *source, GstGLShaderSourceType type); void gst_gl_context_clear_shader (GstGLContext *context);
gboolean gst_gl_shader_compile_all_with_attribs_and_check (GstGLShader *shader, const gchar *v_src, const gchar *f_src, const gint n_attribs, const gchar *attrib_names[], GLint attrib_locs[]);
gboolean gst_gl_shader_compile_with_default_f_and_check (GstGLShader *shader, const gchar *v_src, const gint n_attribs, const gchar *attrib_names[], GLint attrib_locs[]);
gboolean gst_gl_shader_compile_with_default_v_and_check (GstGLShader *shader, const gchar *f_src, GLint *pos_loc, GLint *tex_loc);
gboolean gst_gl_shader_compile_with_default_vf_and_check (GstGLShader *shader, GLint *pos_loc, GLint *tex_loc);
void gst_gl_shader_release (GstGLShader *shader);
void gst_gl_shader_use (GstGLShader *shader);
void gst_gl_context_clear_shader (GstGLContext *context);
void gst_gl_shader_set_uniform_1i (GstGLShader *shader, const gchar *name, gint value); void gst_gl_shader_set_uniform_1i (GstGLShader *shader, const gchar *name, gint value);
void gst_gl_shader_set_uniform_1iv (GstGLShader *shader, const gchar *name, guint count, gint *value); void gst_gl_shader_set_uniform_1iv (GstGLShader *shader, const gchar *name, guint count, gint *value);

View file

@ -375,20 +375,60 @@ gst_gl_context_del_fbo (GstGLContext * context, GLuint fbo, GLuint depth_buffer)
gst_object_unref (frame); gst_object_unref (frame);
} }
static void struct _compile_shader
_compile_shader (GstGLContext * context, GstGLShader ** shader)
{ {
GstGLShader **shader;
const gchar *vertex_src;
const gchar *fragment_src;
};
static void
_compile_shader (GstGLContext * context, struct _compile_shader *data)
{
GstGLShader *shader;
GstGLSLStage *vert, *frag;
GError *error = NULL; GError *error = NULL;
gst_gl_shader_compile (*shader, &error); shader = gst_gl_shader_new (context);
if (error) {
gst_gl_context_set_error (context, "%s", error->message); if (data->vertex_src) {
vert = gst_glsl_stage_new_with_string (context, GL_VERTEX_SHADER,
GST_GLSL_VERSION_NONE, GST_GLSL_PROFILE_NONE, data->vertex_src);
if (!gst_glsl_stage_compile (vert, &error)) {
GST_ERROR_OBJECT (vert, "%s", error->message);
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_NONE, data->fragment_src);
if (!gst_glsl_stage_compile (frag, &error)) {
GST_ERROR_OBJECT (frag, "%s", error->message);
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); g_error_free (error);
error = NULL; error = NULL;
gst_gl_context_clear_shader (context); gst_gl_context_clear_shader (context);
gst_object_unref (*shader); gst_object_unref (shader);
*shader = NULL; return;
} }
*data->shader = shader;
} }
/* Called by glfilter */ /* Called by glfilter */
@ -396,18 +436,17 @@ gboolean
gst_gl_context_gen_shader (GstGLContext * context, const gchar * vert_src, gst_gl_context_gen_shader (GstGLContext * context, const gchar * vert_src,
const gchar * frag_src, GstGLShader ** shader) const gchar * frag_src, GstGLShader ** shader)
{ {
struct _compile_shader data;
g_return_val_if_fail (frag_src != NULL || vert_src != NULL, FALSE); g_return_val_if_fail (frag_src != NULL || vert_src != NULL, FALSE);
g_return_val_if_fail (shader != NULL, FALSE); g_return_val_if_fail (shader != NULL, FALSE);
*shader = gst_gl_shader_new (context); data.shader = shader;
data.vertex_src = vert_src;
if (frag_src) data.fragment_src = frag_src;
gst_gl_shader_set_fragment_source (*shader, frag_src);
if (vert_src)
gst_gl_shader_set_vertex_source (*shader, vert_src);
gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _compile_shader, gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _compile_shader,
shader); &data);
return *shader != NULL; return *shader != NULL;
} }

View file

@ -28,29 +28,6 @@
#include <stdio.h> #include <stdio.h>
#if GST_GL_HAVE_GLES2
/* *INDENT-OFF* */
static const gchar *vertex_shader_str_gles2 =
"attribute vec4 a_position; \n"
"attribute vec2 a_texCoord; \n"
"varying vec2 v_texCoord; \n"
"void main() \n"
"{ \n"
" gl_Position = a_position; \n"
" v_texCoord = a_texCoord; \n"
"} \n";
static const gchar *fragment_shader_str_gles2 =
"precision mediump float; \n"
"varying vec2 v_texCoord; \n"
"uniform sampler2D s_texture; \n"
"void main() \n"
"{ \n"
" gl_FragColor = texture2D( s_texture, v_texCoord );\n"
"} \n";
/* *INDENT-ON* */
#endif
static GstGLDisplay *display; static GstGLDisplay *display;
static void static void
@ -67,17 +44,15 @@ teardown (void)
static GLuint fbo_id, rbo, tex; static GLuint fbo_id, rbo, tex;
static GstGLFramebuffer *fbo; static GstGLFramebuffer *fbo;
#if GST_GL_HAVE_GLES2
static GError *error;
static GstGLShader *shader; static GstGLShader *shader;
static GLint shader_attr_position_loc; static GLint shader_attr_position_loc;
static GLint shader_attr_texture_loc; static GLint shader_attr_texture_loc;
#endif
static void static void
init (gpointer data) init (gpointer data)
{ {
GstGLContext *context = data; GstGLContext *context = data;
GError *error = NULL;
/* has to be called in the thread that is going to use the framebuffer */ /* has to be called in the thread that is going to use the framebuffer */
fbo = gst_gl_framebuffer_new (context); fbo = gst_gl_framebuffer_new (context);
@ -88,25 +63,14 @@ init (gpointer data)
gst_gl_context_gen_texture (context, &tex, GST_VIDEO_FORMAT_RGBA, 320, 240); gst_gl_context_gen_texture (context, &tex, GST_VIDEO_FORMAT_RGBA, 320, 240);
fail_if (tex == 0, "failed to create texture"); fail_if (tex == 0, "failed to create texture");
#if GST_GL_HAVE_GLES2 shader = gst_gl_shader_new_default (context, &error);
if (gst_gl_context_get_gl_api (context) & GST_GL_API_GLES2) { fail_if (shader == NULL, "failed to create shader object: %s",
shader = gst_gl_shader_new (context); error->message);
fail_if (shader == NULL, "failed to create shader object");
gst_gl_shader_set_vertex_source (shader, vertex_shader_str_gles2); shader_attr_position_loc =
gst_gl_shader_set_fragment_source (shader, fragment_shader_str_gles2); gst_gl_shader_get_attribute_location (shader, "a_position");
shader_attr_texture_loc =
error = NULL; gst_gl_shader_get_attribute_location (shader, "a_texcoord");
gst_gl_shader_compile (shader, &error);
fail_if (error != NULL, "Error compiling shader %s\n",
error ? error->message : "Unknown Error");
shader_attr_position_loc =
gst_gl_shader_get_attribute_location (shader, "a_position");
shader_attr_texture_loc =
gst_gl_shader_get_attribute_location (shader, "a_texCoord");
}
#endif
} }
static void static void
@ -116,10 +80,7 @@ deinit (gpointer data)
GstGLFuncs *gl = context->gl_vtable; GstGLFuncs *gl = context->gl_vtable;
gl->DeleteTextures (1, &tex); gl->DeleteTextures (1, &tex);
gst_object_unref (fbo); gst_object_unref (fbo);
#if GST_GL_HAVE_GLES2 gst_object_unref (shader);
if (gst_gl_context_get_gl_api (context) & GST_GL_API_GLES2)
gst_object_unref (shader);
#endif
} }
static void static void
@ -150,81 +111,38 @@ draw_render (gpointer data)
GstGLContext *context = data; GstGLContext *context = data;
GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context); GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context);
const GstGLFuncs *gl = context->gl_vtable; const GstGLFuncs *gl = context->gl_vtable;
const GLfloat vVertices[] = { 1.0f, 1.0f, 0.0f,
1.0f, 0.0f,
-1.0f, 1.0f, 0.0f,
0.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
0.0f, 1.0f,
1.0f, -1.0f, 0.0f,
1.0f, 1.0f
};
/* redraw the texture into the system provided framebuffer */ GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
#if GST_GL_HAVE_OPENGL gl->Clear (GL_COLOR_BUFFER_BIT);
if (gst_gl_context_get_gl_api (context) & GST_GL_API_OPENGL) {
GLfloat verts[8] = { 1.0f, 1.0f,
-1.0f, 1.0f,
-1.0f, -1.0f,
1.0f, -1.0f
};
GLfloat texcoords[8] = { 1.0f, 0.0f,
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f
};
gl->Viewport (0, 0, 320, 240); gst_gl_shader_use (shader);
gl->Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* Load the vertex position */
gl->VertexAttribPointer (shader_attr_position_loc, 3,
GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), vVertices);
gl->MatrixMode (GL_PROJECTION); /* Load the texture coordinate */
gl->LoadIdentity (); gl->VertexAttribPointer (shader_attr_texture_loc, 2,
GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]);
gl->ActiveTexture (GL_TEXTURE0); gl->EnableVertexAttribArray (shader_attr_position_loc);
gl->BindTexture (GL_TEXTURE_2D, tex); gl->EnableVertexAttribArray (shader_attr_texture_loc);
gl->EnableClientState (GL_VERTEX_ARRAY); gl->ActiveTexture (GL_TEXTURE0);
gl->VertexPointer (2, GL_FLOAT, 0, &verts); gl->BindTexture (GL_TEXTURE_2D, tex);
gst_gl_shader_set_uniform_1i (shader, "s_texture", 0);
gl->ClientActiveTexture (GL_TEXTURE0); gl->DrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
gl->EnableClientState (GL_TEXTURE_COORD_ARRAY);
gl->TexCoordPointer (2, GL_FLOAT, 0, &texcoords);
gl->DrawArrays (GL_TRIANGLE_FAN, 0, 4);
gl->DisableClientState (GL_VERTEX_ARRAY);
gl->DisableClientState (GL_TEXTURE_COORD_ARRAY);
}
#endif
#if GST_GL_HAVE_GLES2
if (gst_gl_context_get_gl_api (context) & GST_GL_API_GLES2) {
const GLfloat vVertices[] = { 1.0f, 1.0f, 0.0f,
1.0f, 0.0f,
-1.0f, 1.0f, 0.0f,
0.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
0.0f, 1.0f,
1.0f, -1.0f, 0.0f,
1.0f, 1.0f
};
GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
gl->Clear (GL_COLOR_BUFFER_BIT);
gst_gl_shader_use (shader);
/* Load the vertex position */
gl->VertexAttribPointer (shader_attr_position_loc, 3,
GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), vVertices);
/* Load the texture coordinate */
gl->VertexAttribPointer (shader_attr_texture_loc, 2,
GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]);
gl->EnableVertexAttribArray (shader_attr_position_loc);
gl->EnableVertexAttribArray (shader_attr_texture_loc);
gl->ActiveTexture (GL_TEXTURE0);
gl->BindTexture (GL_TEXTURE_2D, tex);
gst_gl_shader_set_uniform_1i (shader, "s_texture", 0);
gl->DrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
}
#endif
context_class->swap_buffers (context); context_class->swap_buffers (context);
} }
@ -314,6 +232,7 @@ check_wrapped (gpointer data)
fail_if (!ret, "error received %s\n", fail_if (!ret, "error received %s\n",
error ? error->message : "Unknown error"); error ? error->message : "Unknown error");
fail_if (wrapped_context->gl_vtable->TexImage2D == NULL); fail_if (wrapped_context->gl_vtable->TexImage2D == NULL);
gst_gl_context_activate (wrapped_context, FALSE);
} }
GST_START_TEST (test_wrapped_context) GST_START_TEST (test_wrapped_context)

View file

@ -29,41 +29,14 @@
#include <stdio.h> #include <stdio.h>
#if GST_GL_HAVE_GLES2
/* *INDENT-OFF* */
static const gchar *vertex_shader_str_gles2 =
"attribute vec4 a_position; \n"
"attribute vec2 a_texCoord; \n"
"varying vec2 v_texCoord; \n"
"void main() \n"
"{ \n"
" gl_Position = a_position; \n"
" v_texCoord = a_texCoord; \n"
"} \n";
static const gchar *fragment_shader_str_gles2 =
"precision mediump float; \n"
"varying vec2 v_texCoord; \n"
"uniform sampler2D s_texture; \n"
"void main() \n"
"{ \n"
" gl_FragColor = texture2D( s_texture, v_texCoord );\n"
"} \n";
/* *INDENT-ON* */
#endif
static GstGLDisplay *display; static GstGLDisplay *display;
static GstGLContext *context; static GstGLContext *context;
static GstGLWindow *window; static GstGLWindow *window;
static GstGLUpload *upload; static GstGLUpload *upload;
static guint tex_id; static guint tex_id;
#if GST_GL_HAVE_GLES2
static GError *error;
static GstGLShader *shader; static GstGLShader *shader;
static GLint shader_attr_position_loc; static GLint shader_attr_position_loc;
static GLint shader_attr_texture_loc; static GLint shader_attr_texture_loc;
#endif
#define FORMAT GST_VIDEO_GL_TEXTURE_TYPE_RGBA #define FORMAT GST_VIDEO_GL_TEXTURE_TYPE_RGBA
#define WIDTH 10 #define WIDTH 10
@ -118,25 +91,15 @@ teardown (void)
static void static void
init (gpointer data) init (gpointer data)
{ {
#if GST_GL_HAVE_GLES2 GError *error = NULL;
if (gst_gl_context_get_gl_api (context) & GST_GL_API_GLES2) {
shader = gst_gl_shader_new (context);
fail_if (shader == NULL, "failed to create shader object");
gst_gl_shader_set_vertex_source (shader, vertex_shader_str_gles2); shader = gst_gl_shader_new_default (context, &error);
gst_gl_shader_set_fragment_source (shader, fragment_shader_str_gles2); fail_if (shader == NULL, "failed to create shader object %s", error->message);
error = NULL; shader_attr_position_loc =
gst_gl_shader_compile (shader, &error); gst_gl_shader_get_attribute_location (shader, "a_position");
fail_if (error != NULL, "Error compiling shader %s\n", shader_attr_texture_loc =
error ? error->message : "Unknown Error"); gst_gl_shader_get_attribute_location (shader, "a_texCoord");
shader_attr_position_loc =
gst_gl_shader_get_attribute_location (shader, "a_position");
shader_attr_texture_loc =
gst_gl_shader_get_attribute_location (shader, "a_texCoord");
}
#endif
} }
static void static void
@ -145,81 +108,38 @@ draw_render (gpointer data)
GstGLContext *context = data; GstGLContext *context = data;
GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context); GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context);
const GstGLFuncs *gl = context->gl_vtable; const GstGLFuncs *gl = context->gl_vtable;
const GLfloat vVertices[] = { 1.0f, 1.0f, 0.0f,
1.0f, 0.0f,
-1.0f, 1.0f, 0.0f,
0.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
0.0f, 1.0f,
1.0f, -1.0f, 0.0f,
1.0f, 1.0f
};
/* redraw the texture into the system provided framebuffer */ GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
#if GST_GL_HAVE_OPENGL gl->Clear (GL_COLOR_BUFFER_BIT);
if (gst_gl_context_get_gl_api (context) & GST_GL_API_OPENGL) {
GLfloat verts[8] = { 1.0f, 1.0f,
-1.0f, 1.0f,
-1.0f, -1.0f,
1.0f, -1.0f
};
GLfloat texcoords[8] = { 1.0f, 0.0f,
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f
};
gl->Viewport (0, 0, 10, 10); gst_gl_shader_use (shader);
gl->Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* Load the vertex position */
gl->VertexAttribPointer (shader_attr_position_loc, 3,
GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), vVertices);
gl->MatrixMode (GL_PROJECTION); /* Load the texture coordinate */
gl->LoadIdentity (); gl->VertexAttribPointer (shader_attr_texture_loc, 2,
GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]);
gl->ActiveTexture (GL_TEXTURE_2D); gl->EnableVertexAttribArray (shader_attr_position_loc);
gl->BindTexture (GL_TEXTURE_2D, tex_id); gl->EnableVertexAttribArray (shader_attr_texture_loc);
gl->EnableClientState (GL_VERTEX_ARRAY); gl->ActiveTexture (GL_TEXTURE0);
gl->VertexPointer (2, GL_FLOAT, 0, &verts); gl->BindTexture (GL_TEXTURE_2D, tex_id);
gst_gl_shader_set_uniform_1i (shader, "s_texture", 0);
gl->ClientActiveTexture (GL_TEXTURE0); gl->DrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
gl->EnableClientState (GL_TEXTURE_COORD_ARRAY);
gl->TexCoordPointer (2, GL_FLOAT, 0, &texcoords);
gl->DrawArrays (GL_TRIANGLE_FAN, 0, 4);
gl->DisableClientState (GL_VERTEX_ARRAY);
gl->DisableClientState (GL_TEXTURE_COORD_ARRAY);
}
#endif
#if GST_GL_HAVE_GLES2
if (gst_gl_context_get_gl_api (context) & GST_GL_API_GLES2) {
const GLfloat vVertices[] = { 1.0f, 1.0f, 0.0f,
1.0f, 0.0f,
-1.0f, 1.0f, 0.0f,
0.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
0.0f, 1.0f,
1.0f, -1.0f, 0.0f,
1.0f, 1.0f
};
GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
gl->Clear (GL_COLOR_BUFFER_BIT);
gst_gl_shader_use (shader);
/* Load the vertex position */
gl->VertexAttribPointer (shader_attr_position_loc, 3,
GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), vVertices);
/* Load the texture coordinate */
gl->VertexAttribPointer (shader_attr_texture_loc, 2,
GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]);
gl->EnableVertexAttribArray (shader_attr_position_loc);
gl->EnableVertexAttribArray (shader_attr_texture_loc);
gl->ActiveTexture (GL_TEXTURE0);
gl->BindTexture (GL_TEXTURE_2D, tex_id);
gst_gl_shader_set_uniform_1i (shader, "s_texture", 0);
gl->DrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
}
#endif
context_class->swap_buffers (context); context_class->swap_buffers (context);
} }