diff options
Diffstat (limited to '')
| -rw-r--r-- | src/core/hle/kernel/hle_ipc.cpp | 10 | ||||
| -rw-r--r-- | src/core/hle/kernel/hle_ipc.h | 4 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue.cpp | 20 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue.h | 8 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/nvflinger.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/service/vi/vi.cpp | 8 |
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 | ||
| 30 | SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread, | 30 | SharedPtr<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 { | |||
| 13 | namespace NVFlinger { | 13 | namespace NVFlinger { |
| 14 | 14 | ||
| 15 | BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) { | 15 | BufferQueue::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 | ||
| 20 | void BufferQueue::SetPreallocatedBuffer(u32 slot, IGBPBuffer& igbp_buffer) { | 20 | void 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 | ||
| 35 | boost::optional<u32> BufferQueue::DequeueBuffer(u32 width, u32 height) { | 32 | boost::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 | ||
| 96 | u32 BufferQueue::Query(QueryType type) { | 89 | u32 BufferQueue::Query(QueryType type) { |
| @@ -106,10 +99,5 @@ u32 BufferQueue::Query(QueryType type) { | |||
| 106 | return 0; | 99 | return 0; |
| 107 | } | 100 | } |
| 108 | 101 | ||
| 109 | void 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 | ||
| 90 | private: | 89 | private: |
| @@ -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; |