Doing a flush every frame caused a crash in certain cases; only do it when necessary.

This commit is contained in:
Stephen Anthony
2026-05-14 12:18:08 -02:30
parent 42f16ce2c8
commit 37e84036f6
5 changed files with 21 additions and 7 deletions
+8 -6
View File
@@ -698,15 +698,17 @@ void FBBackendSDL::clear()
{
ASSERT_MAIN_THREAD;
// SDL3 Metal: flush before clear so any preceding GEOMETRY commands land in
// their own command queue. METAL_RunCommandQueue does not reset the texture
// statecache on CLEAR, so a subsequent GEOMETRY with the same scale/address
// mode skips sampler re-binding on the freshly-created encoder → Metal API
// Validation abort. Flushing here guarantees a fresh statecache after CLEAR.
SDL_FlushRenderer(myRenderer);
SDL_RenderClear(myRenderer);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBBackendSDL::flush()
{
ASSERT_MAIN_THREAD;
SDL_FlushRenderer(myRenderer);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBBackendSDL::detectFeatures()
{
+1
View File
@@ -136,6 +136,7 @@ class FBBackendSDL : public FBBackend
Clear the frame buffer.
*/
void clear() override;
void flush() override;
/**
This method is called to query and initialize the video hardware
+8
View File
@@ -85,6 +85,14 @@ class FBBackend
*/
virtual void clear() = 0;
/**
Flush pending render commands without presenting. Used to ensure a
clean command-queue boundary before clear() in dialog rendering, so
any preceding geometry from the previous frame lands in its own
command queue rather than sharing a queue with the subsequent clear.
*/
virtual void flush() = 0;
/**
Updates window title.
+1
View File
@@ -383,6 +383,7 @@ class FrameBuffer
Clear the framebuffer.
*/
void clear() { myBackend->clear(); }
void flush() { myBackend->flush(); }
/**
Transform from window to renderer coordinates, x/y direction.
+3 -1
View File
@@ -127,8 +127,10 @@ void DialogContainer::render()
#endif
// Make sure we start in a clean state (with zero'ed buffers)
if(!myOSystem.eventHandler().inTIAMode())
if(!myOSystem.eventHandler().inTIAMode()) {
myOSystem.frameBuffer().flush();
myOSystem.frameBuffer().clear();
}
// Render all dialogs
myDialogStack.applyAll([&](Dialog*& d) {