diff --git a/Common/UI/Screen.cpp b/Common/UI/Screen.cpp index 1bf1d32f95f4..bf626ce653bd 100644 --- a/Common/UI/Screen.cpp +++ b/Common/UI/Screen.cpp @@ -168,9 +168,10 @@ ScreenRenderFlags ScreenManager::render() { auto iter = stack_.end(); Screen *coveringScreen = nullptr; Screen *backgroundScreen = nullptr; + bool first = true; do { --iter; - if (!backgroundScreen && iter->screen->canBeBackground()) { + if (!backgroundScreen && iter->screen->canBeBackground(first)) { // There still might be a screen that wants to be background - generally the EmuScreen if present. layers.push_back(iter->screen); backgroundScreen = iter->screen; @@ -180,6 +181,7 @@ ScreenRenderFlags ScreenManager::render() { if (iter->flags != LAYER_TRANSPARENT) { coveringScreen = iter->screen; } + first = false; } while (iter != stack_.begin()); // Confusing-looking expression, argh! Note the '_' @@ -189,7 +191,6 @@ ScreenRenderFlags ScreenManager::render() { } // OK, now we iterate backwards over our little pile of collected screens. - bool first = true; for (int i = (int)layers.size() - 1; i >= 0; i--) { ScreenRenderMode mode = ScreenRenderMode::DEFAULT; if (i == (int)layers.size() - 1) { diff --git a/Common/UI/Screen.h b/Common/UI/Screen.h index e65b0d8d7993..e7232a84009e 100644 --- a/Common/UI/Screen.h +++ b/Common/UI/Screen.h @@ -76,7 +76,7 @@ class Screen { virtual void sendMessage(UIMessage message, const char *value) {} virtual void deviceLost() {} virtual void deviceRestored() {} - virtual bool canBeBackground() const { return false; } + virtual bool canBeBackground(bool isTop) const { return false; } virtual bool wantBrightBackground() const { return false; } // special hack for DisplayLayoutScreen. virtual void focusChanged(ScreenFocusChange focusChange); diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 51f1fc47c44b..74d34a2c0c04 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1415,9 +1415,10 @@ static void DrawFPS(UIContext *ctx, const Bounds &bounds) { ctx->RebindTexture(); } -bool EmuScreen::canBeBackground() const { - if (g_Config.bSkipBufferEffects) - return false; +bool EmuScreen::canBeBackground(bool isTop) const { + if (g_Config.bSkipBufferEffects) { + return isTop || (g_Config.bTransparentBackground && g_Config.bRunBehindPauseMenu); + } bool forceTransparent = false; // this needs to be true somehow on the display layout screen. @@ -1446,6 +1447,8 @@ ScreenRenderFlags EmuScreen::render(ScreenRenderMode mode) { if (!draw) return flags; // shouldn't really happen but I've seen a suspicious stack trace.. + bool skipBufferEffects = g_Config.bSkipBufferEffects; + if (mode & ScreenRenderMode::FIRST) { // Actually, always gonna be first when it exists (?) @@ -1472,6 +1475,8 @@ ScreenRenderFlags EmuScreen::render(ScreenRenderMode mode) { viewport.MaxDepth = 1.0; viewport.MinDepth = 0.0; draw->SetViewport(viewport); + + skipBufferEffects = true; } draw->SetTargetSize(g_display.pixel_xres, g_display.pixel_yres); } @@ -1568,14 +1573,22 @@ ScreenRenderFlags EmuScreen::render(ScreenRenderMode mode) { PSP_EndHostFrame(); } - if (gpu && !gpu->PresentedThisFrame()) { + if (gpu && !gpu->PresentedThisFrame() && !skipBufferEffects) { draw->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::CLEAR, RPAction::CLEAR }, "EmuScreen_NoFrame"); + Viewport viewport{ 0.0f, 0.0f, (float)g_display.pixel_xres, (float)g_display.pixel_yres, 0.0f, 1.0f }; + draw->SetViewport(viewport); + draw->SetScissorRect(0, 0, g_display.pixel_xres, g_display.pixel_yres); } if (!(mode & ScreenRenderMode::TOP)) { // We're in run-behind mode, but we don't want to draw chat, debug UI and stuff. // So, darken and bail here. - + if (skipBufferEffects) { + // Need to reset viewport/scissor. + Viewport viewport{ 0.0f, 0.0f, (float)g_display.pixel_xres, (float)g_display.pixel_yres, 0.0f, 1.0f }; + draw->SetViewport(viewport); + draw->SetScissorRect(0, 0, g_display.pixel_xres, g_display.pixel_yres); + } darken(); return flags; } diff --git a/UI/EmuScreen.h b/UI/EmuScreen.h index a97273027450..bcf3171a3e48 100644 --- a/UI/EmuScreen.h +++ b/UI/EmuScreen.h @@ -46,7 +46,7 @@ class EmuScreen : public UIScreen { void dialogFinished(const Screen *dialog, DialogResult result) override; void sendMessage(UIMessage message, const char *value) override; void resized() override; - bool canBeBackground() const override; + bool canBeBackground(bool isTop) const override; // Note: Unlike your average boring UIScreen, here we override the Unsync* functions // to get minimal latency and full control. We forward to UIScreen when needed.