diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 93ebbe75f6..6e1bf481bb 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -361,7 +361,7 @@ public: static const FunctionInfo functions[] = { {0, &IHOSBinderDriver::TransactParcel, "TransactParcel"}, {1, &IHOSBinderDriver::AdjustRefcount, "AdjustRefcount"}, - {2, nullptr, "GetNativeHandle"}, + {2, &IHOSBinderDriver::GetNativeHandle, "GetNativeHandle"}, {3, nullptr, "TransactParcelAuto"}, }; RegisterHandlers(functions); @@ -463,6 +463,21 @@ private: rb.Push(RESULT_SUCCESS); } + void GetNativeHandle(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + u32 id = rp.Pop(); + u32 unknown = rp.Pop(); + + auto buffer_queue = nv_flinger->GetBufferQueue(id); + + // TODO(Subv): Find out what this actually is. + + LOG_WARNING(Service, "(STUBBED) called id=%u, unknown=%08X", id, unknown); + IPC::RequestBuilder rb{ctx, 2, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushCopyObjects(buffer_queue->GetNativeHandle()); + } + std::shared_ptr nv_flinger; }; @@ -565,6 +580,15 @@ void IApplicationDisplayService::GetManagerDisplayService(Kernel::HLERequestCont rb.PushIpcInterface(nv_flinger); } +void IApplicationDisplayService::GetIndirectDisplayTransactionService( + Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called"); + + IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface(nv_flinger); +} + void IApplicationDisplayService::OpenDisplay(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service, "(STUBBED) called"); IPC::RequestParser rp{ctx}; @@ -580,6 +604,15 @@ void IApplicationDisplayService::OpenDisplay(Kernel::HLERequestContext& ctx) { rb.Push(nv_flinger->OpenDisplay(name)); } +void IApplicationDisplayService::CloseDisplay(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + u64 display_id = rp.Pop(); + + IPC::RequestBuilder rb = rp.MakeBuilder(4, 0, 0, 0); + rb.Push(RESULT_SUCCESS); +} + void IApplicationDisplayService::OpenLayer(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service, "(STUBBED) called"); IPC::RequestParser rp{ctx}; @@ -605,6 +638,40 @@ void IApplicationDisplayService::OpenLayer(Kernel::HLERequestContext& ctx) { rb.Push(data.size()); } +void IApplicationDisplayService::CreateStrayLayer(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called"); + + IPC::RequestParser rp{ctx}; + u32 flags = rp.Pop(); + u64 display_id = rp.Pop(); + + auto& buffer = ctx.BufferDescriptorB()[0]; + + // TODO(Subv): What's the difference between a Stray and a Managed layer? + + u64 layer_id = nv_flinger->CreateLayer(display_id); + u32 buffer_queue_id = nv_flinger->GetBufferQueueId(display_id, layer_id); + + NativeWindow native_window{buffer_queue_id}; + auto data = native_window.Serialize(); + Memory::WriteBlock(buffer.Address(), data.data(), data.size()); + + IPC::RequestBuilder rb = rp.MakeBuilder(6, 0, 0, 0); + rb.Push(RESULT_SUCCESS); + rb.Push(layer_id); + rb.Push(data.size()); +} + +void IApplicationDisplayService::DestroyStrayLayer(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called"); + + IPC::RequestParser rp{ctx}; + u64 layer_id = rp.Pop(); + + IPC::RequestBuilder rb = rp.MakeBuilder(2, 0, 0, 0); + rb.Push(RESULT_SUCCESS); +} + void IApplicationDisplayService::SetLayerScalingMode(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service, "(STUBBED) called"); IPC::RequestParser rp{ctx}; @@ -633,11 +700,15 @@ IApplicationDisplayService::IApplicationDisplayService(std::shared_ptr GetNativeHandle() const { + return native_handle; + } + private: u32 id; u64 layer_id; std::vector queue; + Kernel::SharedPtr native_handle; }; struct Layer { @@ -138,9 +143,13 @@ private: void GetRelayService(Kernel::HLERequestContext& ctx); void GetSystemDisplayService(Kernel::HLERequestContext& ctx); void GetManagerDisplayService(Kernel::HLERequestContext& ctx); + void GetIndirectDisplayTransactionService(Kernel::HLERequestContext& ctx); void OpenDisplay(Kernel::HLERequestContext& ctx); + void CloseDisplay(Kernel::HLERequestContext& ctx); void SetLayerScalingMode(Kernel::HLERequestContext& ctx); void OpenLayer(Kernel::HLERequestContext& ctx); + void CreateStrayLayer(Kernel::HLERequestContext& ctx); + void DestroyStrayLayer(Kernel::HLERequestContext& ctx); void GetDisplayVsyncEvent(Kernel::HLERequestContext& ctx); std::shared_ptr nv_flinger;