aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/service/vi/vi.cpp
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2018-03-18 22:25:09 -0400
committerGitHub <noreply@github.com>2018-03-18 22:25:09 -0400
commit2dc3a56e9602e0bfba9bfc19f31f0433d1564ccc (patch)
tree6e49476a6c0c1a333090a01afa7a4fbfd11b8888 /src/core/hle/service/vi/vi.cpp
parent2332a44b681473509ca67438b5b3a2bddc91a60b (diff)
parentc1c92c30f9951e41a2091770cc5bf1354fba7794 (diff)
Merge pull request #250 from bunnei/buffer-dequeue-wait
vi: TransactParcel DequeueBuffer should wait current thread
Diffstat (limited to 'src/core/hle/service/vi/vi.cpp')
-rw-r--r--src/core/hle/service/vi/vi.cpp30
1 files changed, 24 insertions, 6 deletions
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 0aa621dfe..7b6453447 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -486,12 +486,30 @@ private:
ctx.WriteBuffer(response.Serialize());
} else if (transaction == TransactionId::DequeueBuffer) {
IGBPDequeueBufferRequestParcel request{ctx.ReadBuffer()};
-
- u32 slot = buffer_queue->DequeueBuffer(request.data.pixel_format, request.data.width,
- request.data.height);
-
- IGBPDequeueBufferResponseParcel response{slot};
- ctx.WriteBuffer(response.Serialize());
+ const u32 width{request.data.width};
+ const u32 height{request.data.height};
+ boost::optional<u32> slot = buffer_queue->DequeueBuffer(width, height);
+
+ if (slot != boost::none) {
+ // Buffer is available
+ IGBPDequeueBufferResponseParcel response{*slot};
+ ctx.WriteBuffer(response.Serialize());
+ } else {
+ // Wait the current thread until a buffer becomes available
+ auto wait_event = ctx.SleepClientThread(
+ Kernel::GetCurrentThread(), "IHOSBinderDriver::DequeueBuffer", -1,
+ [=](Kernel::SharedPtr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx,
+ ThreadWakeupReason reason) {
+ // Repeat TransactParcel DequeueBuffer when a buffer is available
+ auto buffer_queue = nv_flinger->GetBufferQueue(id);
+ boost::optional<u32> slot = buffer_queue->DequeueBuffer(width, height);
+ IGBPDequeueBufferResponseParcel response{*slot};
+ ctx.WriteBuffer(response.Serialize());
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+ });
+ buffer_queue->SetBufferWaitEvent(std::move(wait_event));
+ }
} else if (transaction == TransactionId::RequestBuffer) {
IGBPRequestBufferRequestParcel request{ctx.ReadBuffer()};