diff options
author | bunnei <bunneidev@gmail.com> | 2020-12-17 06:09:06 +0100 |
---|---|---|
committer | bunnei <bunneidev@gmail.com> | 2020-12-29 06:33:34 +0100 |
commit | 6433b1dfd67f4c4f0c4b2e3742dc437a0d1e906e (patch) | |
tree | d2a9a23be1a80d9351f99d7feb7978f3c2237882 /src/core/hle/service/nvflinger/buffer_queue.cpp | |
parent | hle: service: Ensure system is powered on before writing IPC result. (diff) | |
download | yuzu-6433b1dfd67f4c4f0c4b2e3742dc437a0d1e906e.tar yuzu-6433b1dfd67f4c4f0c4b2e3742dc437a0d1e906e.tar.gz yuzu-6433b1dfd67f4c4f0c4b2e3742dc437a0d1e906e.tar.bz2 yuzu-6433b1dfd67f4c4f0c4b2e3742dc437a0d1e906e.tar.lz yuzu-6433b1dfd67f4c4f0c4b2e3742dc437a0d1e906e.tar.xz yuzu-6433b1dfd67f4c4f0c4b2e3742dc437a0d1e906e.tar.zst yuzu-6433b1dfd67f4c4f0c4b2e3742dc437a0d1e906e.zip |
Diffstat (limited to 'src/core/hle/service/nvflinger/buffer_queue.cpp')
-rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue.cpp | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index 377f47e8e..c8c6a4d64 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp @@ -25,7 +25,12 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer) ASSERT(slot < buffer_slots); LOG_WARNING(Service, "Adding graphics buffer {}", slot); - free_buffers.push_back(slot); + { + std::unique_lock lock{queue_mutex}; + free_buffers.push_back(slot); + } + condition.notify_one(); + buffers[slot] = { .slot = slot, .status = Buffer::Status::Free, @@ -41,10 +46,20 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer) std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> BufferQueue::DequeueBuffer(u32 width, u32 height) { + // Wait for first request before trying to dequeue + { + std::unique_lock lock{queue_mutex}; + condition.wait(lock, [this] { return !free_buffers.empty() || !is_connect; }); + } - if (free_buffers.empty()) { + if (!is_connect) { + // Buffer was disconnected while the thread was blocked, this is most likely due to + // emulation being stopped return std::nullopt; } + + std::unique_lock lock{queue_mutex}; + auto f_itr = free_buffers.begin(); auto slot = buffers.size(); @@ -97,7 +112,11 @@ void BufferQueue::CancelBuffer(u32 slot, const Service::Nvidia::MultiFence& mult buffers[slot].multi_fence = multi_fence; buffers[slot].swap_interval = 0; - free_buffers.push_back(slot); + { + std::unique_lock lock{queue_mutex}; + free_buffers.push_back(slot); + } + condition.notify_one(); buffer_wait_event.writable->Signal(); } @@ -127,15 +146,28 @@ void BufferQueue::ReleaseBuffer(u32 slot) { ASSERT(buffers[slot].slot == slot); buffers[slot].status = Buffer::Status::Free; - free_buffers.push_back(slot); + { + std::unique_lock lock{queue_mutex}; + free_buffers.push_back(slot); + } + condition.notify_one(); buffer_wait_event.writable->Signal(); } +void BufferQueue::Connect() { + queue_sequence.clear(); + id = 1; + layer_id = 1; + is_connect = true; +} + void BufferQueue::Disconnect() { buffers.fill({}); queue_sequence.clear(); buffer_wait_event.writable->Signal(); + is_connect = false; + condition.notify_one(); } u32 BufferQueue::Query(QueryType type) { |