From 42859461f3d6db8ea64facdf388d4791f713c7b1 Mon Sep 17 00:00:00 2001
From: Subv <subv2112@gmail.com>
Date: Mon, 22 Jan 2018 13:40:02 -0500
Subject: [PATCH] Services: Vi shouldn't be responsible for creating nvflinger.

It is now created during Service initialization and passed to all the services that need it.
---
 src/core/hle/service/service.cpp | 6 +++++-
 src/core/hle/service/vi/vi.cpp   | 5 +++--
 src/core/hle/service/vi/vi.h     | 3 ++-
 src/core/hle/service/vi/vi_m.cpp | 4 ++--
 src/core/hle/service/vi/vi_m.h   | 2 +-
 5 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 3f5ce56c60..403cce8e5b 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -165,6 +165,10 @@ void AddNamedPort(std::string name, SharedPtr<ClientPort> port) {
 
 /// Initialize ServiceManager
 void Init() {
+    // NVFlinger needs to be accessed by several services like Vi and AppletOE so we instantiate it
+    // here and pass it into the respective InstallInterfaces functions.
+    auto nv_flinger = std::make_shared<NVFlinger::NVFlinger>();
+
     SM::g_service_manager = std::make_shared<SM::ServiceManager>();
     SM::ServiceManager::InstallInterfaces(SM::g_service_manager);
 
@@ -180,7 +184,7 @@ void Init() {
     PCTL::InstallInterfaces(*SM::g_service_manager);
     Sockets::InstallInterfaces(*SM::g_service_manager);
     Time::InstallInterfaces(*SM::g_service_manager);
-    VI::InstallInterfaces(*SM::g_service_manager);
+    VI::InstallInterfaces(*SM::g_service_manager, nv_flinger);
     Set::InstallInterfaces(*SM::g_service_manager);
 
     LOG_DEBUG(Service, "initialized OK");
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index e0bfad2909..6576f81db1 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -753,8 +753,9 @@ IApplicationDisplayService::IApplicationDisplayService(
     RegisterHandlers(functions);
 }
 
-void InstallInterfaces(SM::ServiceManager& service_manager) {
-    std::make_shared<VI_M>()->InstallAsService(service_manager);
+void InstallInterfaces(SM::ServiceManager& service_manager,
+                       std::shared_ptr<NVFlinger::NVFlinger> nv_flinger) {
+    std::make_shared<VI_M>(nv_flinger)->InstallAsService(service_manager);
 }
 
 } // namespace VI
diff --git a/src/core/hle/service/vi/vi.h b/src/core/hle/service/vi/vi.h
index 5e9b7e6cf2..a6e084f874 100644
--- a/src/core/hle/service/vi/vi.h
+++ b/src/core/hle/service/vi/vi.h
@@ -39,7 +39,8 @@ private:
 };
 
 /// Registers all VI services with the specified service manager.
-void InstallInterfaces(SM::ServiceManager& service_manager);
+void InstallInterfaces(SM::ServiceManager& service_manager,
+                       std::shared_ptr<NVFlinger::NVFlinger> nv_flinger);
 
 } // namespace VI
 } // namespace Service
diff --git a/src/core/hle/service/vi/vi_m.cpp b/src/core/hle/service/vi/vi_m.cpp
index 6deedf8423..20b24658e7 100644
--- a/src/core/hle/service/vi/vi_m.cpp
+++ b/src/core/hle/service/vi/vi_m.cpp
@@ -17,13 +17,13 @@ void VI_M::GetDisplayService(Kernel::HLERequestContext& ctx) {
     rb.PushIpcInterface<IApplicationDisplayService>(nv_flinger);
 }
 
-VI_M::VI_M() : ServiceFramework("vi:m") {
+VI_M::VI_M(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger)
+    : ServiceFramework("vi:m"), nv_flinger(std::move(nv_flinger)) {
     static const FunctionInfo functions[] = {
         {2, &VI_M::GetDisplayService, "GetDisplayService"},
         {3, nullptr, "GetDisplayServiceWithProxyNameExchange"},
     };
     RegisterHandlers(functions);
-    nv_flinger = std::make_shared<NVFlinger::NVFlinger>();
 }
 
 } // namespace VI
diff --git a/src/core/hle/service/vi/vi_m.h b/src/core/hle/service/vi/vi_m.h
index ebe79d5c73..e5319b1e79 100644
--- a/src/core/hle/service/vi/vi_m.h
+++ b/src/core/hle/service/vi/vi_m.h
@@ -16,7 +16,7 @@ namespace VI {
 
 class VI_M final : public ServiceFramework<VI_M> {
 public:
-    VI_M();
+    VI_M(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger);
     ~VI_M() = default;
 
 private: