diff options
author | Rodrigo Locatti <reinuseslisp@airmail.cc> | 2020-04-11 22:58:15 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-11 22:58:15 +0200 |
commit | 75e39f7f88a51cd21a8de57913d737322768367e (patch) | |
tree | 1b24d408d57078d59334f010014b3ec5442248e9 | |
parent | Merge pull request #3611 from FearlessTobi/port-4956 (diff) | |
parent | Buffer queue: Correct behavior of free buffer. (diff) | |
download | yuzu-75e39f7f88a51cd21a8de57913d737322768367e.tar yuzu-75e39f7f88a51cd21a8de57913d737322768367e.tar.gz yuzu-75e39f7f88a51cd21a8de57913d737322768367e.tar.bz2 yuzu-75e39f7f88a51cd21a8de57913d737322768367e.tar.lz yuzu-75e39f7f88a51cd21a8de57913d737322768367e.tar.xz yuzu-75e39f7f88a51cd21a8de57913d737322768367e.tar.zst yuzu-75e39f7f88a51cd21a8de57913d737322768367e.zip |
-rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue.cpp | 41 | ||||
-rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue.h | 1 |
2 files changed, 33 insertions, 9 deletions
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index 32b6f4b27..9bcafa5fc 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp @@ -28,6 +28,7 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer) buffer.slot = slot; buffer.igbp_buffer = igbp_buffer; buffer.status = Buffer::Status::Free; + free_buffers.push_back(slot); queue.emplace_back(buffer); buffer_wait_event.writable->Signal(); @@ -35,16 +36,37 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer) std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> BufferQueue::DequeueBuffer(u32 width, u32 height) { - auto itr = std::find_if(queue.begin(), queue.end(), [&](const Buffer& buffer) { - // Only consider free buffers. Buffers become free once again after they've been Acquired - // and Released by the compositor, see the NVFlinger::Compose method. - if (buffer.status != Buffer::Status::Free) { - return false; - } - // Make sure that the parameters match. - return buffer.igbp_buffer.width == width && buffer.igbp_buffer.height == height; - }); + if (free_buffers.empty()) { + return {}; + } + + auto f_itr = free_buffers.begin(); + auto itr = queue.end(); + + while (f_itr != free_buffers.end()) { + auto slot = *f_itr; + itr = std::find_if(queue.begin(), queue.end(), [&](const Buffer& buffer) { + // Only consider free buffers. Buffers become free once again after they've been + // Acquired and Released by the compositor, see the NVFlinger::Compose method. + if (buffer.status != Buffer::Status::Free) { + return false; + } + + if (buffer.slot != slot) { + return false; + } + + // Make sure that the parameters match. + return buffer.igbp_buffer.width == width && buffer.igbp_buffer.height == height; + }); + + if (itr != queue.end()) { + free_buffers.erase(f_itr); + break; + } + ++f_itr; + } if (itr == queue.end()) { return {}; @@ -99,6 +121,7 @@ void BufferQueue::ReleaseBuffer(u32 slot) { ASSERT(itr != queue.end()); ASSERT(itr->status == Buffer::Status::Acquired); itr->status = Buffer::Status::Free; + free_buffers.push_back(slot); buffer_wait_event.writable->Signal(); } diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h index f4bbfd945..f674823b0 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.h +++ b/src/core/hle/service/nvflinger/buffer_queue.h @@ -101,6 +101,7 @@ private: u32 id; u64 layer_id; + std::list<u32> free_buffers; std::vector<Buffer> queue; std::list<u32> queue_sequence; Kernel::EventPair buffer_wait_event; |