hle: services: Fix a crash with improper NVFlinger lifetime management. (#4977)

* hle: services: Fix a crash with improper NVFlinger lifetime management.

- This crash would happen when attempting to shutdown yuzu early on in boot.
This commit is contained in:
bunnei 2020-11-24 14:31:58 -08:00 committed by GitHub
parent fbda5e9ec9
commit 7791cc8c2e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 104 additions and 100 deletions

View File

@ -187,7 +187,7 @@ struct System::Impl {
service_manager = std::make_shared<Service::SM::ServiceManager>(kernel); service_manager = std::make_shared<Service::SM::ServiceManager>(kernel);
Service::Init(service_manager, system); services = std::make_unique<Service::Services>(service_manager, system);
GDBStub::DeferStart(); GDBStub::DeferStart();
interrupt_manager = std::make_unique<Core::Hardware::InterruptManager>(system); interrupt_manager = std::make_unique<Core::Hardware::InterruptManager>(system);
@ -296,7 +296,7 @@ struct System::Impl {
// Shutdown emulation session // Shutdown emulation session
GDBStub::Shutdown(); GDBStub::Shutdown();
Service::Shutdown(); services.reset();
service_manager.reset(); service_manager.reset();
cheat_engine.reset(); cheat_engine.reset();
telemetry_session.reset(); telemetry_session.reset();
@ -306,8 +306,8 @@ struct System::Impl {
cpu_manager.Shutdown(); cpu_manager.Shutdown();
// Shutdown kernel and core timing // Shutdown kernel and core timing
kernel.Shutdown();
core_timing.Shutdown(); core_timing.Shutdown();
kernel.Shutdown();
// Close app loader // Close app loader
app_loader.reset(); app_loader.reset();
@ -398,6 +398,9 @@ struct System::Impl {
/// Service manager /// Service manager
std::shared_ptr<Service::SM::ServiceManager> service_manager; std::shared_ptr<Service::SM::ServiceManager> service_manager;
/// Services
std::unique_ptr<Service::Services> services;
/// Telemetry session for this emulation session /// Telemetry session for this emulation session
std::unique_ptr<Core::TelemetrySession> telemetry_session; std::unique_ptr<Core::TelemetrySession> telemetry_session;

View File

@ -246,9 +246,8 @@ IDebugFunctions::IDebugFunctions() : ServiceFramework{"IDebugFunctions"} {
IDebugFunctions::~IDebugFunctions() = default; IDebugFunctions::~IDebugFunctions() = default;
ISelfController::ISelfController(Core::System& system, ISelfController::ISelfController(Core::System& system, NVFlinger::NVFlinger& nvflinger)
std::shared_ptr<NVFlinger::NVFlinger> nvflinger) : ServiceFramework("ISelfController"), system(system), nvflinger(nvflinger) {
: ServiceFramework("ISelfController"), system(system), nvflinger(std::move(nvflinger)) {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &ISelfController::Exit, "Exit"}, {0, &ISelfController::Exit, "Exit"},
@ -458,8 +457,8 @@ void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx)
// TODO(Subv): Find out how AM determines the display to use, for now just // TODO(Subv): Find out how AM determines the display to use, for now just
// create the layer in the Default display. // create the layer in the Default display.
const auto display_id = nvflinger->OpenDisplay("Default"); const auto display_id = nvflinger.OpenDisplay("Default");
const auto layer_id = nvflinger->CreateLayer(*display_id); const auto layer_id = nvflinger.CreateLayer(*display_id);
IPC::ResponseBuilder rb{ctx, 4}; IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
@ -476,8 +475,8 @@ void ISelfController::CreateManagedDisplaySeparableLayer(Kernel::HLERequestConte
// Outputting 1 layer id instead of the expected 2 has not been observed to cause any adverse // Outputting 1 layer id instead of the expected 2 has not been observed to cause any adverse
// side effects. // side effects.
// TODO: Support multiple layers // TODO: Support multiple layers
const auto display_id = nvflinger->OpenDisplay("Default"); const auto display_id = nvflinger.OpenDisplay("Default");
const auto layer_id = nvflinger->CreateLayer(*display_id); const auto layer_id = nvflinger.CreateLayer(*display_id);
IPC::ResponseBuilder rb{ctx, 4}; IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
@ -1586,8 +1585,8 @@ void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(Kernel::HLERe
rb.PushCopyObjects(friend_invitation_storage_channel_event.readable); rb.PushCopyObjects(friend_invitation_storage_channel_event.readable);
} }
void InstallInterfaces(SM::ServiceManager& service_manager, void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger,
std::shared_ptr<NVFlinger::NVFlinger> nvflinger, Core::System& system) { Core::System& system) {
auto message_queue = std::make_shared<AppletMessageQueue>(system.Kernel()); auto message_queue = std::make_shared<AppletMessageQueue>(system.Kernel());
// Needed on game boot // Needed on game boot
message_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged); message_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);

View File

@ -121,8 +121,7 @@ public:
class ISelfController final : public ServiceFramework<ISelfController> { class ISelfController final : public ServiceFramework<ISelfController> {
public: public:
explicit ISelfController(Core::System& system_, explicit ISelfController(Core::System& system_, NVFlinger::NVFlinger& nvflinger_);
std::shared_ptr<NVFlinger::NVFlinger> nvflinger_);
~ISelfController() override; ~ISelfController() override;
private: private:
@ -156,7 +155,7 @@ private:
}; };
Core::System& system; Core::System& system;
std::shared_ptr<NVFlinger::NVFlinger> nvflinger; NVFlinger::NVFlinger& nvflinger;
Kernel::EventPair launchable_event; Kernel::EventPair launchable_event;
Kernel::EventPair accumulated_suspended_tick_changed_event; Kernel::EventPair accumulated_suspended_tick_changed_event;
@ -332,7 +331,7 @@ public:
}; };
/// Registers all AM services with the specified service manager. /// Registers all AM services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& service_manager, void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger,
std::shared_ptr<NVFlinger::NVFlinger> nvflinger, Core::System& system); Core::System& system);
} // namespace Service::AM } // namespace Service::AM

