diff options
| -rw-r--r-- | src/core/CMakeLists.txt | 6 | ||||
| -rw-r--r-- | src/core/hle/service/am/applet.h | 6 | ||||
| -rw-r--r-- | src/core/hle/service/am/display_layer_manager.cpp | 149 | ||||
| -rw-r--r-- | src/core/hle/service/am/display_layer_manager.h | 56 | ||||
| -rw-r--r-- | src/core/hle/service/am/managed_layer_holder.cpp | 59 | ||||
| -rw-r--r-- | src/core/hle/service/am/managed_layer_holder.h | 32 | ||||
| -rw-r--r-- | src/core/hle/service/am/service/display_controller.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/service/am/service/library_applet_creator.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/am/service/self_controller.cpp | 51 | ||||
| -rw-r--r-- | src/core/hle/service/am/service/window_controller.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/am/system_buffer_manager.cpp | 80 | ||||
| -rw-r--r-- | src/core/hle/service/am/system_buffer_manager.h | 52 |
12 files changed, 240 insertions, 261 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 7770dbeae..6456ae634 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -423,12 +423,12 @@ add_library(core STATIC | |||
| 423 | hle/service/am/applet_manager.h | 423 | hle/service/am/applet_manager.h |
| 424 | hle/service/am/applet_message_queue.cpp | 424 | hle/service/am/applet_message_queue.cpp |
| 425 | hle/service/am/applet_message_queue.h | 425 | hle/service/am/applet_message_queue.h |
| 426 | hle/service/am/display_layer_manager.cpp | ||
| 427 | hle/service/am/display_layer_manager.h | ||
| 426 | hle/service/am/hid_registration.cpp | 428 | hle/service/am/hid_registration.cpp |
| 427 | hle/service/am/hid_registration.h | 429 | hle/service/am/hid_registration.h |
| 428 | hle/service/am/library_applet_storage.cpp | 430 | hle/service/am/library_applet_storage.cpp |
| 429 | hle/service/am/library_applet_storage.h | 431 | hle/service/am/library_applet_storage.h |
| 430 | hle/service/am/managed_layer_holder.cpp | ||
| 431 | hle/service/am/managed_layer_holder.h | ||
| 432 | hle/service/am/process.cpp | 432 | hle/service/am/process.cpp |
| 433 | hle/service/am/process.h | 433 | hle/service/am/process.h |
| 434 | hle/service/am/service/all_system_applet_proxies_service.cpp | 434 | hle/service/am/service/all_system_applet_proxies_service.cpp |
| @@ -481,8 +481,6 @@ add_library(core STATIC | |||
| 481 | hle/service/am/service/system_applet_proxy.h | 481 | hle/service/am/service/system_applet_proxy.h |
| 482 | hle/service/am/service/window_controller.cpp | 482 | hle/service/am/service/window_controller.cpp |
| 483 | hle/service/am/service/window_controller.h | 483 | hle/service/am/service/window_controller.h |
| 484 | hle/service/am/system_buffer_manager.cpp | ||
| 485 | hle/service/am/system_buffer_manager.h | ||
| 486 | hle/service/aoc/aoc_u.cpp | 484 | hle/service/aoc/aoc_u.cpp |
| 487 | hle/service/aoc/aoc_u.h | 485 | hle/service/aoc/aoc_u.h |
| 488 | hle/service/apm/apm.cpp | 486 | hle/service/apm/apm.cpp |
diff --git a/src/core/hle/service/am/applet.h b/src/core/hle/service/am/applet.h index 4f34d4811..ad602153e 100644 --- a/src/core/hle/service/am/applet.h +++ b/src/core/hle/service/am/applet.h | |||
| @@ -14,10 +14,9 @@ | |||
| 14 | 14 | ||
| 15 | #include "core/hle/service/am/am_types.h" | 15 | #include "core/hle/service/am/am_types.h" |
| 16 | #include "core/hle/service/am/applet_message_queue.h" | 16 | #include "core/hle/service/am/applet_message_queue.h" |
| 17 | #include "core/hle/service/am/display_layer_manager.h" | ||
| 17 | #include "core/hle/service/am/hid_registration.h" | 18 | #include "core/hle/service/am/hid_registration.h" |
| 18 | #include "core/hle/service/am/managed_layer_holder.h" | ||
| 19 | #include "core/hle/service/am/process.h" | 19 | #include "core/hle/service/am/process.h" |
| 20 | #include "core/hle/service/am/system_buffer_manager.h" | ||
| 21 | 20 | ||
| 22 | namespace Service::AM { | 21 | namespace Service::AM { |
| 23 | 22 | ||
| @@ -54,8 +53,7 @@ struct Applet { | |||
| 54 | HidRegistration hid_registration; | 53 | HidRegistration hid_registration; |
| 55 | 54 | ||
| 56 | // vi state | 55 | // vi state |
| 57 | SystemBufferManager system_buffer_manager{}; | 56 | DisplayLayerManager display_layer_manager{}; |
| 58 | ManagedLayerHolder managed_layer_holder{}; | ||
| 59 | 57 | ||
| 60 | // Applet common functions | 58 | // Applet common functions |
| 61 | Result terminate_result{}; | 59 | Result terminate_result{}; |
diff --git a/src/core/hle/service/am/display_layer_manager.cpp b/src/core/hle/service/am/display_layer_manager.cpp new file mode 100644 index 000000000..50674c325 --- /dev/null +++ b/src/core/hle/service/am/display_layer_manager.cpp | |||
| @@ -0,0 +1,149 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/display_layer_manager.h" | ||
| 5 | #include "core/hle/service/nvnflinger/fb_share_buffer_manager.h" | ||
| 6 | #include "core/hle/service/nvnflinger/nvnflinger.h" | ||
| 7 | #include "core/hle/service/vi/vi_results.h" | ||
| 8 | |||
| 9 | namespace Service::AM { | ||
| 10 | |||
| 11 | DisplayLayerManager::DisplayLayerManager() = default; | ||
| 12 | DisplayLayerManager::~DisplayLayerManager() { | ||
| 13 | this->Finalize(); | ||
| 14 | } | ||
| 15 | |||
| 16 | void DisplayLayerManager::Initialize(Nvnflinger::Nvnflinger* nvnflinger, Kernel::KProcess* process, | ||
| 17 | AppletId applet_id, LibraryAppletMode mode) { | ||
| 18 | m_process = process; | ||
| 19 | m_nvnflinger = nvnflinger; | ||
| 20 | m_system_shared_buffer_id = 0; | ||
| 21 | m_system_shared_layer_id = 0; | ||
| 22 | m_applet_id = applet_id; | ||
| 23 | m_buffer_sharing_enabled = false; | ||
| 24 | m_blending_enabled = mode == LibraryAppletMode::PartialForeground || | ||
| 25 | mode == LibraryAppletMode::PartialForegroundIndirectDisplay; | ||
| 26 | } | ||
| 27 | |||
| 28 | void DisplayLayerManager::Finalize() { | ||
| 29 | if (!m_nvnflinger) { | ||
| 30 | return; | ||
| 31 | } | ||
| 32 | |||
| 33 | // Clean up managed layers. | ||
| 34 | for (const auto& layer : m_managed_display_layers) { | ||
| 35 | m_nvnflinger->DestroyLayer(layer); | ||
| 36 | } | ||
| 37 | |||
| 38 | for (const auto& layer : m_managed_display_recording_layers) { | ||
| 39 | m_nvnflinger->DestroyLayer(layer); | ||
| 40 | } | ||
| 41 | |||
| 42 | // Clean up shared layers. | ||
| 43 | if (m_buffer_sharing_enabled) { | ||
| 44 | m_nvnflinger->GetSystemBufferManager().Finalize(m_process); | ||
| 45 | } | ||
| 46 | |||
| 47 | m_nvnflinger = nullptr; | ||
| 48 | } | ||
| 49 | |||
| 50 | Result DisplayLayerManager::CreateManagedDisplayLayer(u64* out_layer) { | ||
| 51 | R_UNLESS(m_nvnflinger != nullptr, VI::ResultOperationFailed); | ||
| 52 | |||
| 53 | // TODO(Subv): Find out how AM determines the display to use, for now just | ||
| 54 | // create the layer in the Default display. | ||
| 55 | const auto display_id = m_nvnflinger->OpenDisplay("Default"); | ||
| 56 | const auto layer_id = m_nvnflinger->CreateLayer(*display_id); | ||
| 57 | |||
| 58 | m_nvnflinger->SetLayerVisibility(*layer_id, m_visible); | ||
| 59 | m_managed_display_layers.emplace(*layer_id); | ||
| 60 | |||
| 61 | *out_layer = *layer_id; | ||
| 62 | |||
| 63 | R_SUCCEED(); | ||
| 64 | } | ||
| 65 | |||
| 66 | Result DisplayLayerManager::CreateManagedDisplaySeparableLayer(u64* out_layer, | ||
| 67 | u64* out_recording_layer) { | ||
| 68 | R_UNLESS(m_nvnflinger != nullptr, VI::ResultOperationFailed); | ||
| 69 | |||
| 70 | // TODO(Subv): Find out how AM determines the display to use, for now just | ||
| 71 | // create the layer in the Default display. | ||
| 72 | // This calls nn::vi::CreateRecordingLayer() which creates another layer. | ||
| 73 | // Currently we do not support more than 1 layer per display, output 1 layer id for now. | ||
| 74 | // Outputting 1 layer id instead of the expected 2 has not been observed to cause any adverse | ||
| 75 | // side effects. | ||
| 76 | // TODO: Support multiple layers | ||
| 77 | const auto display_id = m_nvnflinger->OpenDisplay("Default"); | ||
| 78 | const auto layer_id = m_nvnflinger->CreateLayer(*display_id); | ||
| 79 | |||
| 80 | m_nvnflinger->SetLayerVisibility(*layer_id, m_visible); | ||
| 81 | m_managed_display_layers.emplace(*layer_id); | ||
| 82 | |||
| 83 | *out_layer = *layer_id; | ||
| 84 | *out_recording_layer = 0; | ||
| 85 | |||
| 86 | R_SUCCEED(); | ||
| 87 | } | ||
| 88 | |||
| 89 | Result DisplayLayerManager::IsSystemBufferSharingEnabled() { | ||
| 90 | // Succeed if already enabled. | ||
| 91 | R_SUCCEED_IF(m_buffer_sharing_enabled); | ||
| 92 | |||
| 93 | // Ensure we can access shared layers. | ||
| 94 | R_UNLESS(m_nvnflinger != nullptr, VI::ResultOperationFailed); | ||
| 95 | R_UNLESS(m_applet_id != AppletId::Application, VI::ResultPermissionDenied); | ||
| 96 | |||
| 97 | // Create the shared layer. | ||
| 98 | const auto blend = | ||
| 99 | m_blending_enabled ? Nvnflinger::LayerBlending::Coverage : Nvnflinger::LayerBlending::None; | ||
| 100 | const auto display_id = m_nvnflinger->OpenDisplay("Default").value(); | ||
| 101 | R_TRY(m_nvnflinger->GetSystemBufferManager().Initialize( | ||
| 102 | m_process, &m_system_shared_buffer_id, &m_system_shared_layer_id, display_id, blend)); | ||
| 103 | |||
| 104 | // We succeeded, so set up remaining state. | ||
| 105 | m_buffer_sharing_enabled = true; | ||
| 106 | m_nvnflinger->SetLayerVisibility(m_system_shared_layer_id, m_visible); | ||
| 107 | R_SUCCEED(); | ||
| 108 | } | ||
| 109 | |||
| 110 | Result DisplayLayerManager::GetSystemSharedLayerHandle(u64* out_system_shared_buffer_id, | ||
| 111 | u64* out_system_shared_layer_id) { | ||
| 112 | R_TRY(this->IsSystemBufferSharingEnabled()); | ||
| 113 | |||
| 114 | *out_system_shared_buffer_id = m_system_shared_buffer_id; | ||
| 115 | *out_system_shared_layer_id = m_system_shared_layer_id; | ||
| 116 | |||
| 117 | R_SUCCEED(); | ||
| 118 | } | ||
| 119 | |||
| 120 | void DisplayLayerManager::SetWindowVisibility(bool visible) { | ||
| 121 | if (m_visible == visible) { | ||
| 122 | return; | ||
| 123 | } | ||
| 124 | |||
| 125 | m_visible = visible; | ||
| 126 | |||
| 127 | if (m_nvnflinger) { | ||
| 128 | if (m_system_shared_layer_id) { | ||
| 129 | m_nvnflinger->SetLayerVisibility(m_system_shared_layer_id, m_visible); | ||
| 130 | } | ||
| 131 | |||
| 132 | for (const auto layer_id : m_managed_display_layers) { | ||
| 133 | m_nvnflinger->SetLayerVisibility(layer_id, m_visible); | ||
| 134 | } | ||
| 135 | } | ||
| 136 | } | ||
| 137 | |||
| 138 | bool DisplayLayerManager::GetWindowVisibility() const { | ||
| 139 | return m_visible; | ||
| 140 | } | ||
| 141 | |||
| 142 | Result DisplayLayerManager::WriteAppletCaptureBuffer(bool* out_was_written, | ||
| 143 | s32* out_fbshare_layer_index) { | ||
| 144 | R_UNLESS(m_buffer_sharing_enabled, VI::ResultPermissionDenied); | ||
| 145 | R_RETURN(m_nvnflinger->GetSystemBufferManager().WriteAppletCaptureBuffer( | ||
| 146 | out_was_written, out_fbshare_layer_index)); | ||
| 147 | } | ||
| 148 | |||
| 149 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/display_layer_manager.h b/src/core/hle/service/am/display_layer_manager.h new file mode 100644 index 000000000..45023a88c --- /dev/null +++ b/src/core/hle/service/am/display_layer_manager.h | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <set> | ||
| 7 | |||
| 8 | #include "common/common_types.h" | ||
| 9 | #include "core/hle/result.h" | ||
| 10 | #include "core/hle/service/am/am_types.h" | ||
| 11 | |||
| 12 | namespace Kernel { | ||
| 13 | class KProcess; | ||
| 14 | } | ||
| 15 | |||
| 16 | namespace Service::Nvnflinger { | ||
| 17 | class Nvnflinger; | ||
| 18 | } | ||
| 19 | |||
| 20 | namespace Service::AM { | ||
| 21 | |||
| 22 | class DisplayLayerManager { | ||
| 23 | public: | ||
| 24 | explicit DisplayLayerManager(); | ||
| 25 | ~DisplayLayerManager(); | ||
| 26 | |||
| 27 | void Initialize(Nvnflinger::Nvnflinger* nvnflinger, Kernel::KProcess* process, | ||
| 28 | AppletId applet_id, LibraryAppletMode mode); | ||
| 29 | void Finalize(); | ||
| 30 | |||
| 31 | Result CreateManagedDisplayLayer(u64* out_layer); | ||
| 32 | Result CreateManagedDisplaySeparableLayer(u64* out_layer, u64* out_recording_layer); | ||
| 33 | |||
| 34 | Result IsSystemBufferSharingEnabled(); | ||
| 35 | Result GetSystemSharedLayerHandle(u64* out_system_shared_buffer_id, | ||
| 36 | u64* out_system_shared_layer_id); | ||
| 37 | |||
| 38 | void SetWindowVisibility(bool visible); | ||
| 39 | bool GetWindowVisibility() const; | ||
| 40 | |||
| 41 | Result WriteAppletCaptureBuffer(bool* out_was_written, s32* out_fbshare_layer_index); | ||
| 42 | |||
| 43 | private: | ||
| 44 | Kernel::KProcess* m_process{}; | ||
| 45 | Nvnflinger::Nvnflinger* m_nvnflinger{}; | ||
| 46 | std::set<u64> m_managed_display_layers{}; | ||
| 47 | std::set<u64> m_managed_display_recording_layers{}; | ||
| 48 | u64 m_system_shared_buffer_id{}; | ||
| 49 | u64 m_system_shared_layer_id{}; | ||
| 50 | AppletId m_applet_id{}; | ||
| 51 | bool m_buffer_sharing_enabled{}; | ||
| 52 | bool m_blending_enabled{}; | ||
| 53 | bool m_visible{true}; | ||
| 54 | }; | ||
| 55 | |||
| 56 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/managed_layer_holder.cpp b/src/core/hle/service/am/managed_layer_holder.cpp deleted file mode 100644 index 61eb8641a..000000000 --- a/src/core/hle/service/am/managed_layer_holder.cpp +++ /dev/null | |||
| @@ -1,59 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/managed_layer_holder.h" | ||
| 5 | #include "core/hle/service/nvnflinger/nvnflinger.h" | ||
| 6 | |||
| 7 | namespace Service::AM { | ||
| 8 | |||
| 9 | ManagedLayerHolder::ManagedLayerHolder() = default; | ||
| 10 | ManagedLayerHolder::~ManagedLayerHolder() { | ||
| 11 | if (!m_nvnflinger) { | ||
| 12 | return; | ||
| 13 | } | ||
| 14 | |||
| 15 | for (const auto& layer : m_managed_display_layers) { | ||
| 16 | m_nvnflinger->DestroyLayer(layer); | ||
| 17 | } | ||
| 18 | |||
| 19 | for (const auto& layer : m_managed_display_recording_layers) { | ||
| 20 | m_nvnflinger->DestroyLayer(layer); | ||
| 21 | } | ||
| 22 | |||
| 23 | m_nvnflinger = nullptr; | ||
| 24 | } | ||
| 25 | |||
| 26 | void ManagedLayerHolder::Initialize(Nvnflinger::Nvnflinger* nvnflinger) { | ||
| 27 | m_nvnflinger = nvnflinger; | ||
| 28 | } | ||
| 29 | |||
| 30 | void ManagedLayerHolder::CreateManagedDisplayLayer(u64* out_layer) { | ||
| 31 | // TODO(Subv): Find out how AM determines the display to use, for now just | ||
| 32 | // create the layer in the Default display. | ||
| 33 | const auto display_id = m_nvnflinger->OpenDisplay("Default"); | ||
| 34 | const auto layer_id = m_nvnflinger->CreateLayer(*display_id); | ||
| 35 | |||
| 36 | m_managed_display_layers.emplace(*layer_id); | ||
| 37 | |||
| 38 | *out_layer = *layer_id; | ||
| 39 | } | ||
| 40 | |||
| 41 | void ManagedLayerHolder::CreateManagedDisplaySeparableLayer(u64* out_layer, | ||
| 42 | u64* out_recording_layer) { | ||
| 43 | // TODO(Subv): Find out how AM determines the display to use, for now just | ||
| 44 | // create the layer in the Default display. | ||
| 45 | // This calls nn::vi::CreateRecordingLayer() which creates another layer. | ||
| 46 | // Currently we do not support more than 1 layer per display, output 1 layer id for now. | ||
| 47 | // Outputting 1 layer id instead of the expected 2 has not been observed to cause any adverse | ||
| 48 | // side effects. | ||
| 49 | // TODO: Support multiple layers | ||
| 50 | const auto display_id = m_nvnflinger->OpenDisplay("Default"); | ||
| 51 | const auto layer_id = m_nvnflinger->CreateLayer(*display_id); | ||
| 52 | |||
| 53 | m_managed_display_layers.emplace(*layer_id); | ||
| 54 | |||
| 55 | *out_layer = *layer_id; | ||
| 56 | *out_recording_layer = 0; | ||
| 57 | } | ||
| 58 | |||
| 59 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/managed_layer_holder.h b/src/core/hle/service/am/managed_layer_holder.h deleted file mode 100644 index f7fe03f24..000000000 --- a/src/core/hle/service/am/managed_layer_holder.h +++ /dev/null | |||
| @@ -1,32 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <set> | ||
| 7 | |||
| 8 | #include "common/common_funcs.h" | ||
| 9 | #include "common/common_types.h" | ||
| 10 | |||
| 11 | namespace Service::Nvnflinger { | ||
| 12 | class Nvnflinger; | ||
| 13 | } | ||
| 14 | |||
| 15 | namespace Service::AM { | ||
| 16 | |||
| 17 | class ManagedLayerHolder { | ||
| 18 | public: | ||
| 19 | ManagedLayerHolder(); | ||
| 20 | ~ManagedLayerHolder(); | ||
| 21 | |||
| 22 | void Initialize(Nvnflinger::Nvnflinger* nvnflinger); | ||
| 23 | void CreateManagedDisplayLayer(u64* out_layer); | ||
| 24 | void CreateManagedDisplaySeparableLayer(u64* out_layer, u64* out_recording_layer); | ||
| 25 | |||
| 26 | private: | ||
| 27 | Nvnflinger::Nvnflinger* m_nvnflinger{}; | ||
| 28 | std::set<u64> m_managed_display_layers{}; | ||
| 29 | std::set<u64> m_managed_display_recording_layers{}; | ||
| 30 | }; | ||
| 31 | |||
| 32 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/display_controller.cpp b/src/core/hle/service/am/service/display_controller.cpp index 249c73dfb..ed71f9093 100644 --- a/src/core/hle/service/am/service/display_controller.cpp +++ b/src/core/hle/service/am/service/display_controller.cpp | |||
| @@ -69,7 +69,7 @@ Result IDisplayController::ClearCaptureBuffer(bool unknown0, s32 fbshare_layer_i | |||
| 69 | Result IDisplayController::AcquireLastForegroundCaptureSharedBuffer( | 69 | Result IDisplayController::AcquireLastForegroundCaptureSharedBuffer( |
| 70 | Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) { | 70 | Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) { |
| 71 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 71 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 72 | R_RETURN(applet->system_buffer_manager.WriteAppletCaptureBuffer(out_was_written, | 72 | R_RETURN(applet->display_layer_manager.WriteAppletCaptureBuffer(out_was_written, |
| 73 | out_fbshare_layer_index)); | 73 | out_fbshare_layer_index)); |
| 74 | } | 74 | } |
| 75 | 75 | ||
| @@ -81,7 +81,7 @@ Result IDisplayController::ReleaseLastForegroundCaptureSharedBuffer() { | |||
| 81 | Result IDisplayController::AcquireCallerAppletCaptureSharedBuffer( | 81 | Result IDisplayController::AcquireCallerAppletCaptureSharedBuffer( |
| 82 | Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) { | 82 | Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) { |
| 83 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 83 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 84 | R_RETURN(applet->system_buffer_manager.WriteAppletCaptureBuffer(out_was_written, | 84 | R_RETURN(applet->display_layer_manager.WriteAppletCaptureBuffer(out_was_written, |
| 85 | out_fbshare_layer_index)); | 85 | out_fbshare_layer_index)); |
| 86 | } | 86 | } |
| 87 | 87 | ||
| @@ -93,7 +93,7 @@ Result IDisplayController::ReleaseCallerAppletCaptureSharedBuffer() { | |||
| 93 | Result IDisplayController::AcquireLastApplicationCaptureSharedBuffer( | 93 | Result IDisplayController::AcquireLastApplicationCaptureSharedBuffer( |
| 94 | Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) { | 94 | Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) { |
| 95 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 95 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 96 | R_RETURN(applet->system_buffer_manager.WriteAppletCaptureBuffer(out_was_written, | 96 | R_RETURN(applet->display_layer_manager.WriteAppletCaptureBuffer(out_was_written, |
| 97 | out_fbshare_layer_index)); | 97 | out_fbshare_layer_index)); |
| 98 | } | 98 | } |
| 99 | 99 | ||
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 166637d60..c97358d81 100644 --- a/src/core/hle/service/am/service/library_applet_creator.cpp +++ b/src/core/hle/service/am/service/library_applet_creator.cpp | |||
| @@ -135,7 +135,7 @@ std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system, | |||
| 135 | case LibraryAppletMode::AllForegroundInitiallyHidden: | 135 | case LibraryAppletMode::AllForegroundInitiallyHidden: |
| 136 | applet->hid_registration.EnableAppletToGetInput(false); | 136 | applet->hid_registration.EnableAppletToGetInput(false); |
| 137 | applet->focus_state = FocusState::NotInFocus; | 137 | applet->focus_state = FocusState::NotInFocus; |
| 138 | applet->system_buffer_manager.SetWindowVisibility(false); | 138 | applet->display_layer_manager.SetWindowVisibility(false); |
| 139 | applet->message_queue.PushMessage(AppletMessage::ChangeIntoBackground); | 139 | applet->message_queue.PushMessage(AppletMessage::ChangeIntoBackground); |
| 140 | break; | 140 | break; |
| 141 | } | 141 | } |
diff --git a/src/core/hle/service/am/service/self_controller.cpp b/src/core/hle/service/am/service/self_controller.cpp index 5c4c13de1..6b77e423a 100644 --- a/src/core/hle/service/am/service/self_controller.cpp +++ b/src/core/hle/service/am/service/self_controller.cpp | |||
| @@ -16,8 +16,8 @@ namespace Service::AM { | |||
| 16 | 16 | ||
| 17 | ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet> applet, | 17 | ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet> applet, |
| 18 | Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger) | 18 | Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger) |
| 19 | : ServiceFramework{system_, "ISelfController"}, | 19 | : ServiceFramework{system_, "ISelfController"}, m_nvnflinger{nvnflinger}, m_process{process}, |
| 20 | m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} { | 20 | m_applet{std::move(applet)} { |
| 21 | // clang-format off | 21 | // clang-format off |
| 22 | static const FunctionInfo functions[] = { | 22 | static const FunctionInfo functions[] = { |
| 23 | {0, D<&ISelfController::Exit>, "Exit"}, | 23 | {0, D<&ISelfController::Exit>, "Exit"}, |
| @@ -72,9 +72,16 @@ ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet> | |||
| 72 | // clang-format on | 72 | // clang-format on |
| 73 | 73 | ||
| 74 | RegisterHandlers(functions); | 74 | RegisterHandlers(functions); |
| 75 | |||
| 76 | std::scoped_lock lk{m_applet->lock}; | ||
| 77 | m_applet->display_layer_manager.Initialize(&m_nvnflinger, m_process, m_applet->applet_id, | ||
| 78 | m_applet->library_applet_mode); | ||
| 75 | } | 79 | } |
| 76 | 80 | ||
| 77 | ISelfController::~ISelfController() = default; | 81 | ISelfController::~ISelfController() { |
| 82 | std::scoped_lock lk{m_applet->lock}; | ||
| 83 | m_applet->display_layer_manager.Finalize(); | ||
| 84 | } | ||
| 78 | 85 | ||
| 79 | Result ISelfController::Exit() { | 86 | Result ISelfController::Exit() { |
| 80 | LOG_DEBUG(Service_AM, "called"); | 87 | LOG_DEBUG(Service_AM, "called"); |
| @@ -212,48 +219,42 @@ Result ISelfController::SetAlbumImageOrientation( | |||
| 212 | 219 | ||
| 213 | Result ISelfController::IsSystemBufferSharingEnabled() { | 220 | Result ISelfController::IsSystemBufferSharingEnabled() { |
| 214 | LOG_INFO(Service_AM, "called"); | 221 | LOG_INFO(Service_AM, "called"); |
| 215 | R_SUCCEED_IF(m_applet->system_buffer_manager.Initialize( | 222 | |
| 216 | &m_nvnflinger, m_process, m_applet->applet_id, m_applet->library_applet_mode)); | 223 | std::scoped_lock lk{m_applet->lock}; |
| 217 | R_THROW(VI::ResultOperationFailed); | 224 | R_RETURN(m_applet->display_layer_manager.IsSystemBufferSharingEnabled()); |
| 218 | } | 225 | } |
| 219 | 226 | ||
| 220 | Result ISelfController::GetSystemSharedBufferHandle(Out<u64> out_buffer_id) { | 227 | Result ISelfController::GetSystemSharedBufferHandle(Out<u64> out_buffer_id) { |
| 221 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 228 | LOG_INFO(Service_AM, "called"); |
| 222 | |||
| 223 | R_TRY(this->IsSystemBufferSharingEnabled()); | ||
| 224 | 229 | ||
| 225 | u64 layer_id; | 230 | u64 layer_id; |
| 226 | m_applet->system_buffer_manager.GetSystemSharedLayerHandle(out_buffer_id, &layer_id); | 231 | |
| 227 | R_SUCCEED(); | 232 | std::scoped_lock lk{m_applet->lock}; |
| 233 | R_RETURN(m_applet->display_layer_manager.GetSystemSharedLayerHandle(out_buffer_id, &layer_id)); | ||
| 228 | } | 234 | } |
| 229 | 235 | ||
| 230 | Result ISelfController::GetSystemSharedLayerHandle(Out<u64> out_buffer_id, Out<u64> out_layer_id) { | 236 | Result ISelfController::GetSystemSharedLayerHandle(Out<u64> out_buffer_id, Out<u64> out_layer_id) { |
| 231 | LOG_INFO(Service_AM, "(STUBBED) called"); | 237 | LOG_INFO(Service_AM, "called"); |
| 232 | |||
| 233 | R_TRY(this->IsSystemBufferSharingEnabled()); | ||
| 234 | 238 | ||
| 235 | m_applet->system_buffer_manager.GetSystemSharedLayerHandle(out_buffer_id, out_layer_id); | 239 | std::scoped_lock lk{m_applet->lock}; |
| 236 | R_SUCCEED(); | 240 | R_RETURN( |
| 241 | m_applet->display_layer_manager.GetSystemSharedLayerHandle(out_buffer_id, out_layer_id)); | ||
| 237 | } | 242 | } |
| 238 | 243 | ||
| 239 | Result ISelfController::CreateManagedDisplayLayer(Out<u64> out_layer_id) { | 244 | Result ISelfController::CreateManagedDisplayLayer(Out<u64> out_layer_id) { |
| 240 | LOG_INFO(Service_AM, "called"); | 245 | LOG_INFO(Service_AM, "called"); |
| 241 | 246 | ||
| 242 | m_applet->managed_layer_holder.Initialize(&m_nvnflinger); | 247 | std::scoped_lock lk{m_applet->lock}; |
| 243 | m_applet->managed_layer_holder.CreateManagedDisplayLayer(out_layer_id); | 248 | R_RETURN(m_applet->display_layer_manager.CreateManagedDisplayLayer(out_layer_id)); |
| 244 | |||
| 245 | R_SUCCEED(); | ||
| 246 | } | 249 | } |
| 247 | 250 | ||
| 248 | Result ISelfController::CreateManagedDisplaySeparableLayer(Out<u64> out_layer_id, | 251 | Result ISelfController::CreateManagedDisplaySeparableLayer(Out<u64> out_layer_id, |
| 249 | Out<u64> out_recording_layer_id) { | 252 | Out<u64> out_recording_layer_id) { |
| 250 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 253 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 251 | 254 | ||
| 252 | m_applet->managed_layer_holder.Initialize(&m_nvnflinger); | 255 | std::scoped_lock lk{m_applet->lock}; |
| 253 | m_applet->managed_layer_holder.CreateManagedDisplaySeparableLayer(out_layer_id, | 256 | R_RETURN(m_applet->display_layer_manager.CreateManagedDisplaySeparableLayer( |
| 254 | out_recording_layer_id); | 257 | out_layer_id, out_recording_layer_id)); |
| 255 | |||
| 256 | R_SUCCEED(); | ||
| 257 | } | 258 | } |
| 258 | 259 | ||
| 259 | Result ISelfController::SetHandlesRequestToDisplay(bool enable) { | 260 | Result ISelfController::SetHandlesRequestToDisplay(bool enable) { |
diff --git a/src/core/hle/service/am/service/window_controller.cpp b/src/core/hle/service/am/service/window_controller.cpp index b874ecb91..99a4f50a2 100644 --- a/src/core/hle/service/am/service/window_controller.cpp +++ b/src/core/hle/service/am/service/window_controller.cpp | |||
| @@ -63,7 +63,7 @@ Result IWindowController::RejectToChangeIntoBackground() { | |||
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | Result IWindowController::SetAppletWindowVisibility(bool visible) { | 65 | Result IWindowController::SetAppletWindowVisibility(bool visible) { |
| 66 | m_applet->system_buffer_manager.SetWindowVisibility(visible); | 66 | m_applet->display_layer_manager.SetWindowVisibility(visible); |
| 67 | m_applet->hid_registration.EnableAppletToGetInput(visible); | 67 | m_applet->hid_registration.EnableAppletToGetInput(visible); |
| 68 | 68 | ||
| 69 | if (visible) { | 69 | if (visible) { |
diff --git a/src/core/hle/service/am/system_buffer_manager.cpp b/src/core/hle/service/am/system_buffer_manager.cpp deleted file mode 100644 index 48923fe41..000000000 --- a/src/core/hle/service/am/system_buffer_manager.cpp +++ /dev/null | |||
| @@ -1,80 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/system_buffer_manager.h" | ||
| 5 | #include "core/hle/service/nvnflinger/fb_share_buffer_manager.h" | ||
| 6 | #include "core/hle/service/nvnflinger/nvnflinger.h" | ||
| 7 | #include "core/hle/service/vi/vi_results.h" | ||
| 8 | |||
| 9 | namespace Service::AM { | ||
| 10 | |||
| 11 | SystemBufferManager::SystemBufferManager() = default; | ||
| 12 | |||
| 13 | SystemBufferManager::~SystemBufferManager() { | ||
| 14 | if (!m_nvnflinger) { | ||
| 15 | return; | ||
| 16 | } | ||
| 17 | |||
| 18 | // Clean up shared layers. | ||
| 19 | if (m_buffer_sharing_enabled) { | ||
| 20 | m_nvnflinger->GetSystemBufferManager().Finalize(m_process); | ||
| 21 | } | ||
| 22 | } | ||
| 23 | |||
| 24 | bool SystemBufferManager::Initialize(Nvnflinger::Nvnflinger* nvnflinger, Kernel::KProcess* process, | ||
| 25 | AppletId applet_id, LibraryAppletMode mode) { | ||
| 26 | if (m_nvnflinger) { | ||
| 27 | return m_buffer_sharing_enabled; | ||
| 28 | } | ||
| 29 | |||
| 30 | m_process = process; | ||
| 31 | m_nvnflinger = nvnflinger; | ||
| 32 | m_buffer_sharing_enabled = false; | ||
| 33 | m_system_shared_buffer_id = 0; | ||
| 34 | m_system_shared_layer_id = 0; | ||
| 35 | |||
| 36 | if (applet_id <= AppletId::Application) { | ||
| 37 | return false; | ||
| 38 | } | ||
| 39 | |||
| 40 | Nvnflinger::LayerBlending blending = Nvnflinger::LayerBlending::None; | ||
| 41 | if (mode == LibraryAppletMode::PartialForeground || | ||
| 42 | mode == LibraryAppletMode::PartialForegroundIndirectDisplay) { | ||
| 43 | blending = Nvnflinger::LayerBlending::Coverage; | ||
| 44 | } | ||
| 45 | |||
| 46 | const auto display_id = m_nvnflinger->OpenDisplay("Default").value(); | ||
| 47 | const auto res = m_nvnflinger->GetSystemBufferManager().Initialize( | ||
| 48 | m_process, &m_system_shared_buffer_id, &m_system_shared_layer_id, display_id, blending); | ||
| 49 | |||
| 50 | if (res.IsSuccess()) { | ||
| 51 | m_buffer_sharing_enabled = true; | ||
| 52 | m_nvnflinger->SetLayerVisibility(m_system_shared_layer_id, m_visible); | ||
| 53 | } | ||
| 54 | |||
| 55 | return m_buffer_sharing_enabled; | ||
| 56 | } | ||
| 57 | |||
| 58 | void SystemBufferManager::SetWindowVisibility(bool visible) { | ||
| 59 | if (m_visible == visible) { | ||
| 60 | return; | ||
| 61 | } | ||
| 62 | |||
| 63 | m_visible = visible; | ||
| 64 | |||
| 65 | if (m_nvnflinger) { | ||
| 66 | m_nvnflinger->SetLayerVisibility(m_system_shared_layer_id, m_visible); | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | Result SystemBufferManager::WriteAppletCaptureBuffer(bool* out_was_written, | ||
| 71 | s32* out_fbshare_layer_index) { | ||
| 72 | if (!m_buffer_sharing_enabled) { | ||
| 73 | return VI::ResultPermissionDenied; | ||
| 74 | } | ||
| 75 | |||
| 76 | return m_nvnflinger->GetSystemBufferManager().WriteAppletCaptureBuffer(out_was_written, | ||
| 77 | out_fbshare_layer_index); | ||
| 78 | } | ||
| 79 | |||
| 80 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/system_buffer_manager.h b/src/core/hle/service/am/system_buffer_manager.h deleted file mode 100644 index 0690f68b6..000000000 --- a/src/core/hle/service/am/system_buffer_manager.h +++ /dev/null | |||
| @@ -1,52 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <set> | ||
| 7 | |||
| 8 | #include "common/common_funcs.h" | ||
| 9 | #include "common/common_types.h" | ||
| 10 | |||
| 11 | #include "core/hle/service/am/am_types.h" | ||
| 12 | |||
| 13 | namespace Kernel { | ||
| 14 | class KProcess; | ||
| 15 | } | ||
| 16 | |||
| 17 | namespace Service::Nvnflinger { | ||
| 18 | class Nvnflinger; | ||
| 19 | } | ||
| 20 | |||
| 21 | union Result; | ||
| 22 | |||
| 23 | namespace Service::AM { | ||
| 24 | |||
| 25 | class SystemBufferManager { | ||
| 26 | public: | ||
| 27 | SystemBufferManager(); | ||
| 28 | ~SystemBufferManager(); | ||
| 29 | |||
| 30 | bool Initialize(Nvnflinger::Nvnflinger* flinger, Kernel::KProcess* process, AppletId applet_id, | ||
| 31 | LibraryAppletMode mode); | ||
| 32 | |||
| 33 | void GetSystemSharedLayerHandle(u64* out_system_shared_buffer_id, | ||
| 34 | u64* out_system_shared_layer_id) { | ||
| 35 | *out_system_shared_buffer_id = m_system_shared_buffer_id; | ||
| 36 | *out_system_shared_layer_id = m_system_shared_layer_id; | ||
| 37 | } | ||
| 38 | |||
| 39 | void SetWindowVisibility(bool visible); | ||
| 40 | |||
| 41 | Result WriteAppletCaptureBuffer(bool* out_was_written, s32* out_fbshare_layer_index); | ||
| 42 | |||
| 43 | private: | ||
| 44 | Kernel::KProcess* m_process{}; | ||
| 45 | Nvnflinger::Nvnflinger* m_nvnflinger{}; | ||
| 46 | bool m_buffer_sharing_enabled{}; | ||
| 47 | bool m_visible{true}; | ||
| 48 | u64 m_system_shared_buffer_id{}; | ||
| 49 | u64 m_system_shared_layer_id{}; | ||
| 50 | }; | ||
| 51 | |||
| 52 | } // namespace Service::AM | ||