core: Eliminate more uses of Core::System::GetInstance(). (#7313)

This commit is contained in:
Steveice10
2024-01-05 12:07:28 -08:00
committed by GitHub
parent 8e2037b3ff
commit f2ee9baec7
47 changed files with 416 additions and 387 deletions

View File

@@ -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() {

View File

@@ -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);

View File

@@ -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);