Compare commits

...

1 commit

2 changed files with 18 additions and 27 deletions

View file

@ -45,6 +45,17 @@ Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer,
auto front(core->queue.begin());
// prefer newest queued frame for lower input latency (if no present deadline is requested).
if (expected_present.count() == 0 && core->queue.size() > 1) {
while (core->queue.size() > 1) {
const auto stale = core->queue.begin();
if (core->StillTracking(*stale)) slots[stale->slot].buffer_state = BufferState::Free;
core->queue.erase(stale);
}
core->SignalDequeueCondition();
front = core->queue.begin();
}
// If expected_present is specified, we may not want to return a buffer yet.
if (expected_present.count() != 0) {
constexpr auto MAX_REASONABLE_NSEC = 1000000000LL; // 1 second

View file

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
@ -77,26 +77,7 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display,
// Acquire all necessary framebuffers.
for (auto& layer : display.stack.layers) {
auto consumer_id = layer->consumer_id;
bool should_try_acquire = true;
if (!layer->is_overlay) {
auto fb_it = m_framebuffers.find(consumer_id);
if (fb_it != m_framebuffers.end() && fb_it->second.is_acquired) {
const u64 frames_since_last_acquire = m_frame_number - fb_it->second.last_acquire_frame;
const s32 expected_interval = NormalizeSwapInterval(nullptr, fb_it->second.item.swap_interval);
if (frames_since_last_acquire < static_cast<u64>(expected_interval)) {
should_try_acquire = false;
}
}
}
// Try to fetch the framebuffer (either new or stale).
const auto result = should_try_acquire
? this->CacheFramebufferLocked(*layer, consumer_id)
: (m_framebuffers.find(consumer_id) != m_framebuffers.end() && m_framebuffers[consumer_id].is_acquired
? CacheStatus::CachedBufferReused
: CacheStatus::NoBufferAvailable);
const auto result = this->CacheFramebufferLocked(*layer, consumer_id);
// If we failed, skip this layer.
if (result == CacheStatus::NoBufferAvailable) {
@ -134,9 +115,9 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display,
continue;
}
// We need to compose again either before this frame is supposed to
// be released, or exactly on the vsync period it should be released.
const s32 item_swap_interval = NormalizeSwapInterval(out_speed_scale, item.swap_interval);
// hard-throttle non-overlay presentation cadence on 1..4 removed!!
NormalizeSwapInterval(out_speed_scale, item.swap_interval);
const s32 item_swap_interval = 1;
// TODO: handle cases where swap intervals are relatively prime. So far,
// only swap intervals of 0, 1 and 2 have been observed, but if 3 were
@ -233,9 +214,8 @@ bool HardwareComposer::TryAcquireFramebufferLocked(Layer& layer, Framebuffer& fr
return false;
}
// We succeeded, so set the new release frame info.
const s32 swap_interval = layer.is_overlay ? 1 : NormalizeSwapInterval(nullptr, framebuffer.item.swap_interval);
framebuffer.release_frame_number = m_frame_number + swap_interval;
// Keep 60Hz consumer cadence and let producer queue timing decide effective FPS.
framebuffer.release_frame_number = m_frame_number + 1;
framebuffer.last_acquire_frame = m_frame_number;
framebuffer.is_acquired = true;