Fix a bunch of edge cases

This commit is contained in:
Henrik Rydgård 2023-12-11 15:58:08 +01:00
parent 6e369e5188
commit 25ab7b9170
4 changed files with 23 additions and 9 deletions

View File

@ -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) {

View File

@ -76,7 +76,7 @@ public:
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);

View File

@ -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;
}

View File

@ -46,7 +46,7 @@ public:
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.