mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +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");
|
||||
if (!shader) {
|
||||
shader = gst_gl_shader_new (context);
|
||||
g_hash_table_insert (effects->shaderstable, (gchar *) "identity0", shader);
|
||||
GError *error = NULL;
|
||||
|
||||
if (!gst_gl_shader_compile_with_default_vf_and_check (shader,
|
||||
&filter->draw_attr_position_loc, &filter->draw_attr_texture_loc)) {
|
||||
/* gst gl context error is already set */
|
||||
if (!(shader = gst_gl_shader_new_default (context, &error))) {
|
||||
GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
|
||||
("Failed to initialize identity shader, %s",
|
||||
gst_gl_context_get_error ()), (NULL));
|
||||
("Failed to initialize identity shader: %s", error->message), (NULL));
|
||||
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);
|
||||
|
||||
|
|
|
@ -142,19 +142,20 @@ gst_gl_colorscale_gl_start (GstGLBaseFilter * base_filter)
|
|||
GstGLColorscale *colorscale = GST_GL_COLORSCALE (base_filter);
|
||||
GstGLFilter *filter = GST_GL_FILTER (base_filter);
|
||||
GstGLShader *shader;
|
||||
GError *error = NULL;
|
||||
|
||||
shader = gst_gl_shader_new (base_filter->context);
|
||||
|
||||
if (!gst_gl_shader_compile_with_default_vf_and_check (shader,
|
||||
&filter->draw_attr_position_loc, &filter->draw_attr_texture_loc)) {
|
||||
gst_gl_context_clear_shader (base_filter->context);
|
||||
if (!(shader = gst_gl_shader_new_default (base_filter->context, &error))) {
|
||||
GST_ERROR_OBJECT (colorscale, "Failed to initialize shader: %s",
|
||||
error->message);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (!gst_gl_shader_compile_with_default_v_and_check (differencematte->shader
|
||||
[0], difference_fragment_source, &filter->draw_attr_position_loc,
|
||||
&filter->draw_attr_texture_loc)) {
|
||||
gst_gl_context_set_error (GST_GL_BASE_FILTER (differencematte)->context,
|
||||
"Failed to initialize difference shader");
|
||||
if (!(differencematte->shader[0] =
|
||||
gst_gl_shader_new_link_with_stages (context, &error,
|
||||
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,
|
||||
difference_fragment_source), NULL))) {
|
||||
GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s",
|
||||
gst_gl_context_get_error ()), (NULL));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!gst_gl_shader_compile_with_default_v_and_check (differencematte->shader
|
||||
[1], hconv7_fragment_source_gles2, &filter->draw_attr_position_loc,
|
||||
&filter->draw_attr_texture_loc)) {
|
||||
gst_gl_context_set_error (GST_GL_BASE_FILTER (differencematte)->context,
|
||||
"Failed to initialize hconv7 shader");
|
||||
if (!(differencematte->shader[1] =
|
||||
gst_gl_shader_new_link_with_stages (context, &error,
|
||||
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,
|
||||
hconv7_fragment_source_gles2), NULL))) {
|
||||
GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s",
|
||||
gst_gl_context_get_error ()), (NULL));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!gst_gl_shader_compile_with_default_v_and_check (differencematte->shader
|
||||
[2], vconv7_fragment_source_gles2, &filter->draw_attr_position_loc,
|
||||
&filter->draw_attr_texture_loc)) {
|
||||
gst_gl_context_set_error (GST_GL_BASE_FILTER (differencematte)->context,
|
||||
"Failed to initialize vconv7 shader");
|
||||
if (!(differencematte->shader[2] =
|
||||
gst_gl_shader_new_link_with_stages (context, &error,
|
||||
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,
|
||||
vconv7_fragment_source_gles2), NULL))) {
|
||||
GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s",
|
||||
gst_gl_context_get_error ()), (NULL));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!gst_gl_shader_compile_with_default_v_and_check (differencematte->shader
|
||||
[3], texture_interp_fragment_source, &filter->draw_attr_position_loc,
|
||||
&filter->draw_attr_texture_loc)) {
|
||||
gst_gl_context_set_error (GST_GL_BASE_FILTER (differencematte)->context,
|
||||
"Failed to initialize interp shader");
|
||||
if (!(differencematte->shader[3] =
|
||||
gst_gl_shader_new_link_with_stages (context, &error,
|
||||
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,
|
||||
texture_interp_fragment_source), NULL))) {
|
||||
GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s",
|
||||
gst_gl_context_get_error ()), (NULL));
|
||||
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 */
|
||||
|
|
|
@ -545,21 +545,22 @@ gst_gl_effects_get_fragment_shader (GstGLEffects * effects,
|
|||
shader = g_hash_table_lookup (effects->shaderstable, shader_name);
|
||||
|
||||
if (!shader) {
|
||||
shader = gst_gl_shader_new (context);
|
||||
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;
|
||||
}
|
||||
}
|
||||
GError *error = NULL;
|
||||
|
||||
if (!shader)
|
||||
return NULL;
|
||||
if (!(shader = gst_gl_shader_new_link_with_stages (context, &error,
|
||||
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);
|
||||
|
||||
|
|
|
@ -1682,13 +1682,23 @@ static void
|
|||
gst_glimage_sink_thread_init_redisplay (GstGLImageSink * gl_sink)
|
||||
{
|
||||
const GstGLFuncs *gl = gl_sink->context->gl_vtable;
|
||||
GError *error = NULL;
|
||||
|
||||
gl_sink->redisplay_shader = gst_gl_shader_new (gl_sink->context);
|
||||
|
||||
if (!gst_gl_shader_compile_with_default_vf_and_check
|
||||
(gl_sink->redisplay_shader, &gl_sink->attr_position,
|
||||
&gl_sink->attr_texture))
|
||||
if (!(gl_sink->redisplay_shader =
|
||||
gst_gl_shader_new_link_with_stages (gl_sink->context, &error,
|
||||
gst_glsl_stage_new_default_vertex (gl_sink->context),
|
||||
gst_glsl_stage_new_default_fragment (gl_sink->context), NULL))) {
|
||||
GST_ERROR_OBJECT (gl_sink, "Failed to link shader: %s", error->message);
|
||||
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) {
|
||||
gl->GenVertexArrays (1, &gl_sink->vao);
|
||||
|
|
|
@ -425,12 +425,24 @@ gst_gl_overlay_compositor_init_gl (GstGLContext * context,
|
|||
{
|
||||
GstGLOverlayCompositor *compositor =
|
||||
(GstGLOverlayCompositor *) compositor_pointer;
|
||||
GError *error = NULL;
|
||||
|
||||
if (!gst_gl_shader_compile_with_default_v_and_check (compositor->shader,
|
||||
fragment_shader, &compositor->position_attrib,
|
||||
&compositor->texcoord_attrib)) {
|
||||
GST_ERROR ("could not initialize shader.");
|
||||
if (!(compositor->shader =
|
||||
gst_gl_shader_new_link_with_stages (context, &error,
|
||||
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 | 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 *
|
||||
|
@ -441,8 +453,6 @@ gst_gl_overlay_compositor_new (GstGLContext * context)
|
|||
|
||||
compositor->context = gst_object_ref (context);
|
||||
|
||||
compositor->shader = gst_gl_shader_new (compositor->context);
|
||||
|
||||
gst_gl_context_thread_add (compositor->context,
|
||||
gst_gl_overlay_compositor_init_gl, compositor);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -26,6 +26,7 @@
|
|||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GType gst_gl_shader_get_type (void);
|
||||
#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_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_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 {
|
||||
/*< private >*/
|
||||
GstObject parent;
|
||||
|
@ -53,6 +41,8 @@ struct _GstGLShader {
|
|||
GstGLContext *context;
|
||||
|
||||
GstGLShaderPrivate *priv;
|
||||
|
||||
gpointer _padding[GST_PADDING];
|
||||
};
|
||||
|
||||
struct _GstGLShaderClass {
|
||||
|
@ -60,33 +50,29 @@ struct _GstGLShaderClass {
|
|||
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);
|
||||
GType gst_gl_shader_get_type (void);
|
||||
gboolean gst_gl_shader_attach (GstGLShader * shader, GstGLSLStage * stage);
|
||||
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);
|
||||
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);
|
||||
int gst_gl_shader_get_program_handle (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_use (GstGLShader *shader);
|
||||
void gst_gl_context_clear_shader (GstGLContext *context);
|
||||
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_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_1iv (GstGLShader *shader, const gchar *name, guint count, gint *value);
|
||||
|
|
|
@ -375,20 +375,60 @@ gst_gl_context_del_fbo (GstGLContext * context, GLuint fbo, GLuint depth_buffer)
|
|||
gst_object_unref (frame);
|
||||
}
|
||||
|
||||
static void
|
||||
_compile_shader (GstGLContext * context, GstGLShader ** shader)
|
||||
struct _compile_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;
|
||||
|
||||
gst_gl_shader_compile (*shader, &error);
|
||||
if (error) {
|
||||
gst_gl_context_set_error (context, "%s", error->message);
|
||||
shader = gst_gl_shader_new (context);
|
||||
|
||||
if (data->vertex_src) {
|
||||
vert = gst_glsl_stage_new_with_string (context, GL_VERTEX_SHADER,
|
||||
GST_GLSL_VERSION_NONE, GST_GLSL_PROFILE_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);
|
||||
error = NULL;
|
||||
gst_gl_context_clear_shader (context);
|
||||
gst_object_unref (*shader);
|
||||
*shader = NULL;
|
||||
gst_object_unref (shader);
|
||||
return;
|
||||
}
|
||||
|
||||
*data->shader = shader;
|
||||
}
|
||||
|
||||
/* Called by glfilter */
|
||||
|
@ -396,18 +436,17 @@ gboolean
|
|||
gst_gl_context_gen_shader (GstGLContext * context, const gchar * vert_src,
|
||||
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 (shader != NULL, FALSE);
|
||||
|
||||
*shader = gst_gl_shader_new (context);
|
||||
|
||||
if (frag_src)
|
||||
gst_gl_shader_set_fragment_source (*shader, frag_src);
|
||||
if (vert_src)
|
||||
gst_gl_shader_set_vertex_source (*shader, vert_src);
|
||||
data.shader = shader;
|
||||
data.vertex_src = vert_src;
|
||||
data.fragment_src = frag_src;
|
||||
|
||||
gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _compile_shader,
|
||||
shader);
|
||||
&data);
|
||||
|
||||
return *shader != NULL;
|
||||
}
|
||||
|
|
|
@ -28,29 +28,6 @@
|
|||
|
||||
#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 void
|
||||
|
@ -67,17 +44,15 @@ teardown (void)
|
|||
|
||||
static GLuint fbo_id, rbo, tex;
|
||||
static GstGLFramebuffer *fbo;
|
||||
#if GST_GL_HAVE_GLES2
|
||||
static GError *error;
|
||||
static GstGLShader *shader;
|
||||
static GLint shader_attr_position_loc;
|
||||
static GLint shader_attr_texture_loc;
|
||||
#endif
|
||||
|
||||
static void
|
||||
init (gpointer data)
|
||||
{
|
||||
GstGLContext *context = data;
|
||||
GError *error = NULL;
|
||||
|
||||
/* has to be called in the thread that is going to use the framebuffer */
|
||||
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);
|
||||
fail_if (tex == 0, "failed to create texture");
|
||||
|
||||
#if GST_GL_HAVE_GLES2
|
||||
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");
|
||||
shader = gst_gl_shader_new_default (context, &error);
|
||||
fail_if (shader == NULL, "failed to create shader object: %s",
|
||||
error->message);
|
||||
|
||||
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 =
|
||||
gst_gl_shader_get_attribute_location (shader, "a_position");
|
||||
shader_attr_texture_loc =
|
||||
gst_gl_shader_get_attribute_location (shader, "a_texCoord");
|
||||
}
|
||||
#endif
|
||||
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");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -116,10 +80,7 @@ deinit (gpointer data)
|
|||
GstGLFuncs *gl = context->gl_vtable;
|
||||
gl->DeleteTextures (1, &tex);
|
||||
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);
|
||||
#endif
|
||||
gst_object_unref (shader);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -150,81 +111,38 @@ draw_render (gpointer data)
|
|||
GstGLContext *context = data;
|
||||
GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context);
|
||||
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
|
||||
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->Clear (GL_COLOR_BUFFER_BIT);
|
||||
|
||||
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);
|
||||
gl->LoadIdentity ();
|
||||
/* Load the texture coordinate */
|
||||
gl->VertexAttribPointer (shader_attr_texture_loc, 2,
|
||||
GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]);
|
||||
|
||||
gl->ActiveTexture (GL_TEXTURE0);
|
||||
gl->BindTexture (GL_TEXTURE_2D, tex);
|
||||
gl->EnableVertexAttribArray (shader_attr_position_loc);
|
||||
gl->EnableVertexAttribArray (shader_attr_texture_loc);
|
||||
|
||||
gl->EnableClientState (GL_VERTEX_ARRAY);
|
||||
gl->VertexPointer (2, GL_FLOAT, 0, &verts);
|
||||
gl->ActiveTexture (GL_TEXTURE0);
|
||||
gl->BindTexture (GL_TEXTURE_2D, tex);
|
||||
gst_gl_shader_set_uniform_1i (shader, "s_texture", 0);
|
||||
|
||||
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,
|
||||
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
|
||||
gl->DrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
|
||||
|
||||
context_class->swap_buffers (context);
|
||||
}
|
||||
|
@ -314,6 +232,7 @@ check_wrapped (gpointer data)
|
|||
fail_if (!ret, "error received %s\n",
|
||||
error ? error->message : "Unknown error");
|
||||
fail_if (wrapped_context->gl_vtable->TexImage2D == NULL);
|
||||
gst_gl_context_activate (wrapped_context, FALSE);
|
||||
}
|
||||
|
||||
GST_START_TEST (test_wrapped_context)
|
||||
|
|
|
@ -29,41 +29,14 @@
|
|||
|
||||
#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 GstGLContext *context;
|
||||
static GstGLWindow *window;
|
||||
static GstGLUpload *upload;
|
||||
static guint tex_id;
|
||||
#if GST_GL_HAVE_GLES2
|
||||
static GError *error;
|
||||
static GstGLShader *shader;
|
||||
static GLint shader_attr_position_loc;
|
||||
static GLint shader_attr_texture_loc;
|
||||
#endif
|
||||
|
||||
|
||||
#define FORMAT GST_VIDEO_GL_TEXTURE_TYPE_RGBA
|
||||
#define WIDTH 10
|
||||
|
@ -118,25 +91,15 @@ teardown (void)
|
|||
static void
|
||||
init (gpointer data)
|
||||
{
|
||||
#if GST_GL_HAVE_GLES2
|
||||
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");
|
||||
GError *error = NULL;
|
||||
|
||||
gst_gl_shader_set_vertex_source (shader, vertex_shader_str_gles2);
|
||||
gst_gl_shader_set_fragment_source (shader, fragment_shader_str_gles2);
|
||||
shader = gst_gl_shader_new_default (context, &error);
|
||||
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 =
|
||||
gst_gl_shader_get_attribute_location (shader, "a_position");
|
||||
shader_attr_texture_loc =
|
||||
gst_gl_shader_get_attribute_location (shader, "a_texCoord");
|
||||
}
|
||||
#endif
|
||||
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");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -145,81 +108,38 @@ draw_render (gpointer data)
|
|||
GstGLContext *context = data;
|
||||
GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context);
|
||||
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
|
||||
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->Clear (GL_COLOR_BUFFER_BIT);
|
||||
|
||||
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);
|
||||
gl->LoadIdentity ();
|
||||
/* Load the texture coordinate */
|
||||
gl->VertexAttribPointer (shader_attr_texture_loc, 2,
|
||||
GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]);
|
||||
|
||||
gl->ActiveTexture (GL_TEXTURE_2D);
|
||||
gl->BindTexture (GL_TEXTURE_2D, tex_id);
|
||||
gl->EnableVertexAttribArray (shader_attr_position_loc);
|
||||
gl->EnableVertexAttribArray (shader_attr_texture_loc);
|
||||
|
||||
gl->EnableClientState (GL_VERTEX_ARRAY);
|
||||
gl->VertexPointer (2, GL_FLOAT, 0, &verts);
|
||||
gl->ActiveTexture (GL_TEXTURE0);
|
||||
gl->BindTexture (GL_TEXTURE_2D, tex_id);
|
||||
gst_gl_shader_set_uniform_1i (shader, "s_texture", 0);
|
||||
|
||||
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,
|
||||
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
|
||||
gl->DrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
|
||||
|
||||
context_class->swap_buffers (context);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue