summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp10
-rw-r--r--src/core/hle/kernel/hle_ipc.h4
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.cpp20
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.h8
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp3
-rw-r--r--src/core/hle/service/vi/vi.cpp8
6 files changed, 21 insertions, 32 deletions
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index 2532dd450..b1e6f565b 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -29,7 +29,8 @@ void SessionRequestHandler::ClientDisconnected(SharedPtr<ServerSession> server_s
29 29
30SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread, 30SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread,
31 const std::string& reason, u64 timeout, 31 const std::string& reason, u64 timeout,
32 WakeupCallback&& callback) { 32 WakeupCallback&& callback,
33 Kernel::SharedPtr<Kernel::Event> event) {
33 34
34 // Put the client thread to sleep until the wait event is signaled or the timeout expires. 35 // Put the client thread to sleep until the wait event is signaled or the timeout expires.
35 thread->wakeup_callback = 36 thread->wakeup_callback =
@@ -41,7 +42,12 @@ SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread,
41 return true; 42 return true;
42 }; 43 };
43 44
44 auto event = Kernel::Event::Create(Kernel::ResetType::OneShot, "HLE Pause Event: " + reason); 45 if (!event) {
46 // Create event if not provided
47 event = Kernel::Event::Create(Kernel::ResetType::OneShot, "HLE Pause Event: " + reason);
48 }
49
50 event->Clear();
45 thread->status = THREADSTATUS_WAIT_HLE_EVENT; 51 thread->status = THREADSTATUS_WAIT_HLE_EVENT;
46 thread->wait_objects = {event}; 52 thread->wait_objects = {event};
47 event->AddWaitingThread(thread); 53 event->AddWaitingThread(thread);
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h
index 376263eac..c6eca7404 100644
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/src/core/hle/kernel/hle_ipc.h
@@ -118,10 +118,12 @@ public:
118 * @param callback Callback to be invoked when the thread is resumed. This callback must write 118 * @param callback Callback to be invoked when the thread is resumed. This callback must write
119 * the entire command response once again, regardless of the state of it before this function 119 * the entire command response once again, regardless of the state of it before this function
120 * was called. 120 * was called.
121 * @param event Event to use to wake up the thread. If unspecified, an event will be created.
121 * @returns Event that when signaled will resume the thread and call the callback function. 122 * @returns Event that when signaled will resume the thread and call the callback function.
122 */ 123 */
123 SharedPtr<Event> SleepClientThread(SharedPtr<Thread> thread, const std::string& reason, 124 SharedPtr<Event> SleepClientThread(SharedPtr<Thread> thread, const std::string& reason,
124 u64 timeout, WakeupCallback&& callback); 125 u64 timeout, WakeupCallback&& callback,
126 Kernel::SharedPtr<Kernel::Event> event = nullptr);
125 127
126 void ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming); 128 void ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming);
127 129
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp
index f7f2fe1b2..a181cd2dc 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue.cpp
@@ -13,8 +13,8 @@ namespace Service {
13namespace NVFlinger { 13namespace NVFlinger {
14 14
15BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) { 15BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) {
16 native_handle = Kernel::Event::Create(Kernel::ResetType::OneShot, "BufferQueue NativeHandle"); 16 buffer_wait_event =
17 native_handle->Signal(); 17 Kernel::Event::Create(Kernel::ResetType::Sticky, "BufferQueue NativeHandle");
18} 18}
19 19
20void BufferQueue::SetPreallocatedBuffer(u32 slot, IGBPBuffer& igbp_buffer) { 20void BufferQueue::SetPreallocatedBuffer(u32 slot, IGBPBuffer& igbp_buffer) {
@@ -26,10 +26,7 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, IGBPBuffer& igbp_buffer) {
26 LOG_WARNING(Service, "Adding graphics buffer {}", slot); 26 LOG_WARNING(Service, "Adding graphics buffer {}", slot);
27 27
28 queue.emplace_back(buffer); 28 queue.emplace_back(buffer);
29 29 buffer_wait_event->Signal();
30 if (buffer_wait_event) {
31 buffer_wait_event->Signal();
32 }
33} 30}
34 31
35boost::optional<u32> BufferQueue::DequeueBuffer(u32 width, u32 height) { 32boost::optional<u32> BufferQueue::DequeueBuffer(u32 width, u32 height) {
@@ -48,8 +45,6 @@ boost::optional<u32> BufferQueue::DequeueBuffer(u32 width, u32 height) {
48 return boost::none; 45 return boost::none;
49 } 46 }
50 47
51 buffer_wait_event = nullptr;
52
53 itr->status = Buffer::Status::Dequeued; 48 itr->status = Buffer::Status::Dequeued;
54 return itr->slot; 49 return itr->slot;
55} 50}
@@ -88,9 +83,7 @@ void BufferQueue::ReleaseBuffer(u32 slot) {
88 ASSERT(itr->status == Buffer::Status::Acquired); 83 ASSERT(itr->status == Buffer::Status::Acquired);
89 itr->status = Buffer::Status::Free; 84 itr->status = Buffer::Status::Free;
90 85
91 if (buffer_wait_event) { 86 buffer_wait_event->Signal();
92 buffer_wait_event->Signal();
93 }
94} 87}
95 88
96u32 BufferQueue::Query(QueryType type) { 89u32 BufferQueue::Query(QueryType type) {
@@ -106,10 +99,5 @@ u32 BufferQueue::Query(QueryType type) {
106 return 0; 99 return 0;
107} 100}
108 101
109void BufferQueue::SetBufferWaitEvent(Kernel::SharedPtr<Kernel::Event>&& wait_event) {
110 ASSERT_MSG(!buffer_wait_event, "buffer_wait_event only supports a single waiting thread!");
111 buffer_wait_event = std::move(wait_event);
112}
113
114} // namespace NVFlinger 102} // namespace NVFlinger
115} // namespace Service 103} // namespace Service
diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h
index 1de5767cb..1e55b487e 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.h
+++ b/src/core/hle/service/nvflinger/buffer_queue.h
@@ -77,14 +77,13 @@ public:
77 boost::optional<const Buffer&> AcquireBuffer(); 77 boost::optional<const Buffer&> AcquireBuffer();
78 void ReleaseBuffer(u32 slot); 78 void ReleaseBuffer(u32 slot);
79 u32 Query(QueryType type); 79 u32 Query(QueryType type);
80 void SetBufferWaitEvent(Kernel::SharedPtr<Kernel::Event>&& wait_event);
81 80
82 u32 GetId() const { 81 u32 GetId() const {
83 return id; 82 return id;
84 } 83 }
85 84
86 Kernel::SharedPtr<Kernel::Event> GetNativeHandle() const { 85 Kernel::SharedPtr<Kernel::Event> GetBufferWaitEvent() const {
87 return native_handle; 86 return buffer_wait_event;
88 } 87 }
89 88
90private: 89private:
@@ -92,9 +91,6 @@ private:
92 u64 layer_id; 91 u64 layer_id;
93 92
94 std::vector<Buffer> queue; 93 std::vector<Buffer> queue;
95 Kernel::SharedPtr<Kernel::Event> native_handle;
96
97 /// Used to signal waiting thread when no buffers are available
98 Kernel::SharedPtr<Kernel::Event> buffer_wait_event; 94 Kernel::SharedPtr<Kernel::Event> buffer_wait_event;
99}; 95};
100 96
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index ef3c2cc98..826646b7d 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -152,9 +152,6 @@ void NVFlinger::Compose() {
152 igbp_buffer.width, igbp_buffer.height, igbp_buffer.stride, buffer->transform); 152 igbp_buffer.width, igbp_buffer.height, igbp_buffer.stride, buffer->transform);
153 153
154 buffer_queue->ReleaseBuffer(buffer->slot); 154 buffer_queue->ReleaseBuffer(buffer->slot);
155
156 // TODO(Subv): Figure out when we should actually signal this event.
157 buffer_queue->GetNativeHandle()->Signal();
158 } 155 }
159} 156}
160 157
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index f3765b555..e094510bf 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -495,7 +495,7 @@ private:
495 ctx.WriteBuffer(response.Serialize()); 495 ctx.WriteBuffer(response.Serialize());
496 } else { 496 } else {
497 // Wait the current thread until a buffer becomes available 497 // Wait the current thread until a buffer becomes available
498 auto wait_event = ctx.SleepClientThread( 498 ctx.SleepClientThread(
499 Kernel::GetCurrentThread(), "IHOSBinderDriver::DequeueBuffer", -1, 499 Kernel::GetCurrentThread(), "IHOSBinderDriver::DequeueBuffer", -1,
500 [=](Kernel::SharedPtr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx, 500 [=](Kernel::SharedPtr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx,
501 ThreadWakeupReason reason) { 501 ThreadWakeupReason reason) {
@@ -506,8 +506,8 @@ private:
506 ctx.WriteBuffer(response.Serialize()); 506 ctx.WriteBuffer(response.Serialize());
507 IPC::ResponseBuilder rb{ctx, 2}; 507 IPC::ResponseBuilder rb{ctx, 2};
508 rb.Push(RESULT_SUCCESS); 508 rb.Push(RESULT_SUCCESS);
509 }); 509 },
510 buffer_queue->SetBufferWaitEvent(std::move(wait_event)); 510 buffer_queue->GetBufferWaitEvent());
511 } 511 }
512 } else if (transaction == TransactionId::RequestBuffer) { 512 } else if (transaction == TransactionId::RequestBuffer) {
513 IGBPRequestBufferRequestParcel request{ctx.ReadBuffer()}; 513 IGBPRequestBufferRequestParcel request{ctx.ReadBuffer()};
@@ -565,7 +565,7 @@ private:
565 LOG_WARNING(Service_VI, "(STUBBED) called id={}, unknown={:08X}", id, unknown); 565 LOG_WARNING(Service_VI, "(STUBBED) called id={}, unknown={:08X}", id, unknown);
566 IPC::ResponseBuilder rb{ctx, 2, 1}; 566 IPC::ResponseBuilder rb{ctx, 2, 1};
567 rb.Push(RESULT_SUCCESS); 567 rb.Push(RESULT_SUCCESS);
568 rb.PushCopyObjects(buffer_queue->GetNativeHandle()); 568 rb.PushCopyObjects(buffer_queue->GetBufferWaitEvent());
569 } 569 }
570 570
571 std::shared_ptr<NVFlinger::NVFlinger> nv_flinger; 571 std::shared_ptr<NVFlinger::NVFlinger> nv_flinger;