Merge pull request #6971 from bunnei/buffer-queue-kevent
core: hle: service: buffer_queue: Improve management of KEvent.
This commit is contained in:
commit
eb1ba45c39
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue