summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/service/vi/vi.cpp77
1 files changed, 43 insertions, 34 deletions
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 45cfffe06..93a113b93 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -536,9 +536,6 @@ private:
LOG_DEBUG(Service_VI, "called. id=0x{:08X} transaction={:X}, flags=0x{:08X}", id,
transaction, flags);
- const auto guard = nv_flinger.Lock();
- auto& buffer_queue = nv_flinger.FindBufferQueue(id);
-
switch (transaction) {
case TransactionId::Connect: {
IGBPConnectRequestParcel request{ctx.ReadBuffer()};
@@ -553,7 +550,11 @@ private:
case TransactionId::SetPreallocatedBuffer: {
IGBPSetPreallocatedBufferRequestParcel request{ctx.ReadBuffer()};
- buffer_queue.SetPreallocatedBuffer(request.data.slot, request.buffer_container.buffer);
+ {
+ const auto guard = nv_flinger.Lock();
+ auto& buffer_queue = nv_flinger.FindBufferQueue(id);
+ buffer_queue.SetPreallocatedBuffer(request.data.slot, request.buffer_container.buffer);
+ }
IGBPSetPreallocatedBufferResponseParcel response{};
ctx.WriteBuffer(response.Serialize());
@@ -563,48 +564,46 @@ private:
IGBPDequeueBufferRequestParcel request{ctx.ReadBuffer()};
const u32 width{request.data.width};
const u32 height{request.data.height};
- auto result = buffer_queue.DequeueBuffer(width, height);
-
- if (result) {
- // Buffer is available
- IGBPDequeueBufferResponseParcel response{result->first, *result->second};
- ctx.WriteBuffer(response.Serialize());
- } else {
- // Wait the current thread until a buffer becomes available
- ctx.SleepClientThread(
- "IHOSBinderDriver::DequeueBuffer", UINT64_MAX,
- [=, this](std::shared_ptr<Kernel::Thread> thread,
- Kernel::HLERequestContext& ctx, Kernel::ThreadWakeupReason reason) {
- // Repeat TransactParcel DequeueBuffer when a buffer is available
- const auto guard = nv_flinger.Lock();
- auto& buffer_queue = nv_flinger.FindBufferQueue(id);
- auto result = buffer_queue.DequeueBuffer(width, height);
- ASSERT_MSG(result != std::nullopt, "Could not dequeue buffer.");
-
- IGBPDequeueBufferResponseParcel response{result->first, *result->second};
- ctx.WriteBuffer(response.Serialize());
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
- },
- buffer_queue.GetWritableBufferWaitEvent());
+
+ std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> result;
+
+ while (!result) {
+ {
+ const auto guard = nv_flinger.Lock();
+ auto& buffer_queue = nv_flinger.FindBufferQueue(id);
+ result = buffer_queue.DequeueBuffer(width, height);
+ }
+
+ if (result) {
+ // Buffer is available
+ IGBPDequeueBufferResponseParcel response{result->first, *result->second};
+ ctx.WriteBuffer(response.Serialize());
+ }
}
+
break;
}
case TransactionId::RequestBuffer: {
IGBPRequestBufferRequestParcel request{ctx.ReadBuffer()};
+ const auto guard = nv_flinger.Lock();
+ auto& buffer_queue = nv_flinger.FindBufferQueue(id);
auto& buffer = buffer_queue.RequestBuffer(request.slot);
-
IGBPRequestBufferResponseParcel response{buffer};
ctx.WriteBuffer(response.Serialize());
+
break;
}
case TransactionId::QueueBuffer: {
IGBPQueueBufferRequestParcel request{ctx.ReadBuffer()};
- buffer_queue.QueueBuffer(request.data.slot, request.data.transform,
- request.data.GetCropRect(), request.data.swap_interval,
- request.data.multi_fence);
+ {
+ const auto guard = nv_flinger.Lock();
+ auto& buffer_queue = nv_flinger.FindBufferQueue(id);
+ buffer_queue.QueueBuffer(request.data.slot, request.data.transform,
+ request.data.GetCropRect(), request.data.swap_interval,
+ request.data.multi_fence);
+ }
IGBPQueueBufferResponseParcel response{1280, 720};
ctx.WriteBuffer(response.Serialize());
@@ -613,6 +612,8 @@ private:
case TransactionId::Query: {
IGBPQueryRequestParcel request{ctx.ReadBuffer()};
+ const auto guard = nv_flinger.Lock();
+ auto& buffer_queue = nv_flinger.FindBufferQueue(id);
const u32 value =
buffer_queue.Query(static_cast<NVFlinger::BufferQueue::QueryType>(request.type));
@@ -623,7 +624,11 @@ private:
case TransactionId::CancelBuffer: {
IGBPCancelBufferRequestParcel request{ctx.ReadBuffer()};
- buffer_queue.CancelBuffer(request.data.slot, request.data.multi_fence);
+ {
+ const auto guard = nv_flinger.Lock();
+ auto& buffer_queue = nv_flinger.FindBufferQueue(id);
+ buffer_queue.CancelBuffer(request.data.slot, request.data.multi_fence);
+ }
IGBPCancelBufferResponseParcel response{};
ctx.WriteBuffer(response.Serialize());
@@ -633,7 +638,11 @@ private:
LOG_WARNING(Service_VI, "(STUBBED) called, transaction=Disconnect");
const auto buffer = ctx.ReadBuffer();
- buffer_queue.Disconnect();
+ {
+ const auto guard = nv_flinger.Lock();
+ auto& buffer_queue = nv_flinger.FindBufferQueue(id);
+ buffer_queue.Disconnect();
+ }
IGBPEmptyResponseParcel response{};
ctx.WriteBuffer(response.Serialize());