From 63cbd9c79bb892fb7a64a72c3107ac8371c0ff46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 20 Nov 2022 12:22:50 +0100 Subject: [PATCH 1/2] Make the pause screen "transparent" When paused (ESC or back), you now see the paused game below, darkened, instead of the usual menu background. Not enabled in VR mode for now because it could get weird. Also not trivial in skip-buffered mode (would require taking a screenshot) so disabled in that case too. --- UI/EmuScreen.cpp | 16 +++++++++++++--- UI/PauseScreen.cpp | 18 ++++++++++++++++++ UI/PauseScreen.h | 9 ++++++--- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 8c3c74a994..5d5baee855 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,18 @@ 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->CopyDisplayToOutput(true); + } + 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); From 37ec31dedd308b24d50506b5afa1485aa228b844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 20 Nov 2022 12:57:32 +0100 Subject: [PATCH 2/2] Fix resizing issue. Took some refactoring. --- GPU/D3D11/GPU_D3D11.cpp | 9 +-------- GPU/D3D11/GPU_D3D11.h | 2 +- GPU/Directx9/GPU_DX9.cpp | 9 +-------- GPU/Directx9/GPU_DX9.h | 2 +- GPU/GLES/GPU_GLES.cpp | 9 +-------- GPU/GLES/GPU_GLES.h | 2 +- GPU/GPUCommon.cpp | 14 ++++++++++++++ GPU/GPUCommon.h | 3 +++ GPU/GPUInterface.h | 1 + GPU/Software/SoftGpu.h | 2 ++ GPU/Vulkan/GPU_Vulkan.cpp | 10 +--------- GPU/Vulkan/GPU_Vulkan.h | 2 +- UI/EmuScreen.cpp | 12 ++++++++++++ 13 files changed, 40 insertions(+), 37 deletions(-) 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 5d5baee855..ea8bc74b42 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1398,8 +1398,20 @@ void EmuScreen::render() { // 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; }