From f0d2346c52f2b87de4e02eb274b73b50cbb30f8e Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Tue, 21 Oct 2014 22:18:51 +1100 Subject: [PATCH] glimagesink: use vbo's and vao's for gl3 --- ext/gl/gstglimagesink.c | 164 ++++++++++++++++------------------------ ext/gl/gstglimagesink.h | 9 +-- 2 files changed, 68 insertions(+), 105 deletions(-) diff --git a/ext/gl/gstglimagesink.c b/ext/gl/gstglimagesink.c index 1c3a7c49f2..7966819c9b 100644 --- a/ext/gl/gstglimagesink.c +++ b/ext/gl/gstglimagesink.c @@ -111,9 +111,8 @@ GST_DEBUG_CATEGORY (gst_debug_glimage_sink); #define USING_GLES2(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 2, 0)) #define USING_GLES3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0)) -#if GST_GL_HAVE_GLES2 static void gst_glimage_sink_thread_init_redisplay (GstGLImageSink * gl_sink); -#endif +static void gst_glimage_sink_cleanup_glthread (GstGLImageSink * gl_sink); static void gst_glimage_sink_on_close (GstGLImageSink * gl_sink); static void gst_glimage_sink_on_resize (GstGLImageSink * gl_sink, gint width, gint height); @@ -595,21 +594,6 @@ gst_glimage_sink_query (GstBaseSink * bsink, GstQuery * query) return res; } -static void -gst_glimage_sink_cleanup_glthread (GstGLImageSink * gl_sink) -{ -#if GST_GL_HAVE_GLES2 - if (gl_sink->redisplay_shader) { - gst_object_unref (gl_sink->redisplay_shader); - gl_sink->redisplay_shader = NULL; - } -#endif -} - -/* - * GstElement methods - */ - static gboolean gst_glimage_sink_stop (GstBaseSink * bsink) { @@ -1162,19 +1146,63 @@ config_failed: } } -#if GST_GL_HAVE_GLES2 +/* *INDENT-OFF* */ +static const GLfloat vertices[] = { + 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 +}; +/* *INDENT-ON* */ + /* Called in the gl thread */ static void gst_glimage_sink_thread_init_redisplay (GstGLImageSink * gl_sink) { + const GstGLFuncs *gl = gl_sink->context->gl_vtable; + int attr_position, attr_texture; + 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->redisplay_attr_position_loc, - &gl_sink->redisplay_attr_texture_loc)) + (gl_sink->redisplay_shader, &attr_position, &attr_texture)) gst_glimage_sink_cleanup_glthread (gl_sink); + + gl->GenVertexArrays (1, &gl_sink->vao); + gl->BindVertexArray (gl_sink->vao); + + gl->GenBuffers (1, &gl_sink->vertex_buffer); + gl->BindBuffer (GL_ARRAY_BUFFER, gl_sink->vertex_buffer); + gl->BufferData (GL_ARRAY_BUFFER, 4 * 5 * sizeof (GLfloat), vertices, + GL_STATIC_DRAW); + + /* Load the vertex position */ + gl->VertexAttribPointer (attr_position, 3, GL_FLOAT, GL_FALSE, + 5 * sizeof (GLfloat), (void *) 0); + + /* Load the texture coordinate */ + gl->VertexAttribPointer (attr_texture, 2, GL_FLOAT, GL_FALSE, + 5 * sizeof (GLfloat), (void *) (3 * sizeof (GLfloat))); + + gl->EnableVertexAttribArray (attr_position); + gl->EnableVertexAttribArray (attr_texture); + + gl->BindVertexArray (0); + gl->BindBuffer (GL_ARRAY_BUFFER, 0); +} + +static void +gst_glimage_sink_cleanup_glthread (GstGLImageSink * gl_sink) +{ + const GstGLFuncs *gl = gl_sink->context->gl_vtable; + + if (gl_sink->redisplay_shader) { + gst_object_unref (gl_sink->redisplay_shader); + gl_sink->redisplay_shader = NULL; + } + + gl->DeleteVertexArrays (1, &gl_sink->vao); } -#endif static void gst_glimage_sink_on_resize (GstGLImageSink * gl_sink, gint width, gint height) @@ -1228,7 +1256,6 @@ gst_glimage_sink_on_resize (GstGLImageSink * gl_sink, gint width, gint height) } } - static void gst_glimage_sink_on_draw (GstGLImageSink * gl_sink) { @@ -1285,78 +1312,22 @@ gst_glimage_sink_on_draw (GstGLImageSink * gl_sink) GST_VIDEO_INFO_HEIGHT (&gl_sink->info), &do_redisplay); if (!do_redisplay) { -#if GST_GL_HAVE_OPENGL - if (USING_OPENGL (gl_sink->context)) { - 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 - }; + GLushort indices[] = { 0, 1, 2, 0, 2, 3 }; - gl->ClearColor (0.0, 0.0, 0.0, 0.0); - gl->Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + gl->ClearColor (0.0, 0.0, 0.0, 0.0); + gl->Clear (GL_COLOR_BUFFER_BIT); - gl->MatrixMode (GL_PROJECTION); - gl->LoadIdentity (); + gst_gl_shader_use (gl_sink->redisplay_shader); - gl->Enable (GL_TEXTURE_2D); - gl->BindTexture (GL_TEXTURE_2D, gl_sink->redisplay_texture); + gl->BindVertexArray (gl_sink->vao); - gl->EnableClientState (GL_VERTEX_ARRAY); - gl->EnableClientState (GL_TEXTURE_COORD_ARRAY); - gl->VertexPointer (2, GL_FLOAT, 0, &verts); - gl->TexCoordPointer (2, GL_FLOAT, 0, &texcoords); + gl->ActiveTexture (GL_TEXTURE0); + gl->BindTexture (GL_TEXTURE_2D, gl_sink->redisplay_texture); + gst_gl_shader_set_uniform_1i (gl_sink->redisplay_shader, "tex", 0); - gl->DrawArrays (GL_TRIANGLE_FAN, 0, 4); + gl->DrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices); - gl->DisableClientState (GL_VERTEX_ARRAY); - gl->DisableClientState (GL_TEXTURE_COORD_ARRAY); - - gl->Disable (GL_TEXTURE_2D); - } -#endif -#if GST_GL_HAVE_GLES2 - if (USING_GLES2 (gl_sink->context)) { - 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->ClearColor (0.0, 0.0, 0.0, 0.0); - gl->Clear (GL_COLOR_BUFFER_BIT); - - gst_gl_shader_use (gl_sink->redisplay_shader); - - /* Load the vertex position */ - gl->VertexAttribPointer (gl_sink->redisplay_attr_position_loc, 3, - GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), vVertices); - - /* Load the texture coordinate */ - gl->VertexAttribPointer (gl_sink->redisplay_attr_texture_loc, 2, - GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]); - - gl->EnableVertexAttribArray (gl_sink->redisplay_attr_position_loc); - gl->EnableVertexAttribArray (gl_sink->redisplay_attr_texture_loc); - - gl->ActiveTexture (GL_TEXTURE0); - gl->BindTexture (GL_TEXTURE_2D, gl_sink->redisplay_texture); - gst_gl_shader_set_uniform_1i (gl_sink->redisplay_shader, "tex", 0); - - gl->DrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices); - } -#endif + gl->BindVertexArray (0); } /* end default opengl scene */ window->is_drawing = FALSE; @@ -1393,21 +1364,16 @@ gst_glimage_sink_redisplay (GstGLImageSink * gl_sink) return FALSE; if (gst_gl_window_is_running (window)) { + if (G_UNLIKELY (!gl_sink->redisplay_shader)) { + gst_gl_window_send_message (window, + GST_GL_WINDOW_CB (gst_glimage_sink_thread_init_redisplay), gl_sink); -#if GST_GL_HAVE_GLES2 - if (USING_GLES2 (gl_sink->context)) { + /* if the shader is still null it means it failed to be useable */ if (G_UNLIKELY (!gl_sink->redisplay_shader)) { - gst_gl_window_send_message (window, - GST_GL_WINDOW_CB (gst_glimage_sink_thread_init_redisplay), gl_sink); - - /* if the shader is still null it means it failed to be useable */ - if (G_UNLIKELY (!gl_sink->redisplay_shader)) { - gst_object_unref (window); - return FALSE; - } + gst_object_unref (window); + return FALSE; } } -#endif /* Drawing is asynchronous: gst_gl_window_draw is not blocking * It means that it does not wait for stuff to be executed in other threads diff --git a/ext/gl/gstglimagesink.h b/ext/gl/gstglimagesink.h index c6fd4d8ae3..12d729308f 100644 --- a/ext/gl/gstglimagesink.h +++ b/ext/gl/gstglimagesink.h @@ -87,12 +87,9 @@ struct _GstGLImageSink guint window_width; guint window_height; -#if GST_GL_HAVE_GLES2 - GstGLShader *redisplay_shader; - GLint redisplay_attr_position_loc; - GLint redisplay_attr_texture_loc; -#endif - + GstGLShader *redisplay_shader; + GLuint vao; + GLuint vertex_buffer; }; struct _GstGLImageSinkClass