diff options
Diffstat (limited to 'src/core/hle/service')
-rw-r--r-- | src/core/hle/service/friend/friend.cpp | 11 | ||||
-rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue.cpp | 48 | ||||
-rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue.h | 2 | ||||
-rw-r--r-- | src/core/hle/service/vi/vi.cpp | 46 |
4 files changed, 87 insertions, 20 deletions
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp index 6aadb3ea8..7938b4b80 100644 --- a/src/core/hle/service/friend/friend.cpp +++ b/src/core/hle/service/friend/friend.cpp @@ -27,7 +27,7 @@ public: {10110, nullptr, "GetFriendProfileImage"}, {10200, nullptr, "SendFriendRequestForApplication"}, {10211, nullptr, "AddFacedFriendRequestForApplication"}, - {10400, nullptr, "GetBlockedUserListIds"}, + {10400, &IFriendService::GetBlockedUserListIds, "GetBlockedUserListIds"}, {10500, nullptr, "GetProfileList"}, {10600, nullptr, "DeclareOpenOnlinePlaySession"}, {10601, &IFriendService::DeclareCloseOnlinePlaySession, "DeclareCloseOnlinePlaySession"}, @@ -121,6 +121,15 @@ private: }; static_assert(sizeof(SizedFriendFilter) == 0x10, "SizedFriendFilter is an invalid size"); + void GetBlockedUserListIds(Kernel::HLERequestContext& ctx) { + // This is safe to stub, as there should be no adverse consequences from reporting no + // blocked users. + LOG_WARNING(Service_ACC, "(STUBBED) called"); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push<u32>(0); // Indicates there are no blocked users + } + void DeclareCloseOnlinePlaySession(Kernel::HLERequestContext& ctx) { // Stub used by Splatoon 2 LOG_WARNING(Service_ACC, "(STUBBED) called"); diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index 32b6f4b27..f1e3d832a 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp @@ -28,6 +28,7 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer) buffer.slot = slot; buffer.igbp_buffer = igbp_buffer; buffer.status = Buffer::Status::Free; + free_buffers.push_back(slot); queue.emplace_back(buffer); buffer_wait_event.writable->Signal(); @@ -35,16 +36,37 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer) std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> BufferQueue::DequeueBuffer(u32 width, u32 height) { - auto itr = std::find_if(queue.begin(), queue.end(), [&](const Buffer& buffer) { - // Only consider free buffers. Buffers become free once again after they've been Acquired - // and Released by the compositor, see the NVFlinger::Compose method. - if (buffer.status != Buffer::Status::Free) { - return false; - } - // Make sure that the parameters match. - return buffer.igbp_buffer.width == width && buffer.igbp_buffer.height == height; - }); + if (free_buffers.empty()) { + return {}; + } + + auto f_itr = free_buffers.begin(); + auto itr = queue.end(); + + while (f_itr != free_buffers.end()) { + auto slot = *f_itr; + itr = std::find_if(queue.begin(), queue.end(), [&](const Buffer& buffer) { + // Only consider free buffers. Buffers become free once again after they've been + // Acquired and Released by the compositor, see the NVFlinger::Compose method. + if (buffer.status != Buffer::Status::Free) { + return false; + } + + if (buffer.slot != slot) { + return false; + } + + // Make sure that the parameters match. + return buffer.igbp_buffer.width == width && buffer.igbp_buffer.height == height; + }); + + if (itr != queue.end()) { + free_buffers.erase(f_itr); + break; + } + ++f_itr; + } if (itr == queue.end()) { return {}; @@ -99,10 +121,18 @@ void BufferQueue::ReleaseBuffer(u32 slot) { ASSERT(itr != queue.end()); ASSERT(itr->status == Buffer::Status::Acquired); itr->status = Buffer::Status::Free; + free_buffers.push_back(slot); buffer_wait_event.writable->Signal(); } +void BufferQueue::Disconnect() { + queue.clear(); + queue_sequence.clear(); + id = 1; + layer_id = 1; +} + u32 BufferQueue::Query(QueryType type) { LOG_WARNING(Service, "(STUBBED) called type={}", static_cast<u32>(type)); diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h index f4bbfd945..d5f31e567 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.h +++ b/src/core/hle/service/nvflinger/buffer_queue.h @@ -87,6 +87,7 @@ public: Service::Nvidia::MultiFence& multi_fence); std::optional<std::reference_wrapper<const Buffer>> AcquireBuffer(); void ReleaseBuffer(u32 slot); + void Disconnect(); u32 Query(QueryType type); u32 GetId() const { @@ -101,6 +102,7 @@ private: u32 id; u64 layer_id; + std::list<u32> free_buffers; std::vector<Buffer> queue; std::list<u32> queue_sequence; Kernel::EventPair buffer_wait_event; diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 519da74e0..fdc62d05b 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -513,7 +513,8 @@ private: auto& buffer_queue = nv_flinger->FindBufferQueue(id); - if (transaction == TransactionId::Connect) { + switch (transaction) { + case TransactionId::Connect: { IGBPConnectRequestParcel request{ctx.ReadBuffer()}; IGBPConnectResponseParcel response{ static_cast<u32>(static_cast<u32>(DisplayResolution::UndockedWidth) * @@ -521,14 +522,18 @@ private: static_cast<u32>(static_cast<u32>(DisplayResolution::UndockedHeight) * Settings::values.resolution_factor)}; ctx.WriteBuffer(response.Serialize()); - } else if (transaction == TransactionId::SetPreallocatedBuffer) { + break; + } + case TransactionId::SetPreallocatedBuffer: { IGBPSetPreallocatedBufferRequestParcel request{ctx.ReadBuffer()}; buffer_queue.SetPreallocatedBuffer(request.data.slot, request.buffer); IGBPSetPreallocatedBufferResponseParcel response{}; ctx.WriteBuffer(response.Serialize()); - } else if (transaction == TransactionId::DequeueBuffer) { + break; + } + case TransactionId::DequeueBuffer: { IGBPDequeueBufferRequestParcel request{ctx.ReadBuffer()}; const u32 width{request.data.width}; const u32 height{request.data.height}; @@ -556,14 +561,18 @@ private: }, buffer_queue.GetWritableBufferWaitEvent()); } - } else if (transaction == TransactionId::RequestBuffer) { + break; + } + case TransactionId::RequestBuffer: { IGBPRequestBufferRequestParcel request{ctx.ReadBuffer()}; auto& buffer = buffer_queue.RequestBuffer(request.slot); IGBPRequestBufferResponseParcel response{buffer}; ctx.WriteBuffer(response.Serialize()); - } else if (transaction == TransactionId::QueueBuffer) { + break; + } + case TransactionId::QueueBuffer: { IGBPQueueBufferRequestParcel request{ctx.ReadBuffer()}; buffer_queue.QueueBuffer(request.data.slot, request.data.transform, @@ -572,7 +581,9 @@ private: IGBPQueueBufferResponseParcel response{1280, 720}; ctx.WriteBuffer(response.Serialize()); - } else if (transaction == TransactionId::Query) { + break; + } + case TransactionId::Query: { IGBPQueryRequestParcel request{ctx.ReadBuffer()}; const u32 value = @@ -580,15 +591,30 @@ private: IGBPQueryResponseParcel response{value}; ctx.WriteBuffer(response.Serialize()); - } else if (transaction == TransactionId::CancelBuffer) { + break; + } + case TransactionId::CancelBuffer: { LOG_CRITICAL(Service_VI, "(STUBBED) called, transaction=CancelBuffer"); - } else if (transaction == TransactionId::Disconnect || - transaction == TransactionId::DetachBuffer) { + break; + } + case TransactionId::Disconnect: { + LOG_WARNING(Service_VI, "(STUBBED) called, transaction=Disconnect"); + const auto buffer = ctx.ReadBuffer(); + + buffer_queue.Disconnect(); + + IGBPEmptyResponseParcel response{}; + ctx.WriteBuffer(response.Serialize()); + break; + } + case TransactionId::DetachBuffer: { const auto buffer = ctx.ReadBuffer(); IGBPEmptyResponseParcel response{}; ctx.WriteBuffer(response.Serialize()); - } else { + break; + } + default: ASSERT_MSG(false, "Unimplemented"); } |