From: Steinar H. Gunderson Date: Sun, 12 Jan 2014 22:51:21 +0000 (+0100) Subject: Add back automatic cleanup of OpenGL fences. X-Git-Url: https://git.sesse.net/?p=mlt;a=commitdiff_plain;h=cfa126d75a26e7a9e793134b7f1ccf9d2be9ee82 Add back automatic cleanup of OpenGL fences. Instead of having the client do deletion of fences, work around the problem with missing contexts by adding them to a list in the GlslManager, which then it garbage-collected before creating more fences. --- diff --git a/src/modules/opengl/filter_glsl_manager.cpp b/src/modules/opengl/filter_glsl_manager.cpp index 72ca55af..9cb0855c 100644 --- a/src/modules/opengl/filter_glsl_manager.cpp +++ b/src/modules/opengl/filter_glsl_manager.cpp @@ -80,6 +80,10 @@ GlslManager::~GlslManager() if (prev_sync != NULL) { glDeleteSync( prev_sync ); } + while (syncs_to_delete.count() > 0) { + GLsync sync = (GLsync) syncs_to_delete.pop_front(); + glDeleteSync( sync ); + } } GlslManager* GlslManager::get_instance() @@ -198,6 +202,17 @@ void GlslManager::release_texture(glsl_texture texture) texture->used = 0; } +void GlslManager::delete_sync(GLsync sync) +{ + // We do not know which thread we are called from, and we can only + // delete this if we are in one with a valid OpenGL context. + // Thus, store it for later deletion in render_frame_texture(). + GlslManager* g = GlslManager::get_instance(); + g->lock(); + g->syncs_to_delete.push_back(sync); + g->unlock(); +} + glsl_pbo GlslManager::get_pbo(int size) { lock(); @@ -412,6 +427,13 @@ int GlslManager::render_frame_texture(mlt_service service, mlt_frame frame, int glBindFramebuffer( GL_FRAMEBUFFER, 0 ); check_error(); + lock(); + while (syncs_to_delete.count() > 0) { + GLsync sync = (GLsync) syncs_to_delete.pop_front(); + glDeleteSync( sync ); + } + unlock(); + // Make sure we never have more than one frame pending at any time. // This ensures we do not swamp the GPU with so much work // that we cannot actually display the frames we generate. @@ -433,7 +455,8 @@ int GlslManager::render_frame_texture(mlt_service service, mlt_frame frame, int mlt_frame_set_image( frame, *image, 0, NULL ); mlt_properties_set_data( MLT_FRAME_PROPERTIES(frame), "movit.convert.texture", texture, 0, (mlt_destructor) GlslManager::release_texture, NULL ); - mlt_properties_set_data( MLT_FRAME_PROPERTIES(frame), "movit.convert.fence", sync, 0, NULL, NULL ); + mlt_properties_set_data( MLT_FRAME_PROPERTIES(frame), "movit.convert.fence", sync, 0, + (mlt_destructor) GlslManager::delete_sync, NULL ); return 0; } diff --git a/src/modules/opengl/filter_glsl_manager.h b/src/modules/opengl/filter_glsl_manager.h index 5263e5cb..4bc3836b 100644 --- a/src/modules/opengl/filter_glsl_manager.h +++ b/src/modules/opengl/filter_glsl_manager.h @@ -104,6 +104,7 @@ private: static void onPropertyChanged( mlt_properties owner, mlt_service service, const char* property ); Mlt::Deque fbo_list; Mlt::Deque texture_list; + Mlt::Deque syncs_to_delete; glsl_pbo pbo; Mlt::Event* initEvent; Mlt::Event* closeEvent;