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:
@@ -382,11 +382,15 @@ void ViewerDisplayWidget::OnPaint()
|
||||
bg_color.blueF());
|
||||
|
||||
// We only draw if we have a pipeline
|
||||
qDebug() << "[VIEWER] OnPaint push_mode=" << push_mode_
|
||||
<< "color_service=" << (color_service() != nullptr)
|
||||
<< "has_load_frame=" << !load_frame_.isNull();
|
||||
if (push_mode_ != kPushNull) {
|
||||
// Draw texture through color transform
|
||||
VideoParams device_params = GetViewportParams();
|
||||
|
||||
if (push_mode_ == kPushBlank) {
|
||||
qDebug() << "[VIEWER] OnPaint drawing blank";
|
||||
DrawBlank(device_params);
|
||||
} else if (color_service()) {
|
||||
if (FramePtr frame = load_frame_.value<FramePtr>()) {
|
||||
@@ -490,7 +494,10 @@ void ViewerDisplayWidget::OnPaint()
|
||||
ctj.SetForceOpaque(true);
|
||||
|
||||
renderer()->BlitColorManaged(ctj, device_params);
|
||||
qDebug() << "[VIEWER] OnPaint BlitColorManaged done";
|
||||
}
|
||||
} else {
|
||||
qDebug() << "[VIEWER] OnPaint no color_service, skipping texture draw";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user