mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-20 00:31:13 +00:00
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:
parent
8c922ca96b
commit
f688a8f0b2
11 changed files with 692 additions and 829 deletions
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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,
|
if (!(shader = gst_gl_shader_new_link_with_stages (context, &error,
|
||||||
&filter->draw_attr_texture_loc)) {
|
gst_glsl_stage_new_default_vertex (context),
|
||||||
/* gst gl context error is already set */
|
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,
|
GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
|
||||||
("Failed to initialize %s shader, %s",
|
("Failed to initialize %s shader", shader_name), (NULL));
|
||||||
shader_name, gst_gl_context_get_error ()), (NULL));
|
|
||||||
gst_object_unref (shader);
|
|
||||||
shader = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!shader)
|
filter->draw_attr_position_loc =
|
||||||
return NULL;
|
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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
@ -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,31 +50,27 @@ struct _GstGLShaderClass {
|
||||||
GstObjectClass parent_class;
|
GstObjectClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* methods */
|
|
||||||
|
|
||||||
GQuark gst_gl_shader_error_quark (void);
|
|
||||||
GType gst_gl_shader_get_type (void);
|
|
||||||
|
|
||||||
GstGLShader * gst_gl_shader_new (GstGLContext *context);
|
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);
|
||||||
|
|
||||||
|
gboolean gst_gl_shader_attach (GstGLShader * shader, GstGLSLStage * stage);
|
||||||
|
gboolean gst_gl_shader_attach_unlocked (GstGLShader * shader, GstGLSLStage * stage);
|
||||||
|
|
||||||
|
void gst_gl_shader_detach (GstGLShader * shader, GstGLSLStage * stage);
|
||||||
|
void gst_gl_shader_detach_unlocked (GstGLShader * shader, GstGLSLStage * stage);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
int gst_gl_shader_get_program_handle (GstGLShader * shader);
|
int gst_gl_shader_get_program_handle (GstGLShader * shader);
|
||||||
|
|
||||||
void gst_gl_shader_set_vertex_source (GstGLShader *shader, const gchar *src);
|
|
||||||
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);
|
|
||||||
gboolean gst_gl_shader_is_compiled (GstGLShader *shader);
|
|
||||||
gboolean gst_gl_shader_compile (GstGLShader *shader, GError **error);
|
|
||||||
gboolean gst_gl_shader_compile_and_check (GstGLShader *shader, const gchar *source, GstGLShaderSourceType type);
|
|
||||||
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_release (GstGLShader *shader);
|
||||||
|
void gst_gl_shader_release_unlocked (GstGLShader * shader);
|
||||||
void gst_gl_shader_use (GstGLShader *shader);
|
void gst_gl_shader_use (GstGLShader *shader);
|
||||||
void gst_gl_context_clear_shader (GstGLContext *context);
|
void gst_gl_context_clear_shader (GstGLContext *context);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
gst_gl_shader_set_fragment_source (shader, fragment_shader_str_gles2);
|
|
||||||
|
|
||||||
error = NULL;
|
|
||||||
gst_gl_shader_compile (shader, &error);
|
|
||||||
fail_if (error != NULL, "Error compiling shader %s\n",
|
|
||||||
error ? error->message : "Unknown Error");
|
|
||||||
|
|
||||||
shader_attr_position_loc =
|
shader_attr_position_loc =
|
||||||
gst_gl_shader_get_attribute_location (shader, "a_position");
|
gst_gl_shader_get_attribute_location (shader, "a_position");
|
||||||
shader_attr_texture_loc =
|
shader_attr_texture_loc =
|
||||||
gst_gl_shader_get_attribute_location (shader, "a_texCoord");
|
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
|
|
||||||
if (gst_gl_context_get_gl_api (context) & GST_GL_API_GLES2)
|
|
||||||
gst_object_unref (shader);
|
gst_object_unref (shader);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -150,47 +111,6 @@ 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;
|
||||||
|
|
||||||
/* redraw the texture into the system provided framebuffer */
|
|
||||||
|
|
||||||
#if GST_GL_HAVE_OPENGL
|
|
||||||
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);
|
|
||||||
|
|
||||||
gl->Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
||||||
|
|
||||||
gl->MatrixMode (GL_PROJECTION);
|
|
||||||
gl->LoadIdentity ();
|
|
||||||
|
|
||||||
gl->ActiveTexture (GL_TEXTURE0);
|
|
||||||
gl->BindTexture (GL_TEXTURE_2D, tex);
|
|
||||||
|
|
||||||
gl->EnableClientState (GL_VERTEX_ARRAY);
|
|
||||||
gl->VertexPointer (2, GL_FLOAT, 0, &verts);
|
|
||||||
|
|
||||||
gl->ClientActiveTexture (GL_TEXTURE0);
|
|
||||||
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,
|
const GLfloat vVertices[] = { 1.0f, 1.0f, 0.0f,
|
||||||
1.0f, 0.0f,
|
1.0f, 0.0f,
|
||||||
-1.0f, 1.0f, 0.0f,
|
-1.0f, 1.0f, 0.0f,
|
||||||
|
@ -223,8 +143,6 @@ draw_render (gpointer data)
|
||||||
gst_gl_shader_set_uniform_1i (shader, "s_texture", 0);
|
gst_gl_shader_set_uniform_1i (shader, "s_texture", 0);
|
||||||
|
|
||||||
gl->DrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
|
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)
|
||||||
|
|
|
@ -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,26 +91,16 @@ 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;
|
|
||||||
gst_gl_shader_compile (shader, &error);
|
|
||||||
fail_if (error != NULL, "Error compiling shader %s\n",
|
|
||||||
error ? error->message : "Unknown Error");
|
|
||||||
|
|
||||||
shader_attr_position_loc =
|
shader_attr_position_loc =
|
||||||
gst_gl_shader_get_attribute_location (shader, "a_position");
|
gst_gl_shader_get_attribute_location (shader, "a_position");
|
||||||
shader_attr_texture_loc =
|
shader_attr_texture_loc =
|
||||||
gst_gl_shader_get_attribute_location (shader, "a_texCoord");
|
gst_gl_shader_get_attribute_location (shader, "a_texCoord");
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
draw_render (gpointer data)
|
draw_render (gpointer data)
|
||||||
|
@ -145,47 +108,6 @@ 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;
|
||||||
|
|
||||||
/* redraw the texture into the system provided framebuffer */
|
|
||||||
|
|
||||||
#if GST_GL_HAVE_OPENGL
|
|
||||||
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);
|
|
||||||
|
|
||||||
gl->Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
||||||
|
|
||||||
gl->MatrixMode (GL_PROJECTION);
|
|
||||||
gl->LoadIdentity ();
|
|
||||||
|
|
||||||
gl->ActiveTexture (GL_TEXTURE_2D);
|
|
||||||
gl->BindTexture (GL_TEXTURE_2D, tex_id);
|
|
||||||
|
|
||||||
gl->EnableClientState (GL_VERTEX_ARRAY);
|
|
||||||
gl->VertexPointer (2, GL_FLOAT, 0, &verts);
|
|
||||||
|
|
||||||
gl->ClientActiveTexture (GL_TEXTURE0);
|
|
||||||
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,
|
const GLfloat vVertices[] = { 1.0f, 1.0f, 0.0f,
|
||||||
1.0f, 0.0f,
|
1.0f, 0.0f,
|
||||||
-1.0f, 1.0f, 0.0f,
|
-1.0f, 1.0f, 0.0f,
|
||||||
|
@ -218,8 +140,6 @@ draw_render (gpointer data)
|
||||||
gst_gl_shader_set_uniform_1i (shader, "s_texture", 0);
|
gst_gl_shader_set_uniform_1i (shader, "s_texture", 0);
|
||||||
|
|
||||||
gl->DrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
|
gl->DrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
context_class->swap_buffers (context);
|
context_class->swap_buffers (context);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue