forked from eden-emu/eden
		
	core: hle: service: buffer_queue: Improve management of KEvent.
This commit is contained in:
		
							parent
							
								
									4860b008ec
								
							
						
					
					
						commit
						b690071dd5
					
				
					 3 changed files with 24 additions and 14 deletions
				
			
		|  | @ -9,17 +9,20 @@ | |||
| #include "core/core.h" | ||||
| #include "core/hle/kernel/k_writable_event.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/service/kernel_helpers.h" | ||||
| #include "core/hle/service/nvflinger/buffer_queue.h" | ||||
| 
 | ||||
| namespace Service::NVFlinger { | ||||
| 
 | ||||
| BufferQueue::BufferQueue(Kernel::KernelCore& kernel, u32 id_, u64 layer_id_) | ||||
|     : id(id_), layer_id(layer_id_), buffer_wait_event{kernel} { | ||||
|     Kernel::KAutoObject::Create(std::addressof(buffer_wait_event)); | ||||
|     buffer_wait_event.Initialize("BufferQueue:WaitEvent"); | ||||
| BufferQueue::BufferQueue(Kernel::KernelCore& kernel, u32 id_, u64 layer_id_, | ||||
|                          KernelHelpers::ServiceContext& service_context_) | ||||
|     : id(id_), layer_id(layer_id_), service_context{service_context_} { | ||||
|     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) { | ||||
|     ASSERT(slot < buffer_slots); | ||||
|  | @ -41,7 +44,7 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer) | |||
|         .multi_fence = {}, | ||||
|     }; | ||||
| 
 | ||||
|     buffer_wait_event.GetWritableEvent().Signal(); | ||||
|     buffer_wait_event->GetWritableEvent().Signal(); | ||||
| } | ||||
| 
 | ||||
| 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(); | ||||
| 
 | ||||
|     buffer_wait_event.GetWritableEvent().Signal(); | ||||
|     buffer_wait_event->GetWritableEvent().Signal(); | ||||
| } | ||||
| 
 | ||||
| std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() { | ||||
|  | @ -154,7 +157,7 @@ void BufferQueue::ReleaseBuffer(u32 slot) { | |||
|     } | ||||
|     free_buffers_condition.notify_one(); | ||||
| 
 | ||||
|     buffer_wait_event.GetWritableEvent().Signal(); | ||||
|     buffer_wait_event->GetWritableEvent().Signal(); | ||||
| } | ||||
| 
 | ||||
| void BufferQueue::Connect() { | ||||
|  | @ -169,7 +172,7 @@ void BufferQueue::Disconnect() { | |||
|         std::unique_lock lock{queue_sequence_mutex}; | ||||
|         queue_sequence.clear(); | ||||
|     } | ||||
|     buffer_wait_event.GetWritableEvent().Signal(); | ||||
|     buffer_wait_event->GetWritableEvent().Signal(); | ||||
|     is_connect = false; | ||||
|     free_buffers_condition.notify_one(); | ||||
| } | ||||
|  | @ -189,11 +192,11 @@ u32 BufferQueue::Query(QueryType type) { | |||
| } | ||||
| 
 | ||||
| Kernel::KWritableEvent& BufferQueue::GetWritableBufferWaitEvent() { | ||||
|     return buffer_wait_event.GetWritableEvent(); | ||||
|     return buffer_wait_event->GetWritableEvent(); | ||||
| } | ||||
| 
 | ||||
| Kernel::KReadableEvent& BufferQueue::GetBufferWaitEvent() { | ||||
|     return buffer_wait_event.GetReadableEvent(); | ||||
|     return buffer_wait_event->GetReadableEvent(); | ||||
| } | ||||
| 
 | ||||
| } // namespace Service::NVFlinger
 | ||||
|  |  | |||
|  | @ -24,6 +24,10 @@ class KReadableEvent; | |||
| class KWritableEvent; | ||||
| } // namespace Kernel
 | ||||
| 
 | ||||
| namespace Service::KernelHelpers { | ||||
| class ServiceContext; | ||||
| } // namespace Service::KernelHelpers
 | ||||
| 
 | ||||
| namespace Service::NVFlinger { | ||||
| 
 | ||||
| constexpr u32 buffer_slots = 0x40; | ||||
|  | @ -54,7 +58,8 @@ public: | |||
|         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(); | ||||
| 
 | ||||
|     enum class BufferTransformFlags : u32 { | ||||
|  | @ -130,12 +135,14 @@ private: | |||
|     std::list<u32> free_buffers; | ||||
|     std::array<Buffer, buffer_slots> buffers; | ||||
|     std::list<u32> queue_sequence; | ||||
|     Kernel::KEvent buffer_wait_event; | ||||
|     Kernel::KEvent* buffer_wait_event{}; | ||||
| 
 | ||||
|     std::mutex free_buffers_mutex; | ||||
|     std::condition_variable free_buffers_condition; | ||||
| 
 | ||||
|     std::mutex queue_sequence_mutex; | ||||
| 
 | ||||
|     KernelHelpers::ServiceContext& service_context; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Service::NVFlinger
 | ||||
|  |  | |||
|  | @ -147,7 +147,7 @@ std::optional<u64> NVFlinger::CreateLayer(u64 display_id) { | |||
| void NVFlinger::CreateLayerAtId(VI::Display& display, u64 layer_id) { | ||||
|     const u32 buffer_queue_id = next_buffer_queue_id++; | ||||
|     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()); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bunnei
						bunnei