hle: service: nvflinger: Refactor locking and interfaces.

This commit is contained in:
bunnei 2020-12-10 15:32:52 -08:00
parent b377da042b
commit 19a8f03ad5
3 changed files with 31 additions and 45 deletions

View file

@ -104,6 +104,8 @@ void NVFlinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) {
} }
std::optional<u64> NVFlinger::OpenDisplay(std::string_view name) { std::optional<u64> NVFlinger::OpenDisplay(std::string_view name) {
const auto guard = Lock();
LOG_DEBUG(Service, "Opening \"{}\" display", name); LOG_DEBUG(Service, "Opening \"{}\" display", name);
// TODO(Subv): Currently we only support the Default display. // TODO(Subv): Currently we only support the Default display.
@ -121,6 +123,7 @@ std::optional<u64> NVFlinger::OpenDisplay(std::string_view name) {
} }
std::optional<u64> NVFlinger::CreateLayer(u64 display_id) { std::optional<u64> NVFlinger::CreateLayer(u64 display_id) {
const auto guard = Lock();
auto* const display = FindDisplay(display_id); auto* const display = FindDisplay(display_id);
if (display == nullptr) { if (display == nullptr) {
@ -135,12 +138,15 @@ std::optional<u64> NVFlinger::CreateLayer(u64 display_id) {
} }
void NVFlinger::CloseLayer(u64 layer_id) { void NVFlinger::CloseLayer(u64 layer_id) {
const auto guard = Lock();
for (auto& display : displays) { for (auto& display : displays) {
display.CloseLayer(layer_id); display.CloseLayer(layer_id);
} }
} }
std::optional<u32> NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) const { std::optional<u32> NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) const {
const auto guard = Lock();
const auto* const layer = FindLayer(display_id, layer_id); const auto* const layer = FindLayer(display_id, layer_id);
if (layer == nullptr) { if (layer == nullptr) {
@ -151,6 +157,7 @@ std::optional<u32> NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) co
} }
std::shared_ptr<Kernel::ReadableEvent> NVFlinger::FindVsyncEvent(u64 display_id) const { std::shared_ptr<Kernel::ReadableEvent> NVFlinger::FindVsyncEvent(u64 display_id) const {
const auto guard = Lock();
auto* const display = FindDisplay(display_id); auto* const display = FindDisplay(display_id);
if (display == nullptr) { if (display == nullptr) {
@ -160,20 +167,16 @@ std::shared_ptr<Kernel::ReadableEvent> NVFlinger::FindVsyncEvent(u64 display_id)
return display->GetVSyncEvent(); return display->GetVSyncEvent();
} }
BufferQueue& NVFlinger::FindBufferQueue(u32 id) { BufferQueue* NVFlinger::FindBufferQueue(u32 id) {
const auto guard = Lock();
const auto itr = std::find_if(buffer_queues.begin(), buffer_queues.end(), const auto itr = std::find_if(buffer_queues.begin(), buffer_queues.end(),
[id](const auto& queue) { return queue.GetId() == id; }); [id](const auto& queue) { return queue.GetId() == id; });
ASSERT(itr != buffer_queues.end()); if (itr == buffer_queues.end()) {
return *itr; return nullptr;
} }
const BufferQueue& NVFlinger::FindBufferQueue(u32 id) const { return &*itr;
const auto itr = std::find_if(buffer_queues.begin(), buffer_queues.end(),
[id](const auto& queue) { return queue.GetId() == id; });
ASSERT(itr != buffer_queues.end());
return *itr;
} }
VI::Display* NVFlinger::FindDisplay(u64 display_id) { VI::Display* NVFlinger::FindDisplay(u64 display_id) {

View file

@ -75,10 +75,7 @@ public:
[[nodiscard]] std::shared_ptr<Kernel::ReadableEvent> FindVsyncEvent(u64 display_id) const; [[nodiscard]] std::shared_ptr<Kernel::ReadableEvent> FindVsyncEvent(u64 display_id) const;
/// Obtains a buffer queue identified by the ID. /// Obtains a buffer queue identified by the ID.
[[nodiscard]] BufferQueue& FindBufferQueue(u32 id); [[nodiscard]] BufferQueue* FindBufferQueue(u32 id);
/// Obtains a buffer queue identified by the ID.
[[nodiscard]] const BufferQueue& FindBufferQueue(u32 id) const;
/// Performs a composition request to the emulated nvidia GPU and triggers the vsync events when /// Performs a composition request to the emulated nvidia GPU and triggers the vsync events when
/// finished. /// finished.
@ -86,11 +83,11 @@ public:
[[nodiscard]] s64 GetNextTicks() const; [[nodiscard]] s64 GetNextTicks() const;
private:
[[nodiscard]] std::unique_lock<std::mutex> Lock() const { [[nodiscard]] std::unique_lock<std::mutex> Lock() const {
return std::unique_lock{*guard}; return std::unique_lock{*guard};
} }
private:
/// Finds the display identified by the specified ID. /// Finds the display identified by the specified ID.
[[nodiscard]] VI::Display* FindDisplay(u64 display_id); [[nodiscard]] VI::Display* FindDisplay(u64 display_id);

View file

@ -551,9 +551,9 @@ private:
IGBPSetPreallocatedBufferRequestParcel request{ctx.ReadBuffer()}; IGBPSetPreallocatedBufferRequestParcel request{ctx.ReadBuffer()};
{ {
const auto guard = nv_flinger.Lock(); auto& buffer_queue = *nv_flinger.FindBufferQueue(id);
auto& buffer_queue = nv_flinger.FindBufferQueue(id); buffer_queue.SetPreallocatedBuffer(request.data.slot,
buffer_queue.SetPreallocatedBuffer(request.data.slot, request.buffer_container.buffer); request.buffer_container.buffer);
} }
IGBPSetPreallocatedBufferResponseParcel response{}; IGBPSetPreallocatedBufferResponseParcel response{};
@ -568,11 +568,8 @@ private:
std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> result; std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> result;
while (!result) { while (!result) {
{ auto& buffer_queue = *nv_flinger.FindBufferQueue(id);
const auto guard = nv_flinger.Lock();
auto& buffer_queue = nv_flinger.FindBufferQueue(id);
result = buffer_queue.DequeueBuffer(width, height); result = buffer_queue.DequeueBuffer(width, height);
}
if (result) { if (result) {
// Buffer is available // Buffer is available
@ -586,8 +583,7 @@ private:
case TransactionId::RequestBuffer: { case TransactionId::RequestBuffer: {
IGBPRequestBufferRequestParcel request{ctx.ReadBuffer()}; IGBPRequestBufferRequestParcel request{ctx.ReadBuffer()};
const auto guard = nv_flinger.Lock(); auto& buffer_queue = *nv_flinger.FindBufferQueue(id);
auto& buffer_queue = nv_flinger.FindBufferQueue(id);
auto& buffer = buffer_queue.RequestBuffer(request.slot); auto& buffer = buffer_queue.RequestBuffer(request.slot);
IGBPRequestBufferResponseParcel response{buffer}; IGBPRequestBufferResponseParcel response{buffer};
ctx.WriteBuffer(response.Serialize()); ctx.WriteBuffer(response.Serialize());
@ -597,13 +593,10 @@ private:
case TransactionId::QueueBuffer: { case TransactionId::QueueBuffer: {
IGBPQueueBufferRequestParcel request{ctx.ReadBuffer()}; IGBPQueueBufferRequestParcel request{ctx.ReadBuffer()};
{ auto& buffer_queue = *nv_flinger.FindBufferQueue(id);
const auto guard = nv_flinger.Lock();
auto& buffer_queue = nv_flinger.FindBufferQueue(id);
buffer_queue.QueueBuffer(request.data.slot, request.data.transform, buffer_queue.QueueBuffer(request.data.slot, request.data.transform,
request.data.GetCropRect(), request.data.swap_interval, request.data.GetCropRect(), request.data.swap_interval,
request.data.multi_fence); request.data.multi_fence);
}
IGBPQueueBufferResponseParcel response{1280, 720}; IGBPQueueBufferResponseParcel response{1280, 720};
ctx.WriteBuffer(response.Serialize()); ctx.WriteBuffer(response.Serialize());
@ -612,8 +605,7 @@ private:
case TransactionId::Query: { case TransactionId::Query: {
IGBPQueryRequestParcel request{ctx.ReadBuffer()}; IGBPQueryRequestParcel request{ctx.ReadBuffer()};
const auto guard = nv_flinger.Lock(); auto& buffer_queue = *nv_flinger.FindBufferQueue(id);
auto& buffer_queue = nv_flinger.FindBufferQueue(id);
const u32 value = const u32 value =
buffer_queue.Query(static_cast<NVFlinger::BufferQueue::QueryType>(request.type)); buffer_queue.Query(static_cast<NVFlinger::BufferQueue::QueryType>(request.type));
@ -624,11 +616,8 @@ private:
case TransactionId::CancelBuffer: { case TransactionId::CancelBuffer: {
IGBPCancelBufferRequestParcel request{ctx.ReadBuffer()}; IGBPCancelBufferRequestParcel request{ctx.ReadBuffer()};
{ auto& buffer_queue = *nv_flinger.FindBufferQueue(id);
const auto guard = nv_flinger.Lock();
auto& buffer_queue = nv_flinger.FindBufferQueue(id);
buffer_queue.CancelBuffer(request.data.slot, request.data.multi_fence); buffer_queue.CancelBuffer(request.data.slot, request.data.multi_fence);
}
IGBPCancelBufferResponseParcel response{}; IGBPCancelBufferResponseParcel response{};
ctx.WriteBuffer(response.Serialize()); ctx.WriteBuffer(response.Serialize());
@ -638,11 +627,8 @@ private:
LOG_WARNING(Service_VI, "(STUBBED) called, transaction=Disconnect"); LOG_WARNING(Service_VI, "(STUBBED) called, transaction=Disconnect");
const auto buffer = ctx.ReadBuffer(); const auto buffer = ctx.ReadBuffer();
{ auto& buffer_queue = *nv_flinger.FindBufferQueue(id);
const auto guard = nv_flinger.Lock();
auto& buffer_queue = nv_flinger.FindBufferQueue(id);
buffer_queue.Disconnect(); buffer_queue.Disconnect();
}
IGBPEmptyResponseParcel response{}; IGBPEmptyResponseParcel response{};
ctx.WriteBuffer(response.Serialize()); ctx.WriteBuffer(response.Serialize());
@ -691,7 +677,7 @@ private:
LOG_WARNING(Service_VI, "(STUBBED) called id={}, unknown={:08X}", id, unknown); LOG_WARNING(Service_VI, "(STUBBED) called id={}, unknown={:08X}", id, unknown);
const auto& buffer_queue = nv_flinger.FindBufferQueue(id); const auto& buffer_queue = *nv_flinger.FindBufferQueue(id);
// TODO(Subv): Find out what this actually is. // TODO(Subv): Find out what this actually is.
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};