fix(renderer): macOS TBDR cross-context sync and OFX instance thread-safety
This commit fixes crashes (SIGSEGV in CImg blur_bilateral) and black-frame corruption artifacts during playback and scrubbing on macOS Apple Silicon. Root cause analysis: 1. macOS uses Tile-Based Deferred Rendering (TBDR). glFlush() does not guarantee tile memory writeback, causing glReadPixels to read incomplete tiles (black/corrupted frames) and cache them to disk. 2. Olive uses multiple shared OpenGL contexts (RenderProcessor contexts vs. thread-local PluginRenderer context). glFinish() only waits for the current context, not the shared context that produced the texture. CPU readback in PluginRenderer could read partially-rendered tiles. 3. OlivePluginInstance and OliveClipInstance are not thread-safe. Concurrent RenderProcessors could corrupt internal QMap/images_ and params_ via setInputTexture/renderAction races. Fixes: - OpenGLRenderer::Flush() on macOS now uses glFinish() unconditionally. - OpenGLRenderer::DownloadFromTexture() and OpenGLRenderer::Blit() insert glFinish() before readback/detach to ensure tile writeback completes. - PluginRenderer::RenderPlugin() now acquires a per-instance mutex to serialize concurrent OFX render calls. - Before CPU readback in PluginRenderer, flush the renderer that originally produced each input texture, ensuring cross-context synchronization. - RenderProcessor::ProcessVideoFootage() flushes after BlitColorManaged. - Add black-frame detection in ProcessVideoCacheJob() to auto-purge TBDR- corrupted cache files. - Add diagnostic qDebug() logging in viewer, decoder, renderer, and plugin paths to aid future debugging.
This commit is contained in:
@@ -370,6 +370,9 @@ void OpenGLRenderer::DownloadFromTexture(const QVariant &id,
|
||||
|
||||
functions_->glPixelStorei(GL_PACK_ROW_LENGTH, linesize);
|
||||
|
||||
// Ensure all rendering is complete before reading back on TBDR architectures (macOS)
|
||||
functions_->glFinish();
|
||||
|
||||
{
|
||||
PRINT_GL_ERRORS;
|
||||
functions_->glReadPixels(0, 0, p.effective_width(),
|
||||
@@ -392,7 +395,14 @@ void OpenGLRenderer::Flush()
|
||||
if (OLIVE_CONFIG("UseGLFinish").toBool()) {
|
||||
functions_->glFinish();
|
||||
} else {
|
||||
#if defined(Q_OS_MAC)
|
||||
// macOS uses Tile-Based Deferred Rendering (TBDR). glFlush() does not
|
||||
// guarantee that tile memory has been written back to texture memory.
|
||||
// Using glFinish() prevents partial tile corruption ("black ink" artifacts).
|
||||
functions_->glFinish();
|
||||
#else
|
||||
functions_->glFlush();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user