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().
This commit is contained in:
Matthew Waters 2016-07-12 12:59:57 +10:00
parent c8c016ed17
commit 5a74878988
5 changed files with 59 additions and 36 deletions

View file

@ -410,8 +410,6 @@ static void
gst_gl_mixer_init (GstGLMixer * mix) gst_gl_mixer_init (GstGLMixer * mix)
{ {
mix->priv = GST_GL_MIXER_GET_PRIVATE (mix); mix->priv = GST_GL_MIXER_GET_PRIVATE (mix);
mix->fbo = 0;
mix->depthbuffer = 0;
mix->priv->gl_resource_ready = FALSE; mix->priv->gl_resource_ready = FALSE;
g_mutex_init (&mix->priv->gl_resource_lock); g_mutex_init (&mix->priv->gl_resource_lock);
@ -512,33 +510,38 @@ gst_gl_mixer_get_output_buffer (GstVideoAggregator * videoaggregator,
return ret; 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 static gboolean
gst_gl_mixer_decide_allocation (GstGLBaseMixer * base_mix, GstQuery * query) gst_gl_mixer_decide_allocation (GstGLBaseMixer * base_mix, GstQuery * query)
{ {
GstGLMixer *mix = GST_GL_MIXER (base_mix); GstGLMixer *mix = GST_GL_MIXER (base_mix);
GstGLMixerClass *mixer_class = GST_GL_MIXER_GET_CLASS (mix); GstGLMixerClass *mixer_class = GST_GL_MIXER_GET_CLASS (mix);
GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (mix);
GstGLContext *context = base_mix->context; GstGLContext *context = base_mix->context;
GstBufferPool *pool = NULL; GstBufferPool *pool = NULL;
GstStructure *config; GstStructure *config;
GstCaps *caps; GstCaps *caps;
guint min, max, size; guint min, max, size;
gboolean update_pool; 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); g_mutex_lock (&mix->priv->gl_resource_lock);
mix->priv->gl_resource_ready = FALSE; mix->priv->gl_resource_ready = FALSE;
if (mix->fbo) { if (mix->fbo)
gst_gl_context_del_fbo (context, mix->fbo, mix->depthbuffer); gst_object_unref (mix->fbo);
mix->fbo = 0;
mix->depthbuffer = 0;
}
if (!gst_gl_context_gen_fbo (context, out_width, out_height, gst_gl_context_thread_add (context,
&mix->fbo, &mix->depthbuffer)) { (GstGLContextThreadFunc) _mixer_create_fbo, mix);
if (!mix->fbo) {
g_cond_signal (&mix->priv->gl_resource_cond); g_cond_signal (&mix->priv->gl_resource_cond);
g_mutex_unlock (&mix->priv->gl_resource_lock); g_mutex_unlock (&mix->priv->gl_resource_lock);
goto context_error; goto context_error;
@ -735,14 +738,13 @@ gst_gl_mixer_stop (GstAggregator * agg)
{ {
GstGLMixer *mix = GST_GL_MIXER (agg); GstGLMixer *mix = GST_GL_MIXER (agg);
GstGLMixerClass *mixer_class = GST_GL_MIXER_GET_CLASS (mix); GstGLMixerClass *mixer_class = GST_GL_MIXER_GET_CLASS (mix);
GstGLContext *context = GST_GL_BASE_MIXER (mix)->context;
if (mixer_class->reset) if (mixer_class->reset)
mixer_class->reset (mix); mixer_class->reset (mix);
if (mix->fbo) { if (mix->fbo) {
gst_gl_context_del_fbo (context, mix->fbo, mix->depthbuffer); gst_object_unref (mix->fbo);
mix->fbo = 0; mix->fbo = NULL;
mix->depthbuffer = 0;
} }
gst_gl_mixer_reset (mix); gst_gl_mixer_reset (mix);

View file

@ -84,8 +84,7 @@ struct _GstGLMixer
{ {
GstGLBaseMixer vaggregator; GstGLBaseMixer vaggregator;
GLuint fbo; GstGLFramebuffer *fbo;
GLuint depthbuffer;
GstCaps *out_caps; GstCaps *out_caps;

View file

@ -71,7 +71,7 @@ static gboolean gst_gl_mosaic_init_shader (GstGLMixer * mixer,
static gboolean gst_gl_mosaic_process_textures (GstGLMixer * mixer, static gboolean gst_gl_mosaic_process_textures (GstGLMixer * mixer,
GstGLMemory * out_tex); GstGLMemory * out_tex);
static void gst_gl_mosaic_callback (gpointer stuff); static gboolean gst_gl_mosaic_callback (gpointer stuff);
//vertex source //vertex source
static const gchar *mosaic_v_src = 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); 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 static gboolean
gst_gl_mosaic_process_textures (GstGLMixer * mix, GstGLMemory * out_tex) gst_gl_mosaic_process_textures (GstGLMixer * mix, GstGLMemory * out_tex)
{ {
GstGLMosaic *mosaic = GST_GL_MOSAIC (mix); GstGLMosaic *mosaic = GST_GL_MOSAIC (mix);
GstGLContext *context = GST_GL_BASE_MIXER (mix)->context;
//blocking call, use a FBO mosaic->out_tex = out_tex;
gst_gl_context_use_fbo_v2 (GST_GL_BASE_MIXER (mix)->context,
GST_VIDEO_INFO_WIDTH (&GST_VIDEO_AGGREGATOR (mix)->info), gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _mosaic_render,
GST_VIDEO_INFO_HEIGHT (&GST_VIDEO_AGGREGATOR (mix)->info), mix->fbo, mosaic);
mix->depthbuffer, out_tex->tex_id, gst_gl_mosaic_callback,
(gpointer) mosaic);
return TRUE; return TRUE;
} }
/* opengl scene, params: input texture (not the output mixer->texture) */ /* opengl scene, params: input texture (not the output mixer->texture) */
static void static gboolean
gst_gl_mosaic_callback (gpointer stuff) gst_gl_mosaic_callback (gpointer stuff)
{ {
GstGLMosaic *mosaic = GST_GL_MOSAIC (stuff); GstGLMosaic *mosaic = GST_GL_MOSAIC (stuff);
@ -345,4 +353,6 @@ gst_gl_mosaic_callback (gpointer stuff)
xrot += 0.6f; xrot += 0.6f;
yrot += 0.4f; yrot += 0.4f;
zrot += 0.8f; zrot += 0.8f;
return TRUE;
} }

View file

@ -475,7 +475,7 @@ static gboolean gst_gl_video_mixer_init_shader (GstGLMixer * mixer,
static gboolean gst_gl_video_mixer_process_textures (GstGLMixer * mixer, static gboolean gst_gl_video_mixer_process_textures (GstGLMixer * mixer,
GstGLMemory * out_tex); GstGLMemory * out_tex);
static void gst_gl_video_mixer_callback (gpointer stuff); static gboolean gst_gl_video_mixer_callback (gpointer stuff);
/* *INDENT-OFF* */ /* *INDENT-OFF* */
@ -1155,16 +1155,25 @@ gst_gl_video_mixer_init_shader (GstGLMixer * mixer, GstCaps * outcaps)
video_mixer_f_src, &video_mixer->shader); 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 static gboolean
gst_gl_video_mixer_process_textures (GstGLMixer * mix, GstGLMemory * out_tex) gst_gl_video_mixer_process_textures (GstGLMixer * mix, GstGLMemory * out_tex)
{ {
GstGLVideoMixer *video_mixer = GST_GL_VIDEO_MIXER (mix); 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, video_mixer->out_tex = out_tex;
GST_VIDEO_INFO_WIDTH (&GST_VIDEO_AGGREGATOR (mix)->info),
GST_VIDEO_INFO_HEIGHT (&GST_VIDEO_AGGREGATOR (mix)->info), gst_gl_context_thread_add (context,
mix->fbo, mix->depthbuffer, (GstGLContextThreadFunc) _video_mixer_process_gl, video_mixer);
out_tex->tex_id, gst_gl_video_mixer_callback, (gpointer) video_mixer);
return TRUE; 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) */ /* opengl scene, params: input texture (not the output mixer->texture) */
static void static gboolean
gst_gl_video_mixer_callback (gpointer stuff) gst_gl_video_mixer_callback (gpointer stuff)
{ {
GstGLVideoMixer *video_mixer = GST_GL_VIDEO_MIXER (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)) if (!_draw_background (video_mixer))
return; return FALSE;
gst_gl_shader_use (video_mixer->shader); gst_gl_shader_use (video_mixer->shader);
@ -1546,4 +1555,6 @@ gst_gl_video_mixer_callback (gpointer stuff)
gl->Disable (GL_BLEND); gl->Disable (GL_BLEND);
gst_gl_context_clear_shader (GST_GL_BASE_MIXER (mixer)->context); gst_gl_context_clear_shader (GST_GL_BASE_MIXER (mixer)->context);
return TRUE;
} }

View file

@ -125,6 +125,7 @@ struct _GstGLVideoMixer
GLuint vao; GLuint vao;
GLuint vbo_indices; GLuint vbo_indices;
GLuint checker_vbo; GLuint checker_vbo;
GstGLMemory *out_tex;
}; };
struct _GstGLVideoMixerClass struct _GstGLVideoMixerClass