View File

@ -13,10 +13,10 @@ namespace Service::AM {
class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> { class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> {
public: public:
explicit ILibraryAppletProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger, explicit ILibraryAppletProxy(NVFlinger::NVFlinger& nvflinger,
std::shared_ptr<AppletMessageQueue> msg_queue, std::shared_ptr<AppletMessageQueue> msg_queue,
Core::System& system) Core::System& system)
: ServiceFramework("ILibraryAppletProxy"), nvflinger(std::move(nvflinger)), : ServiceFramework("ILibraryAppletProxy"), nvflinger(nvflinger),
msg_queue(std::move(msg_queue)), system(system) { msg_queue(std::move(msg_queue)), system(system) {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
@ -109,16 +109,16 @@ private:
rb.PushIpcInterface<IApplicationFunctions>(system); rb.PushIpcInterface<IApplicationFunctions>(system);
} }
std::shared_ptr<NVFlinger::NVFlinger> nvflinger; NVFlinger::NVFlinger& nvflinger;
std::shared_ptr<AppletMessageQueue> msg_queue; std::shared_ptr<AppletMessageQueue> msg_queue;
Core::System& system; Core::System& system;
}; };
class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> { class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> {
public: public:
explicit ISystemAppletProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger, explicit ISystemAppletProxy(NVFlinger::NVFlinger& nvflinger,
std::shared_ptr<AppletMessageQueue> msg_queue, Core::System& system) std::shared_ptr<AppletMessageQueue> msg_queue, Core::System& system)
: ServiceFramework("ISystemAppletProxy"), nvflinger(std::move(nvflinger)), : ServiceFramework("ISystemAppletProxy"), nvflinger(nvflinger),
msg_queue(std::move(msg_queue)), system(system) { msg_queue(std::move(msg_queue)), system(system) {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
@ -220,7 +220,8 @@ private:
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IApplicationCreator>(); rb.PushIpcInterface<IApplicationCreator>();
} }
std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
NVFlinger::NVFlinger& nvflinger;
std::shared_ptr<AppletMessageQueue> msg_queue; std::shared_ptr<AppletMessageQueue> msg_queue;
Core::System& system; Core::System& system;
}; };
@ -249,10 +250,10 @@ void AppletAE::OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx) {
rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger, msg_queue, system); rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger, msg_queue, system);
} }
AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger, AppletAE::AppletAE(NVFlinger::NVFlinger& nvflinger, std::shared_ptr<AppletMessageQueue> msg_queue,
std::shared_ptr<AppletMessageQueue> msg_queue, Core::System& system) Core::System& system)
: ServiceFramework("appletAE"), nvflinger(std::move(nvflinger)), : ServiceFramework("appletAE"), nvflinger(nvflinger), msg_queue(std::move(msg_queue)),
msg_queue(std::move(msg_queue)), system(system) { system(system) {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{100, &AppletAE::OpenSystemAppletProxy, "OpenSystemAppletProxy"}, {100, &AppletAE::OpenSystemAppletProxy, "OpenSystemAppletProxy"},

View File

@ -23,7 +23,7 @@ class AppletMessageQueue;
class AppletAE final : public ServiceFramework<AppletAE> { class AppletAE final : public ServiceFramework<AppletAE> {
public: public:
explicit AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger, explicit AppletAE(NVFlinger::NVFlinger& nvflinger,
std::shared_ptr<AppletMessageQueue> msg_queue, Core::System& system); std::shared_ptr<AppletMessageQueue> msg_queue, Core::System& system);
~AppletAE() override; ~AppletAE() override;
@ -34,7 +34,7 @@ private:
void OpenLibraryAppletProxy(Kernel::HLERequestContext& ctx); void OpenLibraryAppletProxy(Kernel::HLERequestContext& ctx);
void OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx); void OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx);
std::shared_ptr<NVFlinger::NVFlinger> nvflinger; NVFlinger::NVFlinger& nvflinger;
std::shared_ptr<AppletMessageQueue> msg_queue; std::shared_ptr<AppletMessageQueue> msg_queue;
Core::System& system; Core::System& system;
}; };

View File

@ -12,9 +12,9 @@ namespace Service::AM {
class IApplicationProxy final : public ServiceFramework<IApplicationProxy> { class IApplicationProxy final : public ServiceFramework<IApplicationProxy> {
public: public:
explicit IApplicationProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger, explicit IApplicationProxy(NVFlinger::NVFlinger& nvflinger,
std::shared_ptr<AppletMessageQueue> msg_queue, Core::System& system) std::shared_ptr<AppletMessageQueue> msg_queue, Core::System& system)
: ServiceFramework("IApplicationProxy"), nvflinger(std::move(nvflinger)), : ServiceFramework("IApplicationProxy"), nvflinger(nvflinger),
msg_queue(std::move(msg_queue)), system(system) { msg_queue(std::move(msg_queue)), system(system) {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
@ -98,7 +98,7 @@ private:
rb.PushIpcInterface<IApplicationFunctions>(system); rb.PushIpcInterface<IApplicationFunctions>(system);
} }
std::shared_ptr<NVFlinger::NVFlinger> nvflinger; NVFlinger::NVFlinger& nvflinger;
std::shared_ptr<AppletMessageQueue> msg_queue; std::shared_ptr<AppletMessageQueue> msg_queue;
Core::System& system; Core::System& system;
}; };
@ -111,10 +111,10 @@ void AppletOE::OpenApplicationProxy(Kernel::HLERequestContext& ctx) {
rb.PushIpcInterface<IApplicationProxy>(nvflinger, msg_queue, system); rb.PushIpcInterface<IApplicationProxy>(nvflinger, msg_queue, system);
} }
AppletOE::AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger, AppletOE::AppletOE(NVFlinger::NVFlinger& nvflinger, std::shared_ptr<AppletMessageQueue> msg_queue,
std::shared_ptr<AppletMessageQueue> msg_queue, Core::System& system) Core::System& system)
: ServiceFramework("appletOE"), nvflinger(std::move(nvflinger)), : ServiceFramework("appletOE"), nvflinger(nvflinger), msg_queue(std::move(msg_queue)),
msg_queue(std::move(msg_queue)), system(system) { system(system) {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &AppletOE::OpenApplicationProxy, "OpenApplicationProxy"}, {0, &AppletOE::OpenApplicationProxy, "OpenApplicationProxy"},
}; };

View File

@ -23,7 +23,7 @@ class AppletMessageQueue;
class AppletOE final : public ServiceFramework<AppletOE> { class AppletOE final : public ServiceFramework<AppletOE> {
public: public:
explicit AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger, explicit AppletOE(NVFlinger::NVFlinger& nvflinger,
std::shared_ptr<AppletMessageQueue> msg_queue, Core::System& system); std::shared_ptr<AppletMessageQueue> msg_queue, Core::System& system);
~AppletOE() override; ~AppletOE() override;
@ -32,7 +32,7 @@ public:
private: private:
void OpenApplicationProxy(Kernel::HLERequestContext& ctx); void OpenApplicationProxy(Kernel::HLERequestContext& ctx);
std::shared_ptr<NVFlinger::NVFlinger> nvflinger; NVFlinger::NVFlinger& nvflinger;
std::shared_ptr<AppletMessageQueue> msg_queue; std::shared_ptr<AppletMessageQueue> msg_queue;
Core::System& system; Core::System& system;
}; };

View File

@ -188,17 +188,19 @@ ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& co
return RESULT_SUCCESS; return RESULT_SUCCESS;
} }
/// Initialize ServiceManager /// Initialize Services
void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system) { Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system)
: nv_flinger{std::make_unique<NVFlinger::NVFlinger>(system)} {
// NVFlinger needs to be accessed by several services like Vi and AppletOE so we instantiate it // 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. // here and pass it into the respective InstallInterfaces functions.
auto nv_flinger = std::make_shared<NVFlinger::NVFlinger>(system);
system.GetFileSystemController().CreateFactories(*system.GetFilesystem(), false); system.GetFileSystemController().CreateFactories(*system.GetFilesystem(), false);
SM::ServiceManager::InstallInterfaces(sm, system.Kernel()); SM::ServiceManager::InstallInterfaces(sm, system.Kernel());
Account::InstallInterfaces(system); Account::InstallInterfaces(system);
AM::InstallInterfaces(*sm, nv_flinger, system); AM::InstallInterfaces(*sm, *nv_flinger, system);
AOC::InstallInterfaces(*sm, system); AOC::InstallInterfaces(*sm, system);
APM::InstallInterfaces(system); APM::InstallInterfaces(system);
Audio::InstallInterfaces(*sm, system); Audio::InstallInterfaces(*sm, system);
@ -246,14 +248,10 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system) {
SSL::InstallInterfaces(*sm); SSL::InstallInterfaces(*sm);
Time::InstallInterfaces(system); Time::InstallInterfaces(system);
USB::InstallInterfaces(*sm); USB::InstallInterfaces(*sm);
VI::InstallInterfaces(*sm, nv_flinger); VI::InstallInterfaces(*sm, *nv_flinger);
WLAN::InstallInterfaces(*sm); WLAN::InstallInterfaces(*sm);
LOG_DEBUG(Service, "initialized OK");
} }
/// Shutdown ServiceManager Services::~Services() = default;
void Shutdown() {
LOG_DEBUG(Service, "shutdown OK");
}
} // namespace Service } // namespace Service

View File

@ -29,7 +29,11 @@ namespace Service {
namespace FileSystem { namespace FileSystem {
class FileSystemController; class FileSystemController;
} // namespace FileSystem }
namespace NVFlinger {
class NVFlinger;
}
namespace SM { namespace SM {
class ServiceManager; class ServiceManager;
@ -181,10 +185,17 @@ private:
} }
}; };
/// Initialize ServiceManager /**
void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system); * The purpose of this class is to own any objects that need to be shared across the other service
* implementations. Will be torn down when the global system instance is shutdown.
*/
class Services final {
public:
explicit Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system);
~Services();
/// Shutdown ServiceManager private:
void Shutdown(); std::unique_ptr<NVFlinger::NVFlinger> nv_flinger;
};
} // namespace Service } // namespace Service

View File

