core: Eliminate more uses of Core::System::GetInstance(). (#7313)
This commit is contained in:
@@ -8,6 +8,10 @@
|
||||
#include "core/core.h"
|
||||
#include "core/frontend/input.h"
|
||||
#include "core/hle/applets/applet.h"
|
||||
#include "core/hle/applets/erreula.h"
|
||||
#include "core/hle/applets/mii_selector.h"
|
||||
#include "core/hle/applets/mint.h"
|
||||
#include "core/hle/applets/swkbd.h"
|
||||
#include "core/hle/service/am/am.h"
|
||||
#include "core/hle/service/apt/applet_manager.h"
|
||||
#include "core/hle/service/apt/errors.h"
|
||||
@@ -22,6 +26,8 @@ namespace Service::APT {
|
||||
|
||||
/// The interval at which the home button update callback will be called, 16.6ms
|
||||
static constexpr u64 button_update_interval_us = 16666;
|
||||
/// The interval at which the HLE Applet update callback will be called, 16.6ms.
|
||||
static constexpr u64 hle_applet_update_interval_us = 16666;
|
||||
|
||||
struct AppletTitleData {
|
||||
// There are two possible applet ids for each applet.
|
||||
@@ -222,8 +228,8 @@ void AppletManager::CancelAndSendParameter(const MessageParameter& parameter) {
|
||||
parameter.sender_id, parameter.destination_id, parameter.signal, parameter.buffer.size());
|
||||
|
||||
// If the applet is being HLEd, send directly to the applet.
|
||||
if (auto dest_applet = HLE::Applets::Applet::Get(parameter.destination_id)) {
|
||||
dest_applet->ReceiveParameter(parameter);
|
||||
if (hle_applets.contains(parameter.destination_id)) {
|
||||
hle_applets[parameter.destination_id]->ReceiveParameter(parameter);
|
||||
} else {
|
||||
// Otherwise, send the parameter the LLE way.
|
||||
next_parameter = parameter;
|
||||
@@ -497,6 +503,52 @@ void AppletManager::SendNotificationToAll(Notification notification) {
|
||||
}
|
||||
}
|
||||
|
||||
Result AppletManager::CreateHLEApplet(AppletId id, AppletId parent, bool preload) {
|
||||
switch (id) {
|
||||
case AppletId::SoftwareKeyboard1:
|
||||
case AppletId::SoftwareKeyboard2:
|
||||
hle_applets[id] = std::make_shared<HLE::Applets::SoftwareKeyboard>(
|
||||
system, id, parent, preload, shared_from_this());
|
||||
break;
|
||||
case AppletId::Ed1:
|
||||
case AppletId::Ed2:
|
||||
hle_applets[id] = std::make_shared<HLE::Applets::MiiSelector>(system, id, parent, preload,
|
||||
shared_from_this());
|
||||
break;
|
||||
case AppletId::Error:
|
||||
case AppletId::Error2:
|
||||
hle_applets[id] = std::make_shared<HLE::Applets::ErrEula>(system, id, parent, preload,
|
||||
shared_from_this());
|
||||
break;
|
||||
case AppletId::Mint:
|
||||
case AppletId::Mint2:
|
||||
hle_applets[id] =
|
||||
std::make_shared<HLE::Applets::Mint>(system, id, parent, preload, shared_from_this());
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR(Service_APT, "Could not create applet {}", id);
|
||||
// TODO(Subv): Find the right error code
|
||||
return Result(ErrorDescription::NotFound, ErrorModule::Applet, ErrorSummary::NotSupported,
|
||||
ErrorLevel::Permanent);
|
||||
}
|
||||
|
||||
AppletAttributes attributes;
|
||||
attributes.applet_pos.Assign(AppletPos::AutoLibrary);
|
||||
attributes.is_home_menu.Assign(false);
|
||||
const auto lock_handle_data = GetLockHandle(attributes);
|
||||
|
||||
Initialize(id, lock_handle_data->corrected_attributes);
|
||||
Enable(lock_handle_data->corrected_attributes);
|
||||
if (preload) {
|
||||
FinishPreloadingLibraryApplet(id);
|
||||
}
|
||||
|
||||
// Schedule the update event
|
||||
system.CoreTiming().ScheduleEvent(usToCycles(hle_applet_update_interval_us),
|
||||
hle_applet_update_event, static_cast<u64>(id));
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result AppletManager::PrepareToStartLibraryApplet(AppletId applet_id) {
|
||||
// The real APT service returns an error if there's a pending APT parameter when this function
|
||||
// is called.
|
||||
@@ -523,14 +575,13 @@ Result AppletManager::PrepareToStartLibraryApplet(AppletId applet_id) {
|
||||
}
|
||||
|
||||
// If we weren't able to load the native applet title, try to fallback to an HLE implementation.
|
||||
auto applet = HLE::Applets::Applet::Get(applet_id);
|
||||
if (applet) {
|
||||
LOG_WARNING(Service_APT, "applet has already been started id={:03X}", applet_id);
|
||||
if (hle_applets.contains(applet_id)) {
|
||||
LOG_WARNING(Service_APT, "Applet has already been started id={:03X}", applet_id);
|
||||
return ResultSuccess;
|
||||
} else {
|
||||
auto parent = GetAppletSlotId(last_library_launcher_slot);
|
||||
LOG_DEBUG(Service_APT, "Creating HLE applet {:03X} with parent {:03X}", applet_id, parent);
|
||||
return HLE::Applets::Applet::Create(applet_id, parent, false, shared_from_this());
|
||||
return CreateHLEApplet(applet_id, parent, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -551,14 +602,13 @@ Result AppletManager::PreloadLibraryApplet(AppletId applet_id) {
|
||||
}
|
||||
|
||||
// If we weren't able to load the native applet title, try to fallback to an HLE implementation.
|
||||
auto applet = HLE::Applets::Applet::Get(applet_id);
|
||||
if (applet) {
|
||||
LOG_WARNING(Service_APT, "applet has already been started id={:08X}", applet_id);
|
||||
if (hle_applets.contains(applet_id)) {
|
||||
LOG_WARNING(Service_APT, "Applet has already been started id={:08X}", applet_id);
|
||||
return ResultSuccess;
|
||||
} else {
|
||||
auto parent = GetAppletSlotId(last_library_launcher_slot);
|
||||
LOG_DEBUG(Service_APT, "Creating HLE applet {:03X} with parent {:03X}", applet_id, parent);
|
||||
return HLE::Applets::Applet::Create(applet_id, parent, true, shared_from_this());
|
||||
return CreateHLEApplet(applet_id, parent, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1387,8 +1437,8 @@ static void CaptureFrameBuffer(Core::System& system, u32 capture_offset, VAddr s
|
||||
return;
|
||||
}
|
||||
|
||||
Memory::RasterizerFlushVirtualRegion(src, GSP::FRAMEBUFFER_WIDTH * height * bpp,
|
||||
Memory::FlushMode::Flush);
|
||||
system.Memory().RasterizerFlushVirtualRegion(src, GSP::FRAMEBUFFER_WIDTH * height * bpp,
|
||||
Memory::FlushMode::Flush);
|
||||
|
||||
// Address in VRAM that APT copies framebuffer captures to.
|
||||
constexpr VAddr screen_capture_base_vaddr = Memory::VRAM_VADDR + 0x500000;
|
||||
@@ -1416,8 +1466,8 @@ static void CaptureFrameBuffer(Core::System& system, u32 capture_offset, VAddr s
|
||||
}
|
||||
}
|
||||
|
||||
Memory::RasterizerFlushVirtualRegion(dst_vaddr, GSP::FRAMEBUFFER_WIDTH_POW2 * height * bpp,
|
||||
Memory::FlushMode::Invalidate);
|
||||
system.Memory().RasterizerFlushVirtualRegion(
|
||||
dst_vaddr, GSP::FRAMEBUFFER_WIDTH_POW2 * height * bpp, Memory::FlushMode::Invalidate);
|
||||
}
|
||||
|
||||
void AppletManager::CaptureFrameBuffers() {
|
||||
@@ -1441,6 +1491,30 @@ void AppletManager::LoadInputDevices() {
|
||||
Settings::values.current_input_profile.buttons[Settings::NativeButton::Power]);
|
||||
}
|
||||
|
||||
/// Handles updating the current Applet every time it's called.
|
||||
void AppletManager::HLEAppletUpdateEvent(std::uintptr_t user_data, s64 cycles_late) {
|
||||
const auto id = static_cast<AppletId>(user_data);
|
||||
if (!hle_applets.contains(id)) {
|
||||
// Dead applet, exit event loop.
|
||||
LOG_WARNING(Service_APT, "Attempted to update dead applet id={:03X}", id);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto applet = hle_applets[id];
|
||||
if (applet->IsActive()) {
|
||||
applet->Update();
|
||||
}
|
||||
|
||||
// If the applet is still running after the last update, reschedule the event
|
||||
if (applet->IsRunning()) {
|
||||
system.CoreTiming().ScheduleEvent(usToCycles(hle_applet_update_interval_us) - cycles_late,
|
||||
hle_applet_update_event, user_data);
|
||||
} else {
|
||||
// Otherwise the applet has terminated, in which case we should clean it up
|
||||
hle_applets[id] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void AppletManager::ButtonUpdateEvent(std::uintptr_t user_data, s64 cycles_late) {
|
||||
if (is_device_reload_pending.exchange(false)) {
|
||||
LoadInputDevices();
|
||||
@@ -1485,7 +1559,10 @@ AppletManager::AppletManager(Core::System& system) : system(system) {
|
||||
slot_data.parameter_event =
|
||||
system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "APT:Parameter");
|
||||
}
|
||||
HLE::Applets::Init();
|
||||
hle_applet_update_event = system.CoreTiming().RegisterEvent(
|
||||
"HLE Applet Update Event", [this](std::uintptr_t user_data, s64 cycles_late) {
|
||||
HLEAppletUpdateEvent(user_data, cycles_late);
|
||||
});
|
||||
button_update_event = system.CoreTiming().RegisterEvent(
|
||||
"APT Button Update Event", [this](std::uintptr_t user_data, s64 cycles_late) {
|
||||
ButtonUpdateEvent(user_data, cycles_late);
|
||||
@@ -1494,7 +1571,8 @@ AppletManager::AppletManager(Core::System& system) : system(system) {
|
||||
}
|
||||
|
||||
AppletManager::~AppletManager() {
|
||||
HLE::Applets::Shutdown();
|
||||
system.CoreTiming().RemoveEvent(hle_applet_update_event);
|
||||
system.CoreTiming().RemoveEvent(button_update_event);
|
||||
}
|
||||
|
||||
void AppletManager::ReloadInputDevices() {
|
||||
|
||||
@@ -23,6 +23,10 @@ namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace HLE::Applets {
|
||||
class Applet;
|
||||
}
|
||||
|
||||
namespace Service::APT {
|
||||
|
||||
/// Signals used by APT functions
|
||||
@@ -291,7 +295,6 @@ public:
|
||||
|
||||
ResultVal<Notification> InquireNotification(AppletId app_id);
|
||||
Result SendNotification(Notification notification);
|
||||
void SendNotificationToAll(Notification notification);
|
||||
|
||||
Result PrepareToStartLibraryApplet(AppletId applet_id);
|
||||
Result PreloadLibraryApplet(AppletId applet_id);
|
||||
@@ -481,6 +484,9 @@ private:
|
||||
// It also affects the results of APT:GetTargetPlatform and APT:GetApplicationRunningMode.
|
||||
bool new_3ds_mode_blocked = false;
|
||||
|
||||
std::unordered_map<AppletId, std::shared_ptr<HLE::Applets::Applet>> hle_applets;
|
||||
Core::TimingEventType* hle_applet_update_event;
|
||||
|
||||
Core::TimingEventType* button_update_event;
|
||||
std::atomic<bool> is_device_reload_pending{true};
|
||||
std::unique_ptr<Input::ButtonDevice> home_button;
|
||||
@@ -506,10 +512,15 @@ private:
|
||||
/// otherwise it queues for sending when the application registers itself with APT::Enable.
|
||||
void SendApplicationParameterAfterRegistration(const MessageParameter& parameter);
|
||||
|
||||
void SendNotificationToAll(Notification notification);
|
||||
|
||||
void EnsureHomeMenuLoaded();
|
||||
|
||||
void CaptureFrameBuffers();
|
||||
|
||||
Result CreateHLEApplet(AppletId id, AppletId parent, bool preload);
|
||||
void HLEAppletUpdateEvent(std::uintptr_t user_data, s64 cycles_late);
|
||||
|
||||
void LoadInputDevices();
|
||||
void ButtonUpdateEvent(std::uintptr_t user_data, s64 cycles_late);
|
||||
|
||||
|
||||
@@ -1133,8 +1133,7 @@ void Module::APTInterface::GetProgramId(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(3, 0);
|
||||
rb.Push(ResultSuccess);
|
||||
|
||||
auto fs_user =
|
||||
Core::System::GetInstance().ServiceManager().GetService<Service::FS::FS_USER>("fs:USER");
|
||||
auto fs_user = apt->system.ServiceManager().GetService<Service::FS::FS_USER>("fs:USER");
|
||||
ASSERT_MSG(fs_user != nullptr, "fs:USER service is missing.");
|
||||
|
||||
auto program_info_result = fs_user->GetProgramLaunchInfo(process_id);
|
||||
|
||||
Reference in New Issue
Block a user