From 5a74878988db8d82eba1da78cb325018b031c080 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Tue, 12 Jul 2016 12:59:57 +1000 Subject: [PATCH] glframebuffer: rewrite for a more consistent API Facilities are given to create fbo's and attach GL memory (renderbuffers or textures). It also keeps track of the renderable size for use with effective use with glViewport(). --- ext/gl/gstglmixer.c | 38 ++++++++++++++++++++------------------ ext/gl/gstglmixer.h | 3 +-- ext/gl/gstglmosaic.c | 26 ++++++++++++++++++-------- ext/gl/gstglvideomixer.c | 27 +++++++++++++++++++-------- ext/gl/gstglvideomixer.h | 1 + 5 files changed, 59 insertions(+), 36 deletions(-) diff --git a/ext/gl/gstglmixer.c b/ext/gl/gstglmixer.c index f9c22a1d2e..3fc5aa6f50 100644 --- a/ext/gl/gstglmixer.c +++ b/ext/gl/gstglmixer.c @@ -410,8 +410,6 @@ static void gst_gl_mixer_init (GstGLMixer * mix) { mix->priv = GST_GL_MIXER_GET_PRIVATE (mix); - mix->fbo = 0; - mix->depthbuffer = 0; mix->priv->gl_resource_ready = FALSE; g_mutex_init (&mix->priv->gl_resource_lock); @@ -512,33 +510,38 @@ gst_gl_mixer_get_output_buffer (GstVideoAggregator * videoaggregator, return ret; } +static void +_mixer_create_fbo (GstGLContext * context, GstGLMixer * mix) +{ + GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (mix); + guint out_width = GST_VIDEO_INFO_WIDTH (&vagg->info); + guint out_height = GST_VIDEO_INFO_HEIGHT (&vagg->info); + + mix->fbo = + gst_gl_framebuffer_new_with_default_depth (context, out_width, + out_height); +} + static gboolean gst_gl_mixer_decide_allocation (GstGLBaseMixer * base_mix, GstQuery * query) { GstGLMixer *mix = GST_GL_MIXER (base_mix); GstGLMixerClass *mixer_class = GST_GL_MIXER_GET_CLASS (mix); - GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (mix); GstGLContext *context = base_mix->context; GstBufferPool *pool = NULL; GstStructure *config; GstCaps *caps; guint min, max, size; gboolean update_pool; - guint out_width, out_height; - - out_width = GST_VIDEO_INFO_WIDTH (&vagg->info); - out_height = GST_VIDEO_INFO_HEIGHT (&vagg->info); g_mutex_lock (&mix->priv->gl_resource_lock); mix->priv->gl_resource_ready = FALSE; - if (mix->fbo) { - gst_gl_context_del_fbo (context, mix->fbo, mix->depthbuffer); - mix->fbo = 0; - mix->depthbuffer = 0; - } + if (mix->fbo) + gst_object_unref (mix->fbo); - if (!gst_gl_context_gen_fbo (context, out_width, out_height, - &mix->fbo, &mix->depthbuffer)) { + gst_gl_context_thread_add (context, + (GstGLContextThreadFunc) _mixer_create_fbo, mix); + if (!mix->fbo) { g_cond_signal (&mix->priv->gl_resource_cond); g_mutex_unlock (&mix->priv->gl_resource_lock); goto context_error; @@ -735,14 +738,13 @@ gst_gl_mixer_stop (GstAggregator * agg) { GstGLMixer *mix = GST_GL_MIXER (agg); GstGLMixerClass *mixer_class = GST_GL_MIXER_GET_CLASS (mix); - GstGLContext *context = GST_GL_BASE_MIXER (mix)->context; if (mixer_class->reset) mixer_class->reset (mix); + if (mix->fbo) { - gst_gl_context_del_fbo (context, mix->fbo, mix->depthbuffer); - mix->fbo = 0; - mix->depthbuffer = 0; + gst_object_unref (mix->fbo); + mix->fbo = NULL; } gst_gl_mixer_reset (mix); diff --git a/ext/gl/gstglmixer.h b/ext/gl/gstglmixer.h index de5a3dc4ef..309f6bbf0c 100644 --- a/ext/gl/gstglmixer.h +++ b/ext/gl/gstglmixer.h @@ -84,8 +84,7 @@ struct _GstGLMixer { GstGLBaseMixer vaggregator; - GLuint fbo; - GLuint depthbuffer; + GstGLFramebuffer *fbo; GstCaps *out_caps; diff --git a/ext/gl/gstglmosaic.c b/ext/gl/gstglmosaic.c index 701435f804..41441b0649 100644 --- a/ext/gl/gstglmosaic.c +++ b/ext/gl/gstglmosaic.c @@ -71,7 +71,7 @@ static gboolean gst_gl_mosaic_init_shader (GstGLMixer * mixer, static gboolean gst_gl_mosaic_process_textures (GstGLMixer * mixer, GstGLMemory * out_tex); -static void gst_gl_mosaic_callback (gpointer stuff); +static gboolean gst_gl_mosaic_callback (gpointer stuff); //vertex source static const gchar *mosaic_v_src = @@ -193,23 +193,31 @@ gst_gl_mosaic_init_shader (GstGLMixer * mixer, GstCaps * outcaps) mosaic_v_src, mosaic_f_src, &mosaic->shader); } +static void +_mosaic_render (GstGLContext * context, GstGLMosaic * mosaic) +{ + GstGLMixer *mixer = GST_GL_MIXER (mosaic); + + gst_gl_framebuffer_draw_to_texture (mixer->fbo, mosaic->out_tex, + gst_gl_mosaic_callback, mosaic); +} + static gboolean gst_gl_mosaic_process_textures (GstGLMixer * mix, GstGLMemory * out_tex) { GstGLMosaic *mosaic = GST_GL_MOSAIC (mix); + GstGLContext *context = GST_GL_BASE_MIXER (mix)->context; - //blocking call, use a FBO - gst_gl_context_use_fbo_v2 (GST_GL_BASE_MIXER (mix)->context, - GST_VIDEO_INFO_WIDTH (&GST_VIDEO_AGGREGATOR (mix)->info), - GST_VIDEO_INFO_HEIGHT (&GST_VIDEO_AGGREGATOR (mix)->info), mix->fbo, - mix->depthbuffer, out_tex->tex_id, gst_gl_mosaic_callback, - (gpointer) mosaic); + mosaic->out_tex = out_tex; + + gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _mosaic_render, + mosaic); return TRUE; } /* opengl scene, params: input texture (not the output mixer->texture) */ -static void +static gboolean gst_gl_mosaic_callback (gpointer stuff) { GstGLMosaic *mosaic = GST_GL_MOSAIC (stuff); @@ -345,4 +353,6 @@ gst_gl_mosaic_callback (gpointer stuff) xrot += 0.6f; yrot += 0.4f; zrot += 0.8f; + + return TRUE; } diff --git a/ext/gl/gstglvideomixer.c b/ext/gl/gstglvideomixer.c index 176d27e547..4491823d13 100644 --- a/ext/gl/gstglvideomixer.c +++ b/ext/gl/gstglvideomixer.c @@ -475,7 +475,7 @@ static gboolean gst_gl_video_mixer_init_shader (GstGLMixer * mixer, static gboolean gst_gl_video_mixer_process_textures (GstGLMixer * mixer, GstGLMemory * out_tex); -static void gst_gl_video_mixer_callback (gpointer stuff); +static gboolean gst_gl_video_mixer_callback (gpointer stuff); /* *INDENT-OFF* */ @@ -1155,16 +1155,25 @@ gst_gl_video_mixer_init_shader (GstGLMixer * mixer, GstCaps * outcaps) video_mixer_f_src, &video_mixer->shader); } +static void +_video_mixer_process_gl (GstGLContext * context, GstGLVideoMixer * video_mixer) +{ + GstGLMixer *mixer = GST_GL_MIXER (video_mixer); + + gst_gl_framebuffer_draw_to_texture (mixer->fbo, video_mixer->out_tex, + gst_gl_video_mixer_callback, video_mixer); +} + static gboolean gst_gl_video_mixer_process_textures (GstGLMixer * mix, GstGLMemory * out_tex) { GstGLVideoMixer *video_mixer = GST_GL_VIDEO_MIXER (mix); + GstGLContext *context = GST_GL_BASE_MIXER (mix)->context; - gst_gl_context_use_fbo_v2 (GST_GL_BASE_MIXER (mix)->context, - GST_VIDEO_INFO_WIDTH (&GST_VIDEO_AGGREGATOR (mix)->info), - GST_VIDEO_INFO_HEIGHT (&GST_VIDEO_AGGREGATOR (mix)->info), - mix->fbo, mix->depthbuffer, - out_tex->tex_id, gst_gl_video_mixer_callback, (gpointer) video_mixer); + video_mixer->out_tex = out_tex; + + gst_gl_context_thread_add (context, + (GstGLContextThreadFunc) _video_mixer_process_gl, video_mixer); return TRUE; } @@ -1383,7 +1392,7 @@ _set_blend_state (GstGLVideoMixer * video_mixer, GstGLVideoMixerPad * mix_pad) } /* opengl scene, params: input texture (not the output mixer->texture) */ -static void +static gboolean gst_gl_video_mixer_callback (gpointer stuff) { GstGLVideoMixer *video_mixer = GST_GL_VIDEO_MIXER (stuff); @@ -1411,7 +1420,7 @@ gst_gl_video_mixer_callback (gpointer stuff) } if (!_draw_background (video_mixer)) - return; + return FALSE; gst_gl_shader_use (video_mixer->shader); @@ -1546,4 +1555,6 @@ gst_gl_video_mixer_callback (gpointer stuff) gl->Disable (GL_BLEND); gst_gl_context_clear_shader (GST_GL_BASE_MIXER (mixer)->context); + + return TRUE; } diff --git a/ext/gl/gstglvideomixer.h b/ext/gl/gstglvideomixer.h index a0776fd9fc..f3526465eb 100644 --- a/ext/gl/gstglvideomixer.h +++ b/ext/gl/gstglvideomixer.h @@ -125,6 +125,7 @@ struct _GstGLVideoMixer GLuint vao; GLuint vbo_indices; GLuint checker_vbo; + GstGLMemory *out_tex; }; struct _GstGLVideoMixerClass