summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/Present.cpp
diff options
context:
space:
mode:
authorScott Mansell <phiren@gmail.com>2023-02-03 17:42:47 +1300
committerScott Mansell <phiren@gmail.com>2023-02-09 18:36:20 +1300
commitb2a31103b43c365d4c48a55b805001bfb07d974e (patch)
tree96949bf616e98ac2602a61240f466f6d1f97a1c1 /Source/Core/VideoCommon/Present.cpp
parent83b7b01265598067494eca228175e5b5805e36a2 (diff)
Presenter: Handle blanked frames correctly
Diffstat (limited to 'Source/Core/VideoCommon/Present.cpp')
-rw-r--r--Source/Core/VideoCommon/Present.cpp46
1 files changed, 25 insertions, 21 deletions
diff --git a/Source/Core/VideoCommon/Present.cpp b/Source/Core/VideoCommon/Present.cpp
index 1f3b8b8ad8..fa3be6acc5 100644
--- a/Source/Core/VideoCommon/Present.cpp
+++ b/Source/Core/VideoCommon/Present.cpp
@@ -66,54 +66,58 @@ bool Presenter::Initialize()
bool Presenter::FetchXFB(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u64 ticks)
{
ReleaseXFBContentLock();
+ u64 old_xfb_id = m_last_xfb_id;
- m_xfb_entry =
- g_texture_cache->GetXFBTexture(xfb_addr, fb_width, fb_height, fb_stride, &m_xfb_rect);
- bool is_duplicate = m_xfb_entry->id == m_last_xfb_id;
-
- m_xfb_entry->AcquireContentLock();
+ if (fb_width == 0 || fb_height == 0)
+ {
+ // Game is blanking the screen
+ m_xfb_entry.reset();
+ m_last_xfb_id = std::numeric_limits<u64>::max();
+ }
+ else
+ {
+ m_xfb_entry =
+ g_texture_cache->GetXFBTexture(xfb_addr, fb_width, fb_height, fb_stride, &m_xfb_rect);
+ m_last_xfb_id = m_xfb_entry->id;
+ m_xfb_entry->AcquireContentLock();
+ }
m_last_xfb_addr = xfb_addr;
m_last_xfb_ticks = ticks;
m_last_xfb_width = fb_width;
m_last_xfb_stride = fb_stride;
m_last_xfb_height = fb_height;
- m_last_xfb_id = m_xfb_entry->id;
- return !is_duplicate;
+ return old_xfb_id == m_last_xfb_id;
}
void Presenter::ViSwap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u64 ticks)
{
- bool unique = FetchXFB(xfb_addr, fb_width, fb_stride, fb_height, ticks);
+ bool is_duplicate = FetchXFB(xfb_addr, fb_width, fb_stride, fb_height, ticks);
PresentInfo present_info;
present_info.emulated_timestamp = ticks;
- if (unique)
+ present_info.present_count = m_present_count++;
+ if (is_duplicate)
{
- present_info.frame_count = m_frame_count++;
- present_info.reason = PresentInfo::PresentReason::VideoInterface;
+ present_info.frame_count = m_frame_count - 1; // Previous frame
+ present_info.reason = PresentInfo::PresentReason::VideoInterfaceDuplicate;
}
else
{
- present_info.frame_count = m_frame_count - 1; // Previous frame
- present_info.reason = PresentInfo::PresentReason::VideoInterfaceDuplicate;
+ present_info.frame_count = m_frame_count++;
+ present_info.reason = PresentInfo::PresentReason::VideoInterface;
}
- present_info.present_count = m_present_count;
BeforePresentEvent::Trigger(present_info);
- if (unique || !g_ActiveConfig.bSkipPresentingDuplicateXFBs)
+ if (!is_duplicate || !g_ActiveConfig.bSkipPresentingDuplicateXFBs)
{
Present();
ProcessFrameDumping(ticks);
AfterPresentEvent::Trigger(present_info);
}
- else
- {
- g_gfx->Flush();
- }
}
void Presenter::ImmediateSwap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u64 ticks)
@@ -121,7 +125,7 @@ void Presenter::ImmediateSwap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_
FetchXFB(xfb_addr, fb_width, fb_stride, fb_height, ticks);
PresentInfo present_info;
- present_info.emulated_timestamp = ticks;
+ present_info.emulated_timestamp = ticks; // TODO: This should be the time of the next VI field
present_info.frame_count = m_frame_count++;
present_info.reason = PresentInfo::PresentReason::Immediate;
present_info.present_count = m_present_count++;
@@ -136,7 +140,7 @@ void Presenter::ImmediateSwap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_
void Presenter::ProcessFrameDumping(u64 ticks) const
{
- if (g_frame_dumper->IsFrameDumping())
+ if (g_frame_dumper->IsFrameDumping() && m_xfb_entry)
{
MathUtil::Rectangle<int> target_rect;
if (!g_ActiveConfig.bInternalResolutionFrameDumps && !g_gfx->IsHeadless())