core: hle: service: buffer_queue: Improve management of KEvent.

master
bunnei 2021-08-07 01:17:13 +07:00
parent d9ce179ec2
commit e05bfd2f54
3 changed files with 24 additions and 14 deletions

@ -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());
} }