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);