diff options
51 files changed, 519 insertions, 402 deletions
@@ -1,7 +1,7 @@ | |||
1 | yuzu emulator early access | 1 | yuzu emulator early access |
2 | ============= | 2 | ============= |
3 | 3 | ||
4 | This is the source code for early-access 4172. | 4 | This is the source code for early-access 4173. |
5 | 5 | ||
6 | ## Legal Notice | 6 | ## Legal Notice |
7 | 7 | ||
diff --git a/externals/sse2neon/sse2neon.h b/externals/sse2neon/sse2neon.h index 56254b5f9..66b93c1c7 100755 --- a/externals/sse2neon/sse2neon.h +++ b/externals/sse2neon/sse2neon.h | |||
@@ -1,3 +1,6 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2015-2024 SSE2NEON Contributors | ||
2 | // SPDX-License-Identifier: MIT | ||
3 | |||
1 | #ifndef SSE2NEON_H | 4 | #ifndef SSE2NEON_H |
2 | #define SSE2NEON_H | 5 | #define SSE2NEON_H |
3 | 6 | ||
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 419c9e650..9a1085ee5 100755 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
@@ -401,14 +401,16 @@ add_library(core STATIC | |||
401 | hle/service/am/am_types.h | 401 | hle/service/am/am_types.h |
402 | hle/service/am/applet.cpp | 402 | hle/service/am/applet.cpp |
403 | hle/service/am/applet.h | 403 | hle/service/am/applet.h |
404 | hle/service/am/applet_manager.cpp | ||
404 | hle/service/am/applet_data_broker.cpp | 405 | hle/service/am/applet_data_broker.cpp |
405 | hle/service/am/applet_data_broker.h | 406 | hle/service/am/applet_data_broker.h |
406 | hle/service/am/applet_manager.cpp | ||
407 | hle/service/am/applet_manager.h | 407 | hle/service/am/applet_manager.h |
408 | hle/service/am/applet_message_queue.cpp | 408 | hle/service/am/button_poller.cpp |
409 | hle/service/am/applet_message_queue.h | 409 | hle/service/am/button_poller.h |
410 | hle/service/am/display_layer_manager.cpp | 410 | hle/service/am/display_layer_manager.cpp |
411 | hle/service/am/display_layer_manager.h | 411 | hle/service/am/display_layer_manager.h |
412 | hle/service/am/event_observer.cpp | ||
413 | hle/service/am/event_observer.h | ||
412 | hle/service/am/frontend/applet_cabinet.cpp | 414 | hle/service/am/frontend/applet_cabinet.cpp |
413 | hle/service/am/frontend/applet_cabinet.h | 415 | hle/service/am/frontend/applet_cabinet.h |
414 | hle/service/am/frontend/applet_controller.cpp | 416 | hle/service/am/frontend/applet_controller.cpp |
@@ -434,8 +436,12 @@ add_library(core STATIC | |||
434 | hle/service/am/hid_registration.h | 436 | hle/service/am/hid_registration.h |
435 | hle/service/am/library_applet_storage.cpp | 437 | hle/service/am/library_applet_storage.cpp |
436 | hle/service/am/library_applet_storage.h | 438 | hle/service/am/library_applet_storage.h |
437 | hle/service/am/process.cpp | 439 | hle/service/am/lifecycle_manager.cpp |
438 | hle/service/am/process.h | 440 | hle/service/am/lifecycle_manager.h |
441 | hle/service/am/process_creation.cpp | ||
442 | hle/service/am/process_creation.h | ||
443 | hle/service/am/process_holder.cpp | ||
444 | hle/service/am/process_holder.h | ||
439 | hle/service/am/service/all_system_applet_proxies_service.cpp | 445 | hle/service/am/service/all_system_applet_proxies_service.cpp |
440 | hle/service/am/service/all_system_applet_proxies_service.h | 446 | hle/service/am/service/all_system_applet_proxies_service.h |
441 | hle/service/am/service/applet_common_functions.cpp | 447 | hle/service/am/service/applet_common_functions.cpp |
@@ -486,6 +492,8 @@ add_library(core STATIC | |||
486 | hle/service/am/service/system_applet_proxy.h | 492 | hle/service/am/service/system_applet_proxy.h |
487 | hle/service/am/service/window_controller.cpp | 493 | hle/service/am/service/window_controller.cpp |
488 | hle/service/am/service/window_controller.h | 494 | hle/service/am/service/window_controller.h |
495 | hle/service/am/window_system.cpp | ||
496 | hle/service/am/window_system.h | ||
489 | hle/service/aoc/addon_content_manager.cpp | 497 | hle/service/aoc/addon_content_manager.cpp |
490 | hle/service/aoc/addon_content_manager.h | 498 | hle/service/aoc/addon_content_manager.h |
491 | hle/service/aoc/purchase_event_manager.cpp | 499 | hle/service/aoc/purchase_event_manager.cpp |
@@ -918,6 +926,8 @@ add_library(core STATIC | |||
918 | hle/service/os/multi_wait_utils.h | 926 | hle/service/os/multi_wait_utils.h |
919 | hle/service/os/mutex.cpp | 927 | hle/service/os/mutex.cpp |
920 | hle/service/os/mutex.h | 928 | hle/service/os/mutex.h |
929 | hle/service/os/process.cpp | ||
930 | hle/service/os/process.h | ||
921 | hle/service/pcie/pcie.cpp | 931 | hle/service/pcie/pcie.cpp |
922 | hle/service/pcie/pcie.h | 932 | hle/service/pcie/pcie.h |
923 | hle/service/pctl/parental_control_service_factory.cpp | 933 | hle/service/pctl/parental_control_service_factory.cpp |
diff --git a/src/core/core.cpp b/src/core/core.cpp index 56f5dd67d..6ea4c7849 100755 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
@@ -3,7 +3,6 @@ | |||
3 | 3 | ||
4 | #include <array> | 4 | #include <array> |
5 | #include <atomic> | 5 | #include <atomic> |
6 | #include <exception> | ||
7 | #include <memory> | 6 | #include <memory> |
8 | #include <utility> | 7 | #include <utility> |
9 | 8 | ||
@@ -20,7 +19,6 @@ | |||
20 | #include "core/cpu_manager.h" | 19 | #include "core/cpu_manager.h" |
21 | #include "core/debugger/debugger.h" | 20 | #include "core/debugger/debugger.h" |
22 | #include "core/device_memory.h" | 21 | #include "core/device_memory.h" |
23 | #include "core/file_sys/bis_factory.h" | ||
24 | #include "core/file_sys/fs_filesystem.h" | 22 | #include "core/file_sys/fs_filesystem.h" |
25 | #include "core/file_sys/patch_manager.h" | 23 | #include "core/file_sys/patch_manager.h" |
26 | #include "core/file_sys/registered_cache.h" | 24 | #include "core/file_sys/registered_cache.h" |
@@ -38,6 +36,7 @@ | |||
38 | #include "core/hle/service/acc/profile_manager.h" | 36 | #include "core/hle/service/acc/profile_manager.h" |
39 | #include "core/hle/service/am/applet_manager.h" | 37 | #include "core/hle/service/am/applet_manager.h" |
40 | #include "core/hle/service/am/frontend/applets.h" | 38 | #include "core/hle/service/am/frontend/applets.h" |
39 | #include "core/hle/service/am/process_creation.h" | ||
41 | #include "core/hle/service/apm/apm_controller.h" | 40 | #include "core/hle/service/apm/apm_controller.h" |
42 | #include "core/hle/service/filesystem/filesystem.h" | 41 | #include "core/hle/service/filesystem/filesystem.h" |
43 | #include "core/hle/service/glue/glue_manager.h" | 42 | #include "core/hle/service/glue/glue_manager.h" |
@@ -72,30 +71,6 @@ MICROPROFILE_DEFINE(ARM_CPU3, "ARM", "CPU 3", MP_RGB(255, 64, 64)); | |||
72 | 71 | ||
73 | namespace Core { | 72 | namespace Core { |
74 | 73 | ||
75 | namespace { | ||
76 | |||
77 | FileSys::StorageId GetStorageIdForFrontendSlot( | ||
78 | std::optional<FileSys::ContentProviderUnionSlot> slot) { | ||
79 | if (!slot.has_value()) { | ||
80 | return FileSys::StorageId::None; | ||
81 | } | ||
82 | |||
83 | switch (*slot) { | ||
84 | case FileSys::ContentProviderUnionSlot::UserNAND: | ||
85 | return FileSys::StorageId::NandUser; | ||
86 | case FileSys::ContentProviderUnionSlot::SysNAND: | ||
87 | return FileSys::StorageId::NandSystem; | ||
88 | case FileSys::ContentProviderUnionSlot::SDMC: | ||
89 | return FileSys::StorageId::SdCard; | ||
90 | case FileSys::ContentProviderUnionSlot::FrontendManual: | ||
91 | return FileSys::StorageId::Host; | ||
92 | default: | ||
93 | return FileSys::StorageId::None; | ||
94 | } | ||
95 | } | ||
96 | |||
97 | } // Anonymous namespace | ||
98 | |||
99 | FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, | 74 | FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, |
100 | const std::string& path) { | 75 | const std::string& path) { |
101 | // To account for split 00+01+etc files. | 76 | // To account for split 00+01+etc files. |
@@ -297,9 +272,6 @@ struct System::Impl { | |||
297 | } | 272 | } |
298 | 273 | ||
299 | SystemResultStatus SetupForApplicationProcess(System& system, Frontend::EmuWindow& emu_window) { | 274 | SystemResultStatus SetupForApplicationProcess(System& system, Frontend::EmuWindow& emu_window) { |
300 | /// Reset all glue registrations | ||
301 | arp_manager.ResetAll(); | ||
302 | |||
303 | telemetry_session = std::make_unique<Core::TelemetrySession>(); | 275 | telemetry_session = std::make_unique<Core::TelemetrySession>(); |
304 | 276 | ||
305 | host1x_core = std::make_unique<Tegra::Host1x::Host1x>(system); | 277 | host1x_core = std::make_unique<Tegra::Host1x::Host1x>(system); |
@@ -335,8 +307,24 @@ struct System::Impl { | |||
335 | SystemResultStatus Load(System& system, Frontend::EmuWindow& emu_window, | 307 | SystemResultStatus Load(System& system, Frontend::EmuWindow& emu_window, |
336 | const std::string& filepath, | 308 | const std::string& filepath, |
337 | Service::AM::FrontendAppletParameters& params) { | 309 | Service::AM::FrontendAppletParameters& params) { |
338 | app_loader = Loader::GetLoader(system, GetGameFileFromPath(virtual_filesystem, filepath), | 310 | InitializeKernel(system); |
339 | params.program_id, params.program_index); | 311 | |
312 | const auto file = GetGameFileFromPath(virtual_filesystem, filepath); | ||
313 | |||
314 | // Create the application process | ||
315 | Loader::ResultStatus load_result{}; | ||
316 | std::vector<u8> control; | ||
317 | auto process = | ||
318 | Service::AM::CreateApplicationProcess(control, app_loader, load_result, system, file, | ||
319 | params.program_id, params.program_index); | ||
320 | |||
321 | if (load_result != Loader::ResultStatus::Success) { | ||
322 | LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result); | ||
323 | ShutdownMainProcess(); | ||
324 | |||
325 | return static_cast<SystemResultStatus>( | ||
326 | static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result)); | ||
327 | } | ||
340 | 328 | ||
341 | if (!app_loader) { | 329 | if (!app_loader) { |
342 | LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath); | 330 | LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath); |
@@ -344,7 +332,7 @@ struct System::Impl { | |||
344 | } | 332 | } |
345 | 333 | ||
346 | if (app_loader->ReadProgramId(params.program_id) != Loader::ResultStatus::Success) { | 334 | if (app_loader->ReadProgramId(params.program_id) != Loader::ResultStatus::Success) { |
347 | LOG_ERROR(Core, "Failed to find title id for ROM!"); | 335 | LOG_ERROR(Core, "Failed to find program id for ROM!"); |
348 | } | 336 | } |
349 | 337 | ||
350 | std::string name = "Unknown program"; | 338 | std::string name = "Unknown program"; |
@@ -352,23 +340,10 @@ struct System::Impl { | |||
352 | LOG_ERROR(Core, "Failed to read title for ROM!"); | 340 | LOG_ERROR(Core, "Failed to read title for ROM!"); |
353 | } | 341 | } |
354 | 342 | ||
355 | LOG_INFO(Core, "Loading {} ({})", name, params.program_id); | 343 | LOG_INFO(Core, "Loading {} ({:016X}) ...", name, params.program_id); |
356 | 344 | ||
357 | InitializeKernel(system); | 345 | // Make the process created be the application |
358 | 346 | kernel.MakeApplicationProcess(process->GetHandle()); | |
359 | // Create the application process. | ||
360 | auto main_process = Kernel::KProcess::Create(system.Kernel()); | ||
361 | Kernel::KProcess::Register(system.Kernel(), main_process); | ||
362 | kernel.AppendNewProcess(main_process); | ||
363 | kernel.MakeApplicationProcess(main_process); | ||
364 | const auto [load_result, load_parameters] = app_loader->Load(*main_process, system); | ||
365 | if (load_result != Loader::ResultStatus::Success) { | ||
366 | LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result); | ||
367 | ShutdownMainProcess(); | ||
368 | |||
369 | return static_cast<SystemResultStatus>( | ||
370 | static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result)); | ||
371 | } | ||
372 | 347 | ||
373 | // Set up the rest of the system. | 348 | // Set up the rest of the system. |
374 | SystemResultStatus init_result{SetupForApplicationProcess(system, emu_window)}; | 349 | SystemResultStatus init_result{SetupForApplicationProcess(system, emu_window)}; |
@@ -379,7 +354,6 @@ struct System::Impl { | |||
379 | return init_result; | 354 | return init_result; |
380 | } | 355 | } |
381 | 356 | ||
382 | AddGlueRegistrationForProcess(*app_loader, *main_process); | ||
383 | telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider); | 357 | telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider); |
384 | 358 | ||
385 | // Initialize cheat engine | 359 | // Initialize cheat engine |
@@ -387,14 +361,9 @@ struct System::Impl { | |||
387 | cheat_engine->Initialize(); | 361 | cheat_engine->Initialize(); |
388 | } | 362 | } |
389 | 363 | ||
390 | // Register with applet manager. | 364 | // Register with applet manager |
391 | applet_manager.CreateAndInsertByFrontendAppletParameters(main_process->GetProcessId(), | 365 | // All threads are started, begin main process execution, now that we're in the clear |
392 | params); | 366 | applet_manager.CreateAndInsertByFrontendAppletParameters(std::move(process), params); |
393 | |||
394 | // All threads are started, begin main process execution, now that we're in the clear. | ||
395 | main_process->Run(load_parameters->main_thread_priority, | ||
396 | load_parameters->main_thread_stack_size); | ||
397 | main_process->Close(); | ||
398 | 367 | ||
399 | if (Settings::values.gamecard_inserted) { | 368 | if (Settings::values.gamecard_inserted) { |
400 | if (Settings::values.gamecard_current_game) { | 369 | if (Settings::values.gamecard_current_game) { |
@@ -466,7 +435,6 @@ struct System::Impl { | |||
466 | kernel.SuspendEmulation(true); | 435 | kernel.SuspendEmulation(true); |
467 | kernel.CloseServices(); | 436 | kernel.CloseServices(); |
468 | kernel.ShutdownCores(); | 437 | kernel.ShutdownCores(); |
469 | applet_manager.Reset(); | ||
470 | services.reset(); | 438 | services.reset(); |
471 | service_manager.reset(); | 439 | service_manager.reset(); |
472 | fs_controller.Reset(); | 440 | fs_controller.Reset(); |
@@ -492,6 +460,9 @@ struct System::Impl { | |||
492 | // Workarounds | 460 | // Workarounds |
493 | Settings::values.renderer_amdvlk_depth_bias_workaround = false; | 461 | Settings::values.renderer_amdvlk_depth_bias_workaround = false; |
494 | 462 | ||
463 | // Reset all glue registrations | ||
464 | arp_manager.ResetAll(); | ||
465 | |||
495 | LOG_DEBUG(Core, "Shutdown OK"); | 466 | LOG_DEBUG(Core, "Shutdown OK"); |
496 | } | 467 | } |
497 | 468 | ||
@@ -509,31 +480,6 @@ struct System::Impl { | |||
509 | return app_loader->ReadTitle(out); | 480 | return app_loader->ReadTitle(out); |
510 | } | 481 | } |
511 | 482 | ||
512 | void AddGlueRegistrationForProcess(Loader::AppLoader& loader, Kernel::KProcess& process) { | ||
513 | std::vector<u8> nacp_data; | ||
514 | FileSys::NACP nacp; | ||
515 | if (loader.ReadControlData(nacp) == Loader::ResultStatus::Success) { | ||
516 | nacp_data = nacp.GetRawBytes(); | ||
517 | } else { | ||
518 | nacp_data.resize(sizeof(FileSys::RawNACP)); | ||
519 | } | ||
520 | |||
521 | Service::Glue::ApplicationLaunchProperty launch{}; | ||
522 | launch.title_id = process.GetProgramId(); | ||
523 | |||
524 | FileSys::PatchManager pm{launch.title_id, fs_controller, *content_provider}; | ||
525 | launch.version = pm.GetGameVersion().value_or(0); | ||
526 | |||
527 | // TODO(DarkLordZach): When FSController/Game Card Support is added, if | ||
528 | // current_process_game_card use correct StorageId | ||
529 | launch.base_game_storage_id = GetStorageIdForFrontendSlot(content_provider->GetSlotForEntry( | ||
530 | launch.title_id, FileSys::ContentRecordType::Program)); | ||
531 | launch.update_storage_id = GetStorageIdForFrontendSlot(content_provider->GetSlotForEntry( | ||
532 | FileSys::GetUpdateTitleID(launch.title_id), FileSys::ContentRecordType::Program)); | ||
533 | |||
534 | arp_manager.Register(launch.title_id, launch, std::move(nacp_data)); | ||
535 | } | ||
536 | |||
537 | void SetStatus(SystemResultStatus new_status, const char* details = nullptr) { | 483 | void SetStatus(SystemResultStatus new_status, const char* details = nullptr) { |
538 | status = new_status; | 484 | status = new_status; |
539 | if (details) { | 485 | if (details) { |
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index cd38d0f53..2600ece5b 100755 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp | |||
@@ -1170,6 +1170,7 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std: | |||
1170 | // Determine if we are an application. | 1170 | // Determine if we are an application. |
1171 | if (pool == KMemoryManager::Pool::Application) { | 1171 | if (pool == KMemoryManager::Pool::Application) { |
1172 | flag |= Svc::CreateProcessFlag::IsApplication; | 1172 | flag |= Svc::CreateProcessFlag::IsApplication; |
1173 | m_is_application = true; | ||
1173 | } | 1174 | } |
1174 | 1175 | ||
1175 | // If we are 64-bit, create as such. | 1176 | // If we are 64-bit, create as such. |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index df2e7abd7..9ec5bb48c 100755 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
@@ -2,19 +2,26 @@ | |||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
3 | 3 | ||
4 | #include "core/hle/service/am/am.h" | 4 | #include "core/hle/service/am/am.h" |
5 | #include "core/hle/service/am/button_poller.h" | ||
6 | #include "core/hle/service/am/event_observer.h" | ||
5 | #include "core/hle/service/am/service/all_system_applet_proxies_service.h" | 7 | #include "core/hle/service/am/service/all_system_applet_proxies_service.h" |
6 | #include "core/hle/service/am/service/application_proxy_service.h" | 8 | #include "core/hle/service/am/service/application_proxy_service.h" |
9 | #include "core/hle/service/am/window_system.h" | ||
7 | #include "core/hle/service/server_manager.h" | 10 | #include "core/hle/service/server_manager.h" |
8 | 11 | ||
9 | namespace Service::AM { | 12 | namespace Service::AM { |
10 | 13 | ||
11 | void LoopProcess(Core::System& system) { | 14 | void LoopProcess(Core::System& system) { |
15 | WindowSystem window_system(system); | ||
16 | ButtonPoller button_poller(system, window_system); | ||
17 | EventObserver event_observer(system, window_system); | ||
18 | |||
12 | auto server_manager = std::make_unique<ServerManager>(system); | 19 | auto server_manager = std::make_unique<ServerManager>(system); |
13 | 20 | ||
14 | server_manager->RegisterNamedService("appletAE", | 21 | server_manager->RegisterNamedService( |
15 | std::make_shared<IAllSystemAppletProxiesService>(system)); | 22 | "appletAE", std::make_shared<IAllSystemAppletProxiesService>(system, window_system)); |
16 | server_manager->RegisterNamedService("appletOE", | 23 | server_manager->RegisterNamedService( |
17 | std::make_shared<IApplicationProxyService>(system)); | 24 | "appletOE", std::make_shared<IApplicationProxyService>(system, window_system)); |
18 | ServerManager::RunServer(std::move(server_manager)); | 25 | ServerManager::RunServer(std::move(server_manager)); |
19 | } | 26 | } |
20 | 27 | ||
diff --git a/src/core/hle/service/am/am_results.h b/src/core/hle/service/am/am_results.h index a2afc9eec..44846aa2e 100755 --- a/src/core/hle/service/am/am_results.h +++ b/src/core/hle/service/am/am_results.h | |||
@@ -9,6 +9,7 @@ namespace Service::AM { | |||
9 | 9 | ||
10 | constexpr Result ResultNoDataInChannel{ErrorModule::AM, 2}; | 10 | constexpr Result ResultNoDataInChannel{ErrorModule::AM, 2}; |
11 | constexpr Result ResultNoMessages{ErrorModule::AM, 3}; | 11 | constexpr Result ResultNoMessages{ErrorModule::AM, 3}; |
12 | constexpr Result ResultLibraryAppletTerminated{ErrorModule::AM, 22}; | ||
12 | constexpr Result ResultInvalidOffset{ErrorModule::AM, 503}; | 13 | constexpr Result ResultInvalidOffset{ErrorModule::AM, 503}; |
13 | constexpr Result ResultInvalidStorageType{ErrorModule::AM, 511}; | 14 | constexpr Result ResultInvalidStorageType{ErrorModule::AM, 511}; |
14 | constexpr Result ResultFatalSectionCountImbalance{ErrorModule::AM, 512}; | 15 | constexpr Result ResultFatalSectionCountImbalance{ErrorModule::AM, 512}; |
diff --git a/src/core/hle/service/am/am_types.h b/src/core/hle/service/am/am_types.h index a14defb40..eb9ad0ac5 100755 --- a/src/core/hle/service/am/am_types.h +++ b/src/core/hle/service/am/am_types.h | |||
@@ -61,12 +61,6 @@ enum class ScreenshotPermission : u32 { | |||
61 | Disable = 2, | 61 | Disable = 2, |
62 | }; | 62 | }; |
63 | 63 | ||
64 | struct FocusHandlingMode { | ||
65 | bool notify; | ||
66 | bool background; | ||
67 | bool suspend; | ||
68 | }; | ||
69 | |||
70 | enum class IdleTimeDetectionExtension : u32 { | 64 | enum class IdleTimeDetectionExtension : u32 { |
71 | Disabled = 0, | 65 | Disabled = 0, |
72 | Extended = 1, | 66 | Extended = 1, |
@@ -239,7 +233,6 @@ struct ApplicationPlayStatistics { | |||
239 | static_assert(sizeof(ApplicationPlayStatistics) == 0x18, | 233 | static_assert(sizeof(ApplicationPlayStatistics) == 0x18, |
240 | "ApplicationPlayStatistics has incorrect size."); | 234 | "ApplicationPlayStatistics has incorrect size."); |
241 | 235 | ||
242 | using AppletResourceUserId = u64; | ||
243 | using ProgramId = u64; | 236 | using ProgramId = u64; |
244 | 237 | ||
245 | struct Applet; | 238 | struct Applet; |
diff --git a/src/core/hle/service/am/applet.cpp b/src/core/hle/service/am/applet.cpp index 5b9056c12..6847f250c 100755 --- a/src/core/hle/service/am/applet.cpp +++ b/src/core/hle/service/am/applet.cpp | |||
@@ -1,27 +1,71 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
3 | 3 | ||
4 | #include "common/scope_exit.h" | ||
5 | |||
6 | #include "core/core.h" | 4 | #include "core/core.h" |
7 | #include "core/hle/service/am/am_results.h" | ||
8 | #include "core/hle/service/am/applet.h" | 5 | #include "core/hle/service/am/applet.h" |
9 | #include "core/hle/service/am/applet_manager.h" | 6 | #include "core/hle/service/am/applet_manager.h" |
10 | 7 | ||
11 | namespace Service::AM { | 8 | namespace Service::AM { |
12 | 9 | ||
13 | Applet::Applet(Core::System& system, std::unique_ptr<Process> process_) | 10 | Applet::Applet(Core::System& system, std::unique_ptr<Process> process_, bool is_application) |
14 | : context(system, "Applet"), message_queue(system), process(std::move(process_)), | 11 | : context(system, "Applet"), lifecycle_manager(system, context, is_application), |
15 | hid_registration(system, *process), gpu_error_detected_event(context), | 12 | process(std::move(process_)), hid_registration(system, *process), |
16 | friend_invitation_storage_channel_event(context), notification_storage_channel_event(context), | 13 | gpu_error_detected_event(context), friend_invitation_storage_channel_event(context), |
17 | health_warning_disappeared_system_event(context), acquired_sleep_lock_event(context), | 14 | notification_storage_channel_event(context), health_warning_disappeared_system_event(context), |
18 | pop_from_general_channel_event(context), library_applet_launchable_event(context), | 15 | acquired_sleep_lock_event(context), pop_from_general_channel_event(context), |
19 | accumulated_suspended_tick_changed_event(context), sleep_lock_event(context) { | 16 | library_applet_launchable_event(context), accumulated_suspended_tick_changed_event(context), |
17 | sleep_lock_event(context), state_changed_event(context) { | ||
20 | 18 | ||
21 | aruid = process->GetProcessId(); | 19 | aruid.pid = process->GetProcessId(); |
22 | program_id = process->GetProgramId(); | 20 | program_id = process->GetProgramId(); |
23 | } | 21 | } |
24 | 22 | ||
25 | Applet::~Applet() = default; | 23 | Applet::~Applet() = default; |
26 | 24 | ||
25 | void Applet::UpdateSuspensionStateLocked(bool force_message) { | ||
26 | // Remove any forced resumption. | ||
27 | lifecycle_manager.RemoveForceResumeIfPossible(); | ||
28 | |||
29 | // Check if we're runnable. | ||
30 | const bool curr_activity_runnable = lifecycle_manager.IsRunnable(); | ||
31 | const bool prev_activity_runnable = is_activity_runnable; | ||
32 | const bool was_changed = curr_activity_runnable != prev_activity_runnable; | ||
33 | |||
34 | if (was_changed) { | ||
35 | if (curr_activity_runnable) { | ||
36 | process->Suspend(false); | ||
37 | } else { | ||
38 | process->Suspend(true); | ||
39 | lifecycle_manager.RequestResumeNotification(); | ||
40 | } | ||
41 | |||
42 | is_activity_runnable = curr_activity_runnable; | ||
43 | } | ||
44 | |||
45 | if (lifecycle_manager.GetForcedSuspend()) { | ||
46 | // TODO: why is this allowed? | ||
47 | return; | ||
48 | } | ||
49 | |||
50 | // Signal if the focus state was changed or the process state was changed. | ||
51 | if (lifecycle_manager.UpdateRequestedFocusState() || was_changed || force_message) { | ||
52 | lifecycle_manager.SignalSystemEventIfNeeded(); | ||
53 | } | ||
54 | } | ||
55 | |||
56 | void Applet::SetInteractibleLocked(bool interactible) { | ||
57 | if (is_interactible == interactible) { | ||
58 | return; | ||
59 | } | ||
60 | |||
61 | is_interactible = interactible; | ||
62 | |||
63 | hid_registration.EnableAppletToGetInput(interactible && !lifecycle_manager.GetExitRequested()); | ||
64 | } | ||
65 | |||
66 | void Applet::OnProcessTerminatedLocked() { | ||
67 | is_completed = true; | ||
68 | state_changed_event.Signal(); | ||
69 | } | ||
70 | |||
27 | } // namespace Service::AM | 71 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/applet.h b/src/core/hle/service/am/applet.h index ad602153e..571904fab 100755 --- a/src/core/hle/service/am/applet.h +++ b/src/core/hle/service/am/applet.h | |||
@@ -3,25 +3,28 @@ | |||
3 | 3 | ||
4 | #pragma once | 4 | #pragma once |
5 | 5 | ||
6 | #include <deque> | ||
6 | #include <mutex> | 7 | #include <mutex> |
7 | 8 | ||
8 | #include "common/math_util.h" | 9 | #include "common/math_util.h" |
9 | #include "core/hle/service/apm/apm_controller.h" | 10 | #include "core/hle/service/apm/apm_controller.h" |
10 | #include "core/hle/service/caps/caps_types.h" | 11 | #include "core/hle/service/caps/caps_types.h" |
12 | #include "core/hle/service/cmif_types.h" | ||
11 | #include "core/hle/service/kernel_helpers.h" | 13 | #include "core/hle/service/kernel_helpers.h" |
12 | #include "core/hle/service/os/event.h" | 14 | #include "core/hle/service/os/event.h" |
15 | #include "core/hle/service/os/process.h" | ||
13 | #include "core/hle/service/service.h" | 16 | #include "core/hle/service/service.h" |
14 | 17 | ||
15 | #include "core/hle/service/am/am_types.h" | 18 | #include "core/hle/service/am/am_types.h" |
16 | #include "core/hle/service/am/applet_message_queue.h" | ||
17 | #include "core/hle/service/am/display_layer_manager.h" | 19 | #include "core/hle/service/am/display_layer_manager.h" |
18 | #include "core/hle/service/am/hid_registration.h" | 20 | #include "core/hle/service/am/hid_registration.h" |
19 | #include "core/hle/service/am/process.h" | 21 | #include "core/hle/service/am/lifecycle_manager.h" |
22 | #include "core/hle/service/am/process_holder.h" | ||
20 | 23 | ||
21 | namespace Service::AM { | 24 | namespace Service::AM { |
22 | 25 | ||
23 | struct Applet { | 26 | struct Applet { |
24 | explicit Applet(Core::System& system, std::unique_ptr<Process> process_); | 27 | explicit Applet(Core::System& system, std::unique_ptr<Process> process_, bool is_application); |
25 | ~Applet(); | 28 | ~Applet(); |
26 | 29 | ||
27 | // Lock | 30 | // Lock |
@@ -30,11 +33,13 @@ struct Applet { | |||
30 | // Event creation helper | 33 | // Event creation helper |
31 | KernelHelpers::ServiceContext context; | 34 | KernelHelpers::ServiceContext context; |
32 | 35 | ||
33 | // Applet message queue | 36 | // Lifecycle manager |
34 | AppletMessageQueue message_queue; | 37 | LifecycleManager lifecycle_manager; |
35 | 38 | ||
36 | // Process | 39 | // Process |
37 | std::unique_ptr<Process> process; | 40 | std::unique_ptr<Process> process; |
41 | std::optional<ProcessHolder> process_holder; | ||
42 | bool is_process_running{}; | ||
38 | 43 | ||
39 | // Creation state | 44 | // Creation state |
40 | AppletId applet_id{}; | 45 | AppletId applet_id{}; |
@@ -75,11 +80,9 @@ struct Applet { | |||
75 | bool game_play_recording_supported{}; | 80 | bool game_play_recording_supported{}; |
76 | GamePlayRecordingState game_play_recording_state{GamePlayRecordingState::Disabled}; | 81 | GamePlayRecordingState game_play_recording_state{GamePlayRecordingState::Disabled}; |
77 | bool jit_service_launched{}; | 82 | bool jit_service_launched{}; |
78 | bool is_running{}; | ||
79 | bool application_crash_report_enabled{}; | 83 | bool application_crash_report_enabled{}; |
80 | 84 | ||
81 | // Common state | 85 | // Common state |
82 | FocusState focus_state{}; | ||
83 | bool sleep_lock_enabled{}; | 86 | bool sleep_lock_enabled{}; |
84 | bool vr_mode_enabled{}; | 87 | bool vr_mode_enabled{}; |
85 | bool lcd_backlight_off_enabled{}; | 88 | bool lcd_backlight_off_enabled{}; |
@@ -93,15 +96,12 @@ struct Applet { | |||
93 | // Caller applet | 96 | // Caller applet |
94 | std::weak_ptr<Applet> caller_applet{}; | 97 | std::weak_ptr<Applet> caller_applet{}; |
95 | std::shared_ptr<AppletDataBroker> caller_applet_broker{}; | 98 | std::shared_ptr<AppletDataBroker> caller_applet_broker{}; |
99 | std::list<std::shared_ptr<Applet>> child_applets{}; | ||
100 | bool is_completed{}; | ||
96 | 101 | ||
97 | // Self state | 102 | // Self state |
98 | bool exit_locked{}; | 103 | bool exit_locked{}; |
99 | s32 fatal_section_count{}; | 104 | s32 fatal_section_count{}; |
100 | bool operation_mode_changed_notification_enabled{true}; | ||
101 | bool performance_mode_changed_notification_enabled{true}; | ||
102 | FocusHandlingMode focus_handling_mode{}; | ||
103 | bool restart_message_enabled{}; | ||
104 | bool out_of_focus_suspension_enabled{true}; | ||
105 | Capture::AlbumImageOrientation album_image_orientation{}; | 105 | Capture::AlbumImageOrientation album_image_orientation{}; |
106 | bool handles_request_to_display{}; | 106 | bool handles_request_to_display{}; |
107 | ScreenshotPermission screenshot_permission{}; | 107 | ScreenshotPermission screenshot_permission{}; |
@@ -110,6 +110,9 @@ struct Applet { | |||
110 | u64 suspended_ticks{}; | 110 | u64 suspended_ticks{}; |
111 | bool album_image_taken_notification_enabled{}; | 111 | bool album_image_taken_notification_enabled{}; |
112 | bool record_volume_muted{}; | 112 | bool record_volume_muted{}; |
113 | bool is_activity_runnable{}; | ||
114 | bool is_interactible{true}; | ||
115 | bool window_visible{true}; | ||
113 | 116 | ||
114 | // Events | 117 | // Events |
115 | Event gpu_error_detected_event; | 118 | Event gpu_error_detected_event; |
@@ -121,9 +124,15 @@ struct Applet { | |||
121 | Event library_applet_launchable_event; | 124 | Event library_applet_launchable_event; |
122 | Event accumulated_suspended_tick_changed_event; | 125 | Event accumulated_suspended_tick_changed_event; |
123 | Event sleep_lock_event; | 126 | Event sleep_lock_event; |
127 | Event state_changed_event; | ||
124 | 128 | ||
125 | // Frontend state | 129 | // Frontend state |
126 | std::shared_ptr<Frontend::FrontendApplet> frontend{}; | 130 | std::shared_ptr<Frontend::FrontendApplet> frontend{}; |
131 | |||
132 | // Process state management | ||
133 | void UpdateSuspensionStateLocked(bool force_message); | ||
134 | void SetInteractibleLocked(bool interactible); | ||
135 | void OnProcessTerminatedLocked(); | ||
127 | }; | 136 | }; |
128 | 137 | ||
129 | } // namespace Service::AM | 138 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/applet_data_broker.cpp b/src/core/hle/service/am/applet_data_broker.cpp index 9057244a9..fff78c5af 100755 --- a/src/core/hle/service/am/applet_data_broker.cpp +++ b/src/core/hle/service/am/applet_data_broker.cpp | |||
@@ -44,24 +44,8 @@ Kernel::KReadableEvent* AppletStorageChannel::GetEvent() { | |||
44 | 44 | ||
45 | AppletDataBroker::AppletDataBroker(Core::System& system_) | 45 | AppletDataBroker::AppletDataBroker(Core::System& system_) |
46 | : system(system_), context(system_, "AppletDataBroker"), in_data(context), | 46 | : system(system_), context(system_, "AppletDataBroker"), in_data(context), |
47 | interactive_in_data(context), out_data(context), interactive_out_data(context), | 47 | interactive_in_data(context), out_data(context), interactive_out_data(context) {} |
48 | state_changed_event(context), is_completed(false) {} | ||
49 | 48 | ||
50 | AppletDataBroker::~AppletDataBroker() = default; | 49 | AppletDataBroker::~AppletDataBroker() = default; |
51 | 50 | ||
52 | void AppletDataBroker::SignalCompletion() { | ||
53 | { | ||
54 | std::scoped_lock lk{lock}; | ||
55 | |||
56 | if (is_completed) { | ||
57 | return; | ||
58 | } | ||
59 | |||
60 | is_completed = true; | ||
61 | state_changed_event.Signal(); | ||
62 | } | ||
63 | |||
64 | system.GetAppletManager().FocusStateChanged(); | ||
65 | } | ||
66 | |||
67 | } // namespace Service::AM | 51 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/applet_data_broker.h b/src/core/hle/service/am/applet_data_broker.h index 5a1d43c11..2718f608a 100755 --- a/src/core/hle/service/am/applet_data_broker.h +++ b/src/core/hle/service/am/applet_data_broker.h | |||
@@ -53,16 +53,6 @@ public: | |||
53 | return interactive_out_data; | 53 | return interactive_out_data; |
54 | } | 54 | } |
55 | 55 | ||
56 | Event& GetStateChangedEvent() { | ||
57 | return state_changed_event; | ||
58 | } | ||
59 | |||
60 | bool IsCompleted() const { | ||
61 | return is_completed; | ||
62 | } | ||
63 | |||
64 | void SignalCompletion(); | ||
65 | |||
66 | private: | 56 | private: |
67 | Core::System& system; | 57 | Core::System& system; |
68 | KernelHelpers::ServiceContext context; | 58 | KernelHelpers::ServiceContext context; |
@@ -71,10 +61,6 @@ private: | |||
71 | AppletStorageChannel interactive_in_data; | 61 | AppletStorageChannel interactive_in_data; |
72 | AppletStorageChannel out_data; | 62 | AppletStorageChannel out_data; |
73 | AppletStorageChannel interactive_out_data; | 63 | AppletStorageChannel interactive_out_data; |
74 | Event state_changed_event; | ||
75 | |||
76 | std::mutex lock; | ||
77 | bool is_completed; | ||
78 | }; | 64 | }; |
79 | 65 | ||
80 | } // namespace Service::AM | 66 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/applet_manager.cpp b/src/core/hle/service/am/applet_manager.cpp index 2e109181d..c6b7ec8bb 100755 --- a/src/core/hle/service/am/applet_manager.cpp +++ b/src/core/hle/service/am/applet_manager.cpp | |||
@@ -13,6 +13,7 @@ | |||
13 | #include "core/hle/service/am/frontend/applet_mii_edit_types.h" | 13 | #include "core/hle/service/am/frontend/applet_mii_edit_types.h" |
14 | #include "core/hle/service/am/frontend/applet_software_keyboard_types.h" | 14 | #include "core/hle/service/am/frontend/applet_software_keyboard_types.h" |
15 | #include "core/hle/service/am/service/storage.h" | 15 | #include "core/hle/service/am/service/storage.h" |
16 | #include "core/hle/service/am/window_system.h" | ||
16 | #include "hid_core/hid_types.h" | 17 | #include "hid_core/hid_types.h" |
17 | 18 | ||
18 | namespace Service::AM { | 19 | namespace Service::AM { |
@@ -225,49 +226,46 @@ void PushInShowSoftwareKeyboard(Core::System& system, AppletStorageChannel& chan | |||
225 | } // namespace | 226 | } // namespace |
226 | 227 | ||
227 | AppletManager::AppletManager(Core::System& system) : m_system(system) {} | 228 | AppletManager::AppletManager(Core::System& system) : m_system(system) {} |
228 | AppletManager::~AppletManager() { | 229 | AppletManager::~AppletManager() = default; |
229 | this->Reset(); | ||
230 | } | ||
231 | |||
232 | void AppletManager::InsertApplet(std::shared_ptr<Applet> applet) { | ||
233 | std::scoped_lock lk{m_lock}; | ||
234 | 230 | ||
235 | m_applets.emplace(applet->aruid, std::move(applet)); | 231 | void AppletManager::CreateAndInsertByFrontendAppletParameters( |
236 | } | 232 | std::unique_ptr<Process> process, const FrontendAppletParameters& params) { |
237 | |||
238 | void AppletManager::TerminateAndRemoveApplet(AppletResourceUserId aruid) { | ||
239 | std::shared_ptr<Applet> applet; | ||
240 | bool should_stop = false; | ||
241 | { | 233 | { |
242 | std::scoped_lock lk{m_lock}; | 234 | std::scoped_lock lk{m_lock}; |
235 | m_pending_process = std::move(process); | ||
236 | m_pending_parameters = params; | ||
237 | } | ||
238 | m_cv.notify_all(); | ||
239 | } | ||
243 | 240 | ||
244 | const auto it = m_applets.find(aruid); | 241 | void AppletManager::RequestExit() { |
245 | if (it == m_applets.end()) { | 242 | std::scoped_lock lk{m_lock}; |
246 | return; | 243 | if (m_window_system) { |
247 | } | 244 | m_window_system->OnExitRequested(); |
248 | 245 | } | |
249 | applet = it->second; | 246 | } |
250 | m_applets.erase(it); | ||
251 | 247 | ||
252 | should_stop = m_applets.empty(); | 248 | void AppletManager::OperationModeChanged() { |
249 | std::scoped_lock lk{m_lock}; | ||
250 | if (m_window_system) { | ||
251 | m_window_system->OnOperationModeChanged(); | ||
253 | } | 252 | } |
253 | } | ||
254 | 254 | ||
255 | // Terminate process. | 255 | void AppletManager::SetWindowSystem(WindowSystem* window_system) { |
256 | applet->process->Terminate(); | 256 | std::unique_lock lk{m_lock}; |
257 | 257 | ||
258 | // If there were no applets left, stop emulation. | 258 | m_window_system = window_system; |
259 | if (should_stop) { | 259 | if (!m_window_system) { |
260 | m_system.Exit(); | 260 | return; |
261 | } | 261 | } |
262 | } | ||
263 | 262 | ||
264 | void AppletManager::CreateAndInsertByFrontendAppletParameters( | 263 | m_cv.wait(lk, [&] { return m_pending_process != nullptr; }); |
265 | AppletResourceUserId aruid, const FrontendAppletParameters& params) { | 264 | |
266 | // TODO: this should be run inside AM so that the events will have a parent process | 265 | const auto& params = m_pending_parameters; |
267 | // TODO: have am create the guest process | 266 | auto applet = std::make_shared<Applet>(m_system, std::move(m_pending_process), |
268 | auto applet = std::make_shared<Applet>(m_system, std::make_unique<Process>(m_system)); | 267 | params.applet_id == AppletId::Application); |
269 | 268 | ||
270 | applet->aruid = aruid; | ||
271 | applet->program_id = params.program_id; | 269 | applet->program_id = params.program_id; |
272 | applet->applet_id = params.applet_id; | 270 | applet->applet_id = params.applet_id; |
273 | applet->type = params.applet_type; | 271 | applet->type = params.applet_type; |
@@ -322,59 +320,19 @@ void AppletManager::CreateAndInsertByFrontendAppletParameters( | |||
322 | } | 320 | } |
323 | 321 | ||
324 | // Applet was started by frontend, so it is foreground. | 322 | // Applet was started by frontend, so it is foreground. |
325 | applet->message_queue.PushMessage(AppletMessage::ChangeIntoForeground); | 323 | applet->lifecycle_manager.SetFocusState(FocusState::InFocus); |
326 | applet->message_queue.PushMessage(AppletMessage::FocusStateChanged); | 324 | |
327 | applet->focus_state = FocusState::InFocus; | 325 | if (applet->applet_id == AppletId::QLaunch) { |
328 | 326 | applet->lifecycle_manager.SetFocusHandlingMode(false); | |
329 | this->InsertApplet(std::move(applet)); | 327 | applet->lifecycle_manager.SetOutOfFocusSuspendingEnabled(false); |
330 | } | 328 | m_window_system->TrackApplet(applet, false); |
331 | 329 | m_window_system->RequestHomeMenuToGetForeground(); | |
332 | std::shared_ptr<Applet> AppletManager::GetByAppletResourceUserId(AppletResourceUserId aruid) const { | 330 | } else { |
333 | std::scoped_lock lk{m_lock}; | 331 | m_window_system->TrackApplet(applet, true); |
334 | 332 | m_window_system->RequestApplicationToGetForeground(); | |
335 | if (const auto it = m_applets.find(aruid); it != m_applets.end()) { | ||
336 | return it->second; | ||
337 | } | ||
338 | |||
339 | return {}; | ||
340 | } | ||
341 | |||
342 | void AppletManager::Reset() { | ||
343 | std::scoped_lock lk{m_lock}; | ||
344 | |||
345 | m_applets.clear(); | ||
346 | } | ||
347 | |||
348 | void AppletManager::RequestExit() { | ||
349 | std::scoped_lock lk{m_lock}; | ||
350 | |||
351 | for (const auto& [aruid, applet] : m_applets) { | ||
352 | applet->message_queue.RequestExit(); | ||
353 | } | 333 | } |
354 | } | ||
355 | |||
356 | void AppletManager::RequestResume() { | ||
357 | std::scoped_lock lk{m_lock}; | ||
358 | 334 | ||
359 | for (const auto& [aruid, applet] : m_applets) { | 335 | applet->process->Run(); |
360 | applet->message_queue.RequestResume(); | ||
361 | } | ||
362 | } | ||
363 | |||
364 | void AppletManager::OperationModeChanged() { | ||
365 | std::scoped_lock lk{m_lock}; | ||
366 | |||
367 | for (const auto& [aruid, applet] : m_applets) { | ||
368 | applet->message_queue.OperationModeChanged(); | ||
369 | } | ||
370 | } | ||
371 | |||
372 | void AppletManager::FocusStateChanged() { | ||
373 | std::scoped_lock lk{m_lock}; | ||
374 | |||
375 | for (const auto& [aruid, applet] : m_applets) { | ||
376 | applet->message_queue.FocusStateChanged(); | ||
377 | } | ||
378 | } | 336 | } |
379 | 337 | ||
380 | } // namespace Service::AM | 338 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/applet_manager.h b/src/core/hle/service/am/applet_manager.h index 4875de309..fbdc77140 100755 --- a/src/core/hle/service/am/applet_manager.h +++ b/src/core/hle/service/am/applet_manager.h | |||
@@ -3,17 +3,23 @@ | |||
3 | 3 | ||
4 | #pragma once | 4 | #pragma once |
5 | 5 | ||
6 | #include <map> | 6 | #include <condition_variable> |
7 | #include <mutex> | 7 | #include <mutex> |
8 | 8 | ||
9 | #include "core/hle/service/am/applet.h" | 9 | #include "core/hle/service/am/am_types.h" |
10 | 10 | ||
11 | namespace Core { | 11 | namespace Core { |
12 | class System; | 12 | class System; |
13 | } | 13 | } |
14 | 14 | ||
15 | namespace Service { | ||
16 | class Process; | ||
17 | } | ||
18 | |||
15 | namespace Service::AM { | 19 | namespace Service::AM { |
16 | 20 | ||
21 | class WindowSystem; | ||
22 | |||
17 | enum class LaunchType { | 23 | enum class LaunchType { |
18 | FrontendInitiated, | 24 | FrontendInitiated, |
19 | ApplicationInitiated, | 25 | ApplicationInitiated, |
@@ -33,27 +39,24 @@ public: | |||
33 | explicit AppletManager(Core::System& system); | 39 | explicit AppletManager(Core::System& system); |
34 | ~AppletManager(); | 40 | ~AppletManager(); |
35 | 41 | ||
36 | void InsertApplet(std::shared_ptr<Applet> applet); | 42 | void CreateAndInsertByFrontendAppletParameters(std::unique_ptr<Process> process, |
37 | void TerminateAndRemoveApplet(AppletResourceUserId aruid); | ||
38 | |||
39 | void CreateAndInsertByFrontendAppletParameters(AppletResourceUserId aruid, | ||
40 | const FrontendAppletParameters& params); | 43 | const FrontendAppletParameters& params); |
41 | std::shared_ptr<Applet> GetByAppletResourceUserId(AppletResourceUserId aruid) const; | ||
42 | |||
43 | void Reset(); | ||
44 | |||
45 | void RequestExit(); | 44 | void RequestExit(); |
46 | void RequestResume(); | ||
47 | void OperationModeChanged(); | 45 | void OperationModeChanged(); |
48 | void FocusStateChanged(); | 46 | |
47 | public: | ||
48 | void SetWindowSystem(WindowSystem* window_system); | ||
49 | 49 | ||
50 | private: | 50 | private: |
51 | Core::System& m_system; | 51 | Core::System& m_system; |
52 | 52 | ||
53 | mutable std::mutex m_lock{}; | 53 | std::mutex m_lock; |
54 | std::map<AppletResourceUserId, std::shared_ptr<Applet>> m_applets{}; | 54 | std::condition_variable m_cv; |
55 | |||
56 | WindowSystem* m_window_system{}; | ||
55 | 57 | ||
56 | // AudioController state goes here | 58 | FrontendAppletParameters m_pending_parameters{}; |
59 | std::unique_ptr<Process> m_pending_process{}; | ||
57 | }; | 60 | }; |
58 | 61 | ||
59 | } // namespace Service::AM | 62 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/frontend/applets.cpp b/src/core/hle/service/am/frontend/applets.cpp index e662c6cd6..cdd431857 100755 --- a/src/core/hle/service/am/frontend/applets.cpp +++ b/src/core/hle/service/am/frontend/applets.cpp | |||
@@ -69,7 +69,11 @@ void FrontendApplet::PushInteractiveOutData(std::shared_ptr<IStorage> storage) { | |||
69 | } | 69 | } |
70 | 70 | ||
71 | void FrontendApplet::Exit() { | 71 | void FrontendApplet::Exit() { |
72 | applet.lock()->caller_applet_broker->SignalCompletion(); | 72 | auto applet_ = applet.lock(); |
73 | |||
74 | std::scoped_lock lk{applet_->lock}; | ||
75 | applet_->is_completed = true; | ||
76 | applet_->state_changed_event.Signal(); | ||
73 | } | 77 | } |
74 | 78 | ||
75 | FrontendAppletSet::FrontendAppletSet() = default; | 79 | FrontendAppletSet::FrontendAppletSet() = default; |
diff --git a/src/core/hle/service/am/hid_registration.cpp b/src/core/hle/service/am/hid_registration.cpp index 8ed49bac1..ea4bd8f45 100755 --- a/src/core/hle/service/am/hid_registration.cpp +++ b/src/core/hle/service/am/hid_registration.cpp | |||
@@ -3,24 +3,28 @@ | |||
3 | 3 | ||
4 | #include "core/core.h" | 4 | #include "core/core.h" |
5 | #include "core/hle/service/am/hid_registration.h" | 5 | #include "core/hle/service/am/hid_registration.h" |
6 | #include "core/hle/service/am/process.h" | ||
7 | #include "core/hle/service/hid/hid_server.h" | 6 | #include "core/hle/service/hid/hid_server.h" |
7 | #include "core/hle/service/os/process.h" | ||
8 | #include "core/hle/service/sm/sm.h" | 8 | #include "core/hle/service/sm/sm.h" |
9 | #include "hid_core/resource_manager.h" | 9 | #include "hid_core/resource_manager.h" |
10 | 10 | ||
11 | namespace Service::AM { | 11 | namespace Service::AM { |
12 | 12 | ||
13 | HidRegistration::HidRegistration(Core::System& system, Process& process) : m_process(process) { | 13 | HidRegistration::HidRegistration(Core::System& system, Process& process) : m_process(process) { |
14 | m_hid_server = system.ServiceManager().GetService<HID::IHidServer>("hid"); | 14 | m_hid_server = system.ServiceManager().GetService<HID::IHidServer>("hid", true); |
15 | 15 | ||
16 | if (m_process.IsInitialized()) { | 16 | if (m_process.IsInitialized()) { |
17 | m_hid_server->GetResourceManager()->RegisterAppletResourceUserId(m_process.GetProcessId(), | 17 | m_hid_server->GetResourceManager()->RegisterAppletResourceUserId(m_process.GetProcessId(), |
18 | true); | 18 | true); |
19 | m_hid_server->GetResourceManager()->SetAruidValidForVibration(m_process.GetProcessId(), | ||
20 | true); | ||
19 | } | 21 | } |
20 | } | 22 | } |
21 | 23 | ||
22 | HidRegistration::~HidRegistration() { | 24 | HidRegistration::~HidRegistration() { |
23 | if (m_process.IsInitialized()) { | 25 | if (m_process.IsInitialized()) { |
26 | m_hid_server->GetResourceManager()->SetAruidValidForVibration(m_process.GetProcessId(), | ||
27 | false); | ||
24 | m_hid_server->GetResourceManager()->UnregisterAppletResourceUserId( | 28 | m_hid_server->GetResourceManager()->UnregisterAppletResourceUserId( |
25 | m_process.GetProcessId()); | 29 | m_process.GetProcessId()); |
26 | } | 30 | } |
@@ -28,6 +32,8 @@ HidRegistration::~HidRegistration() { | |||
28 | 32 | ||
29 | void HidRegistration::EnableAppletToGetInput(bool enable) { | 33 | void HidRegistration::EnableAppletToGetInput(bool enable) { |
30 | if (m_process.IsInitialized()) { | 34 | if (m_process.IsInitialized()) { |
35 | m_hid_server->GetResourceManager()->SetAruidValidForVibration(m_process.GetProcessId(), | ||
36 | enable); | ||
31 | m_hid_server->GetResourceManager()->EnableInput(m_process.GetProcessId(), enable); | 37 | m_hid_server->GetResourceManager()->EnableInput(m_process.GetProcessId(), enable); |
32 | } | 38 | } |
33 | } | 39 | } |
diff --git a/src/core/hle/service/am/hid_registration.h b/src/core/hle/service/am/hid_registration.h index 67cd84961..54f42af18 100755 --- a/src/core/hle/service/am/hid_registration.h +++ b/src/core/hle/service/am/hid_registration.h | |||
@@ -13,9 +13,11 @@ namespace Service::HID { | |||
13 | class IHidServer; | 13 | class IHidServer; |
14 | } | 14 | } |
15 | 15 | ||
16 | namespace Service::AM { | 16 | namespace Service { |
17 | |||
18 | class Process; | 17 | class Process; |
18 | } | ||
19 | |||
20 | namespace Service::AM { | ||
19 | 21 | ||
20 | class HidRegistration { | 22 | class HidRegistration { |
21 | public: | 23 | public: |
diff --git a/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp b/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp index 21747783a..bc9c86c55 100755 --- a/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp +++ b/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp | |||
@@ -6,12 +6,14 @@ | |||
6 | #include "core/hle/service/am/service/all_system_applet_proxies_service.h" | 6 | #include "core/hle/service/am/service/all_system_applet_proxies_service.h" |
7 | #include "core/hle/service/am/service/library_applet_proxy.h" | 7 | #include "core/hle/service/am/service/library_applet_proxy.h" |
8 | #include "core/hle/service/am/service/system_applet_proxy.h" | 8 | #include "core/hle/service/am/service/system_applet_proxy.h" |
9 | #include "core/hle/service/am/window_system.h" | ||
9 | #include "core/hle/service/cmif_serialization.h" | 10 | #include "core/hle/service/cmif_serialization.h" |
10 | 11 | ||
11 | namespace Service::AM { | 12 | namespace Service::AM { |
12 | 13 | ||
13 | IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& system_) | 14 | IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& system_, |
14 | : ServiceFramework{system_, "appletAE"} { | 15 | WindowSystem& window_system) |
16 | : ServiceFramework{system_, "appletAE"}, m_window_system{window_system} { | ||
15 | // clang-format off | 17 | // clang-format off |
16 | static const FunctionInfo functions[] = { | 18 | static const FunctionInfo functions[] = { |
17 | {100, D<&IAllSystemAppletProxiesService::OpenSystemAppletProxy>, "OpenSystemAppletProxy"}, | 19 | {100, D<&IAllSystemAppletProxiesService::OpenSystemAppletProxy>, "OpenSystemAppletProxy"}, |
@@ -36,8 +38,8 @@ Result IAllSystemAppletProxiesService::OpenSystemAppletProxy( | |||
36 | LOG_DEBUG(Service_AM, "called"); | 38 | LOG_DEBUG(Service_AM, "called"); |
37 | 39 | ||
38 | if (const auto applet = this->GetAppletFromProcessId(pid); applet) { | 40 | if (const auto applet = this->GetAppletFromProcessId(pid); applet) { |
39 | *out_system_applet_proxy = | 41 | *out_system_applet_proxy = std::make_shared<ISystemAppletProxy>( |
40 | std::make_shared<ISystemAppletProxy>(system, applet, process_handle.Get()); | 42 | system, applet, process_handle.Get(), m_window_system); |
41 | R_SUCCEED(); | 43 | R_SUCCEED(); |
42 | } else { | 44 | } else { |
43 | UNIMPLEMENTED(); | 45 | UNIMPLEMENTED(); |
@@ -52,8 +54,8 @@ Result IAllSystemAppletProxiesService::OpenLibraryAppletProxy( | |||
52 | LOG_DEBUG(Service_AM, "called"); | 54 | LOG_DEBUG(Service_AM, "called"); |
53 | 55 | ||
54 | if (const auto applet = this->GetAppletFromProcessId(pid); applet) { | 56 | if (const auto applet = this->GetAppletFromProcessId(pid); applet) { |
55 | *out_library_applet_proxy = | 57 | *out_library_applet_proxy = std::make_shared<ILibraryAppletProxy>( |
56 | std::make_shared<ILibraryAppletProxy>(system, applet, process_handle.Get()); | 58 | system, applet, process_handle.Get(), m_window_system); |
57 | R_SUCCEED(); | 59 | R_SUCCEED(); |
58 | } else { | 60 | } else { |
59 | UNIMPLEMENTED(); | 61 | UNIMPLEMENTED(); |
@@ -73,7 +75,7 @@ Result IAllSystemAppletProxiesService::OpenLibraryAppletProxyOld( | |||
73 | 75 | ||
74 | std::shared_ptr<Applet> IAllSystemAppletProxiesService::GetAppletFromProcessId( | 76 | std::shared_ptr<Applet> IAllSystemAppletProxiesService::GetAppletFromProcessId( |
75 | ProcessId process_id) { | 77 | ProcessId process_id) { |
76 | return system.GetAppletManager().GetByAppletResourceUserId(process_id.pid); | 78 | return m_window_system.GetByAppletResourceUserId(process_id.pid); |
77 | } | 79 | } |
78 | 80 | ||
79 | } // namespace Service::AM | 81 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/service/all_system_applet_proxies_service.h b/src/core/hle/service/am/service/all_system_applet_proxies_service.h index 0e2dcb86d..e3e79dc4f 100755 --- a/src/core/hle/service/am/service/all_system_applet_proxies_service.h +++ b/src/core/hle/service/am/service/all_system_applet_proxies_service.h | |||
@@ -14,11 +14,12 @@ struct Applet; | |||
14 | struct AppletAttribute; | 14 | struct AppletAttribute; |
15 | class ILibraryAppletProxy; | 15 | class ILibraryAppletProxy; |
16 | class ISystemAppletProxy; | 16 | class ISystemAppletProxy; |
17 | class WindowSystem; | ||
17 | 18 | ||
18 | class IAllSystemAppletProxiesService final | 19 | class IAllSystemAppletProxiesService final |
19 | : public ServiceFramework<IAllSystemAppletProxiesService> { | 20 | : public ServiceFramework<IAllSystemAppletProxiesService> { |
20 | public: | 21 | public: |
21 | explicit IAllSystemAppletProxiesService(Core::System& system_); | 22 | explicit IAllSystemAppletProxiesService(Core::System& system_, WindowSystem& window_system); |
22 | ~IAllSystemAppletProxiesService() override; | 23 | ~IAllSystemAppletProxiesService() override; |
23 | 24 | ||
24 | private: | 25 | private: |
@@ -35,6 +36,8 @@ private: | |||
35 | 36 | ||
36 | private: | 37 | private: |
37 | std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid); | 38 | std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid); |
39 | |||
40 | WindowSystem& m_window_system; | ||
38 | }; | 41 | }; |
39 | 42 | ||
40 | } // namespace AM | 43 | } // namespace AM |
diff --git a/src/core/hle/service/am/service/applet_common_functions.cpp b/src/core/hle/service/am/service/applet_common_functions.cpp index 0f29ab285..a051000af 100755 --- a/src/core/hle/service/am/service/applet_common_functions.cpp +++ b/src/core/hle/service/am/service/applet_common_functions.cpp | |||
@@ -19,7 +19,7 @@ IAppletCommonFunctions::IAppletCommonFunctions(Core::System& system_, | |||
19 | {21, nullptr, "TryPopFromAppletBoundChannel"}, | 19 | {21, nullptr, "TryPopFromAppletBoundChannel"}, |
20 | {40, nullptr, "GetDisplayLogicalResolution"}, | 20 | {40, nullptr, "GetDisplayLogicalResolution"}, |
21 | {42, nullptr, "SetDisplayMagnification"}, | 21 | {42, nullptr, "SetDisplayMagnification"}, |
22 | {50, nullptr, "SetHomeButtonDoubleClickEnabled"}, | 22 | {50, D<&IAppletCommonFunctions::SetHomeButtonDoubleClickEnabled>, "SetHomeButtonDoubleClickEnabled"}, |
23 | {51, D<&IAppletCommonFunctions::GetHomeButtonDoubleClickEnabled>, "GetHomeButtonDoubleClickEnabled"}, | 23 | {51, D<&IAppletCommonFunctions::GetHomeButtonDoubleClickEnabled>, "GetHomeButtonDoubleClickEnabled"}, |
24 | {52, nullptr, "IsHomeButtonShortPressedBlocked"}, | 24 | {52, nullptr, "IsHomeButtonShortPressedBlocked"}, |
25 | {60, nullptr, "IsVrModeCurtainRequired"}, | 25 | {60, nullptr, "IsVrModeCurtainRequired"}, |
@@ -40,6 +40,13 @@ IAppletCommonFunctions::IAppletCommonFunctions(Core::System& system_, | |||
40 | 40 | ||
41 | IAppletCommonFunctions::~IAppletCommonFunctions() = default; | 41 | IAppletCommonFunctions::~IAppletCommonFunctions() = default; |
42 | 42 | ||
43 | Result IAppletCommonFunctions::SetHomeButtonDoubleClickEnabled( | ||
44 | bool home_button_double_click_enabled) { | ||
45 | LOG_WARNING(Service_AM, "(STUBBED) called, home_button_double_click_enabled={}", | ||
46 | home_button_double_click_enabled); | ||
47 | R_SUCCEED(); | ||
48 | } | ||
49 | |||
43 | Result IAppletCommonFunctions::GetHomeButtonDoubleClickEnabled( | 50 | Result IAppletCommonFunctions::GetHomeButtonDoubleClickEnabled( |
44 | Out<bool> out_home_button_double_click_enabled) { | 51 | Out<bool> out_home_button_double_click_enabled) { |
45 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 52 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
diff --git a/src/core/hle/service/am/service/applet_common_functions.h b/src/core/hle/service/am/service/applet_common_functions.h index 4424fc83d..376f85acf 100755 --- a/src/core/hle/service/am/service/applet_common_functions.h +++ b/src/core/hle/service/am/service/applet_common_functions.h | |||
@@ -16,6 +16,7 @@ public: | |||
16 | ~IAppletCommonFunctions() override; | 16 | ~IAppletCommonFunctions() override; |
17 | 17 | ||
18 | private: | 18 | private: |
19 | Result SetHomeButtonDoubleClickEnabled(bool home_button_double_click_enabled); | ||
19 | Result GetHomeButtonDoubleClickEnabled(Out<bool> out_home_button_double_click_enabled); | 20 | Result GetHomeButtonDoubleClickEnabled(Out<bool> out_home_button_double_click_enabled); |
20 | Result SetCpuBoostRequestPriority(s32 priority); | 21 | Result SetCpuBoostRequestPriority(s32 priority); |
21 | Result GetCurrentApplicationId(Out<u64> out_application_id); | 22 | Result GetCurrentApplicationId(Out<u64> out_application_id); |
diff --git a/src/core/hle/service/am/service/application_accessor.cpp b/src/core/hle/service/am/service/application_accessor.cpp index 6e7d110e8..986abc716 100755 --- a/src/core/hle/service/am/service/application_accessor.cpp +++ b/src/core/hle/service/am/service/application_accessor.cpp | |||
@@ -9,12 +9,16 @@ | |||
9 | #include "core/hle/service/am/service/application_accessor.h" | 9 | #include "core/hle/service/am/service/application_accessor.h" |
10 | #include "core/hle/service/am/service/library_applet_accessor.h" | 10 | #include "core/hle/service/am/service/library_applet_accessor.h" |
11 | #include "core/hle/service/am/service/storage.h" | 11 | #include "core/hle/service/am/service/storage.h" |
12 | #include "core/hle/service/am/window_system.h" | ||
12 | #include "core/hle/service/cmif_serialization.h" | 13 | #include "core/hle/service/cmif_serialization.h" |
14 | #include "core/hle/service/glue/glue_manager.h" | ||
13 | 15 | ||
14 | namespace Service::AM { | 16 | namespace Service::AM { |
15 | 17 | ||
16 | IApplicationAccessor::IApplicationAccessor(Core::System& system_, std::shared_ptr<Applet> applet) | 18 | IApplicationAccessor::IApplicationAccessor(Core::System& system_, std::shared_ptr<Applet> applet, |
17 | : ServiceFramework{system_, "IApplicationAccessor"}, m_applet(std::move(applet)) { | 19 | WindowSystem& window_system) |
20 | : ServiceFramework{system_, "IApplicationAccessor"}, m_window_system(window_system), | ||
21 | m_applet(std::move(applet)) { | ||
18 | // clang-format off | 22 | // clang-format off |
19 | static const FunctionInfo functions[] = { | 23 | static const FunctionInfo functions[] = { |
20 | {0, D<&IApplicationAccessor::GetAppletStateChangedEvent>, "GetAppletStateChangedEvent"}, | 24 | {0, D<&IApplicationAccessor::GetAppletStateChangedEvent>, "GetAppletStateChangedEvent"}, |
@@ -59,7 +63,15 @@ Result IApplicationAccessor::Start() { | |||
59 | 63 | ||
60 | Result IApplicationAccessor::RequestExit() { | 64 | Result IApplicationAccessor::RequestExit() { |
61 | LOG_INFO(Service_AM, "called"); | 65 | LOG_INFO(Service_AM, "called"); |
62 | m_applet->message_queue.RequestExit(); | 66 | |
67 | std::scoped_lock lk{m_applet->lock}; | ||
68 | if (m_applet->exit_locked) { | ||
69 | m_applet->lifecycle_manager.RequestExit(); | ||
70 | m_applet->UpdateSuspensionStateLocked(true); | ||
71 | } else { | ||
72 | m_applet->process->Terminate(); | ||
73 | } | ||
74 | |||
63 | R_SUCCEED(); | 75 | R_SUCCEED(); |
64 | } | 76 | } |
65 | 77 | ||
@@ -71,13 +83,14 @@ Result IApplicationAccessor::Terminate() { | |||
71 | 83 | ||
72 | Result IApplicationAccessor::GetResult() { | 84 | Result IApplicationAccessor::GetResult() { |
73 | LOG_INFO(Service_AM, "called"); | 85 | LOG_INFO(Service_AM, "called"); |
74 | R_SUCCEED(); | 86 | std::scoped_lock lk{m_applet->lock}; |
87 | R_RETURN(m_applet->terminate_result); | ||
75 | } | 88 | } |
76 | 89 | ||
77 | Result IApplicationAccessor::GetAppletStateChangedEvent( | 90 | Result IApplicationAccessor::GetAppletStateChangedEvent( |
78 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | 91 | OutCopyHandle<Kernel::KReadableEvent> out_event) { |
79 | LOG_INFO(Service_AM, "called"); | 92 | LOG_INFO(Service_AM, "called"); |
80 | *out_event = m_applet->caller_applet_broker->GetStateChangedEvent().GetHandle(); | 93 | *out_event = m_applet->state_changed_event.GetHandle(); |
81 | R_SUCCEED(); | 94 | R_SUCCEED(); |
82 | } | 95 | } |
83 | 96 | ||
@@ -96,8 +109,15 @@ Result IApplicationAccessor::PushLaunchParameter(LaunchParameterKind kind, | |||
96 | 109 | ||
97 | Result IApplicationAccessor::GetApplicationControlProperty( | 110 | Result IApplicationAccessor::GetApplicationControlProperty( |
98 | OutBuffer<BufferAttr_HipcMapAlias> out_control_property) { | 111 | OutBuffer<BufferAttr_HipcMapAlias> out_control_property) { |
99 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 112 | LOG_INFO(Service_AM, "called"); |
100 | R_THROW(ResultUnknown); | 113 | |
114 | std::vector<u8> nacp; | ||
115 | R_TRY(system.GetARPManager().GetControlProperty(&nacp, m_applet->program_id)); | ||
116 | |||
117 | std::memcpy(out_control_property.data(), nacp.data(), | ||
118 | std::min(out_control_property.size(), nacp.size())); | ||
119 | |||
120 | R_SUCCEED(); | ||
101 | } | 121 | } |
102 | 122 | ||
103 | Result IApplicationAccessor::SetUsers(bool enable, | 123 | Result IApplicationAccessor::SetUsers(bool enable, |
@@ -114,8 +134,9 @@ Result IApplicationAccessor::GetCurrentLibraryApplet( | |||
114 | } | 134 | } |
115 | 135 | ||
116 | Result IApplicationAccessor::RequestForApplicationToGetForeground() { | 136 | Result IApplicationAccessor::RequestForApplicationToGetForeground() { |
117 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 137 | LOG_INFO(Service_AM, "called"); |
118 | R_THROW(ResultUnknown); | 138 | m_window_system.RequestApplicationToGetForeground(); |
139 | R_SUCCEED(); | ||
119 | } | 140 | } |
120 | 141 | ||
121 | Result IApplicationAccessor::CheckRightsEnvironmentAvailable(Out<bool> out_is_available) { | 142 | Result IApplicationAccessor::CheckRightsEnvironmentAvailable(Out<bool> out_is_available) { |
diff --git a/src/core/hle/service/am/service/application_accessor.h b/src/core/hle/service/am/service/application_accessor.h index 39a9b2153..b9797bcc0 100755 --- a/src/core/hle/service/am/service/application_accessor.h +++ b/src/core/hle/service/am/service/application_accessor.h | |||
@@ -13,10 +13,12 @@ namespace Service::AM { | |||
13 | struct Applet; | 13 | struct Applet; |
14 | class ILibraryAppletAccessor; | 14 | class ILibraryAppletAccessor; |
15 | class IStorage; | 15 | class IStorage; |
16 | class WindowSystem; | ||
16 | 17 | ||
17 | class IApplicationAccessor final : public ServiceFramework<IApplicationAccessor> { | 18 | class IApplicationAccessor final : public ServiceFramework<IApplicationAccessor> { |
18 | public: | 19 | public: |
19 | explicit IApplicationAccessor(Core::System& system_, std::shared_ptr<Applet> applet); | 20 | explicit IApplicationAccessor(Core::System& system_, std::shared_ptr<Applet> applet, |
21 | WindowSystem& window_system); | ||
20 | ~IApplicationAccessor() override; | 22 | ~IApplicationAccessor() override; |
21 | 23 | ||
22 | private: | 24 | private: |
@@ -34,6 +36,7 @@ private: | |||
34 | Result GetNsRightsEnvironmentHandle(Out<u64> out_handle); | 36 | Result GetNsRightsEnvironmentHandle(Out<u64> out_handle); |
35 | Result ReportApplicationExitTimeout(); | 37 | Result ReportApplicationExitTimeout(); |
36 | 38 | ||
39 | WindowSystem& m_window_system; | ||
37 | const std::shared_ptr<Applet> m_applet; | 40 | const std::shared_ptr<Applet> m_applet; |
38 | }; | 41 | }; |
39 | 42 | ||
diff --git a/src/core/hle/service/am/service/application_creator.cpp b/src/core/hle/service/am/service/application_creator.cpp index 568bb0122..8994f1914 100755 --- a/src/core/hle/service/am/service/application_creator.cpp +++ b/src/core/hle/service/am/service/application_creator.cpp | |||
@@ -1,17 +1,57 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
3 | 3 | ||
4 | #include "core/file_sys/nca_metadata.h" | ||
5 | #include "core/file_sys/registered_cache.h" | ||
4 | #include "core/hle/service/am/am_types.h" | 6 | #include "core/hle/service/am/am_types.h" |
5 | #include "core/hle/service/am/applet.h" | 7 | #include "core/hle/service/am/applet.h" |
6 | #include "core/hle/service/am/applet_manager.h" | 8 | #include "core/hle/service/am/applet_manager.h" |
9 | #include "core/hle/service/am/process_creation.h" | ||
7 | #include "core/hle/service/am/service/application_accessor.h" | 10 | #include "core/hle/service/am/service/application_accessor.h" |
8 | #include "core/hle/service/am/service/application_creator.h" | 11 | #include "core/hle/service/am/service/application_creator.h" |
12 | #include "core/hle/service/am/window_system.h" | ||
9 | #include "core/hle/service/cmif_serialization.h" | 13 | #include "core/hle/service/cmif_serialization.h" |
14 | #include "core/loader/loader.h" | ||
10 | 15 | ||
11 | namespace Service::AM { | 16 | namespace Service::AM { |
12 | 17 | ||
13 | IApplicationCreator::IApplicationCreator(Core::System& system_) | 18 | namespace { |
14 | : ServiceFramework{system_, "IApplicationCreator"} { | 19 | |
20 | Result CreateGuestApplication(SharedPointer<IApplicationAccessor>* out_application_accessor, | ||
21 | Core::System& system, WindowSystem& window_system, u64 program_id) { | ||
22 | FileSys::VirtualFile nca_raw{}; | ||
23 | |||
24 | // Get the program NCA from storage. | ||
25 | auto& storage = system.GetContentProviderUnion(); | ||
26 | nca_raw = storage.GetEntryRaw(program_id, FileSys::ContentRecordType::Program); | ||
27 | |||
28 | // Ensure we retrieved a program NCA. | ||
29 | R_UNLESS(nca_raw != nullptr, ResultUnknown); | ||
30 | |||
31 | std::vector<u8> control; | ||
32 | std::unique_ptr<Loader::AppLoader> loader; | ||
33 | Loader::ResultStatus result; | ||
34 | auto process = | ||
35 | CreateApplicationProcess(control, loader, result, system, nca_raw, program_id, 0); | ||
36 | R_UNLESS(process != nullptr, ResultUnknown); | ||
37 | |||
38 | const auto applet = std::make_shared<Applet>(system, std::move(process), true); | ||
39 | applet->program_id = program_id; | ||
40 | applet->applet_id = AppletId::Application; | ||
41 | applet->type = AppletType::Application; | ||
42 | applet->library_applet_mode = LibraryAppletMode::AllForeground; | ||
43 | |||
44 | window_system.TrackApplet(applet, true); | ||
45 | |||
46 | *out_application_accessor = | ||
47 | std::make_shared<IApplicationAccessor>(system, applet, window_system); | ||
48 | R_SUCCEED(); | ||
49 | } | ||
50 | |||
51 | } // namespace | ||
52 | |||
53 | IApplicationCreator::IApplicationCreator(Core::System& system_, WindowSystem& window_system) | ||
54 | : ServiceFramework{system_, "IApplicationCreator"}, m_window_system{window_system} { | ||
15 | // clang-format off | 55 | // clang-format off |
16 | static const FunctionInfo functions[] = { | 56 | static const FunctionInfo functions[] = { |
17 | {0, D<&IApplicationCreator::CreateApplication>, "CreateApplication"}, | 57 | {0, D<&IApplicationCreator::CreateApplication>, "CreateApplication"}, |
@@ -28,8 +68,9 @@ IApplicationCreator::~IApplicationCreator() = default; | |||
28 | 68 | ||
29 | Result IApplicationCreator::CreateApplication( | 69 | Result IApplicationCreator::CreateApplication( |
30 | Out<SharedPointer<IApplicationAccessor>> out_application_accessor, u64 application_id) { | 70 | Out<SharedPointer<IApplicationAccessor>> out_application_accessor, u64 application_id) { |
31 | LOG_ERROR(Service_NS, "called, application_id={:x}", application_id); | 71 | LOG_INFO(Service_NS, "called, application_id={:016X}", application_id); |
32 | R_THROW(ResultUnknown); | 72 | R_RETURN( |
73 | CreateGuestApplication(out_application_accessor, system, m_window_system, application_id)); | ||
33 | } | 74 | } |
34 | 75 | ||
35 | } // namespace Service::AM | 76 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/service/application_creator.h b/src/core/hle/service/am/service/application_creator.h index 9f939ebf6..287745af8 100755 --- a/src/core/hle/service/am/service/application_creator.h +++ b/src/core/hle/service/am/service/application_creator.h | |||
@@ -10,14 +10,17 @@ namespace Service::AM { | |||
10 | 10 | ||
11 | class IApplicationAccessor; | 11 | class IApplicationAccessor; |
12 | struct Applet; | 12 | struct Applet; |
13 | class WindowSystem; | ||
13 | 14 | ||
14 | class IApplicationCreator final : public ServiceFramework<IApplicationCreator> { | 15 | class IApplicationCreator final : public ServiceFramework<IApplicationCreator> { |
15 | public: | 16 | public: |
16 | explicit IApplicationCreator(Core::System& system_); | 17 | explicit IApplicationCreator(Core::System& system_, WindowSystem& window_system); |
17 | ~IApplicationCreator() override; | 18 | ~IApplicationCreator() override; |
18 | 19 | ||
19 | private: | 20 | private: |
20 | Result CreateApplication(Out<SharedPointer<IApplicationAccessor>>, u64 application_id); | 21 | Result CreateApplication(Out<SharedPointer<IApplicationAccessor>>, u64 application_id); |
22 | |||
23 | WindowSystem& m_window_system; | ||
21 | }; | 24 | }; |
22 | 25 | ||
23 | } // namespace Service::AM | 26 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/service/application_functions.cpp b/src/core/hle/service/am/service/application_functions.cpp index bfccb6b09..3bab5ac5f 100755 --- a/src/core/hle/service/am/service/application_functions.cpp +++ b/src/core/hle/service/am/service/application_functions.cpp | |||
@@ -181,7 +181,8 @@ Result IApplicationFunctions::GetDesiredLanguage(Out<u64> out_language_code) { | |||
181 | } | 181 | } |
182 | 182 | ||
183 | Result IApplicationFunctions::SetTerminateResult(Result terminate_result) { | 183 | Result IApplicationFunctions::SetTerminateResult(Result terminate_result) { |
184 | LOG_INFO(Service_AM, "(STUBBED) called, result={:#x} ({}-{})", terminate_result.GetInnerValue(), | 184 | LOG_INFO(Service_AM, "(STUBBED) called, result={:#x} ({:04}-{:04})", |
185 | terminate_result.GetInnerValue(), | ||
185 | static_cast<u32>(terminate_result.GetModule()) + 2000, | 186 | static_cast<u32>(terminate_result.GetModule()) + 2000, |
186 | terminate_result.GetDescription()); | 187 | terminate_result.GetDescription()); |
187 | 188 | ||
diff --git a/src/core/hle/service/am/service/application_proxy.cpp b/src/core/hle/service/am/service/application_proxy.cpp index 19d6a3b89..6e1328fee 100755 --- a/src/core/hle/service/am/service/application_proxy.cpp +++ b/src/core/hle/service/am/service/application_proxy.cpp | |||
@@ -17,9 +17,9 @@ | |||
17 | namespace Service::AM { | 17 | namespace Service::AM { |
18 | 18 | ||
19 | IApplicationProxy::IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet, | 19 | IApplicationProxy::IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet, |
20 | Kernel::KProcess* process) | 20 | Kernel::KProcess* process, WindowSystem& window_system) |
21 | : ServiceFramework{system_, "IApplicationProxy"}, m_process{process}, m_applet{ | 21 | : ServiceFramework{system_, "IApplicationProxy"}, |
22 | std::move(applet)} { | 22 | m_window_system{window_system}, m_process{process}, m_applet{std::move(applet)} { |
23 | // clang-format off | 23 | // clang-format off |
24 | static const FunctionInfo functions[] = { | 24 | static const FunctionInfo functions[] = { |
25 | {0, D<&IApplicationProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, | 25 | {0, D<&IApplicationProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, |
@@ -70,7 +70,7 @@ Result IApplicationProxy::GetDebugFunctions( | |||
70 | Result IApplicationProxy::GetWindowController( | 70 | Result IApplicationProxy::GetWindowController( |
71 | Out<SharedPointer<IWindowController>> out_window_controller) { | 71 | Out<SharedPointer<IWindowController>> out_window_controller) { |
72 | LOG_DEBUG(Service_AM, "called"); | 72 | LOG_DEBUG(Service_AM, "called"); |
73 | *out_window_controller = std::make_shared<IWindowController>(system, m_applet); | 73 | *out_window_controller = std::make_shared<IWindowController>(system, m_applet, m_window_system); |
74 | R_SUCCEED(); | 74 | R_SUCCEED(); |
75 | } | 75 | } |
76 | 76 | ||
@@ -91,7 +91,8 @@ Result IApplicationProxy::GetCommonStateGetter( | |||
91 | Result IApplicationProxy::GetLibraryAppletCreator( | 91 | Result IApplicationProxy::GetLibraryAppletCreator( |
92 | Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) { | 92 | Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) { |
93 | LOG_DEBUG(Service_AM, "called"); | 93 | LOG_DEBUG(Service_AM, "called"); |
94 | *out_library_applet_creator = std::make_shared<ILibraryAppletCreator>(system, m_applet); | 94 | *out_library_applet_creator = |
95 | std::make_shared<ILibraryAppletCreator>(system, m_applet, m_window_system); | ||
95 | R_SUCCEED(); | 96 | R_SUCCEED(); |
96 | } | 97 | } |
97 | 98 | ||
diff --git a/src/core/hle/service/am/service/application_proxy.h b/src/core/hle/service/am/service/application_proxy.h index 6da350df7..8c62459c4 100755 --- a/src/core/hle/service/am/service/application_proxy.h +++ b/src/core/hle/service/am/service/application_proxy.h | |||
@@ -18,11 +18,12 @@ class ILibraryAppletCreator; | |||
18 | class IProcessWindingController; | 18 | class IProcessWindingController; |
19 | class ISelfController; | 19 | class ISelfController; |
20 | class IWindowController; | 20 | class IWindowController; |
21 | class WindowSystem; | ||
21 | 22 | ||
22 | class IApplicationProxy final : public ServiceFramework<IApplicationProxy> { | 23 | class IApplicationProxy final : public ServiceFramework<IApplicationProxy> { |
23 | public: | 24 | public: |
24 | explicit IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet, | 25 | explicit IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet, |
25 | Kernel::KProcess* process); | 26 | Kernel::KProcess* process, WindowSystem& window_system); |
26 | ~IApplicationProxy(); | 27 | ~IApplicationProxy(); |
27 | 28 | ||
28 | private: | 29 | private: |
@@ -40,6 +41,7 @@ private: | |||
40 | Out<SharedPointer<IApplicationFunctions>> out_application_functions); | 41 | Out<SharedPointer<IApplicationFunctions>> out_application_functions); |
41 | 42 | ||
42 | private: | 43 | private: |
44 | WindowSystem& m_window_system; | ||
43 | Kernel::KProcess* const m_process; | 45 | Kernel::KProcess* const m_process; |
44 | const std::shared_ptr<Applet> m_applet; | 46 | const std::shared_ptr<Applet> m_applet; |
45 | }; | 47 | }; |
diff --git a/src/core/hle/service/am/service/application_proxy_service.cpp b/src/core/hle/service/am/service/application_proxy_service.cpp index fd66e77b9..b7d7b3c2d 100755 --- a/src/core/hle/service/am/service/application_proxy_service.cpp +++ b/src/core/hle/service/am/service/application_proxy_service.cpp | |||
@@ -6,12 +6,14 @@ | |||
6 | #include "core/hle/service/am/applet_manager.h" | 6 | #include "core/hle/service/am/applet_manager.h" |
7 | #include "core/hle/service/am/service/application_proxy.h" | 7 | #include "core/hle/service/am/service/application_proxy.h" |
8 | #include "core/hle/service/am/service/application_proxy_service.h" | 8 | #include "core/hle/service/am/service/application_proxy_service.h" |
9 | #include "core/hle/service/am/window_system.h" | ||
9 | #include "core/hle/service/cmif_serialization.h" | 10 | #include "core/hle/service/cmif_serialization.h" |
10 | 11 | ||
11 | namespace Service::AM { | 12 | namespace Service::AM { |
12 | 13 | ||
13 | IApplicationProxyService::IApplicationProxyService(Core::System& system_) | 14 | IApplicationProxyService::IApplicationProxyService(Core::System& system_, |
14 | : ServiceFramework{system_, "appletOE"} { | 15 | WindowSystem& window_system) |
16 | : ServiceFramework{system_, "appletOE"}, m_window_system{window_system} { | ||
15 | static const FunctionInfo functions[] = { | 17 | static const FunctionInfo functions[] = { |
16 | {0, D<&IApplicationProxyService::OpenApplicationProxy>, "OpenApplicationProxy"}, | 18 | {0, D<&IApplicationProxyService::OpenApplicationProxy>, "OpenApplicationProxy"}, |
17 | }; | 19 | }; |
@@ -26,8 +28,8 @@ Result IApplicationProxyService::OpenApplicationProxy( | |||
26 | LOG_DEBUG(Service_AM, "called"); | 28 | LOG_DEBUG(Service_AM, "called"); |
27 | 29 | ||
28 | if (const auto applet = this->GetAppletFromProcessId(pid)) { | 30 | if (const auto applet = this->GetAppletFromProcessId(pid)) { |
29 | *out_application_proxy = | 31 | *out_application_proxy = std::make_shared<IApplicationProxy>( |
30 | std::make_shared<IApplicationProxy>(system, applet, process_handle.Get()); | 32 | system, applet, process_handle.Get(), m_window_system); |
31 | R_SUCCEED(); | 33 | R_SUCCEED(); |
32 | } else { | 34 | } else { |
33 | UNIMPLEMENTED(); | 35 | UNIMPLEMENTED(); |
@@ -36,7 +38,7 @@ Result IApplicationProxyService::OpenApplicationProxy( | |||
36 | } | 38 | } |
37 | 39 | ||
38 | std::shared_ptr<Applet> IApplicationProxyService::GetAppletFromProcessId(ProcessId process_id) { | 40 | std::shared_ptr<Applet> IApplicationProxyService::GetAppletFromProcessId(ProcessId process_id) { |
39 | return system.GetAppletManager().GetByAppletResourceUserId(process_id.pid); | 41 | return m_window_system.GetByAppletResourceUserId(process_id.pid); |
40 | } | 42 | } |
41 | 43 | ||
42 | } // namespace Service::AM | 44 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/service/application_proxy_service.h b/src/core/hle/service/am/service/application_proxy_service.h index 8efafa31a..e5f4ea345 100755 --- a/src/core/hle/service/am/service/application_proxy_service.h +++ b/src/core/hle/service/am/service/application_proxy_service.h | |||
@@ -12,10 +12,11 @@ namespace AM { | |||
12 | 12 | ||
13 | struct Applet; | 13 | struct Applet; |
14 | class IApplicationProxy; | 14 | class IApplicationProxy; |
15 | class WindowSystem; | ||
15 | 16 | ||
16 | class IApplicationProxyService final : public ServiceFramework<IApplicationProxyService> { | 17 | class IApplicationProxyService final : public ServiceFramework<IApplicationProxyService> { |
17 | public: | 18 | public: |
18 | explicit IApplicationProxyService(Core::System& system_); | 19 | explicit IApplicationProxyService(Core::System& system_, WindowSystem& window_system); |
19 | ~IApplicationProxyService() override; | 20 | ~IApplicationProxyService() override; |
20 | 21 | ||
21 | private: | 22 | private: |
@@ -24,6 +25,8 @@ private: | |||
24 | 25 | ||
25 | private: | 26 | private: |
26 | std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid); | 27 | std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid); |
28 | |||
29 | WindowSystem& m_window_system; | ||
27 | }; | 30 | }; |
28 | 31 | ||
29 | } // namespace AM | 32 | } // namespace AM |
diff --git a/src/core/hle/service/am/service/common_state_getter.cpp b/src/core/hle/service/am/service/common_state_getter.cpp index a32855ffa..f523bcd9e 100755 --- a/src/core/hle/service/am/service/common_state_getter.cpp +++ b/src/core/hle/service/am/service/common_state_getter.cpp | |||
@@ -80,15 +80,14 @@ ICommonStateGetter::~ICommonStateGetter() = default; | |||
80 | 80 | ||
81 | Result ICommonStateGetter::GetEventHandle(OutCopyHandle<Kernel::KReadableEvent> out_event) { | 81 | Result ICommonStateGetter::GetEventHandle(OutCopyHandle<Kernel::KReadableEvent> out_event) { |
82 | LOG_DEBUG(Service_AM, "called"); | 82 | LOG_DEBUG(Service_AM, "called"); |
83 | *out_event = &m_applet->message_queue.GetMessageReceiveEvent(); | 83 | *out_event = m_applet->lifecycle_manager.GetSystemEvent().GetHandle(); |
84 | R_SUCCEED(); | 84 | R_SUCCEED(); |
85 | } | 85 | } |
86 | 86 | ||
87 | Result ICommonStateGetter::ReceiveMessage(Out<AppletMessage> out_applet_message) { | 87 | Result ICommonStateGetter::ReceiveMessage(Out<AppletMessage> out_applet_message) { |
88 | LOG_DEBUG(Service_AM, "called"); | 88 | LOG_DEBUG(Service_AM, "called"); |
89 | 89 | ||
90 | *out_applet_message = m_applet->message_queue.PopMessage(); | 90 | if (!m_applet->lifecycle_manager.PopMessage(out_applet_message)) { |
91 | if (*out_applet_message == AppletMessage::None) { | ||
92 | LOG_ERROR(Service_AM, "Tried to pop message but none was available!"); | 91 | LOG_ERROR(Service_AM, "Tried to pop message but none was available!"); |
93 | R_THROW(AM::ResultNoMessages); | 92 | R_THROW(AM::ResultNoMessages); |
94 | } | 93 | } |
@@ -100,7 +99,7 @@ Result ICommonStateGetter::GetCurrentFocusState(Out<FocusState> out_focus_state) | |||
100 | LOG_DEBUG(Service_AM, "called"); | 99 | LOG_DEBUG(Service_AM, "called"); |
101 | 100 | ||
102 | std::scoped_lock lk{m_applet->lock}; | 101 | std::scoped_lock lk{m_applet->lock}; |
103 | *out_focus_state = m_applet->focus_state; | 102 | *out_focus_state = m_applet->lifecycle_manager.GetAndClearFocusState(); |
104 | 103 | ||
105 | R_SUCCEED(); | 104 | R_SUCCEED(); |
106 | } | 105 | } |
@@ -137,7 +136,7 @@ Result ICommonStateGetter::GetWriterLockAccessorEx( | |||
137 | Result ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent( | 136 | Result ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent( |
138 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | 137 | OutCopyHandle<Kernel::KReadableEvent> out_event) { |
139 | LOG_DEBUG(Service_AM, "called"); | 138 | LOG_DEBUG(Service_AM, "called"); |
140 | *out_event = &m_applet->message_queue.GetOperationModeChangedEvent(); | 139 | *out_event = m_applet->lifecycle_manager.GetOperationModeChangedSystemEvent().GetHandle(); |
141 | R_SUCCEED(); | 140 | R_SUCCEED(); |
142 | } | 141 | } |
143 | 142 | ||
diff --git a/src/core/hle/service/am/service/home_menu_functions.cpp b/src/core/hle/service/am/service/home_menu_functions.cpp index 0c4d24b58..25f78beb5 100755 --- a/src/core/hle/service/am/service/home_menu_functions.cpp +++ b/src/core/hle/service/am/service/home_menu_functions.cpp | |||
@@ -4,13 +4,16 @@ | |||
4 | #include "core/hle/result.h" | 4 | #include "core/hle/result.h" |
5 | #include "core/hle/service/am/applet_manager.h" | 5 | #include "core/hle/service/am/applet_manager.h" |
6 | #include "core/hle/service/am/service/home_menu_functions.h" | 6 | #include "core/hle/service/am/service/home_menu_functions.h" |
7 | #include "core/hle/service/am/window_system.h" | ||
7 | #include "core/hle/service/cmif_serialization.h" | 8 | #include "core/hle/service/cmif_serialization.h" |
8 | 9 | ||
9 | namespace Service::AM { | 10 | namespace Service::AM { |
10 | 11 | ||
11 | IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_, std::shared_ptr<Applet> applet) | 12 | IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_, std::shared_ptr<Applet> applet, |
12 | : ServiceFramework{system_, "IHomeMenuFunctions"}, m_applet{std::move(applet)}, | 13 | WindowSystem& window_system) |
13 | m_context{system, "IHomeMenuFunctions"}, m_pop_from_general_channel_event{m_context} { | 14 | : ServiceFramework{system_, "IHomeMenuFunctions"}, m_window_system{window_system}, |
15 | m_applet{std::move(applet)}, m_context{system, "IHomeMenuFunctions"}, | ||
16 | m_pop_from_general_channel_event{m_context} { | ||
14 | // clang-format off | 17 | // clang-format off |
15 | static const FunctionInfo functions[] = { | 18 | static const FunctionInfo functions[] = { |
16 | {10, D<&IHomeMenuFunctions::RequestToGetForeground>, "RequestToGetForeground"}, | 19 | {10, D<&IHomeMenuFunctions::RequestToGetForeground>, "RequestToGetForeground"}, |
@@ -37,17 +40,20 @@ IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_, std::shared_ptr<Ap | |||
37 | IHomeMenuFunctions::~IHomeMenuFunctions() = default; | 40 | IHomeMenuFunctions::~IHomeMenuFunctions() = default; |
38 | 41 | ||
39 | Result IHomeMenuFunctions::RequestToGetForeground() { | 42 | Result IHomeMenuFunctions::RequestToGetForeground() { |
40 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 43 | LOG_INFO(Service_AM, "called"); |
44 | m_window_system.RequestHomeMenuToGetForeground(); | ||
41 | R_SUCCEED(); | 45 | R_SUCCEED(); |
42 | } | 46 | } |
43 | 47 | ||
44 | Result IHomeMenuFunctions::LockForeground() { | 48 | Result IHomeMenuFunctions::LockForeground() { |
45 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 49 | LOG_INFO(Service_AM, "called"); |
50 | m_window_system.RequestLockHomeMenuIntoForeground(); | ||
46 | R_SUCCEED(); | 51 | R_SUCCEED(); |
47 | } | 52 | } |
48 | 53 | ||
49 | Result IHomeMenuFunctions::UnlockForeground() { | 54 | Result IHomeMenuFunctions::UnlockForeground() { |
50 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 55 | LOG_INFO(Service_AM, "called"); |
56 | m_window_system.RequestUnlockHomeMenuIntoForeground(); | ||
51 | R_SUCCEED(); | 57 | R_SUCCEED(); |
52 | } | 58 | } |
53 | 59 | ||
diff --git a/src/core/hle/service/am/service/home_menu_functions.h b/src/core/hle/service/am/service/home_menu_functions.h index caf6fbaab..f56094aa9 100755 --- a/src/core/hle/service/am/service/home_menu_functions.h +++ b/src/core/hle/service/am/service/home_menu_functions.h | |||
@@ -11,10 +11,12 @@ | |||
11 | namespace Service::AM { | 11 | namespace Service::AM { |
12 | 12 | ||
13 | struct Applet; | 13 | struct Applet; |
14 | class WindowSystem; | ||
14 | 15 | ||
15 | class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> { | 16 | class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> { |
16 | public: | 17 | public: |
17 | explicit IHomeMenuFunctions(Core::System& system_, std::shared_ptr<Applet> applet); | 18 | explicit IHomeMenuFunctions(Core::System& system_, std::shared_ptr<Applet> applet, |
19 | WindowSystem& window_system); | ||
18 | ~IHomeMenuFunctions() override; | 20 | ~IHomeMenuFunctions() override; |
19 | 21 | ||
20 | private: | 22 | private: |
@@ -26,6 +28,7 @@ private: | |||
26 | Result IsForceTerminateApplicationDisabledForDebug( | 28 | Result IsForceTerminateApplicationDisabledForDebug( |
27 | Out<bool> out_is_force_terminate_application_disabled_for_debug); | 29 | Out<bool> out_is_force_terminate_application_disabled_for_debug); |
28 | 30 | ||
31 | WindowSystem& m_window_system; | ||
29 | const std::shared_ptr<Applet> m_applet; | 32 | const std::shared_ptr<Applet> m_applet; |
30 | KernelHelpers::ServiceContext m_context; | 33 | KernelHelpers::ServiceContext m_context; |
31 | Event m_pop_from_general_channel_event; | 34 | Event m_pop_from_general_channel_event; |
diff --git a/src/core/hle/service/am/service/library_applet_accessor.cpp b/src/core/hle/service/am/service/library_applet_accessor.cpp index 0c2426d4b..cda8c3eb8 100755 --- a/src/core/hle/service/am/service/library_applet_accessor.cpp +++ b/src/core/hle/service/am/service/library_applet_accessor.cpp | |||
@@ -47,20 +47,21 @@ ILibraryAppletAccessor::~ILibraryAppletAccessor() = default; | |||
47 | Result ILibraryAppletAccessor::GetAppletStateChangedEvent( | 47 | Result ILibraryAppletAccessor::GetAppletStateChangedEvent( |
48 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | 48 | OutCopyHandle<Kernel::KReadableEvent> out_event) { |
49 | LOG_DEBUG(Service_AM, "called"); | 49 | LOG_DEBUG(Service_AM, "called"); |
50 | *out_event = m_broker->GetStateChangedEvent().GetHandle(); | 50 | *out_event = m_applet->state_changed_event.GetHandle(); |
51 | R_SUCCEED(); | 51 | R_SUCCEED(); |
52 | } | 52 | } |
53 | 53 | ||
54 | Result ILibraryAppletAccessor::IsCompleted(Out<bool> out_is_completed) { | 54 | Result ILibraryAppletAccessor::IsCompleted(Out<bool> out_is_completed) { |
55 | LOG_DEBUG(Service_AM, "called"); | 55 | LOG_DEBUG(Service_AM, "called"); |
56 | *out_is_completed = m_broker->IsCompleted(); | 56 | std::scoped_lock lk{m_applet->lock}; |
57 | *out_is_completed = m_applet->is_completed; | ||
57 | R_SUCCEED(); | 58 | R_SUCCEED(); |
58 | } | 59 | } |
59 | 60 | ||
60 | Result ILibraryAppletAccessor::GetResult(Out<Result> out_result) { | 61 | Result ILibraryAppletAccessor::GetResult() { |
61 | LOG_DEBUG(Service_AM, "called"); | 62 | LOG_DEBUG(Service_AM, "called"); |
62 | *out_result = m_applet->terminate_result; | 63 | std::scoped_lock lk{m_applet->lock}; |
63 | R_SUCCEED(); | 64 | R_RETURN(m_applet->terminate_result); |
64 | } | 65 | } |
65 | 66 | ||
66 | Result ILibraryAppletAccessor::PresetLibraryAppletGpuTimeSliceZero() { | 67 | Result ILibraryAppletAccessor::PresetLibraryAppletGpuTimeSliceZero() { |
@@ -77,7 +78,10 @@ Result ILibraryAppletAccessor::Start() { | |||
77 | 78 | ||
78 | Result ILibraryAppletAccessor::RequestExit() { | 79 | Result ILibraryAppletAccessor::RequestExit() { |
79 | LOG_DEBUG(Service_AM, "called"); | 80 | LOG_DEBUG(Service_AM, "called"); |
80 | m_applet->message_queue.RequestExit(); | 81 | { |
82 | std::scoped_lock lk{m_applet->lock}; | ||
83 | m_applet->lifecycle_manager.RequestExit(); | ||
84 | } | ||
81 | FrontendRequestExit(); | 85 | FrontendRequestExit(); |
82 | R_SUCCEED(); | 86 | R_SUCCEED(); |
83 | } | 87 | } |
diff --git a/src/core/hle/service/am/service/library_applet_accessor.h b/src/core/hle/service/am/service/library_applet_accessor.h index 97d3b6c8a..36712821a 100755 --- a/src/core/hle/service/am/service/library_applet_accessor.h +++ b/src/core/hle/service/am/service/library_applet_accessor.h | |||
@@ -21,7 +21,7 @@ public: | |||
21 | private: | 21 | private: |
22 | Result GetAppletStateChangedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | 22 | Result GetAppletStateChangedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); |
23 | Result IsCompleted(Out<bool> out_is_completed); | 23 | Result IsCompleted(Out<bool> out_is_completed); |
24 | Result GetResult(Out<Result> out_result); | 24 | Result GetResult(); |
25 | Result PresetLibraryAppletGpuTimeSliceZero(); | 25 | Result PresetLibraryAppletGpuTimeSliceZero(); |
26 | Result Start(); | 26 | Result Start(); |
27 | Result RequestExit(); | 27 | Result RequestExit(); |
diff --git a/src/core/hle/service/am/service/library_applet_creator.cpp b/src/core/hle/service/am/service/library_applet_creator.cpp index c97358d81..3ffb03bc9 100755 --- a/src/core/hle/service/am/service/library_applet_creator.cpp +++ b/src/core/hle/service/am/service/library_applet_creator.cpp | |||
@@ -7,9 +7,11 @@ | |||
7 | #include "core/hle/service/am/applet_manager.h" | 7 | #include "core/hle/service/am/applet_manager.h" |
8 | #include "core/hle/service/am/frontend/applets.h" | 8 | #include "core/hle/service/am/frontend/applets.h" |
9 | #include "core/hle/service/am/library_applet_storage.h" | 9 | #include "core/hle/service/am/library_applet_storage.h" |
10 | #include "core/hle/service/am/process_creation.h" | ||
10 | #include "core/hle/service/am/service/library_applet_accessor.h" | 11 | #include "core/hle/service/am/service/library_applet_accessor.h" |
11 | #include "core/hle/service/am/service/library_applet_creator.h" | 12 | #include "core/hle/service/am/service/library_applet_creator.h" |
12 | #include "core/hle/service/am/service/storage.h" | 13 | #include "core/hle/service/am/service/storage.h" |
14 | #include "core/hle/service/am/window_system.h" | ||
13 | #include "core/hle/service/cmif_serialization.h" | 15 | #include "core/hle/service/cmif_serialization.h" |
14 | #include "core/hle/service/sm/sm.h" | 16 | #include "core/hle/service/sm/sm.h" |
15 | 17 | ||
@@ -93,6 +95,7 @@ AppletProgramId AppletIdToProgramId(AppletId applet_id) { | |||
93 | } | 95 | } |
94 | 96 | ||
95 | std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system, | 97 | std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system, |
98 | WindowSystem& window_system, | ||
96 | std::shared_ptr<Applet> caller_applet, | 99 | std::shared_ptr<Applet> caller_applet, |
97 | AppletId applet_id, | 100 | AppletId applet_id, |
98 | LibraryAppletMode mode) { | 101 | LibraryAppletMode mode) { |
@@ -110,53 +113,38 @@ std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system, | |||
110 | Firmware1700 = 17, | 113 | Firmware1700 = 17, |
111 | }; | 114 | }; |
112 | 115 | ||
113 | auto process = std::make_unique<Process>(system); | 116 | auto process = CreateProcess(system, program_id, Firmware1400, Firmware1700); |
114 | if (!process->Initialize(program_id, Firmware1400, Firmware1700)) { | 117 | if (!process) { |
115 | // Couldn't initialize the guest process | 118 | // Couldn't initialize the guest process |
116 | return {}; | 119 | return {}; |
117 | } | 120 | } |
118 | 121 | ||
119 | const auto applet = std::make_shared<Applet>(system, std::move(process)); | 122 | const auto applet = std::make_shared<Applet>(system, std::move(process), false); |
120 | applet->program_id = program_id; | 123 | applet->program_id = program_id; |
121 | applet->applet_id = applet_id; | 124 | applet->applet_id = applet_id; |
122 | applet->type = AppletType::LibraryApplet; | 125 | applet->type = AppletType::LibraryApplet; |
123 | applet->library_applet_mode = mode; | 126 | applet->library_applet_mode = mode; |
124 | 127 | applet->window_visible = mode != LibraryAppletMode::AllForegroundInitiallyHidden; | |
125 | // Set focus state | ||
126 | switch (mode) { | ||
127 | case LibraryAppletMode::AllForeground: | ||
128 | case LibraryAppletMode::NoUi: | ||
129 | case LibraryAppletMode::PartialForeground: | ||
130 | case LibraryAppletMode::PartialForegroundIndirectDisplay: | ||
131 | applet->hid_registration.EnableAppletToGetInput(true); | ||
132 | applet->focus_state = FocusState::InFocus; | ||
133 | applet->message_queue.PushMessage(AppletMessage::ChangeIntoForeground); | ||
134 | break; | ||
135 | case LibraryAppletMode::AllForegroundInitiallyHidden: | ||
136 | applet->hid_registration.EnableAppletToGetInput(false); | ||
137 | applet->focus_state = FocusState::NotInFocus; | ||
138 | applet->display_layer_manager.SetWindowVisibility(false); | ||
139 | applet->message_queue.PushMessage(AppletMessage::ChangeIntoBackground); | ||
140 | break; | ||
141 | } | ||
142 | 128 | ||
143 | auto broker = std::make_shared<AppletDataBroker>(system); | 129 | auto broker = std::make_shared<AppletDataBroker>(system); |
144 | applet->caller_applet = caller_applet; | 130 | applet->caller_applet = caller_applet; |
145 | applet->caller_applet_broker = broker; | 131 | applet->caller_applet_broker = broker; |
132 | caller_applet->child_applets.push_back(applet); | ||
146 | 133 | ||
147 | system.GetAppletManager().InsertApplet(applet); | 134 | window_system.TrackApplet(applet, false); |
148 | 135 | ||
149 | return std::make_shared<ILibraryAppletAccessor>(system, broker, applet); | 136 | return std::make_shared<ILibraryAppletAccessor>(system, broker, applet); |
150 | } | 137 | } |
151 | 138 | ||
152 | std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(Core::System& system, | 139 | std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(Core::System& system, |
140 | WindowSystem& window_system, | ||
153 | std::shared_ptr<Applet> caller_applet, | 141 | std::shared_ptr<Applet> caller_applet, |
154 | AppletId applet_id, | 142 | AppletId applet_id, |
155 | LibraryAppletMode mode) { | 143 | LibraryAppletMode mode) { |
156 | const auto program_id = static_cast<u64>(AppletIdToProgramId(applet_id)); | 144 | const auto program_id = static_cast<u64>(AppletIdToProgramId(applet_id)); |
157 | 145 | ||
158 | auto process = std::make_unique<Process>(system); | 146 | auto process = std::make_unique<Process>(system); |
159 | auto applet = std::make_shared<Applet>(system, std::move(process)); | 147 | auto applet = std::make_shared<Applet>(system, std::move(process), false); |
160 | applet->program_id = program_id; | 148 | applet->program_id = program_id; |
161 | applet->applet_id = applet_id; | 149 | applet->applet_id = applet_id; |
162 | applet->type = AppletType::LibraryApplet; | 150 | applet->type = AppletType::LibraryApplet; |
@@ -166,14 +154,19 @@ std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(Core::System& syste | |||
166 | applet->caller_applet = caller_applet; | 154 | applet->caller_applet = caller_applet; |
167 | applet->caller_applet_broker = storage; | 155 | applet->caller_applet_broker = storage; |
168 | applet->frontend = system.GetFrontendAppletHolder().GetApplet(applet, applet_id, mode); | 156 | applet->frontend = system.GetFrontendAppletHolder().GetApplet(applet, applet_id, mode); |
157 | caller_applet->child_applets.push_back(applet); | ||
158 | |||
159 | window_system.TrackApplet(applet, false); | ||
169 | 160 | ||
170 | return std::make_shared<ILibraryAppletAccessor>(system, storage, applet); | 161 | return std::make_shared<ILibraryAppletAccessor>(system, storage, applet); |
171 | } | 162 | } |
172 | 163 | ||
173 | } // namespace | 164 | } // namespace |
174 | 165 | ||
175 | ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet) | 166 | ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet, |
176 | : ServiceFramework{system_, "ILibraryAppletCreator"}, m_applet{std::move(applet)} { | 167 | WindowSystem& window_system) |
168 | : ServiceFramework{system_, "ILibraryAppletCreator"}, | ||
169 | m_window_system{window_system}, m_applet{std::move(applet)} { | ||
177 | static const FunctionInfo functions[] = { | 170 | static const FunctionInfo functions[] = { |
178 | {0, D<&ILibraryAppletCreator::CreateLibraryApplet>, "CreateLibraryApplet"}, | 171 | {0, D<&ILibraryAppletCreator::CreateLibraryApplet>, "CreateLibraryApplet"}, |
179 | {1, nullptr, "TerminateAllLibraryApplets"}, | 172 | {1, nullptr, "TerminateAllLibraryApplets"}, |
@@ -195,10 +188,12 @@ Result ILibraryAppletCreator::CreateLibraryApplet( | |||
195 | 188 | ||
196 | std::shared_ptr<ILibraryAppletAccessor> library_applet; | 189 | std::shared_ptr<ILibraryAppletAccessor> library_applet; |
197 | if (ShouldCreateGuestApplet(applet_id)) { | 190 | if (ShouldCreateGuestApplet(applet_id)) { |
198 | library_applet = CreateGuestApplet(system, m_applet, applet_id, library_applet_mode); | 191 | library_applet = |
192 | CreateGuestApplet(system, m_window_system, m_applet, applet_id, library_applet_mode); | ||
199 | } | 193 | } |
200 | if (!library_applet) { | 194 | if (!library_applet) { |
201 | library_applet = CreateFrontendApplet(system, m_applet, applet_id, library_applet_mode); | 195 | library_applet = |
196 | CreateFrontendApplet(system, m_window_system, m_applet, applet_id, library_applet_mode); | ||
202 | } | 197 | } |
203 | if (!library_applet) { | 198 | if (!library_applet) { |
204 | LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id); | 199 | LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id); |
diff --git a/src/core/hle/service/am/service/library_applet_creator.h b/src/core/hle/service/am/service/library_applet_creator.h index fe6d40eb3..a10a76982 100755 --- a/src/core/hle/service/am/service/library_applet_creator.h +++ b/src/core/hle/service/am/service/library_applet_creator.h | |||
@@ -12,10 +12,12 @@ namespace Service::AM { | |||
12 | struct Applet; | 12 | struct Applet; |
13 | class ILibraryAppletAccessor; | 13 | class ILibraryAppletAccessor; |
14 | class IStorage; | 14 | class IStorage; |
15 | class WindowSystem; | ||
15 | 16 | ||
16 | class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> { | 17 | class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> { |
17 | public: | 18 | public: |
18 | explicit ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet); | 19 | explicit ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet, |
20 | WindowSystem& window_system); | ||
19 | ~ILibraryAppletCreator() override; | 21 | ~ILibraryAppletCreator() override; |
20 | 22 | ||
21 | private: | 23 | private: |
@@ -29,6 +31,7 @@ private: | |||
29 | Result CreateHandleStorage(Out<SharedPointer<IStorage>> out_storage, s64 size, | 31 | Result CreateHandleStorage(Out<SharedPointer<IStorage>> out_storage, s64 size, |
30 | InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle); | 32 | InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle); |
31 | 33 | ||
34 | WindowSystem& m_window_system; | ||
32 | const std::shared_ptr<Applet> m_applet; | 35 | const std::shared_ptr<Applet> m_applet; |
33 | }; | 36 | }; |
34 | 37 | ||
diff --git a/src/core/hle/service/am/service/library_applet_proxy.cpp b/src/core/hle/service/am/service/library_applet_proxy.cpp index 58e709347..f9cfb82a9 100755 --- a/src/core/hle/service/am/service/library_applet_proxy.cpp +++ b/src/core/hle/service/am/service/library_applet_proxy.cpp | |||
@@ -19,9 +19,9 @@ | |||
19 | namespace Service::AM { | 19 | namespace Service::AM { |
20 | 20 | ||
21 | ILibraryAppletProxy::ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, | 21 | ILibraryAppletProxy::ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, |
22 | Kernel::KProcess* process) | 22 | Kernel::KProcess* process, WindowSystem& window_system) |
23 | : ServiceFramework{system_, "ILibraryAppletProxy"}, m_process{process}, m_applet{ | 23 | : ServiceFramework{system_, "ILibraryAppletProxy"}, |
24 | std::move(applet)} { | 24 | m_window_system{window_system}, m_process{process}, m_applet{std::move(applet)} { |
25 | // clang-format off | 25 | // clang-format off |
26 | static const FunctionInfo functions[] = { | 26 | static const FunctionInfo functions[] = { |
27 | {0, D<&ILibraryAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, | 27 | {0, D<&ILibraryAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, |
@@ -75,7 +75,7 @@ Result ILibraryAppletProxy::GetDebugFunctions( | |||
75 | Result ILibraryAppletProxy::GetWindowController( | 75 | Result ILibraryAppletProxy::GetWindowController( |
76 | Out<SharedPointer<IWindowController>> out_window_controller) { | 76 | Out<SharedPointer<IWindowController>> out_window_controller) { |
77 | LOG_DEBUG(Service_AM, "called"); | 77 | LOG_DEBUG(Service_AM, "called"); |
78 | *out_window_controller = std::make_shared<IWindowController>(system, m_applet); | 78 | *out_window_controller = std::make_shared<IWindowController>(system, m_applet, m_window_system); |
79 | R_SUCCEED(); | 79 | R_SUCCEED(); |
80 | } | 80 | } |
81 | 81 | ||
@@ -96,7 +96,8 @@ Result ILibraryAppletProxy::GetCommonStateGetter( | |||
96 | Result ILibraryAppletProxy::GetLibraryAppletCreator( | 96 | Result ILibraryAppletProxy::GetLibraryAppletCreator( |
97 | Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) { | 97 | Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) { |
98 | LOG_DEBUG(Service_AM, "called"); | 98 | LOG_DEBUG(Service_AM, "called"); |
99 | *out_library_applet_creator = std::make_shared<ILibraryAppletCreator>(system, m_applet); | 99 | *out_library_applet_creator = |
100 | std::make_shared<ILibraryAppletCreator>(system, m_applet, m_window_system); | ||
100 | R_SUCCEED(); | 101 | R_SUCCEED(); |
101 | } | 102 | } |
102 | 103 | ||
@@ -118,7 +119,8 @@ Result ILibraryAppletProxy::GetAppletCommonFunctions( | |||
118 | Result ILibraryAppletProxy::GetHomeMenuFunctions( | 119 | Result ILibraryAppletProxy::GetHomeMenuFunctions( |
119 | Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions) { | 120 | Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions) { |
120 | LOG_DEBUG(Service_AM, "called"); | 121 | LOG_DEBUG(Service_AM, "called"); |
121 | *out_home_menu_functions = std::make_shared<IHomeMenuFunctions>(system, m_applet); | 122 | *out_home_menu_functions = |
123 | std::make_shared<IHomeMenuFunctions>(system, m_applet, m_window_system); | ||
122 | R_SUCCEED(); | 124 | R_SUCCEED(); |
123 | } | 125 | } |
124 | 126 | ||
diff --git a/src/core/hle/service/am/service/library_applet_proxy.h b/src/core/hle/service/am/service/library_applet_proxy.h index 7d0714b85..792d58582 100755 --- a/src/core/hle/service/am/service/library_applet_proxy.h +++ b/src/core/hle/service/am/service/library_applet_proxy.h | |||
@@ -21,11 +21,12 @@ class ILibraryAppletSelfAccessor; | |||
21 | class IProcessWindingController; | 21 | class IProcessWindingController; |
22 | class ISelfController; | 22 | class ISelfController; |
23 | class IWindowController; | 23 | class IWindowController; |
24 | class WindowSystem; | ||
24 | 25 | ||
25 | class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> { | 26 | class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> { |
26 | public: | 27 | public: |
27 | explicit ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, | 28 | explicit ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, |
28 | Kernel::KProcess* process); | 29 | Kernel::KProcess* process, WindowSystem& window_system); |
29 | ~ILibraryAppletProxy(); | 30 | ~ILibraryAppletProxy(); |
30 | 31 | ||
31 | private: | 32 | private: |
@@ -47,6 +48,7 @@ private: | |||
47 | Result GetGlobalStateController( | 48 | Result GetGlobalStateController( |
48 | Out<SharedPointer<IGlobalStateController>> out_global_state_controller); | 49 | Out<SharedPointer<IGlobalStateController>> out_global_state_controller); |
49 | 50 | ||
51 | WindowSystem& m_window_system; | ||
50 | Kernel::KProcess* const m_process; | 52 | Kernel::KProcess* const m_process; |
51 | const std::shared_ptr<Applet> m_applet; | 53 | const std::shared_ptr<Applet> m_applet; |
52 | }; | 54 | }; |
diff --git a/src/core/hle/service/am/service/library_applet_self_accessor.cpp b/src/core/hle/service/am/service/library_applet_self_accessor.cpp index 330eb26f0..3fe36b899 100755 --- a/src/core/hle/service/am/service/library_applet_self_accessor.cpp +++ b/src/core/hle/service/am/service/library_applet_self_accessor.cpp | |||
@@ -176,8 +176,7 @@ Result ILibraryAppletSelfAccessor::GetMainAppletStorageId(Out<FileSys::StorageId | |||
176 | 176 | ||
177 | Result ILibraryAppletSelfAccessor::ExitProcessAndReturn() { | 177 | Result ILibraryAppletSelfAccessor::ExitProcessAndReturn() { |
178 | LOG_INFO(Service_AM, "called"); | 178 | LOG_INFO(Service_AM, "called"); |
179 | system.GetAppletManager().TerminateAndRemoveApplet(m_applet->aruid); | 179 | m_applet->process->Terminate(); |
180 | m_broker->SignalCompletion(); | ||
181 | R_SUCCEED(); | 180 | R_SUCCEED(); |
182 | } | 181 | } |
183 | 182 | ||
diff --git a/src/core/hle/service/am/service/self_controller.cpp b/src/core/hle/service/am/service/self_controller.cpp index 06314407c..1db02b88f 100755 --- a/src/core/hle/service/am/service/self_controller.cpp +++ b/src/core/hle/service/am/service/self_controller.cpp | |||
@@ -86,8 +86,7 @@ ISelfController::~ISelfController() { | |||
86 | Result ISelfController::Exit() { | 86 | Result ISelfController::Exit() { |
87 | LOG_DEBUG(Service_AM, "called"); | 87 | LOG_DEBUG(Service_AM, "called"); |
88 | 88 | ||
89 | // TODO | 89 | m_applet->process->Terminate(); |
90 | system.Exit(); | ||
91 | 90 | ||
92 | R_SUCCEED(); | 91 | R_SUCCEED(); |
93 | } | 92 | } |
@@ -95,7 +94,16 @@ Result ISelfController::Exit() { | |||
95 | Result ISelfController::LockExit() { | 94 | Result ISelfController::LockExit() { |
96 | LOG_DEBUG(Service_AM, "called"); | 95 | LOG_DEBUG(Service_AM, "called"); |
97 | 96 | ||
98 | system.SetExitLocked(true); | 97 | std::scoped_lock lk{m_applet->lock}; |
98 | |||
99 | if (m_applet->lifecycle_manager.GetExitRequested()) { | ||
100 | // With exit already requested, ignore and terminate immediately. | ||
101 | m_applet->process->Terminate(); | ||
102 | } else { | ||
103 | // Otherwise, set exit lock state. | ||
104 | m_applet->exit_locked = true; | ||
105 | system.SetExitLocked(true); | ||
106 | } | ||
99 | 107 | ||
100 | R_SUCCEED(); | 108 | R_SUCCEED(); |
101 | } | 109 | } |
@@ -103,10 +111,13 @@ Result ISelfController::LockExit() { | |||
103 | Result ISelfController::UnlockExit() { | 111 | Result ISelfController::UnlockExit() { |
104 | LOG_DEBUG(Service_AM, "called"); | 112 | LOG_DEBUG(Service_AM, "called"); |
105 | 113 | ||
114 | std::scoped_lock lk{m_applet->lock}; | ||
115 | |||
116 | m_applet->exit_locked = false; | ||
106 | system.SetExitLocked(false); | 117 | system.SetExitLocked(false); |
107 | 118 | ||
108 | if (system.GetExitRequested()) { | 119 | if (m_applet->lifecycle_manager.GetExitRequested()) { |
109 | system.Exit(); | 120 | m_applet->process->Terminate(); |
110 | } | 121 | } |
111 | 122 | ||
112 | R_SUCCEED(); | 123 | R_SUCCEED(); |
@@ -155,7 +166,7 @@ Result ISelfController::SetOperationModeChangedNotification(bool enabled) { | |||
155 | LOG_INFO(Service_AM, "called, enabled={}", enabled); | 166 | LOG_INFO(Service_AM, "called, enabled={}", enabled); |
156 | 167 | ||
157 | std::scoped_lock lk{m_applet->lock}; | 168 | std::scoped_lock lk{m_applet->lock}; |
158 | m_applet->operation_mode_changed_notification_enabled = enabled; | 169 | m_applet->lifecycle_manager.SetOperationModeChangedNotificationEnabled(enabled); |
159 | 170 | ||
160 | R_SUCCEED(); | 171 | R_SUCCEED(); |
161 | } | 172 | } |
@@ -164,17 +175,18 @@ Result ISelfController::SetPerformanceModeChangedNotification(bool enabled) { | |||
164 | LOG_INFO(Service_AM, "called, enabled={}", enabled); | 175 | LOG_INFO(Service_AM, "called, enabled={}", enabled); |
165 | 176 | ||
166 | std::scoped_lock lk{m_applet->lock}; | 177 | std::scoped_lock lk{m_applet->lock}; |
167 | m_applet->performance_mode_changed_notification_enabled = enabled; | 178 | m_applet->lifecycle_manager.SetPerformanceModeChangedNotificationEnabled(enabled); |
168 | 179 | ||
169 | R_SUCCEED(); | 180 | R_SUCCEED(); |
170 | } | 181 | } |
171 | 182 | ||
172 | Result ISelfController::SetFocusHandlingMode(bool notify, bool background, bool suspend) { | 183 | Result ISelfController::SetFocusHandlingMode(bool notify, bool background, bool suspend) { |
173 | LOG_WARNING(Service_AM, "(STUBBED) called, notify={} background={} suspend={}", notify, | 184 | LOG_INFO(Service_AM, "called, notify={} background={} suspend={}", notify, background, suspend); |
174 | background, suspend); | ||
175 | 185 | ||
176 | std::scoped_lock lk{m_applet->lock}; | 186 | std::scoped_lock lk{m_applet->lock}; |
177 | m_applet->focus_handling_mode = {notify, background, suspend}; | 187 | m_applet->lifecycle_manager.SetFocusStateChangedNotificationEnabled(notify); |
188 | m_applet->lifecycle_manager.SetFocusHandlingMode(suspend); | ||
189 | m_applet->UpdateSuspensionStateLocked(true); | ||
178 | 190 | ||
179 | R_SUCCEED(); | 191 | R_SUCCEED(); |
180 | } | 192 | } |
@@ -183,7 +195,7 @@ Result ISelfController::SetRestartMessageEnabled(bool enabled) { | |||
183 | LOG_INFO(Service_AM, "called, enabled={}", enabled); | 195 | LOG_INFO(Service_AM, "called, enabled={}", enabled); |
184 | 196 | ||
185 | std::scoped_lock lk{m_applet->lock}; | 197 | std::scoped_lock lk{m_applet->lock}; |
186 | m_applet->restart_message_enabled = enabled; | 198 | m_applet->lifecycle_manager.SetResumeNotificationEnabled(enabled); |
187 | 199 | ||
188 | R_SUCCEED(); | 200 | R_SUCCEED(); |
189 | } | 201 | } |
@@ -202,7 +214,8 @@ Result ISelfController::SetOutOfFocusSuspendingEnabled(bool enabled) { | |||
202 | LOG_INFO(Service_AM, "called, enabled={}", enabled); | 214 | LOG_INFO(Service_AM, "called, enabled={}", enabled); |
203 | 215 | ||
204 | std::scoped_lock lk{m_applet->lock}; | 216 | std::scoped_lock lk{m_applet->lock}; |
205 | m_applet->out_of_focus_suspension_enabled = enabled; | 217 | m_applet->lifecycle_manager.SetOutOfFocusSuspendingEnabled(enabled); |
218 | m_applet->UpdateSuspensionStateLocked(false); | ||
206 | 219 | ||
207 | R_SUCCEED(); | 220 | R_SUCCEED(); |
208 | } | 221 | } |
diff --git a/src/core/hle/service/am/service/system_applet_proxy.cpp b/src/core/hle/service/am/service/system_applet_proxy.cpp index d1871ef9b..c435288a2 100755 --- a/src/core/hle/service/am/service/system_applet_proxy.cpp +++ b/src/core/hle/service/am/service/system_applet_proxy.cpp | |||
@@ -19,9 +19,9 @@ | |||
19 | namespace Service::AM { | 19 | namespace Service::AM { |
20 | 20 | ||
21 | ISystemAppletProxy::ISystemAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, | 21 | ISystemAppletProxy::ISystemAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, |
22 | Kernel::KProcess* process) | 22 | Kernel::KProcess* process, WindowSystem& window_system) |
23 | : ServiceFramework{system_, "ISystemAppletProxy"}, m_process{process}, m_applet{ | 23 | : ServiceFramework{system_, "ISystemAppletProxy"}, |
24 | std::move(applet)} { | 24 | m_window_system{window_system}, m_process{process}, m_applet{std::move(applet)} { |
25 | // clang-format off | 25 | // clang-format off |
26 | static const FunctionInfo functions[] = { | 26 | static const FunctionInfo functions[] = { |
27 | {0, D<&ISystemAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, | 27 | {0, D<&ISystemAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, |
@@ -75,7 +75,7 @@ Result ISystemAppletProxy::GetDebugFunctions( | |||
75 | Result ISystemAppletProxy::GetWindowController( | 75 | Result ISystemAppletProxy::GetWindowController( |
76 | Out<SharedPointer<IWindowController>> out_window_controller) { | 76 | Out<SharedPointer<IWindowController>> out_window_controller) { |
77 | LOG_DEBUG(Service_AM, "called"); | 77 | LOG_DEBUG(Service_AM, "called"); |
78 | *out_window_controller = std::make_shared<IWindowController>(system, m_applet); | 78 | *out_window_controller = std::make_shared<IWindowController>(system, m_applet, m_window_system); |
79 | R_SUCCEED(); | 79 | R_SUCCEED(); |
80 | } | 80 | } |
81 | 81 | ||
@@ -96,14 +96,15 @@ Result ISystemAppletProxy::GetCommonStateGetter( | |||
96 | Result ISystemAppletProxy::GetLibraryAppletCreator( | 96 | Result ISystemAppletProxy::GetLibraryAppletCreator( |
97 | Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) { | 97 | Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) { |
98 | LOG_DEBUG(Service_AM, "called"); | 98 | LOG_DEBUG(Service_AM, "called"); |
99 | *out_library_applet_creator = std::make_shared<ILibraryAppletCreator>(system, m_applet); | 99 | *out_library_applet_creator = |
100 | std::make_shared<ILibraryAppletCreator>(system, m_applet, m_window_system); | ||
100 | R_SUCCEED(); | 101 | R_SUCCEED(); |
101 | } | 102 | } |
102 | 103 | ||
103 | Result ISystemAppletProxy::GetApplicationCreator( | 104 | Result ISystemAppletProxy::GetApplicationCreator( |
104 | Out<SharedPointer<IApplicationCreator>> out_application_creator) { | 105 | Out<SharedPointer<IApplicationCreator>> out_application_creator) { |
105 | LOG_DEBUG(Service_AM, "called"); | 106 | LOG_DEBUG(Service_AM, "called"); |
106 | *out_application_creator = std::make_shared<IApplicationCreator>(system); | 107 | *out_application_creator = std::make_shared<IApplicationCreator>(system, m_window_system); |
107 | R_SUCCEED(); | 108 | R_SUCCEED(); |
108 | } | 109 | } |
109 | 110 | ||
@@ -117,7 +118,8 @@ Result ISystemAppletProxy::GetAppletCommonFunctions( | |||
117 | Result ISystemAppletProxy::GetHomeMenuFunctions( | 118 | Result ISystemAppletProxy::GetHomeMenuFunctions( |
118 | Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions) { | 119 | Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions) { |
119 | LOG_DEBUG(Service_AM, "called"); | 120 | LOG_DEBUG(Service_AM, "called"); |
120 | *out_home_menu_functions = std::make_shared<IHomeMenuFunctions>(system, m_applet); | 121 | *out_home_menu_functions = |
122 | std::make_shared<IHomeMenuFunctions>(system, m_applet, m_window_system); | ||
121 | R_SUCCEED(); | 123 | R_SUCCEED(); |
122 | } | 124 | } |
123 | 125 | ||
diff --git a/src/core/hle/service/am/service/system_applet_proxy.h b/src/core/hle/service/am/service/system_applet_proxy.h index 67cd50e03..217d9dc8c 100755 --- a/src/core/hle/service/am/service/system_applet_proxy.h +++ b/src/core/hle/service/am/service/system_applet_proxy.h | |||
@@ -21,11 +21,12 @@ class ILibraryAppletCreator; | |||
21 | class IProcessWindingController; | 21 | class IProcessWindingController; |
22 | class ISelfController; | 22 | class ISelfController; |
23 | class IWindowController; | 23 | class IWindowController; |
24 | class WindowSystem; | ||
24 | 25 | ||
25 | class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> { | 26 | class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> { |
26 | public: | 27 | public: |
27 | explicit ISystemAppletProxy(Core::System& system, std::shared_ptr<Applet> applet, | 28 | explicit ISystemAppletProxy(Core::System& system, std::shared_ptr<Applet> applet, |
28 | Kernel::KProcess* process); | 29 | Kernel::KProcess* process, WindowSystem& window_system); |
29 | ~ISystemAppletProxy(); | 30 | ~ISystemAppletProxy(); |
30 | 31 | ||
31 | private: | 32 | private: |
@@ -46,6 +47,7 @@ private: | |||
46 | Result GetGlobalStateController( | 47 | Result GetGlobalStateController( |
47 | Out<SharedPointer<IGlobalStateController>> out_global_state_controller); | 48 | Out<SharedPointer<IGlobalStateController>> out_global_state_controller); |
48 | 49 | ||
50 | WindowSystem& m_window_system; | ||
49 | Kernel::KProcess* const m_process; | 51 | Kernel::KProcess* const m_process; |
50 | const std::shared_ptr<Applet> m_applet; | 52 | const std::shared_ptr<Applet> m_applet; |
51 | }; | 53 | }; |
diff --git a/src/core/hle/service/am/service/window_controller.cpp b/src/core/hle/service/am/service/window_controller.cpp index 99a4f50a2..54396affb 100755 --- a/src/core/hle/service/am/service/window_controller.cpp +++ b/src/core/hle/service/am/service/window_controller.cpp | |||
@@ -4,12 +4,15 @@ | |||
4 | #include "core/hle/service/am/applet.h" | 4 | #include "core/hle/service/am/applet.h" |
5 | #include "core/hle/service/am/applet_manager.h" | 5 | #include "core/hle/service/am/applet_manager.h" |
6 | #include "core/hle/service/am/service/window_controller.h" | 6 | #include "core/hle/service/am/service/window_controller.h" |
7 | #include "core/hle/service/am/window_system.h" | ||
7 | #include "core/hle/service/cmif_serialization.h" | 8 | #include "core/hle/service/cmif_serialization.h" |
8 | 9 | ||
9 | namespace Service::AM { | 10 | namespace Service::AM { |
10 | 11 | ||
11 | IWindowController::IWindowController(Core::System& system_, std::shared_ptr<Applet> applet) | 12 | IWindowController::IWindowController(Core::System& system_, std::shared_ptr<Applet> applet, |
12 | : ServiceFramework{system_, "IWindowController"}, m_applet{std::move(applet)} { | 13 | WindowSystem& window_system) |
14 | : ServiceFramework{system_, "IWindowController"}, | ||
15 | m_window_system{window_system}, m_applet{std::move(applet)} { | ||
13 | // clang-format off | 16 | // clang-format off |
14 | static const FunctionInfo functions[] = { | 17 | static const FunctionInfo functions[] = { |
15 | {0, nullptr, "CreateWindow"}, | 18 | {0, nullptr, "CreateWindow"}, |
@@ -63,17 +66,9 @@ Result IWindowController::RejectToChangeIntoBackground() { | |||
63 | } | 66 | } |
64 | 67 | ||
65 | Result IWindowController::SetAppletWindowVisibility(bool visible) { | 68 | Result IWindowController::SetAppletWindowVisibility(bool visible) { |
66 | m_applet->display_layer_manager.SetWindowVisibility(visible); | 69 | LOG_INFO(Service_AM, "called"); |
67 | m_applet->hid_registration.EnableAppletToGetInput(visible); | ||
68 | |||
69 | if (visible) { | ||
70 | m_applet->message_queue.PushMessage(AppletMessage::ChangeIntoForeground); | ||
71 | m_applet->focus_state = FocusState::InFocus; | ||
72 | } else { | ||
73 | m_applet->focus_state = FocusState::NotInFocus; | ||
74 | } | ||
75 | 70 | ||
76 | m_applet->message_queue.PushMessage(AppletMessage::FocusStateChanged); | 71 | m_window_system.RequestAppletVisibilityState(*m_applet, visible); |
77 | 72 | ||
78 | R_SUCCEED(); | 73 | R_SUCCEED(); |
79 | } | 74 | } |
diff --git a/src/core/hle/service/am/service/window_controller.h b/src/core/hle/service/am/service/window_controller.h index bfbad9bcc..a784dd4a4 100755 --- a/src/core/hle/service/am/service/window_controller.h +++ b/src/core/hle/service/am/service/window_controller.h | |||
@@ -9,10 +9,12 @@ | |||
9 | namespace Service::AM { | 9 | namespace Service::AM { |
10 | 10 | ||
11 | struct Applet; | 11 | struct Applet; |
12 | class WindowSystem; | ||
12 | 13 | ||
13 | class IWindowController final : public ServiceFramework<IWindowController> { | 14 | class IWindowController final : public ServiceFramework<IWindowController> { |
14 | public: | 15 | public: |
15 | explicit IWindowController(Core::System& system_, std::shared_ptr<Applet> applet); | 16 | explicit IWindowController(Core::System& system_, std::shared_ptr<Applet> applet, |
17 | WindowSystem& window_system); | ||
16 | ~IWindowController() override; | 18 | ~IWindowController() override; |
17 | 19 | ||
18 | private: | 20 | private: |
@@ -24,6 +26,7 @@ private: | |||
24 | Result SetAppletWindowVisibility(bool visible); | 26 | Result SetAppletWindowVisibility(bool visible); |
25 | Result SetAppletGpuTimeSlice(s64 time_slice); | 27 | Result SetAppletGpuTimeSlice(s64 time_slice); |
26 | 28 | ||
29 | WindowSystem& m_window_system; | ||
27 | const std::shared_ptr<Applet> m_applet; | 30 | const std::shared_ptr<Applet> m_applet; |
28 | }; | 31 | }; |
29 | 32 | ||
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 4a2e2c56c..e6a5a0250 100755 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
@@ -23,11 +23,7 @@ void LoopProcess(Core::System& system) { | |||
23 | std::shared_ptr<ResourceManager> resource_manager = | 23 | std::shared_ptr<ResourceManager> resource_manager = |
24 | std::make_shared<ResourceManager>(system, firmware_settings); | 24 | std::make_shared<ResourceManager>(system, firmware_settings); |
25 | 25 | ||
26 | // TODO: Remove this hack when am is emulated properly. | ||
27 | resource_manager->Initialize(); | 26 | resource_manager->Initialize(); |
28 | resource_manager->RegisterAppletResourceUserId(system.ApplicationProcess()->GetProcessId(), | ||
29 | true); | ||
30 | resource_manager->SetAruidValidForVibration(system.ApplicationProcess()->GetProcessId(), true); | ||
31 | 27 | ||
32 | server_manager->RegisterNamedService( | 28 | server_manager->RegisterNamedService( |
33 | "hid", std::make_shared<IHidServer>(system, resource_manager, firmware_settings)); | 29 | "hid", std::make_shared<IHidServer>(system, resource_manager, firmware_settings)); |
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 97e6614c2..f141b9455 100755 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
@@ -49,8 +49,7 @@ struct Memory::Impl { | |||
49 | void SetCurrentPageTable(Kernel::KProcess& process) { | 49 | void SetCurrentPageTable(Kernel::KProcess& process) { |
50 | current_page_table = &process.GetPageTable().GetImpl(); | 50 | current_page_table = &process.GetPageTable().GetImpl(); |
51 | 51 | ||
52 | if (std::addressof(process) == system.ApplicationProcess() && | 52 | if (process.IsApplication() && Settings::IsFastmemEnabled()) { |
53 | Settings::IsFastmemEnabled()) { | ||
54 | current_page_table->fastmem_arena = system.DeviceMemory().buffer.VirtualBasePointer(); | 53 | current_page_table->fastmem_arena = system.DeviceMemory().buffer.VirtualBasePointer(); |
55 | } else { | 54 | } else { |
56 | current_page_table->fastmem_arena = nullptr; | 55 | current_page_table->fastmem_arena = nullptr; |
diff --git a/src/video_core/host1x/vic.cpp b/src/video_core/host1x/vic.cpp index 14d87a9de..86b34289e 100755 --- a/src/video_core/host1x/vic.cpp +++ b/src/video_core/host1x/vic.cpp | |||
@@ -248,16 +248,19 @@ void Vic::ReadProgressiveY8__V8U8_N420(const SlotStruct& slot, | |||
248 | #endif | 248 | #endif |
249 | 249 | ||
250 | #if defined(ARCHITECTURE_x86_64) || defined(ARCHITECTURE_arm64) | 250 | #if defined(ARCHITECTURE_x86_64) || defined(ARCHITECTURE_arm64) |
251 | const auto alpha_linear{static_cast<u16>(slot.config.planar_alpha.Value())}; | ||
251 | const auto alpha = | 252 | const auto alpha = |
252 | _mm_slli_epi64(_mm_set1_epi64x(static_cast<s64>(slot.config.planar_alpha.Value())), 48); | 253 | _mm_slli_epi64(_mm_set1_epi64x(static_cast<s64>(slot.config.planar_alpha.Value())), 48); |
253 | 254 | ||
254 | const auto shuffle_mask = _mm_set_epi8(13, 15, 14, 12, 9, 11, 10, 8, 5, 7, 6, 4, 1, 3, 2, 0); | 255 | const auto shuffle_mask = _mm_set_epi8(13, 15, 14, 12, 9, 11, 10, 8, 5, 7, 6, 4, 1, 3, 2, 0); |
256 | const auto sse_aligned_width = Common::AlignDown(in_luma_width, 16); | ||
255 | 257 | ||
256 | for (s32 y = 0; y < in_luma_height; y++) { | 258 | for (s32 y = 0; y < in_luma_height; y++) { |
257 | const auto src_luma{y * in_luma_stride}; | 259 | const auto src_luma{y * in_luma_stride}; |
258 | const auto src_chroma{(y / 2) * in_chroma_stride}; | 260 | const auto src_chroma{(y / 2) * in_chroma_stride}; |
259 | const auto dst{y * out_luma_stride}; | 261 | const auto dst{y * out_luma_stride}; |
260 | for (s32 x = 0; x < in_luma_width; x += 16) { | 262 | s32 x = 0; |
263 | for (; x < sse_aligned_width; x += 16) { | ||
261 | // clang-format off | 264 | // clang-format off |
262 | // Prefetch next iteration's memory | 265 | // Prefetch next iteration's memory |
263 | _mm_prefetch((const char*)&luma_buffer[src_luma + x + 16], _MM_HINT_T0); | 266 | _mm_prefetch((const char*)&luma_buffer[src_luma + x + 16], _MM_HINT_T0); |
@@ -381,6 +384,23 @@ void Vic::ReadProgressiveY8__V8U8_N420(const SlotStruct& slot, | |||
381 | 384 | ||
382 | // clang-format on | 385 | // clang-format on |
383 | } | 386 | } |
387 | |||
388 | for (; x < in_luma_width; x++) { | ||
389 | slot_surface[dst + x].r = static_cast<u16>(luma_buffer[src_luma + x] << 2); | ||
390 | // Chroma samples are duplicated horizontally and vertically. | ||
391 | if constexpr (Planar) { | ||
392 | slot_surface[dst + x].g = | ||
393 | static_cast<u16>(chroma_u_buffer[src_chroma + x / 2] << 2); | ||
394 | slot_surface[dst + x].b = | ||
395 | static_cast<u16>(chroma_v_buffer[src_chroma + x / 2] << 2); | ||
396 | } else { | ||
397 | slot_surface[dst + x].g = | ||
398 | static_cast<u16>(chroma_u_buffer[src_chroma + (x & ~1) + 0] << 2); | ||
399 | slot_surface[dst + x].b = | ||
400 | static_cast<u16>(chroma_u_buffer[src_chroma + (x & ~1) + 1] << 2); | ||
401 | } | ||
402 | slot_surface[dst + x].a = alpha_linear; | ||
403 | } | ||
384 | } | 404 | } |
385 | #else | 405 | #else |
386 | DecodeLinear(); | 406 | DecodeLinear(); |
@@ -827,11 +847,14 @@ void Vic::WriteY8__V8U8_N420(const OutputSurfaceConfig& output_surface_config) { | |||
827 | // luma_mask = [00 00] [00 00] [00 00] [FF FF] [00 00] [00 00] [00 00] [FF FF] | 847 | // luma_mask = [00 00] [00 00] [00 00] [FF FF] [00 00] [00 00] [00 00] [FF FF] |
828 | const auto luma_mask = _mm_set_epi16(0, 0, 0, -1, 0, 0, 0, -1); | 848 | const auto luma_mask = _mm_set_epi16(0, 0, 0, -1, 0, 0, 0, -1); |
829 | 849 | ||
850 | const auto sse_aligned_width = Common::AlignDown(surface_width, 16); | ||
851 | |||
830 | for (u32 y = 0; y < surface_height; ++y) { | 852 | for (u32 y = 0; y < surface_height; ++y) { |
831 | const auto src = y * surface_stride; | 853 | const auto src = y * surface_stride; |
832 | const auto dst_luma = y * out_luma_stride; | 854 | const auto dst_luma = y * out_luma_stride; |
833 | const auto dst_chroma = (y / 2) * out_chroma_stride; | 855 | const auto dst_chroma = (y / 2) * out_chroma_stride; |
834 | for (u32 x = 0; x < surface_width; x += 16) { | 856 | u32 x = 0; |
857 | for (; x < sse_aligned_width; x += 16) { | ||
835 | // clang-format off | 858 | // clang-format off |
836 | // Prefetch the next cache lines, 2 per iteration | 859 | // Prefetch the next cache lines, 2 per iteration |
837 | _mm_prefetch((const char*)&output_surface[src + x + 16], _MM_HINT_T0); | 860 | _mm_prefetch((const char*)&output_surface[src + x + 16], _MM_HINT_T0); |
@@ -949,6 +972,16 @@ void Vic::WriteY8__V8U8_N420(const OutputSurfaceConfig& output_surface_config) { | |||
949 | 972 | ||
950 | // clang-format on | 973 | // clang-format on |
951 | } | 974 | } |
975 | |||
976 | const auto src_chroma = y * surface_stride; | ||
977 | for (; x < surface_width; x += 2) { | ||
978 | out_luma[dst_luma + x + 0] = static_cast<u8>(output_surface[src + x + 0].r >> 2); | ||
979 | out_luma[dst_luma + x + 1] = static_cast<u8>(output_surface[src + x + 1].r >> 2); | ||
980 | out_chroma[dst_chroma + x + 0] = | ||
981 | static_cast<u8>(output_surface[src_chroma + x].g >> 2); | ||
982 | out_chroma[dst_chroma + x + 1] = | ||
983 | static_cast<u8>(output_surface[src_chroma + x].b >> 2); | ||
984 | } | ||
952 | } | 985 | } |
953 | #else | 986 | #else |
954 | DecodeLinear(out_luma, out_chroma); | 987 | DecodeLinear(out_luma, out_chroma); |
@@ -1083,10 +1116,14 @@ void Vic::WriteABGR(const OutputSurfaceConfig& output_surface_config) { | |||
1083 | #endif | 1116 | #endif |
1084 | 1117 | ||
1085 | #if defined(ARCHITECTURE_x86_64) || defined(ARCHITECTURE_arm64) | 1118 | #if defined(ARCHITECTURE_x86_64) || defined(ARCHITECTURE_arm64) |
1119 | constexpr size_t SseAlignment = 16; | ||
1120 | const auto sse_aligned_width = Common::AlignDown(surface_width, SseAlignment); | ||
1121 | |||
1086 | for (u32 y = 0; y < surface_height; y++) { | 1122 | for (u32 y = 0; y < surface_height; y++) { |
1087 | const auto src = y * surface_stride; | 1123 | const auto src = y * surface_stride; |
1088 | const auto dst = y * out_luma_stride; | 1124 | const auto dst = y * out_luma_stride; |
1089 | for (u32 x = 0; x < surface_width; x += 16) { | 1125 | u32 x = 0; |
1126 | for (; x < sse_aligned_width; x += SseAlignment) { | ||
1090 | // clang-format off | 1127 | // clang-format off |
1091 | // Prefetch the next 2 cache lines | 1128 | // Prefetch the next 2 cache lines |
1092 | _mm_prefetch((const char*)&output_surface[src + x + 16], _MM_HINT_T0); | 1129 | _mm_prefetch((const char*)&output_surface[src + x + 16], _MM_HINT_T0); |
@@ -1146,6 +1183,20 @@ void Vic::WriteABGR(const OutputSurfaceConfig& output_surface_config) { | |||
1146 | 1183 | ||
1147 | // clang-format on | 1184 | // clang-format on |
1148 | } | 1185 | } |
1186 | |||
1187 | for (; x < surface_width; x++) { | ||
1188 | if constexpr (Format == VideoPixelFormat::A8R8G8B8) { | ||
1189 | out_buffer[dst + x * 4 + 0] = static_cast<u8>(output_surface[src + x].b >> 2); | ||
1190 | out_buffer[dst + x * 4 + 1] = static_cast<u8>(output_surface[src + x].g >> 2); | ||
1191 | out_buffer[dst + x * 4 + 2] = static_cast<u8>(output_surface[src + x].r >> 2); | ||
1192 | out_buffer[dst + x * 4 + 3] = static_cast<u8>(output_surface[src + x].a >> 2); | ||
1193 | } else { | ||
1194 | out_buffer[dst + x * 4 + 0] = static_cast<u8>(output_surface[src + x].r >> 2); | ||
1195 | out_buffer[dst + x * 4 + 1] = static_cast<u8>(output_surface[src + x].g >> 2); | ||
1196 | out_buffer[dst + x * 4 + 2] = static_cast<u8>(output_surface[src + x].b >> 2); | ||
1197 | out_buffer[dst + x * 4 + 3] = static_cast<u8>(output_surface[src + x].a >> 2); | ||
1198 | } | ||
1199 | } | ||
1149 | } | 1200 | } |
1150 | #else | 1201 | #else |
1151 | DecodeLinear(out_buffer); | 1202 | DecodeLinear(out_buffer); |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 13f056214..410b6ca8c 100755 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
@@ -2114,7 +2114,9 @@ void TextureCache<P>::TrackImage(ImageBase& image, ImageId image_id) { | |||
2114 | ASSERT(False(image.flags & ImageFlagBits::Tracked)); | 2114 | ASSERT(False(image.flags & ImageFlagBits::Tracked)); |
2115 | image.flags |= ImageFlagBits::Tracked; | 2115 | image.flags |= ImageFlagBits::Tracked; |
2116 | if (False(image.flags & ImageFlagBits::Sparse)) { | 2116 | if (False(image.flags & ImageFlagBits::Sparse)) { |
2117 | device_memory.UpdatePagesCachedCount(image.cpu_addr, image.guest_size_bytes, 1); | 2117 | if (image.cpu_addr < ~(1ULL << 40)) { |
2118 | device_memory.UpdatePagesCachedCount(image.cpu_addr, image.guest_size_bytes, 1); | ||
2119 | } | ||
2118 | return; | 2120 | return; |
2119 | } | 2121 | } |
2120 | if (True(image.flags & ImageFlagBits::Registered)) { | 2122 | if (True(image.flags & ImageFlagBits::Registered)) { |
@@ -2140,7 +2142,9 @@ void TextureCache<P>::UntrackImage(ImageBase& image, ImageId image_id) { | |||
2140 | ASSERT(True(image.flags & ImageFlagBits::Tracked)); | 2142 | ASSERT(True(image.flags & ImageFlagBits::Tracked)); |
2141 | image.flags &= ~ImageFlagBits::Tracked; | 2143 | image.flags &= ~ImageFlagBits::Tracked; |
2142 | if (False(image.flags & ImageFlagBits::Sparse)) { | 2144 | if (False(image.flags & ImageFlagBits::Sparse)) { |
2143 | device_memory.UpdatePagesCachedCount(image.cpu_addr, image.guest_size_bytes, -1); | 2145 | if (image.cpu_addr < ~(1ULL << 40)) { |
2146 | device_memory.UpdatePagesCachedCount(image.cpu_addr, image.guest_size_bytes, -1); | ||
2147 | } | ||
2144 | return; | 2148 | return; |
2145 | } | 2149 | } |
2146 | ASSERT(True(image.flags & ImageFlagBits::Registered)); | 2150 | ASSERT(True(image.flags & ImageFlagBits::Registered)); |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 6c8540186..70e089902 100755 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
@@ -1461,7 +1461,6 @@ void GMainWindow::OnAppFocusStateChanged(Qt::ApplicationState state) { | |||
1461 | OnPauseGame(); | 1461 | OnPauseGame(); |
1462 | } else if (!emu_thread->IsRunning() && auto_paused && state == Qt::ApplicationActive) { | 1462 | } else if (!emu_thread->IsRunning() && auto_paused && state == Qt::ApplicationActive) { |
1463 | auto_paused = false; | 1463 | auto_paused = false; |
1464 | RequestGameResume(); | ||
1465 | OnStartGame(); | 1464 | OnStartGame(); |
1466 | } | 1465 | } |
1467 | } | 1466 | } |
@@ -1702,7 +1701,6 @@ void GMainWindow::OnPrepareForSleep(bool prepare_sleep) { | |||
1702 | } else { | 1701 | } else { |
1703 | if (!emu_thread->IsRunning() && auto_paused) { | 1702 | if (!emu_thread->IsRunning() && auto_paused) { |
1704 | auto_paused = false; | 1703 | auto_paused = false; |
1705 | RequestGameResume(); | ||
1706 | OnStartGame(); | 1704 | OnStartGame(); |
1707 | } | 1705 | } |
1708 | } | 1706 | } |
@@ -3457,7 +3455,6 @@ void GMainWindow::OnPauseContinueGame() { | |||
3457 | if (emu_thread->IsRunning()) { | 3455 | if (emu_thread->IsRunning()) { |
3458 | OnPauseGame(); | 3456 | OnPauseGame(); |
3459 | } else { | 3457 | } else { |
3460 | RequestGameResume(); | ||
3461 | OnStartGame(); | 3458 | OnStartGame(); |
3462 | } | 3459 | } |
3463 | } | 3460 | } |
@@ -5013,10 +5010,6 @@ void GMainWindow::RequestGameExit() { | |||
5013 | system->GetAppletManager().RequestExit(); | 5010 | system->GetAppletManager().RequestExit(); |
5014 | } | 5011 | } |
5015 | 5012 | ||
5016 | void GMainWindow::RequestGameResume() { | ||
5017 | system->GetAppletManager().RequestResume(); | ||
5018 | } | ||
5019 | |||
5020 | void GMainWindow::filterBarSetChecked(bool state) { | 5013 | void GMainWindow::filterBarSetChecked(bool state) { |
5021 | ui->action_Show_Filter_Bar->setChecked(state); | 5014 | ui->action_Show_Filter_Bar->setChecked(state); |
5022 | emit(OnToggleFilterBar()); | 5015 | emit(OnToggleFilterBar()); |
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 697c38e57..1501c99bc 100755 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
@@ -310,7 +310,6 @@ private: | |||
310 | bool ConfirmChangeGame(); | 310 | bool ConfirmChangeGame(); |
311 | bool ConfirmForceLockedExit(); | 311 | bool ConfirmForceLockedExit(); |
312 | void RequestGameExit(); | 312 | void RequestGameExit(); |
313 | void RequestGameResume(); | ||
314 | void changeEvent(QEvent* event) override; | 313 | void changeEvent(QEvent* event) override; |
315 | void closeEvent(QCloseEvent* event) override; | 314 | void closeEvent(QCloseEvent* event) override; |
316 | 315 | ||