Merge pull request #6971 from bunnei/buffer-queue-kevent
core: hle: service: buffer_queue: Improve management of KEvent.
This commit is contained in:
		| @@ -9,17 +9,20 @@ | |||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
| #include "core/hle/kernel/k_writable_event.h" | #include "core/hle/kernel/k_writable_event.h" | ||||||
| #include "core/hle/kernel/kernel.h" | #include "core/hle/kernel/kernel.h" | ||||||
|  | #include "core/hle/service/kernel_helpers.h" | ||||||
| #include "core/hle/service/nvflinger/buffer_queue.h" | #include "core/hle/service/nvflinger/buffer_queue.h" | ||||||
|  |  | ||||||
| namespace Service::NVFlinger { | namespace Service::NVFlinger { | ||||||
|  |  | ||||||
| BufferQueue::BufferQueue(Kernel::KernelCore& kernel, u32 id_, u64 layer_id_) | BufferQueue::BufferQueue(Kernel::KernelCore& kernel, u32 id_, u64 layer_id_, | ||||||
|     : id(id_), layer_id(layer_id_), buffer_wait_event{kernel} { |                          KernelHelpers::ServiceContext& service_context_) | ||||||
|     Kernel::KAutoObject::Create(std::addressof(buffer_wait_event)); |     : id(id_), layer_id(layer_id_), service_context{service_context_} { | ||||||
|     buffer_wait_event.Initialize("BufferQueue:WaitEvent"); |     buffer_wait_event = service_context.CreateEvent("BufferQueue:WaitEvent"); | ||||||
| } | } | ||||||
|  |  | ||||||
| BufferQueue::~BufferQueue() = default; | BufferQueue::~BufferQueue() { | ||||||
|  |     service_context.CloseEvent(buffer_wait_event); | ||||||
|  | } | ||||||
|  |  | ||||||
| void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer) { | void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer) { | ||||||
|     ASSERT(slot < buffer_slots); |     ASSERT(slot < buffer_slots); | ||||||
| @@ -41,7 +44,7 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer) | |||||||
|         .multi_fence = {}, |         .multi_fence = {}, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     buffer_wait_event.GetWritableEvent().Signal(); |     buffer_wait_event->GetWritableEvent().Signal(); | ||||||
| } | } | ||||||
|  |  | ||||||
| std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> BufferQueue::DequeueBuffer(u32 width, | std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> BufferQueue::DequeueBuffer(u32 width, | ||||||
| @@ -119,7 +122,7 @@ void BufferQueue::CancelBuffer(u32 slot, const Service::Nvidia::MultiFence& mult | |||||||
|     } |     } | ||||||
|     free_buffers_condition.notify_one(); |     free_buffers_condition.notify_one(); | ||||||
|  |  | ||||||
|     buffer_wait_event.GetWritableEvent().Signal(); |     buffer_wait_event->GetWritableEvent().Signal(); | ||||||
| } | } | ||||||
|  |  | ||||||
| std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() { | std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() { | ||||||
| @@ -154,7 +157,7 @@ void BufferQueue::ReleaseBuffer(u32 slot) { | |||||||
|     } |     } | ||||||
|     free_buffers_condition.notify_one(); |     free_buffers_condition.notify_one(); | ||||||
|  |  | ||||||
|     buffer_wait_event.GetWritableEvent().Signal(); |     buffer_wait_event->GetWritableEvent().Signal(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void BufferQueue::Connect() { | void BufferQueue::Connect() { | ||||||
| @@ -169,7 +172,7 @@ void BufferQueue::Disconnect() { | |||||||
|         std::unique_lock lock{queue_sequence_mutex}; |         std::unique_lock lock{queue_sequence_mutex}; | ||||||
|         queue_sequence.clear(); |         queue_sequence.clear(); | ||||||
|     } |     } | ||||||
|     buffer_wait_event.GetWritableEvent().Signal(); |     buffer_wait_event->GetWritableEvent().Signal(); | ||||||
|     is_connect = false; |     is_connect = false; | ||||||
|     free_buffers_condition.notify_one(); |     free_buffers_condition.notify_one(); | ||||||
| } | } | ||||||
| @@ -189,11 +192,11 @@ u32 BufferQueue::Query(QueryType type) { | |||||||
| } | } | ||||||
|  |  | ||||||
| Kernel::KWritableEvent& BufferQueue::GetWritableBufferWaitEvent() { | Kernel::KWritableEvent& BufferQueue::GetWritableBufferWaitEvent() { | ||||||
|     return buffer_wait_event.GetWritableEvent(); |     return buffer_wait_event->GetWritableEvent(); | ||||||
| } | } | ||||||
|  |  | ||||||
| Kernel::KReadableEvent& BufferQueue::GetBufferWaitEvent() { | Kernel::KReadableEvent& BufferQueue::GetBufferWaitEvent() { | ||||||
|     return buffer_wait_event.GetReadableEvent(); |     return buffer_wait_event->GetReadableEvent(); | ||||||
| } | } | ||||||
|  |  | ||||||
| } // namespace Service::NVFlinger | } // namespace Service::NVFlinger | ||||||
|   | |||||||
| @@ -24,6 +24,10 @@ class KReadableEvent; | |||||||
| class KWritableEvent; | class KWritableEvent; | ||||||
| } // namespace Kernel | } // namespace Kernel | ||||||
|  |  | ||||||
|  | namespace Service::KernelHelpers { | ||||||
|  | class ServiceContext; | ||||||
|  | } // namespace Service::KernelHelpers | ||||||
|  |  | ||||||
| namespace Service::NVFlinger { | namespace Service::NVFlinger { | ||||||
|  |  | ||||||
| constexpr u32 buffer_slots = 0x40; | constexpr u32 buffer_slots = 0x40; | ||||||
| @@ -54,7 +58,8 @@ public: | |||||||
|         NativeWindowFormat = 2, |         NativeWindowFormat = 2, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     explicit BufferQueue(Kernel::KernelCore& kernel, u32 id_, u64 layer_id_); |     explicit BufferQueue(Kernel::KernelCore& kernel, u32 id_, u64 layer_id_, | ||||||
|  |                          KernelHelpers::ServiceContext& service_context_); | ||||||
|     ~BufferQueue(); |     ~BufferQueue(); | ||||||
|  |  | ||||||
|     enum class BufferTransformFlags : u32 { |     enum class BufferTransformFlags : u32 { | ||||||
| @@ -130,12 +135,14 @@ private: | |||||||
|     std::list<u32> free_buffers; |     std::list<u32> free_buffers; | ||||||
|     std::array<Buffer, buffer_slots> buffers; |     std::array<Buffer, buffer_slots> buffers; | ||||||
|     std::list<u32> queue_sequence; |     std::list<u32> queue_sequence; | ||||||
|     Kernel::KEvent buffer_wait_event; |     Kernel::KEvent* buffer_wait_event{}; | ||||||
|  |  | ||||||
|     std::mutex free_buffers_mutex; |     std::mutex free_buffers_mutex; | ||||||
|     std::condition_variable free_buffers_condition; |     std::condition_variable free_buffers_condition; | ||||||
|  |  | ||||||
|     std::mutex queue_sequence_mutex; |     std::mutex queue_sequence_mutex; | ||||||
|  |  | ||||||
|  |     KernelHelpers::ServiceContext& service_context; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } // namespace Service::NVFlinger | } // namespace Service::NVFlinger | ||||||
|   | |||||||
| @@ -147,7 +147,7 @@ std::optional<u64> NVFlinger::CreateLayer(u64 display_id) { | |||||||
| void NVFlinger::CreateLayerAtId(VI::Display& display, u64 layer_id) { | void NVFlinger::CreateLayerAtId(VI::Display& display, u64 layer_id) { | ||||||
|     const u32 buffer_queue_id = next_buffer_queue_id++; |     const u32 buffer_queue_id = next_buffer_queue_id++; | ||||||
|     buffer_queues.emplace_back( |     buffer_queues.emplace_back( | ||||||
|         std::make_unique<BufferQueue>(system.Kernel(), buffer_queue_id, layer_id)); |         std::make_unique<BufferQueue>(system.Kernel(), buffer_queue_id, layer_id, service_context)); | ||||||
|     display.CreateLayer(layer_id, *buffer_queues.back()); |     display.CreateLayer(layer_id, *buffer_queues.back()); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user