@ -492,8 +492,8 @@ private:
class IHOSBinderDriver final : public ServiceFramework<IHOSBinderDriver> { class IHOSBinderDriver final : public ServiceFramework<IHOSBinderDriver> {
public: public:
explicit IHOSBinderDriver(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger) explicit IHOSBinderDriver(NVFlinger::NVFlinger& nv_flinger)
: ServiceFramework("IHOSBinderDriver"), nv_flinger(std::move(nv_flinger)) { : ServiceFramework("IHOSBinderDriver"), nv_flinger(nv_flinger) {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &IHOSBinderDriver::TransactParcel, "TransactParcel"}, {0, &IHOSBinderDriver::TransactParcel, "TransactParcel"},
{1, &IHOSBinderDriver::AdjustRefcount, "AdjustRefcount"}, {1, &IHOSBinderDriver::AdjustRefcount, "AdjustRefcount"},
@ -530,8 +530,8 @@ private:
LOG_DEBUG(Service_VI, "called. id=0x{:08X} transaction={:X}, flags=0x{:08X}", id, LOG_DEBUG(Service_VI, "called. id=0x{:08X} transaction={:X}, flags=0x{:08X}", id,
static_cast<u32>(transaction), flags); static_cast<u32>(transaction), flags);
const auto guard = nv_flinger->Lock(); const auto guard = nv_flinger.Lock();
auto& buffer_queue = nv_flinger->FindBufferQueue(id); auto& buffer_queue = nv_flinger.FindBufferQueue(id);
switch (transaction) { switch (transaction) {
case TransactionId::Connect: { case TransactionId::Connect: {
@ -570,8 +570,8 @@ private:
[=, this](std::shared_ptr<Kernel::Thread> thread, [=, this](std::shared_ptr<Kernel::Thread> thread,
Kernel::HLERequestContext& ctx, Kernel::ThreadWakeupReason reason) { Kernel::HLERequestContext& ctx, Kernel::ThreadWakeupReason reason) {
// Repeat TransactParcel DequeueBuffer when a buffer is available // Repeat TransactParcel DequeueBuffer when a buffer is available
const auto guard = nv_flinger->Lock(); const auto guard = nv_flinger.Lock();
auto& buffer_queue = nv_flinger->FindBufferQueue(id); auto& buffer_queue = nv_flinger.FindBufferQueue(id);
auto result = buffer_queue.DequeueBuffer(width, height); auto result = buffer_queue.DequeueBuffer(width, height);
ASSERT_MSG(result != std::nullopt, "Could not dequeue buffer."); ASSERT_MSG(result != std::nullopt, "Could not dequeue buffer.");
@ -676,7 +676,7 @@ private:
LOG_WARNING(Service_VI, "(STUBBED) called id={}, unknown={:08X}", id, unknown); LOG_WARNING(Service_VI, "(STUBBED) called id={}, unknown={:08X}", id, unknown);
const auto& buffer_queue = nv_flinger->FindBufferQueue(id); const auto& buffer_queue = nv_flinger.FindBufferQueue(id);
// TODO(Subv): Find out what this actually is. // TODO(Subv): Find out what this actually is.
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
@ -684,8 +684,8 @@ private:
rb.PushCopyObjects(buffer_queue.GetBufferWaitEvent()); rb.PushCopyObjects(buffer_queue.GetBufferWaitEvent());
} }
std::shared_ptr<NVFlinger::NVFlinger> nv_flinger; NVFlinger::NVFlinger& nv_flinger;
}; // namespace VI };
class ISystemDisplayService final : public ServiceFramework<ISystemDisplayService> { class ISystemDisplayService final : public ServiceFramework<ISystemDisplayService> {
public: public:
@ -790,8 +790,8 @@ private:
class IManagerDisplayService final : public ServiceFramework<IManagerDisplayService> { class IManagerDisplayService final : public ServiceFramework<IManagerDisplayService> {
public: public:
explicit IManagerDisplayService(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger) explicit IManagerDisplayService(NVFlinger::NVFlinger& nv_flinger)
: ServiceFramework("IManagerDisplayService"), nv_flinger(std::move(nv_flinger)) { : ServiceFramework("IManagerDisplayService"), nv_flinger(nv_flinger) {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{200, nullptr, "AllocateProcessHeapBlock"}, {200, nullptr, "AllocateProcessHeapBlock"},
@ -893,7 +893,7 @@ private:
"(STUBBED) called. unknown=0x{:08X}, display=0x{:016X}, aruid=0x{:016X}", "(STUBBED) called. unknown=0x{:08X}, display=0x{:016X}, aruid=0x{:016X}",
unknown, display, aruid); unknown, display, aruid);
const auto layer_id = nv_flinger->CreateLayer(display); const auto layer_id = nv_flinger.CreateLayer(display);
if (!layer_id) { if (!layer_id) {
LOG_ERROR(Service_VI, "Layer not found! display=0x{:016X}", display); LOG_ERROR(Service_VI, "Layer not found! display=0x{:016X}", display);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
@ -930,12 +930,12 @@ private:
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
std::shared_ptr<NVFlinger::NVFlinger> nv_flinger; NVFlinger::NVFlinger& nv_flinger;
}; };
class IApplicationDisplayService final : public ServiceFramework<IApplicationDisplayService> { class IApplicationDisplayService final : public ServiceFramework<IApplicationDisplayService> {
public: public:
explicit IApplicationDisplayService(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger); explicit IApplicationDisplayService(NVFlinger::NVFlinger& nv_flinger);
private: private:
enum class ConvertedScaleMode : u64 { enum class ConvertedScaleMode : u64 {
@ -1010,7 +1010,7 @@ private:
ASSERT_MSG(name == "Default", "Non-default displays aren't supported yet"); ASSERT_MSG(name == "Default", "Non-default displays aren't supported yet");
const auto display_id = nv_flinger->OpenDisplay(name); const auto display_id = nv_flinger.OpenDisplay(name);
if (!display_id) { if (!display_id) {
LOG_ERROR(Service_VI, "Display not found! display_name={}", name); LOG_ERROR(Service_VI, "Display not found! display_name={}", name);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
@ -1110,7 +1110,7 @@ private:
LOG_DEBUG(Service_VI, "called. layer_id=0x{:016X}, aruid=0x{:016X}", layer_id, aruid); LOG_DEBUG(Service_VI, "called. layer_id=0x{:016X}, aruid=0x{:016X}", layer_id, aruid);
const auto display_id = nv_flinger->OpenDisplay(display_name); const auto display_id = nv_flinger.OpenDisplay(display_name);
if (!display_id) { if (!display_id) {
LOG_ERROR(Service_VI, "Layer not found! layer_id={}", layer_id); LOG_ERROR(Service_VI, "Layer not found! layer_id={}", layer_id);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
@ -1118,7 +1118,7 @@ private:
return; return;
} }
const auto buffer_queue_id = nv_flinger->FindBufferQueueId(*display_id, layer_id); const auto buffer_queue_id = nv_flinger.FindBufferQueueId(*display_id, layer_id);
if (!buffer_queue_id) { if (!buffer_queue_id) {
LOG_ERROR(Service_VI, "Buffer queue id not found! display_id={}", *display_id); LOG_ERROR(Service_VI, "Buffer queue id not found! display_id={}", *display_id);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
@ -1138,7 +1138,7 @@ private:
LOG_DEBUG(Service_VI, "called. layer_id=0x{:016X}", layer_id); LOG_DEBUG(Service_VI, "called. layer_id=0x{:016X}", layer_id);
nv_flinger->CloseLayer(layer_id); nv_flinger.CloseLayer(layer_id);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
@ -1154,7 +1154,7 @@ private:
// TODO(Subv): What's the difference between a Stray and a Managed layer? // TODO(Subv): What's the difference between a Stray and a Managed layer?
const auto layer_id = nv_flinger->CreateLayer(display_id); const auto layer_id = nv_flinger.CreateLayer(display_id);
if (!layer_id) { if (!layer_id) {
LOG_ERROR(Service_VI, "Layer not found! layer_id={}", *layer_id); LOG_ERROR(Service_VI, "Layer not found! layer_id={}", *layer_id);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
@ -1162,7 +1162,7 @@ private:
return; return;
} }
const auto buffer_queue_id = nv_flinger->FindBufferQueueId(display_id, *layer_id); const auto buffer_queue_id = nv_flinger.FindBufferQueueId(display_id, *layer_id);
if (!buffer_queue_id) { if (!buffer_queue_id) {
LOG_ERROR(Service_VI, "Buffer queue id not found! display_id={}", display_id); LOG_ERROR(Service_VI, "Buffer queue id not found! display_id={}", display_id);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
@ -1193,7 +1193,7 @@ private:
LOG_WARNING(Service_VI, "(STUBBED) called. display_id=0x{:016X}", display_id); LOG_WARNING(Service_VI, "(STUBBED) called. display_id=0x{:016X}", display_id);
const auto vsync_event = nv_flinger->FindVsyncEvent(display_id); const auto vsync_event = nv_flinger.FindVsyncEvent(display_id);
if (!vsync_event) { if (!vsync_event) {
LOG_ERROR(Service_VI, "Vsync event was not found for display_id={}", display_id); LOG_ERROR(Service_VI, "Vsync event was not found for display_id={}", display_id);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
@ -1258,12 +1258,11 @@ private:
} }
} }
std::shared_ptr<NVFlinger::NVFlinger> nv_flinger; NVFlinger::NVFlinger& nv_flinger;
}; };
IApplicationDisplayService::IApplicationDisplayService( IApplicationDisplayService::IApplicationDisplayService(NVFlinger::NVFlinger& nv_flinger)
std::shared_ptr<NVFlinger::NVFlinger> nv_flinger) : ServiceFramework("IApplicationDisplayService"), nv_flinger(nv_flinger) {
: ServiceFramework("IApplicationDisplayService"), nv_flinger(std::move(nv_flinger)) {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{100, &IApplicationDisplayService::GetRelayService, "GetRelayService"}, {100, &IApplicationDisplayService::GetRelayService, "GetRelayService"},
{101, &IApplicationDisplayService::GetSystemDisplayService, "GetSystemDisplayService"}, {101, &IApplicationDisplayService::GetSystemDisplayService, "GetSystemDisplayService"},
@ -1304,8 +1303,7 @@ static bool IsValidServiceAccess(Permission permission, Policy policy) {
return false; return false;
} }
void detail::GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, void detail::GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, NVFlinger::NVFlinger& nv_flinger,
std::shared_ptr<NVFlinger::NVFlinger> nv_flinger,
Permission permission) { Permission permission) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto policy = rp.PopEnum<Policy>(); const auto policy = rp.PopEnum<Policy>();
@ -1319,11 +1317,10 @@ void detail::GetDisplayServiceImpl(Kernel::HLERequestContext& ctx,
IPC::ResponseBuilder rb{ctx, 2, 0, 1}; IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IApplicationDisplayService>(std::move(nv_flinger)); rb.PushIpcInterface<IApplicationDisplayService>(nv_flinger);
} }
void InstallInterfaces(SM::ServiceManager& service_manager, void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nv_flinger) {
std::shared_ptr<NVFlinger::NVFlinger> nv_flinger) {
std::make_shared<VI_M>(nv_flinger)->InstallAsService(service_manager); std::make_shared<VI_M>(nv_flinger)->InstallAsService(service_manager);
std::make_shared<VI_S>(nv_flinger)->InstallAsService(service_manager); std::make_shared<VI_S>(nv_flinger)->InstallAsService(service_manager);
std::make_shared<VI_U>(nv_flinger)->InstallAsService(service_manager); std::make_shared<VI_U>(nv_flinger)->InstallAsService(service_manager);

View File

@ -43,12 +43,11 @@ enum class Policy {
}; };
namespace detail { namespace detail {
void GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, void GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, NVFlinger::NVFlinger& nv_flinger,
std::shared_ptr<NVFlinger::NVFlinger> nv_flinger, Permission permission); Permission permission);
} // namespace detail } // namespace detail
/// Registers all VI services with the specified service manager. /// Registers all VI services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& service_manager, void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nv_flinger);
std::shared_ptr<NVFlinger::NVFlinger> nv_flinger);
} // namespace Service::VI } // namespace Service::VI

View File

@ -8,8 +8,7 @@
namespace Service::VI { namespace Service::VI {
VI_M::VI_M(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger) VI_M::VI_M(NVFlinger::NVFlinger& nv_flinger) : ServiceFramework{"vi:m"}, nv_flinger{nv_flinger} {
: ServiceFramework{"vi:m"}, nv_flinger{std::move(nv_flinger)} {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{2, &VI_M::GetDisplayService, "GetDisplayService"}, {2, &VI_M::GetDisplayService, "GetDisplayService"},
{3, nullptr, "GetDisplayServiceWithProxyNameExchange"}, {3, nullptr, "GetDisplayServiceWithProxyNameExchange"},

View File

@ -18,13 +18,13 @@ namespace Service::VI {
class VI_M final : public ServiceFramework<VI_M> { class VI_M final : public ServiceFramework<VI_M> {
public: public:
explicit VI_M(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger); explicit VI_M(NVFlinger::NVFlinger& nv_flinger);
~VI_M() override; ~VI_M() override;
private: private:
void GetDisplayService(Kernel::HLERequestContext& ctx); void GetDisplayService(Kernel::HLERequestContext& ctx);
std::shared_ptr<NVFlinger::NVFlinger> nv_flinger; NVFlinger::NVFlinger& nv_flinger;
}; };
} // namespace Service::VI } // namespace Service::VI

View File

@ -8,8 +8,7 @@
namespace Service::VI { namespace Service::VI {
VI_S::VI_S(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger) VI_S::VI_S(NVFlinger::NVFlinger& nv_flinger) : ServiceFramework{"vi:s"}, nv_flinger{nv_flinger} {
: ServiceFramework{"vi:s"}, nv_flinger{std::move(nv_flinger)} {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{1, &VI_S::GetDisplayService, "GetDisplayService"}, {1, &VI_S::GetDisplayService, "GetDisplayService"},
{3, nullptr, "GetDisplayServiceWithProxyNameExchange"}, {3, nullptr, "GetDisplayServiceWithProxyNameExchange"},

View File

@ -18,13 +18,13 @@ namespace Service::VI {
class VI_S final : public ServiceFramework<VI_S> { class VI_S final : public ServiceFramework<VI_S> {
public: public:
explicit VI_S(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger); explicit VI_S(NVFlinger::NVFlinger& nv_flinger);
~VI_S() override; ~VI_S() override;
private: private:
void GetDisplayService(Kernel::HLERequestContext& ctx); void GetDisplayService(Kernel::HLERequestContext& ctx);
std::shared_ptr<NVFlinger::NVFlinger> nv_flinger; NVFlinger::NVFlinger& nv_flinger;
}; };
} // namespace Service::VI } // namespace Service::VI

View File

@ -8,8 +8,7 @@
namespace Service::VI { namespace Service::VI {
VI_U::VI_U(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger) VI_U::VI_U(NVFlinger::NVFlinger& nv_flinger) : ServiceFramework{"vi:u"}, nv_flinger{nv_flinger} {
: ServiceFramework{"vi:u"}, nv_flinger{std::move(nv_flinger)} {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &VI_U::GetDisplayService, "GetDisplayService"}, {0, &VI_U::GetDisplayService, "GetDisplayService"},
{1, nullptr, "GetDisplayServiceWithProxyNameExchange"}, {1, nullptr, "GetDisplayServiceWithProxyNameExchange"},

View File

@ -18,13 +18,13 @@ namespace Service::VI {
class VI_U final : public ServiceFramework<VI_U> { class VI_U final : public ServiceFramework<VI_U> {
public: public:
explicit VI_U(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger); explicit VI_U(NVFlinger::NVFlinger& nv_flinger);
~VI_U() override; ~VI_U() override;
private: private:
void GetDisplayService(Kernel::HLERequestContext& ctx); void GetDisplayService(Kernel::HLERequestContext& ctx);
std::shared_ptr<NVFlinger::NVFlinger> nv_flinger; NVFlinger::NVFlinger& nv_flinger;
}; };
} // namespace Service::VI } // namespace Service::VI