diff options
| author | 2024-01-04 20:37:43 -0600 | |
|---|---|---|
| committer | 2024-01-05 11:41:15 -0600 | |
| commit | ee847f8ff0b1b0aec39c1b78c010bc0c08a0a613 (patch) | |
| tree | 3b95cbb74be05f0ce7a007353f1f9f95e1ed3901 /src/hid_core/resource_manager.cpp | |
| parent | Merge pull request #12437 from ameerj/gl-amd-fixes (diff) | |
| download | yuzu-ee847f8ff0b1b0aec39c1b78c010bc0c08a0a613.tar.gz yuzu-ee847f8ff0b1b0aec39c1b78c010bc0c08a0a613.tar.xz yuzu-ee847f8ff0b1b0aec39c1b78c010bc0c08a0a613.zip | |
hid_core: Move hid to it's own subproject
Diffstat (limited to 'src/hid_core/resource_manager.cpp')
| -rw-r--r-- | src/hid_core/resource_manager.cpp | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/src/hid_core/resource_manager.cpp b/src/hid_core/resource_manager.cpp new file mode 100644 index 000000000..17dacef6e --- /dev/null +++ b/src/hid_core/resource_manager.cpp | |||
| @@ -0,0 +1,362 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #include "common/logging/log.h" | ||
| 5 | #include "core/core.h" | ||
| 6 | #include "core/core_timing.h" | ||
| 7 | #include "core/hle/kernel/k_shared_memory.h" | ||
| 8 | #include "core/hle/service/ipc_helpers.h" | ||
| 9 | #include "hid_core/hid_core.h" | ||
| 10 | #include "hid_core/resource_manager.h" | ||
| 11 | |||
| 12 | #include "hid_core/resources/applet_resource.h" | ||
| 13 | #include "hid_core/resources/debug_pad/debug_pad.h" | ||
| 14 | #include "hid_core/resources/digitizer/digitizer.h" | ||
| 15 | #include "hid_core/resources/keyboard/keyboard.h" | ||
| 16 | #include "hid_core/resources/mouse/debug_mouse.h" | ||
| 17 | #include "hid_core/resources/mouse/mouse.h" | ||
| 18 | #include "hid_core/resources/npad/npad.h" | ||
| 19 | #include "hid_core/resources/palma/palma.h" | ||
| 20 | #include "hid_core/resources/shared_memory_format.h" | ||
| 21 | #include "hid_core/resources/six_axis/console_six_axis.h" | ||
| 22 | #include "hid_core/resources/six_axis/seven_six_axis.h" | ||
| 23 | #include "hid_core/resources/six_axis/six_axis.h" | ||
| 24 | #include "hid_core/resources/system_buttons/capture_button.h" | ||
| 25 | #include "hid_core/resources/system_buttons/home_button.h" | ||
| 26 | #include "hid_core/resources/system_buttons/sleep_button.h" | ||
| 27 | #include "hid_core/resources/touch_screen/gesture.h" | ||
| 28 | #include "hid_core/resources/touch_screen/touch_screen.h" | ||
| 29 | #include "hid_core/resources/unique_pad/unique_pad.h" | ||
| 30 | |||
| 31 | namespace Service::HID { | ||
| 32 | |||
| 33 | // Updating period for each HID device. | ||
| 34 | // Period time is obtained by measuring the number of samples in a second on HW using a homebrew | ||
| 35 | // Correct npad_update_ns is 4ms this is overclocked to lower input lag | ||
| 36 | constexpr auto npad_update_ns = std::chrono::nanoseconds{1 * 1000 * 1000}; // (1ms, 1000Hz) | ||
| 37 | constexpr auto default_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 1000Hz) | ||
| 38 | constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz) | ||
| 39 | constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz) | ||
| 40 | |||
| 41 | ResourceManager::ResourceManager(Core::System& system_) | ||
| 42 | : system{system_}, service_context{system_, "hid"} { | ||
| 43 | applet_resource = std::make_shared<AppletResource>(system); | ||
| 44 | } | ||
| 45 | |||
| 46 | ResourceManager::~ResourceManager() = default; | ||
| 47 | |||
| 48 | void ResourceManager::Initialize() { | ||
| 49 | if (is_initialized) { | ||
| 50 | return; | ||
| 51 | } | ||
| 52 | |||
| 53 | system.HIDCore().ReloadInputDevices(); | ||
| 54 | |||
| 55 | InitializeHidCommonSampler(); | ||
| 56 | InitializeTouchScreenSampler(); | ||
| 57 | InitializeConsoleSixAxisSampler(); | ||
| 58 | InitializeAHidSampler(); | ||
| 59 | |||
| 60 | is_initialized = true; | ||
| 61 | } | ||
| 62 | |||
| 63 | std::shared_ptr<AppletResource> ResourceManager::GetAppletResource() const { | ||
| 64 | return applet_resource; | ||
| 65 | } | ||
| 66 | |||
| 67 | std::shared_ptr<CaptureButton> ResourceManager::GetCaptureButton() const { | ||
| 68 | return capture_button; | ||
| 69 | } | ||
| 70 | |||
| 71 | std::shared_ptr<ConsoleSixAxis> ResourceManager::GetConsoleSixAxis() const { | ||
| 72 | return console_six_axis; | ||
| 73 | } | ||
| 74 | |||
| 75 | std::shared_ptr<DebugMouse> ResourceManager::GetDebugMouse() const { | ||
| 76 | return debug_mouse; | ||
| 77 | } | ||
| 78 | |||
| 79 | std::shared_ptr<DebugPad> ResourceManager::GetDebugPad() const { | ||
| 80 | return debug_pad; | ||
| 81 | } | ||
| 82 | |||
| 83 | std::shared_ptr<Digitizer> ResourceManager::GetDigitizer() const { | ||
| 84 | return digitizer; | ||
| 85 | } | ||
| 86 | |||
| 87 | std::shared_ptr<Gesture> ResourceManager::GetGesture() const { | ||
| 88 | return gesture; | ||
| 89 | } | ||
| 90 | |||
| 91 | std::shared_ptr<HomeButton> ResourceManager::GetHomeButton() const { | ||
| 92 | return home_button; | ||
| 93 | } | ||
| 94 | |||
| 95 | std::shared_ptr<Keyboard> ResourceManager::GetKeyboard() const { | ||
| 96 | return keyboard; | ||
| 97 | } | ||
| 98 | |||
| 99 | std::shared_ptr<Mouse> ResourceManager::GetMouse() const { | ||
| 100 | return mouse; | ||
| 101 | } | ||
| 102 | |||
| 103 | std::shared_ptr<NPad> ResourceManager::GetNpad() const { | ||
| 104 | return npad; | ||
| 105 | } | ||
| 106 | |||
| 107 | std::shared_ptr<Palma> ResourceManager::GetPalma() const { | ||
| 108 | return palma; | ||
| 109 | } | ||
| 110 | |||
| 111 | std::shared_ptr<SevenSixAxis> ResourceManager::GetSevenSixAxis() const { | ||
| 112 | return seven_six_axis; | ||
| 113 | } | ||
| 114 | |||
| 115 | std::shared_ptr<SixAxis> ResourceManager::GetSixAxis() const { | ||
| 116 | return six_axis; | ||
| 117 | } | ||
| 118 | |||
| 119 | std::shared_ptr<SleepButton> ResourceManager::GetSleepButton() const { | ||
| 120 | return sleep_button; | ||
| 121 | } | ||
| 122 | |||
| 123 | std::shared_ptr<TouchScreen> ResourceManager::GetTouchScreen() const { | ||
| 124 | return touch_screen; | ||
| 125 | } | ||
| 126 | |||
| 127 | std::shared_ptr<UniquePad> ResourceManager::GetUniquePad() const { | ||
| 128 | return unique_pad; | ||
| 129 | } | ||
| 130 | |||
| 131 | Result ResourceManager::CreateAppletResource(u64 aruid) { | ||
| 132 | if (aruid == SystemAruid) { | ||
| 133 | const auto result = RegisterCoreAppletResource(); | ||
| 134 | if (result.IsError()) { | ||
| 135 | return result; | ||
| 136 | } | ||
| 137 | return GetNpad()->ActivateNpadResource(); | ||
| 138 | } | ||
| 139 | |||
| 140 | const auto result = CreateAppletResourceImpl(aruid); | ||
| 141 | if (result.IsError()) { | ||
| 142 | return result; | ||
| 143 | } | ||
| 144 | |||
| 145 | // Homebrew doesn't try to activate some controllers, so we activate them by default | ||
| 146 | npad->Activate(); | ||
| 147 | six_axis->Activate(); | ||
| 148 | touch_screen->Activate(); | ||
| 149 | |||
| 150 | return GetNpad()->ActivateNpadResource(aruid); | ||
| 151 | } | ||
| 152 | |||
| 153 | Result ResourceManager::CreateAppletResourceImpl(u64 aruid) { | ||
| 154 | std::scoped_lock lock{shared_mutex}; | ||
| 155 | return applet_resource->CreateAppletResource(aruid); | ||
| 156 | } | ||
| 157 | |||
| 158 | void ResourceManager::InitializeHidCommonSampler() { | ||
| 159 | debug_pad = std::make_shared<DebugPad>(system.HIDCore()); | ||
| 160 | mouse = std::make_shared<Mouse>(system.HIDCore()); | ||
| 161 | debug_mouse = std::make_shared<DebugMouse>(system.HIDCore()); | ||
| 162 | keyboard = std::make_shared<Keyboard>(system.HIDCore()); | ||
| 163 | unique_pad = std::make_shared<UniquePad>(system.HIDCore()); | ||
| 164 | npad = std::make_shared<NPad>(system.HIDCore(), service_context); | ||
| 165 | gesture = std::make_shared<Gesture>(system.HIDCore()); | ||
| 166 | home_button = std::make_shared<HomeButton>(system.HIDCore()); | ||
| 167 | sleep_button = std::make_shared<SleepButton>(system.HIDCore()); | ||
| 168 | capture_button = std::make_shared<CaptureButton>(system.HIDCore()); | ||
| 169 | digitizer = std::make_shared<Digitizer>(system.HIDCore()); | ||
| 170 | |||
| 171 | palma = std::make_shared<Palma>(system.HIDCore(), service_context); | ||
| 172 | six_axis = std::make_shared<SixAxis>(system.HIDCore(), npad); | ||
| 173 | |||
| 174 | debug_pad->SetAppletResource(applet_resource, &shared_mutex); | ||
| 175 | digitizer->SetAppletResource(applet_resource, &shared_mutex); | ||
| 176 | keyboard->SetAppletResource(applet_resource, &shared_mutex); | ||
| 177 | npad->SetNpadExternals(applet_resource, &shared_mutex); | ||
| 178 | six_axis->SetAppletResource(applet_resource, &shared_mutex); | ||
| 179 | mouse->SetAppletResource(applet_resource, &shared_mutex); | ||
| 180 | debug_mouse->SetAppletResource(applet_resource, &shared_mutex); | ||
| 181 | home_button->SetAppletResource(applet_resource, &shared_mutex); | ||
| 182 | sleep_button->SetAppletResource(applet_resource, &shared_mutex); | ||
| 183 | capture_button->SetAppletResource(applet_resource, &shared_mutex); | ||
| 184 | } | ||
| 185 | |||
| 186 | void ResourceManager::InitializeTouchScreenSampler() { | ||
| 187 | gesture = std::make_shared<Gesture>(system.HIDCore()); | ||
| 188 | touch_screen = std::make_shared<TouchScreen>(system.HIDCore()); | ||
| 189 | |||
| 190 | touch_screen->SetAppletResource(applet_resource, &shared_mutex); | ||
| 191 | gesture->SetAppletResource(applet_resource, &shared_mutex); | ||
| 192 | } | ||
| 193 | |||
| 194 | void ResourceManager::InitializeConsoleSixAxisSampler() { | ||
| 195 | console_six_axis = std::make_shared<ConsoleSixAxis>(system.HIDCore()); | ||
| 196 | seven_six_axis = std::make_shared<SevenSixAxis>(system); | ||
| 197 | |||
| 198 | console_six_axis->SetAppletResource(applet_resource, &shared_mutex); | ||
| 199 | } | ||
| 200 | |||
| 201 | void ResourceManager::InitializeAHidSampler() { | ||
| 202 | // TODO | ||
| 203 | } | ||
| 204 | |||
| 205 | Result ResourceManager::RegisterCoreAppletResource() { | ||
| 206 | std::scoped_lock lock{shared_mutex}; | ||
| 207 | return applet_resource->RegisterCoreAppletResource(); | ||
| 208 | } | ||
| 209 | |||
| 210 | Result ResourceManager::UnregisterCoreAppletResource() { | ||
| 211 | std::scoped_lock lock{shared_mutex}; | ||
| 212 | return applet_resource->UnregisterCoreAppletResource(); | ||
| 213 | } | ||
| 214 | |||
| 215 | Result ResourceManager::RegisterAppletResourceUserId(u64 aruid, bool bool_value) { | ||
| 216 | std::scoped_lock lock{shared_mutex}; | ||
| 217 | auto result = applet_resource->RegisterAppletResourceUserId(aruid, bool_value); | ||
| 218 | if (result.IsSuccess()) { | ||
| 219 | result = npad->RegisterAppletResourceUserId(aruid); | ||
| 220 | } | ||
| 221 | return result; | ||
| 222 | } | ||
| 223 | |||
| 224 | void ResourceManager::UnregisterAppletResourceUserId(u64 aruid) { | ||
| 225 | std::scoped_lock lock{shared_mutex}; | ||
| 226 | applet_resource->UnregisterAppletResourceUserId(aruid); | ||
| 227 | } | ||
| 228 | |||
| 229 | Result ResourceManager::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid) { | ||
| 230 | std::scoped_lock lock{shared_mutex}; | ||
| 231 | return applet_resource->GetSharedMemoryHandle(out_handle, aruid); | ||
| 232 | } | ||
| 233 | |||
| 234 | void ResourceManager::FreeAppletResourceId(u64 aruid) { | ||
| 235 | std::scoped_lock lock{shared_mutex}; | ||
| 236 | applet_resource->FreeAppletResourceId(aruid); | ||
| 237 | } | ||
| 238 | |||
| 239 | void ResourceManager::EnableInput(u64 aruid, bool is_enabled) { | ||
| 240 | std::scoped_lock lock{shared_mutex}; | ||
| 241 | applet_resource->EnableInput(aruid, is_enabled); | ||
| 242 | } | ||
| 243 | |||
| 244 | void ResourceManager::EnableSixAxisSensor(u64 aruid, bool is_enabled) { | ||
| 245 | std::scoped_lock lock{shared_mutex}; | ||
| 246 | applet_resource->EnableSixAxisSensor(aruid, is_enabled); | ||
| 247 | } | ||
| 248 | |||
| 249 | void ResourceManager::EnablePadInput(u64 aruid, bool is_enabled) { | ||
| 250 | std::scoped_lock lock{shared_mutex}; | ||
| 251 | applet_resource->EnablePadInput(aruid, is_enabled); | ||
| 252 | } | ||
| 253 | |||
| 254 | void ResourceManager::EnableTouchScreen(u64 aruid, bool is_enabled) { | ||
| 255 | std::scoped_lock lock{shared_mutex}; | ||
| 256 | applet_resource->EnableTouchScreen(aruid, is_enabled); | ||
| 257 | } | ||
| 258 | |||
| 259 | void ResourceManager::UpdateControllers(std::chrono::nanoseconds ns_late) { | ||
| 260 | auto& core_timing = system.CoreTiming(); | ||
| 261 | debug_pad->OnUpdate(core_timing); | ||
| 262 | digitizer->OnUpdate(core_timing); | ||
| 263 | unique_pad->OnUpdate(core_timing); | ||
| 264 | gesture->OnUpdate(core_timing); | ||
| 265 | touch_screen->OnUpdate(core_timing); | ||
| 266 | palma->OnUpdate(core_timing); | ||
| 267 | home_button->OnUpdate(core_timing); | ||
| 268 | sleep_button->OnUpdate(core_timing); | ||
| 269 | capture_button->OnUpdate(core_timing); | ||
| 270 | } | ||
| 271 | |||
| 272 | void ResourceManager::UpdateNpad(std::chrono::nanoseconds ns_late) { | ||
| 273 | auto& core_timing = system.CoreTiming(); | ||
| 274 | npad->OnUpdate(core_timing); | ||
| 275 | } | ||
| 276 | |||
| 277 | void ResourceManager::UpdateMouseKeyboard(std::chrono::nanoseconds ns_late) { | ||
| 278 | auto& core_timing = system.CoreTiming(); | ||
| 279 | mouse->OnUpdate(core_timing); | ||
| 280 | debug_mouse->OnUpdate(core_timing); | ||
| 281 | keyboard->OnUpdate(core_timing); | ||
| 282 | } | ||
| 283 | |||
| 284 | void ResourceManager::UpdateMotion(std::chrono::nanoseconds ns_late) { | ||
| 285 | auto& core_timing = system.CoreTiming(); | ||
| 286 | six_axis->OnUpdate(core_timing); | ||
| 287 | seven_six_axis->OnUpdate(core_timing); | ||
| 288 | console_six_axis->OnUpdate(core_timing); | ||
| 289 | } | ||
| 290 | |||
| 291 | IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource, | ||
| 292 | u64 applet_resource_user_id) | ||
| 293 | : ServiceFramework{system_, "IAppletResource"}, aruid{applet_resource_user_id}, | ||
| 294 | resource_manager{resource} { | ||
| 295 | static const FunctionInfo functions[] = { | ||
| 296 | {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"}, | ||
| 297 | }; | ||
| 298 | RegisterHandlers(functions); | ||
| 299 | |||
| 300 | // Register update callbacks | ||
| 301 | npad_update_event = Core::Timing::CreateEvent( | ||
| 302 | "HID::UpdatePadCallback", | ||
| 303 | [this, resource]( | ||
| 304 | s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { | ||
| 305 | const auto guard = LockService(); | ||
| 306 | resource->UpdateNpad(ns_late); | ||
| 307 | return std::nullopt; | ||
| 308 | }); | ||
| 309 | default_update_event = Core::Timing::CreateEvent( | ||
| 310 | "HID::UpdateDefaultCallback", | ||
| 311 | [this, resource]( | ||
| 312 | s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { | ||
| 313 | const auto guard = LockService(); | ||
| 314 | resource->UpdateControllers(ns_late); | ||
| 315 | return std::nullopt; | ||
| 316 | }); | ||
| 317 | mouse_keyboard_update_event = Core::Timing::CreateEvent( | ||
| 318 | "HID::UpdateMouseKeyboardCallback", | ||
| 319 | [this, resource]( | ||
| 320 | s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { | ||
| 321 | const auto guard = LockService(); | ||
| 322 | resource->UpdateMouseKeyboard(ns_late); | ||
| 323 | return std::nullopt; | ||
| 324 | }); | ||
| 325 | motion_update_event = Core::Timing::CreateEvent( | ||
| 326 | "HID::UpdateMotionCallback", | ||
| 327 | [this, resource]( | ||
| 328 | s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { | ||
| 329 | const auto guard = LockService(); | ||
| 330 | resource->UpdateMotion(ns_late); | ||
| 331 | return std::nullopt; | ||
| 332 | }); | ||
| 333 | |||
| 334 | system.CoreTiming().ScheduleLoopingEvent(npad_update_ns, npad_update_ns, npad_update_event); | ||
| 335 | system.CoreTiming().ScheduleLoopingEvent(default_update_ns, default_update_ns, | ||
| 336 | default_update_event); | ||
| 337 | system.CoreTiming().ScheduleLoopingEvent(mouse_keyboard_update_ns, mouse_keyboard_update_ns, | ||
| 338 | mouse_keyboard_update_event); | ||
| 339 | system.CoreTiming().ScheduleLoopingEvent(motion_update_ns, motion_update_ns, | ||
| 340 | motion_update_event); | ||
| 341 | } | ||
| 342 | |||
| 343 | IAppletResource::~IAppletResource() { | ||
| 344 | system.CoreTiming().UnscheduleEvent(npad_update_event); | ||
| 345 | system.CoreTiming().UnscheduleEvent(default_update_event); | ||
| 346 | system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event); | ||
| 347 | system.CoreTiming().UnscheduleEvent(motion_update_event); | ||
| 348 | resource_manager->FreeAppletResourceId(aruid); | ||
| 349 | } | ||
| 350 | |||
| 351 | void IAppletResource::GetSharedMemoryHandle(HLERequestContext& ctx) { | ||
| 352 | Kernel::KSharedMemory* handle; | ||
| 353 | const auto result = resource_manager->GetSharedMemoryHandle(&handle, aruid); | ||
| 354 | |||
| 355 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, result=0x{:X}", aruid, result.raw); | ||
| 356 | |||
| 357 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 358 | rb.Push(result); | ||
| 359 | rb.PushCopyObjects(handle); | ||
| 360 | } | ||
| 361 | |||
| 362 | } // namespace Service::HID | ||