diff options
Diffstat (limited to 'src')
4 files changed, 16 insertions, 12 deletions
diff --git a/src/core/hle/service/nvflinger/buffer_queue_core.cpp b/src/core/hle/service/nvflinger/buffer_queue_core.cpp index ea4a14ea4..3d1338e66 100644 --- a/src/core/hle/service/nvflinger/buffer_queue_core.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue_core.cpp | |||
| @@ -23,15 +23,17 @@ void BufferQueueCore::NotifyShutdown() { | |||
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | void BufferQueueCore::SignalDequeueCondition() { | 25 | void BufferQueueCore::SignalDequeueCondition() { |
| 26 | dequeue_possible.store(true); | ||
| 26 | dequeue_condition.notify_all(); | 27 | dequeue_condition.notify_all(); |
| 27 | } | 28 | } |
| 28 | 29 | ||
| 29 | bool BufferQueueCore::WaitForDequeueCondition() { | 30 | bool BufferQueueCore::WaitForDequeueCondition(std::unique_lock<std::mutex>& lk) { |
| 30 | if (is_shutting_down) { | 31 | if (is_shutting_down) { |
| 31 | return false; | 32 | return false; |
| 32 | } | 33 | } |
| 33 | 34 | ||
| 34 | dequeue_condition.wait(mutex); | 35 | dequeue_condition.wait(lk, [&] { return dequeue_possible.load(); }); |
| 36 | dequeue_possible.store(false); | ||
| 35 | 37 | ||
| 36 | return true; | 38 | return true; |
| 37 | } | 39 | } |
diff --git a/src/core/hle/service/nvflinger/buffer_queue_core.h b/src/core/hle/service/nvflinger/buffer_queue_core.h index ca6baefaf..85b3bc4c1 100644 --- a/src/core/hle/service/nvflinger/buffer_queue_core.h +++ b/src/core/hle/service/nvflinger/buffer_queue_core.h | |||
| @@ -38,7 +38,7 @@ public: | |||
| 38 | 38 | ||
| 39 | private: | 39 | private: |
| 40 | void SignalDequeueCondition(); | 40 | void SignalDequeueCondition(); |
| 41 | bool WaitForDequeueCondition(); | 41 | bool WaitForDequeueCondition(std::unique_lock<std::mutex>& lk); |
| 42 | 42 | ||
| 43 | s32 GetMinUndequeuedBufferCountLocked(bool async) const; | 43 | s32 GetMinUndequeuedBufferCountLocked(bool async) const; |
| 44 | s32 GetMinMaxBufferCountLocked(bool async) const; | 44 | s32 GetMinMaxBufferCountLocked(bool async) const; |
| @@ -60,7 +60,8 @@ private: | |||
| 60 | BufferQueueDefs::SlotsType slots{}; | 60 | BufferQueueDefs::SlotsType slots{}; |
| 61 | std::vector<BufferItem> queue; | 61 | std::vector<BufferItem> queue; |
| 62 | s32 override_max_buffer_count{}; | 62 | s32 override_max_buffer_count{}; |
| 63 | mutable std::condition_variable_any dequeue_condition; | 63 | std::condition_variable dequeue_condition; |
| 64 | std::atomic<bool> dequeue_possible{}; | ||
| 64 | const bool use_async_buffer{}; // This is always disabled on HOS | 65 | const bool use_async_buffer{}; // This is always disabled on HOS |
| 65 | bool dequeue_buffer_cannot_block{}; | 66 | bool dequeue_buffer_cannot_block{}; |
| 66 | PixelFormat default_buffer_format{PixelFormat::Rgba8888}; | 67 | PixelFormat default_buffer_format{PixelFormat::Rgba8888}; |
diff --git a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvflinger/buffer_queue_producer.cpp index 41ba44b21..e601b5da1 100644 --- a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue_producer.cpp | |||
| @@ -121,8 +121,8 @@ Status BufferQueueProducer::SetBufferCount(s32 buffer_count) { | |||
| 121 | return Status::NoError; | 121 | return Status::NoError; |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | Status BufferQueueProducer::WaitForFreeSlotThenRelock(bool async, s32* found, | 124 | Status BufferQueueProducer::WaitForFreeSlotThenRelock(bool async, s32* found, Status* return_flags, |
| 125 | Status* return_flags) const { | 125 | std::unique_lock<std::mutex>& lk) const { |
| 126 | bool try_again = true; | 126 | bool try_again = true; |
| 127 | 127 | ||
| 128 | while (try_again) { | 128 | while (try_again) { |
| @@ -214,7 +214,7 @@ Status BufferQueueProducer::WaitForFreeSlotThenRelock(bool async, s32* found, | |||
| 214 | return Status::WouldBlock; | 214 | return Status::WouldBlock; |
| 215 | } | 215 | } |
| 216 | 216 | ||
| 217 | if (!core->WaitForDequeueCondition()) { | 217 | if (!core->WaitForDequeueCondition(lk)) { |
| 218 | // We are no longer running | 218 | // We are no longer running |
| 219 | return Status::NoError; | 219 | return Status::NoError; |
| 220 | } | 220 | } |
| @@ -237,7 +237,7 @@ Status BufferQueueProducer::DequeueBuffer(s32* out_slot, Fence* out_fence, bool | |||
| 237 | Status return_flags = Status::NoError; | 237 | Status return_flags = Status::NoError; |
| 238 | bool attached_by_consumer = false; | 238 | bool attached_by_consumer = false; |
| 239 | { | 239 | { |
| 240 | std::scoped_lock lock{core->mutex}; | 240 | std::unique_lock lock{core->mutex}; |
| 241 | core->WaitWhileAllocatingLocked(); | 241 | core->WaitWhileAllocatingLocked(); |
| 242 | 242 | ||
| 243 | if (format == PixelFormat::NoFormat) { | 243 | if (format == PixelFormat::NoFormat) { |
| @@ -248,7 +248,7 @@ Status BufferQueueProducer::DequeueBuffer(s32* out_slot, Fence* out_fence, bool | |||
| 248 | usage |= core->consumer_usage_bit; | 248 | usage |= core->consumer_usage_bit; |
| 249 | 249 | ||
| 250 | s32 found{}; | 250 | s32 found{}; |
| 251 | Status status = WaitForFreeSlotThenRelock(async, &found, &return_flags); | 251 | Status status = WaitForFreeSlotThenRelock(async, &found, &return_flags, lock); |
| 252 | if (status != Status::NoError) { | 252 | if (status != Status::NoError) { |
| 253 | return status; | 253 | return status; |
| 254 | } | 254 | } |
| @@ -400,13 +400,13 @@ Status BufferQueueProducer::AttachBuffer(s32* out_slot, | |||
| 400 | return Status::BadValue; | 400 | return Status::BadValue; |
| 401 | } | 401 | } |
| 402 | 402 | ||
| 403 | std::scoped_lock lock{core->mutex}; | 403 | std::unique_lock lock{core->mutex}; |
| 404 | core->WaitWhileAllocatingLocked(); | 404 | core->WaitWhileAllocatingLocked(); |
| 405 | 405 | ||
| 406 | Status return_flags = Status::NoError; | 406 | Status return_flags = Status::NoError; |
| 407 | s32 found{}; | 407 | s32 found{}; |
| 408 | 408 | ||
| 409 | const auto status = WaitForFreeSlotThenRelock(false, &found, &return_flags); | 409 | const auto status = WaitForFreeSlotThenRelock(false, &found, &return_flags, lock); |
| 410 | if (status != Status::NoError) { | 410 | if (status != Status::NoError) { |
| 411 | return status; | 411 | return status; |
| 412 | } | 412 | } |
diff --git a/src/core/hle/service/nvflinger/buffer_queue_producer.h b/src/core/hle/service/nvflinger/buffer_queue_producer.h index 7526bf8ec..1d380480f 100644 --- a/src/core/hle/service/nvflinger/buffer_queue_producer.h +++ b/src/core/hle/service/nvflinger/buffer_queue_producer.h | |||
| @@ -70,7 +70,8 @@ public: | |||
| 70 | private: | 70 | private: |
| 71 | BufferQueueProducer(const BufferQueueProducer&) = delete; | 71 | BufferQueueProducer(const BufferQueueProducer&) = delete; |
| 72 | 72 | ||
| 73 | Status WaitForFreeSlotThenRelock(bool async, s32* found, Status* return_flags) const; | 73 | Status WaitForFreeSlotThenRelock(bool async, s32* found, Status* return_flags, |
| 74 | std::unique_lock<std::mutex>& lk) const; | ||
| 74 | 75 | ||
| 75 | Kernel::KEvent* buffer_wait_event{}; | 76 | Kernel::KEvent* buffer_wait_event{}; |
| 76 | Service::KernelHelpers::ServiceContext& service_context; | 77 | Service::KernelHelpers::ServiceContext& service_context; |