diff --git a/desmume/src/GPU.cpp b/desmume/src/GPU.cpp index eb6cce8c8..f76dac39e 100644 --- a/desmume/src/GPU.cpp +++ b/desmume/src/GPU.cpp @@ -6760,6 +6760,7 @@ GPUSubsystem::GPUSubsystem() _displayTouch = new NDSDisplay(NDSDisplayID_Touch); _displayTouch->SetEngine(_engineSub); + _frameNeedsFinish = false; _willAutoResolveToCustomBuffer = true; OSDCLASS *previousOSD = osd; @@ -6880,19 +6881,30 @@ void GPUSubsystem::Reset() } void GPUSubsystem::ForceRender3DFinishAndFlush(bool willFlush) +{ + bool need3DDisplayFramebuffer; + bool need3DCaptureFramebuffer; + CurrentRenderer->GetFramebufferFlushStates(need3DDisplayFramebuffer, need3DCaptureFramebuffer); + + CurrentRenderer->SetFramebufferFlushStates(willFlush, willFlush); + CurrentRenderer->RenderFinish(); + CurrentRenderer->SetFramebufferFlushStates(need3DDisplayFramebuffer, need3DCaptureFramebuffer); +} + +void GPUSubsystem::ForceFrameStop() { if (CurrentRenderer->GetRenderNeedsFinish()) { - bool need3DDisplayFramebuffer; - bool need3DCaptureFramebuffer; - CurrentRenderer->GetFramebufferFlushStates(need3DDisplayFramebuffer, need3DCaptureFramebuffer); - - CurrentRenderer->SetFramebufferFlushStates(willFlush, willFlush); - CurrentRenderer->RenderFinish(); - CurrentRenderer->SetFramebufferFlushStates(need3DDisplayFramebuffer, need3DCaptureFramebuffer); + this->ForceRender3DFinishAndFlush(true); CurrentRenderer->SetRenderNeedsFinish(false); this->_event->DidRender3DEnd(); } + + if (this->_frameNeedsFinish) + { + this->_frameNeedsFinish = false; + this->_event->DidFrameEnd(false); + } } void GPUSubsystem::UpdateRenderProperties() @@ -7020,8 +7032,6 @@ void GPUSubsystem::SetCustomFramebufferSize(size_t w, size_t h, void *clientNati return; } - GPU->ForceRender3DFinishAndFlush(false); - const float customWidthScale = (float)w / (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; const float customHeightScale = (float)h / (float)GPU_FRAMEBUFFER_NATIVE_HEIGHT; const float newGpuLargestDstLineCount = (size_t)ceilf(customHeightScale); @@ -7162,8 +7172,6 @@ void GPUSubsystem::SetCustomFramebufferSize(size_t w, size_t h) void GPUSubsystem::SetColorFormat(const NDSColorFormat outputFormat, void *clientNativeBuffer, void *clientCustomBuffer) { - GPU->ForceRender3DFinishAndFlush(false); - this->_displayInfo.colorFormat = outputFormat; this->_displayInfo.pixelBytes = (outputFormat == NDSColorFormat_BGR555_Rev) ? sizeof(u16) : sizeof(FragmentColor); @@ -7305,10 +7313,14 @@ void GPUSubsystem::RenderLine(const u16 l, bool isFrameSkipRequested) const bool isFramebufferRenderNeeded[2] = {(CommonSettings.showGpu.main && !this->_engineMain->GetIsMasterBrightFullIntensity()) || isDisplayCaptureNeeded, CommonSettings.showGpu.sub && !this->_engineSub->GetIsMasterBrightFullIntensity() }; - if (l == 0) + if (!this->_frameNeedsFinish) { this->_event->DidFrameBegin(isFrameSkipRequested); - + this->_frameNeedsFinish = true; + } + + if (l == 0) + { // Clear displays to black if they are turned off by the user. if (!isFrameSkipRequested) { @@ -7384,6 +7396,9 @@ void GPUSubsystem::RenderLine(const u16 l, bool isFrameSkipRequested) if (l == 191) { + this->_engineMain->FramebufferPostprocess(); + this->_engineSub->FramebufferPostprocess(); + if (!isFrameSkipRequested) { if (this->_displayInfo.isCustomSizeRequested) @@ -7425,9 +7440,6 @@ void GPUSubsystem::RenderLine(const u16 l, bool isFrameSkipRequested) } } - this->_engineMain->FramebufferPostprocess(); - this->_engineSub->FramebufferPostprocess(); - gfx3d._videoFrameCount++; if (gfx3d._videoFrameCount == 60) { @@ -7436,7 +7448,11 @@ void GPUSubsystem::RenderLine(const u16 l, bool isFrameSkipRequested) gfx3d._videoFrameCount = 0; } - this->_event->DidFrameEnd(isFrameSkipRequested); + if (this->_frameNeedsFinish) + { + this->_frameNeedsFinish = false; + this->_event->DidFrameEnd(isFrameSkipRequested); + } } } diff --git a/desmume/src/GPU.h b/desmume/src/GPU.h index 12e6cbc9d..b983fed69 100644 --- a/desmume/src/GPU.h +++ b/desmume/src/GPU.h @@ -1608,6 +1608,7 @@ private: NDSDisplay *_displayMain; NDSDisplay *_displayTouch; + bool _frameNeedsFinish; bool _willAutoResolveToCustomBuffer; u16 *_customVRAM; u16 *_customVRAMBlank; @@ -1628,6 +1629,8 @@ public: void Reset(); void ForceRender3DFinishAndFlush(bool willFlush); + void ForceFrameStop(); + const NDSDisplayInfo& GetDisplayInfo(); // Frontends need to call this whenever they need to read the video buffers from the emulator core void SetDisplayDidCustomRender(NDSDisplayID displayID, bool theState); diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index a79ad0801..74f9b82fc 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -1411,8 +1411,8 @@ static void execHardware_hstart_vblankStart() triggerDma(EDMAMode_VBlank); //tracking for arm9 load average - nds.runCycleCollector[0][nds.idleFrameCounter] = 1120380-nds.idleCycles[0]; - nds.runCycleCollector[1][nds.idleFrameCounter] = 1120380-nds.idleCycles[1]; + nds.runCycleCollector[ARMCPU_ARM9][nds.idleFrameCounter] = 1120380-nds.idleCycles[0]; + nds.runCycleCollector[ARMCPU_ARM7][nds.idleFrameCounter] = 1120380-nds.idleCycles[1]; nds.idleFrameCounter++; nds.idleFrameCounter &= 15; nds.idleCycles[0] = 0; @@ -2973,9 +2973,12 @@ void NDS_swapScreen() } -void emu_halt() { +void emu_halt() +{ //printf("halting emu: ARM9 PC=%08X/%08X, ARM7 PC=%08X/%08X\n", NDS_ARM9.R[15], NDS_ARM9.instruct_adr, NDS_ARM7.R[15], NDS_ARM7.instruct_adr); execute = false; + GPU->ForceFrameStop(); + #ifdef LOG_ARM9 if (fp_dis9) { diff --git a/desmume/src/gfx3d.cpp b/desmume/src/gfx3d.cpp index d882b981c..bc5de5392 100644 --- a/desmume/src/gfx3d.cpp +++ b/desmume/src/gfx3d.cpp @@ -527,7 +527,10 @@ void gfx3d_deinit() void gfx3d_reset() { - GPU->ForceRender3DFinishAndFlush(false); + if (CurrentRenderer->GetRenderNeedsFinish()) + { + GPU->ForceRender3DFinishAndFlush(false); + } #ifdef _SHOW_VTX_COUNTERS max_polys = max_verts = 0; @@ -2300,7 +2303,12 @@ void gfx3d_VBlankSignal() void gfx3d_VBlankEndSignal(bool skipFrame) { - GPU->ForceRender3DFinishAndFlush(false); + if (CurrentRenderer->GetRenderNeedsFinish()) + { + GPU->ForceRender3DFinishAndFlush(false); + CurrentRenderer->SetRenderNeedsFinish(false); + GPU->GetEventHandler()->DidRender3DEnd(); + } if (!drawPending) return; if (skipFrame) return; @@ -2308,10 +2316,10 @@ void gfx3d_VBlankEndSignal(bool skipFrame) drawPending = FALSE; GPU->GetEventHandler()->DidRender3DBegin(); + CurrentRenderer->SetRenderNeedsFinish(true); if (CommonSettings.showGpu.main) { - CurrentRenderer->SetRenderNeedsFinish(true); CurrentRenderer->SetTextureProcessingProperties(CommonSettings.GFX3D_Renderer_TextureScalingFactor, CommonSettings.GFX3D_Renderer_TextureDeposterize, CommonSettings.GFX3D_Renderer_TextureSmoothing); @@ -2523,7 +2531,10 @@ void gfx3d_Update3DFramebuffers(FragmentColor *framebufferRGBA6665, u16 *framebu //-------------savestate void gfx3d_savestate(EMUFILE* os) { - GPU->ForceRender3DFinishAndFlush(true); + if (CurrentRenderer->GetRenderNeedsFinish()) + { + GPU->ForceRender3DFinishAndFlush(true); + } //version write32le(4,os); @@ -2556,6 +2567,10 @@ bool gfx3d_loadstate(EMUFILE* is, int size) if (read32le(&version,is) != 1) return false; if (size == 8) version = 0; + if (CurrentRenderer->GetRenderNeedsFinish()) + { + GPU->ForceRender3DFinishAndFlush(false); + } gfx3d_glPolygonAttrib_cache(); gfx3d_glTexImage_cache();