diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index 93793165ac..1f465fa54f 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -160,14 +160,7 @@ void GPU_D3D11::InitClear() { void GPU_D3D11::BeginHostFrame() { GPUCommon::BeginHostFrame(); UpdateCmdInfo(); - if (resized_) { - gstate_c.useFlags = CheckGPUFeatures(); - framebufferManager_->Resized(); - drawEngine_.NotifyConfigChanged(); - textureCache_->NotifyConfigChanged(); - shaderManagerD3D11_->DirtyLastShader(); - resized_ = false; - } + CheckResized(); } void GPU_D3D11::ReapplyGfxState() { diff --git a/GPU/D3D11/GPU_D3D11.h b/GPU/D3D11/GPU_D3D11.h index e45c1ab79d..c0d969926a 100644 --- a/GPU/D3D11/GPU_D3D11.h +++ b/GPU/D3D11/GPU_D3D11.h @@ -66,7 +66,7 @@ private: } // void ApplyDrawState(int prim); void CheckFlushOp(int cmd, u32 diff); - void BuildReportingInfo(); + void BuildReportingInfo() override; void InitClear() override; void BeginFrame() override; diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index 6d8926e0fe..e3aebbc796 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -150,14 +150,7 @@ void GPU_DX9::InitClear() { void GPU_DX9::BeginHostFrame() { GPUCommon::BeginHostFrame(); UpdateCmdInfo(); - if (resized_) { - gstate_c.useFlags = CheckGPUFeatures(); - framebufferManager_->Resized(); - drawEngine_.NotifyConfigChanged(); - textureCache_->NotifyConfigChanged(); - shaderManagerDX9_->DirtyShader(); - resized_ = false; - } + CheckResized(); } void GPU_DX9::ReapplyGfxState() { diff --git a/GPU/Directx9/GPU_DX9.h b/GPU/Directx9/GPU_DX9.h index 7c6a88d180..c877c17482 100644 --- a/GPU/Directx9/GPU_DX9.h +++ b/GPU/Directx9/GPU_DX9.h @@ -63,7 +63,7 @@ private: drawEngine_.Flush(); } void CheckFlushOp(int cmd, u32 diff); - void BuildReportingInfo(); + void BuildReportingInfo() override; void InitClear() override; void BeginFrame() override; diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 16f6ad611e..f0a796f543 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -268,14 +268,7 @@ void GPU_GLES::InitClear() { void GPU_GLES::BeginHostFrame() { GPUCommon::BeginHostFrame(); UpdateCmdInfo(); - if (resized_) { - gstate_c.useFlags = CheckGPUFeatures(); - framebufferManager_->Resized(); - drawEngine_.NotifyConfigChanged(); - textureCache_->NotifyConfigChanged(); - shaderManagerGL_->DirtyShader(); - resized_ = false; - } + CheckResized(); drawEngine_.BeginFrame(); } diff --git a/GPU/GLES/GPU_GLES.h b/GPU/GLES/GPU_GLES.h index 98bb1d9362..4955a3c511 100644 --- a/GPU/GLES/GPU_GLES.h +++ b/GPU/GLES/GPU_GLES.h @@ -73,7 +73,7 @@ private: drawEngine_.Flush(); } void CheckFlushOp(int cmd, u32 diff); - void BuildReportingInfo(); + void BuildReportingInfo() override; void InitClear() override; void BeginFrame() override; diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 9406429e58..6794e0611e 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -611,6 +611,20 @@ void GPUCommon::Resized() { resized_ = true; } +// Called once per frame. Might also get called during the pause screen +// if "transparent". +void GPUCommon::CheckResized() { + if (resized_) { + gstate_c.useFlags = CheckGPUFeatures(); + BuildReportingInfo(); + framebufferManager_->Resized(); + drawEngineCommon_->NotifyConfigChanged(); + textureCache_->NotifyConfigChanged(); + shaderManager_->DirtyLastShader(); + resized_ = false; + } +} + void GPUCommon::DumpNextFrame() { dumpNextFrame_ = true; } diff --git a/GPU/GPUCommon.h b/GPU/GPUCommon.h index fc2cd13888..39aca24454 100644 --- a/GPU/GPUCommon.h +++ b/GPU/GPUCommon.h @@ -77,6 +77,7 @@ public: return draw_; } virtual u32 CheckGPUFeatures() const; + void CheckResized() override; void UpdateCmdInfo(); @@ -309,6 +310,8 @@ protected: size_t FormatGPUStatsCommon(char *buf, size_t size); + virtual void BuildReportingInfo() = 0; + FramebufferManagerCommon *framebufferManager_ = nullptr; TextureCacheCommon *textureCache_ = nullptr; DrawEngineCommon *drawEngineCommon_ = nullptr; diff --git a/GPU/GPUInterface.h b/GPU/GPUInterface.h index 5e523a955a..69260e8625 100644 --- a/GPU/GPUInterface.h +++ b/GPU/GPUInterface.h @@ -197,6 +197,7 @@ public: // Frame managment virtual void BeginHostFrame() = 0; virtual void EndHostFrame() = 0; + virtual void CheckResized() = 0; // Draw queue management virtual DisplayList* getList(int listid) = 0; diff --git a/GPU/Software/SoftGpu.h b/GPU/Software/SoftGpu.h index 6c317d89c9..112d9af3a2 100644 --- a/GPU/Software/SoftGpu.h +++ b/GPU/Software/SoftGpu.h @@ -205,6 +205,8 @@ protected: void CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight); void ConvertTextureDescFrom16(Draw::TextureDesc &desc, int srcwidth, int srcheight, const uint16_t *overrideData = nullptr); + void BuildReportingInfo() override {} + private: void MarkDirty(uint32_t addr, uint32_t stride, uint32_t height, GEBufferFormat fmt, SoftGPUVRAMDirty value); void MarkDirty(uint32_t addr, uint32_t bytes, SoftGPUVRAMDirty value); diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 4232e3f526..8f0b024a50 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -275,15 +275,7 @@ void GPU_Vulkan::BeginHostFrame() { drawEngine_.BeginFrame(); UpdateCmdInfo(); - if (resized_) { - gstate_c.useFlags = CheckGPUFeatures(); - // In case the GPU changed. - BuildReportingInfo(); - framebufferManager_->Resized(); - drawEngine_.NotifyConfigChanged(); - textureCache_->NotifyConfigChanged(); - resized_ = false; - } + CheckResized(); textureCacheVulkan_->StartFrame(); diff --git a/GPU/Vulkan/GPU_Vulkan.h b/GPU/Vulkan/GPU_Vulkan.h index 3fbd329aae..ee45b43e5b 100644 --- a/GPU/Vulkan/GPU_Vulkan.h +++ b/GPU/Vulkan/GPU_Vulkan.h @@ -77,7 +77,7 @@ private: drawEngine_.Flush(); } void CheckFlushOp(int cmd, u32 diff); - void BuildReportingInfo(); + void BuildReportingInfo() override; void InitClear() override; void CopyDisplayToOutput(bool reallyDirty) override; void Reinitialize() override; diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 8c3c74a994..ea8bc74b42 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1105,7 +1105,6 @@ void EmuScreen::update() { } } } - } void EmuScreen::checkPowerDown() { @@ -1356,8 +1355,7 @@ void EmuScreen::preRender() { // We only bind it in FramebufferManager::CopyDisplayToOutput (unless non-buffered)... // We do, however, start the frame in other ways. - bool useBufferedRendering = !g_Config.bSkipBufferEffects; - if ((!useBufferedRendering && !g_Config.bSoftwareRendering) || Core_IsStepping()) { + if ((g_Config.bSkipBufferEffects && !g_Config.bSoftwareRendering) || Core_IsStepping()) { // We need to clear here already so that drawing during the frame is done on a clean slate. if (Core_IsStepping() && gpuStats.numFlips != 0) { draw->BindFramebufferAsRenderTarget(nullptr, { RPAction::KEEP, RPAction::DONT_CARE, RPAction::DONT_CARE }, "EmuScreen_BackBuffer"); @@ -1393,6 +1391,30 @@ void EmuScreen::render() { if (!thin3d) return; // shouldn't really happen but I've seen a suspicious stack trace.. + // We can still render behind the pause screen. + bool paused = screenManager()->topScreen() != this; + + if (paused) { + // If we're paused and PauseScreen is transparent (will only be in buffered rendering mode), we just copy display to output. + thin3d->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::DONT_CARE, RPAction::DONT_CARE }, "EmuScreen_Paused"); + if (PSP_IsInited()) { + gpu->CheckResized(); + gpu->CopyDisplayToOutput(true); + } + + screenManager()->getUIContext()->BeginFrame(); + DrawContext *draw = screenManager()->getDrawContext(); + Viewport viewport; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + viewport.Width = pixel_xres; + viewport.Height = pixel_yres; + viewport.MaxDepth = 1.0; + viewport.MinDepth = 0.0; + draw->SetViewports(1, &viewport); + return; + } + if (invalid_) { // Loading, or after shutdown? if (loadingTextView_->GetVisibility() == UI::V_VISIBLE) diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp index 4cb74d067e..6e3e3d001e 100644 --- a/UI/PauseScreen.cpp +++ b/UI/PauseScreen.cpp @@ -364,6 +364,24 @@ GamePauseScreen::~GamePauseScreen() { __DisplaySetWasPaused(); } +bool GamePauseScreen::isTransparent() const { + // We don't support transparent pause screen in skipbuffereffects mode. + return !g_Config.bSkipBufferEffects && !IsVREnabled(); +} + +void GamePauseScreen::DrawBackground(UIContext &dc) { + if (isTransparent()) { + // Darken the game screen coming from below, so the UI on top stands out. + dc.Flush(); + uint32_t color = blackAlpha(0.45f); + dc.FillRect(UI::Drawable(color), dc.GetBounds()); + dc.Flush(); + return; + } + + UIDialogScreenWithGameBackground::DrawBackground(dc); +} + void GamePauseScreen::CreateViews() { static const int NUM_SAVESLOTS = 5; diff --git a/UI/PauseScreen.h b/UI/PauseScreen.h index 3c66609285..6b48f7bdb2 100644 --- a/UI/PauseScreen.h +++ b/UI/PauseScreen.h @@ -31,15 +31,18 @@ public: GamePauseScreen(const Path &filename) : UIDialogScreenWithGameBackground(filename), gamePath_(filename) {} virtual ~GamePauseScreen(); - virtual void dialogFinished(const Screen *dialog, DialogResult dr) override; + void dialogFinished(const Screen *dialog, DialogResult dr) override; const char *tag() const override { return "GamePause"; } protected: - virtual void CreateViews() override; - virtual void update() override; + void CreateViews() override; + void update() override; void CallbackDeleteConfig(bool yes); + bool isTransparent() const override; + void DrawBackground(UIContext &dc) override; + private: UI::EventReturn OnGameSettings(UI::EventParams &e); UI::EventReturn OnExitToMenu(UI::EventParams &e);