am: unify display layer management
This commit is contained in:
parent
53f8383354
commit
7b79cddacd
12 changed files with 240 additions and 261 deletions
|
@ -423,12 +423,12 @@ add_library(core STATIC
|
||||||
hle/service/am/applet_manager.h
|
hle/service/am/applet_manager.h
|
||||||
hle/service/am/applet_message_queue.cpp
|
hle/service/am/applet_message_queue.cpp
|
||||||
hle/service/am/applet_message_queue.h
|
hle/service/am/applet_message_queue.h
|
||||||
|
hle/service/am/display_layer_manager.cpp
|
||||||
|
hle/service/am/display_layer_manager.h
|
||||||
hle/service/am/hid_registration.cpp
|
hle/service/am/hid_registration.cpp
|
||||||
hle/service/am/hid_registration.h
|
hle/service/am/hid_registration.h
|
||||||
hle/service/am/library_applet_storage.cpp
|
hle/service/am/library_applet_storage.cpp
|
||||||
hle/service/am/library_applet_storage.h
|
hle/service/am/library_applet_storage.h
|
||||||
hle/service/am/managed_layer_holder.cpp
|
|
||||||
hle/service/am/managed_layer_holder.h
|
|
||||||
hle/service/am/process.cpp
|
hle/service/am/process.cpp
|
||||||
hle/service/am/process.h
|
hle/service/am/process.h
|
||||||
hle/service/am/service/all_system_applet_proxies_service.cpp
|
hle/service/am/service/all_system_applet_proxies_service.cpp
|
||||||
|
@ -481,8 +481,6 @@ add_library(core STATIC
|
||||||
hle/service/am/service/system_applet_proxy.h
|
hle/service/am/service/system_applet_proxy.h
|
||||||
hle/service/am/service/window_controller.cpp
|
hle/service/am/service/window_controller.cpp
|
||||||
hle/service/am/service/window_controller.h
|
hle/service/am/service/window_controller.h
|
||||||
hle/service/am/system_buffer_manager.cpp
|
|
||||||
hle/service/am/system_buffer_manager.h
|
|
||||||
hle/service/aoc/aoc_u.cpp
|
hle/service/aoc/aoc_u.cpp
|
||||||
hle/service/aoc/aoc_u.h
|
hle/service/aoc/aoc_u.h
|
||||||
hle/service/apm/apm.cpp
|
hle/service/apm/apm.cpp
|
||||||
|
|
|
@ -14,10 +14,9 @@
|
||||||
|
|
||||||
#include "core/hle/service/am/am_types.h"
|
#include "core/hle/service/am/am_types.h"
|
||||||
#include "core/hle/service/am/applet_message_queue.h"
|
#include "core/hle/service/am/applet_message_queue.h"
|
||||||
|
#include "core/hle/service/am/display_layer_manager.h"
|
||||||
#include "core/hle/service/am/hid_registration.h"
|
#include "core/hle/service/am/hid_registration.h"
|
||||||
#include "core/hle/service/am/managed_layer_holder.h"
|
|
||||||
#include "core/hle/service/am/process.h"
|
#include "core/hle/service/am/process.h"
|
||||||
#include "core/hle/service/am/system_buffer_manager.h"
|
|
||||||
|
|
||||||
namespace Service::AM {
|
namespace Service::AM {
|
||||||
|
|
||||||
|
@ -54,8 +53,7 @@ struct Applet {
|
||||||
HidRegistration hid_registration;
|
HidRegistration hid_registration;
|
||||||
|
|
||||||
// vi state
|
// vi state
|
||||||
SystemBufferManager system_buffer_manager{};
|
DisplayLayerManager display_layer_manager{};
|
||||||
ManagedLayerHolder managed_layer_holder{};
|
|
||||||
|
|
||||||
// Applet common functions
|
// Applet common functions
|
||||||
Result terminate_result{};
|
Result terminate_result{};
|
||||||
|
|
149
src/core/hle/service/am/display_layer_manager.cpp
Normal file
149
src/core/hle/service/am/display_layer_manager.cpp
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "core/hle/service/am/display_layer_manager.h"
|
||||||
|
#include "core/hle/service/nvnflinger/fb_share_buffer_manager.h"
|
||||||
|
#include "core/hle/service/nvnflinger/nvnflinger.h"
|
||||||
|
#include "core/hle/service/vi/vi_results.h"
|
||||||
|
|
||||||
|
namespace Service::AM {
|
||||||
|
|
||||||
|
DisplayLayerManager::DisplayLayerManager() = default;
|
||||||
|
DisplayLayerManager::~DisplayLayerManager() {
|
||||||
|
this->Finalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayLayerManager::Initialize(Nvnflinger::Nvnflinger* nvnflinger, Kernel::KProcess* process,
|
||||||
|
AppletId applet_id, LibraryAppletMode mode) {
|
||||||
|
m_process = process;
|
||||||
|
m_nvnflinger = nvnflinger;
|
||||||
|
m_system_shared_buffer_id = 0;
|
||||||
|
m_system_shared_layer_id = 0;
|
||||||
|
m_applet_id = applet_id;
|
||||||
|
m_buffer_sharing_enabled = false;
|
||||||
|
m_blending_enabled = mode == LibraryAppletMode::PartialForeground ||
|
||||||
|
mode == LibraryAppletMode::PartialForegroundIndirectDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayLayerManager::Finalize() {
|
||||||
|
if (!m_nvnflinger) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up managed layers.
|
||||||
|
for (const auto& layer : m_managed_display_layers) {
|
||||||
|
m_nvnflinger->DestroyLayer(layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& layer : m_managed_display_recording_layers) {
|
||||||
|
m_nvnflinger->DestroyLayer(layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up shared layers.
|
||||||
|
if (m_buffer_sharing_enabled) {
|
||||||
|
m_nvnflinger->GetSystemBufferManager().Finalize(m_process);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_nvnflinger = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result DisplayLayerManager::CreateManagedDisplayLayer(u64* out_layer) {
|
||||||
|
R_UNLESS(m_nvnflinger != nullptr, VI::ResultOperationFailed);
|
||||||
|
|
||||||
|
// TODO(Subv): Find out how AM determines the display to use, for now just
|
||||||
|
// create the layer in the Default display.
|
||||||
|
const auto display_id = m_nvnflinger->OpenDisplay("Default");
|
||||||
|
const auto layer_id = m_nvnflinger->CreateLayer(*display_id);
|
||||||
|
|
||||||
|
m_nvnflinger->SetLayerVisibility(*layer_id, m_visible);
|
||||||
|
m_managed_display_layers.emplace(*layer_id);
|
||||||
|
|
||||||
|
*out_layer = *layer_id;
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result DisplayLayerManager::CreateManagedDisplaySeparableLayer(u64* out_layer,
|
||||||
|
u64* out_recording_layer) {
|
||||||
|
R_UNLESS(m_nvnflinger != nullptr, VI::ResultOperationFailed);
|
||||||
|
|
||||||
|
// TODO(Subv): Find out how AM determines the display to use, for now just
|
||||||
|
// create the layer in the Default display.
|
||||||
|
// This calls nn::vi::CreateRecordingLayer() which creates another layer.
|
||||||
|
// Currently we do not support more than 1 layer per display, output 1 layer id for now.
|
||||||
|
// Outputting 1 layer id instead of the expected 2 has not been observed to cause any adverse
|
||||||
|
// side effects.
|
||||||
|
// TODO: Support multiple layers
|
||||||
|
const auto display_id = m_nvnflinger->OpenDisplay("Default");
|
||||||
|
const auto layer_id = m_nvnflinger->CreateLayer(*display_id);
|
||||||
|
|
||||||
|
m_nvnflinger->SetLayerVisibility(*layer_id, m_visible);
|
||||||
|
m_managed_display_layers.emplace(*layer_id);
|
||||||
|
|
||||||
|
*out_layer = *layer_id;
|
||||||
|
*out_recording_layer = 0;
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result DisplayLayerManager::IsSystemBufferSharingEnabled() {
|
||||||
|
// Succeed if already enabled.
|
||||||
|
R_SUCCEED_IF(m_buffer_sharing_enabled);
|
||||||
|
|
||||||
|
// Ensure we can access shared layers.
|
||||||
|
R_UNLESS(m_nvnflinger != nullptr, VI::ResultOperationFailed);
|
||||||
|
R_UNLESS(m_applet_id != AppletId::Application, VI::ResultPermissionDenied);
|
||||||
|
|
||||||
|
// Create the shared layer.
|
||||||
|
const auto blend =
|
||||||
|
m_blending_enabled ? Nvnflinger::LayerBlending::Coverage : Nvnflinger::LayerBlending::None;
|
||||||
|
const auto display_id = m_nvnflinger->OpenDisplay("Default").value();
|
||||||
|
R_TRY(m_nvnflinger->GetSystemBufferManager().Initialize(
|
||||||
|
m_process, &m_system_shared_buffer_id, &m_system_shared_layer_id, display_id, blend));
|
||||||
|
|
||||||
|
// We succeeded, so set up remaining state.
|
||||||
|
m_buffer_sharing_enabled = true;
|
||||||
|
m_nvnflinger->SetLayerVisibility(m_system_shared_layer_id, m_visible);
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result DisplayLayerManager::GetSystemSharedLayerHandle(u64* out_system_shared_buffer_id,
|
||||||
|
u64* out_system_shared_layer_id) {
|
||||||
|
R_TRY(this->IsSystemBufferSharingEnabled());
|
||||||
|
|
||||||
|
*out_system_shared_buffer_id = m_system_shared_buffer_id;
|
||||||
|
*out_system_shared_layer_id = m_system_shared_layer_id;
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayLayerManager::SetWindowVisibility(bool visible) {
|
||||||
|
if (m_visible == visible) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_visible = visible;
|
||||||
|
|
||||||
|
if (m_nvnflinger) {
|
||||||
|
if (m_system_shared_layer_id) {
|
||||||
|
m_nvnflinger->SetLayerVisibility(m_system_shared_layer_id, m_visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto layer_id : m_managed_display_layers) {
|
||||||
|
m_nvnflinger->SetLayerVisibility(layer_id, m_visible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DisplayLayerManager::GetWindowVisibility() const {
|
||||||
|
return m_visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result DisplayLayerManager::WriteAppletCaptureBuffer(bool* out_was_written,
|
||||||
|
s32* out_fbshare_layer_index) {
|
||||||
|
R_UNLESS(m_buffer_sharing_enabled, VI::ResultPermissionDenied);
|
||||||
|
R_RETURN(m_nvnflinger->GetSystemBufferManager().WriteAppletCaptureBuffer(
|
||||||
|
out_was_written, out_fbshare_layer_index));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Service::AM
|
56
src/core/hle/service/am/display_layer_manager.h
Normal file
56
src/core/hle/service/am/display_layer_manager.h
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include "common/common_types.h"
|
||||||
|
#include "core/hle/result.h"
|
||||||
|
#include "core/hle/service/am/am_types.h"
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
class KProcess;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Service::Nvnflinger {
|
||||||
|
class Nvnflinger;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Service::AM {
|
||||||
|
|
||||||
|
class DisplayLayerManager {
|
||||||
|
public:
|
||||||
|
explicit DisplayLayerManager();
|
||||||
|
~DisplayLayerManager();
|
||||||
|
|
||||||
|
void Initialize(Nvnflinger::Nvnflinger* nvnflinger, Kernel::KProcess* process,
|
||||||
|
AppletId applet_id, LibraryAppletMode mode);
|
||||||
|
void Finalize();
|
||||||
|
|
||||||
|
Result CreateManagedDisplayLayer(u64* out_layer);
|
||||||
|
Result CreateManagedDisplaySeparableLayer(u64* out_layer, u64* out_recording_layer);
|
||||||
|
|
||||||
|
Result IsSystemBufferSharingEnabled();
|
||||||
|
Result GetSystemSharedLayerHandle(u64* out_system_shared_buffer_id,
|
||||||
|
u64* out_system_shared_layer_id);
|
||||||
|
|
||||||
|
void SetWindowVisibility(bool visible);
|
||||||
|
bool GetWindowVisibility() const;
|
||||||
|
|
||||||
|
Result WriteAppletCaptureBuffer(bool* out_was_written, s32* out_fbshare_layer_index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Kernel::KProcess* m_process{};
|
||||||
|
Nvnflinger::Nvnflinger* m_nvnflinger{};
|
||||||
|
std::set<u64> m_managed_display_layers{};
|
||||||
|
std::set<u64> m_managed_display_recording_layers{};
|
||||||
|
u64 m_system_shared_buffer_id{};
|
||||||
|
u64 m_system_shared_layer_id{};
|
||||||
|
AppletId m_applet_id{};
|
||||||
|
bool m_buffer_sharing_enabled{};
|
||||||
|
bool m_blending_enabled{};
|
||||||
|
bool m_visible{true};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Service::AM
|
|
@ -1,59 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include "core/hle/service/am/managed_layer_holder.h"
|
|
||||||
#include "core/hle/service/nvnflinger/nvnflinger.h"
|
|
||||||
|
|
||||||
namespace Service::AM {
|
|
||||||
|
|
||||||
ManagedLayerHolder::ManagedLayerHolder() = default;
|
|
||||||
ManagedLayerHolder::~ManagedLayerHolder() {
|
|
||||||
if (!m_nvnflinger) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& layer : m_managed_display_layers) {
|
|
||||||
m_nvnflinger->DestroyLayer(layer);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& layer : m_managed_display_recording_layers) {
|
|
||||||
m_nvnflinger->DestroyLayer(layer);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_nvnflinger = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ManagedLayerHolder::Initialize(Nvnflinger::Nvnflinger* nvnflinger) {
|
|
||||||
m_nvnflinger = nvnflinger;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ManagedLayerHolder::CreateManagedDisplayLayer(u64* out_layer) {
|
|
||||||
// TODO(Subv): Find out how AM determines the display to use, for now just
|
|
||||||
// create the layer in the Default display.
|
|
||||||
const auto display_id = m_nvnflinger->OpenDisplay("Default");
|
|
||||||
const auto layer_id = m_nvnflinger->CreateLayer(*display_id);
|
|
||||||
|
|
||||||
m_managed_display_layers.emplace(*layer_id);
|
|
||||||
|
|
||||||
*out_layer = *layer_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ManagedLayerHolder::CreateManagedDisplaySeparableLayer(u64* out_layer,
|
|
||||||
u64* out_recording_layer) {
|
|
||||||
// TODO(Subv): Find out how AM determines the display to use, for now just
|
|
||||||
// create the layer in the Default display.
|
|
||||||
// This calls nn::vi::CreateRecordingLayer() which creates another layer.
|
|
||||||
// Currently we do not support more than 1 layer per display, output 1 layer id for now.
|
|
||||||
// Outputting 1 layer id instead of the expected 2 has not been observed to cause any adverse
|
|
||||||
// side effects.
|
|
||||||
// TODO: Support multiple layers
|
|
||||||
const auto display_id = m_nvnflinger->OpenDisplay("Default");
|
|
||||||
const auto layer_id = m_nvnflinger->CreateLayer(*display_id);
|
|
||||||
|
|
||||||
m_managed_display_layers.emplace(*layer_id);
|
|
||||||
|
|
||||||
*out_layer = *layer_id;
|
|
||||||
*out_recording_layer = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Service::AM
|
|
|
@ -1,32 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
#include "common/common_funcs.h"
|
|
||||||
#include "common/common_types.h"
|
|
||||||
|
|
||||||
namespace Service::Nvnflinger {
|
|
||||||
class Nvnflinger;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Service::AM {
|
|
||||||
|
|
||||||
class ManagedLayerHolder {
|
|
||||||
public:
|
|
||||||
ManagedLayerHolder();
|
|
||||||
~ManagedLayerHolder();
|
|
||||||
|
|
||||||
void Initialize(Nvnflinger::Nvnflinger* nvnflinger);
|
|
||||||
void CreateManagedDisplayLayer(u64* out_layer);
|
|
||||||
void CreateManagedDisplaySeparableLayer(u64* out_layer, u64* out_recording_layer);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Nvnflinger::Nvnflinger* m_nvnflinger{};
|
|
||||||
std::set<u64> m_managed_display_layers{};
|
|
||||||
std::set<u64> m_managed_display_recording_layers{};
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Service::AM
|
|
|
@ -69,7 +69,7 @@ Result IDisplayController::ClearCaptureBuffer(bool unknown0, s32 fbshare_layer_i
|
||||||
Result IDisplayController::AcquireLastForegroundCaptureSharedBuffer(
|
Result IDisplayController::AcquireLastForegroundCaptureSharedBuffer(
|
||||||
Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) {
|
Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) {
|
||||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||||
R_RETURN(applet->system_buffer_manager.WriteAppletCaptureBuffer(out_was_written,
|
R_RETURN(applet->display_layer_manager.WriteAppletCaptureBuffer(out_was_written,
|
||||||
out_fbshare_layer_index));
|
out_fbshare_layer_index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ Result IDisplayController::ReleaseLastForegroundCaptureSharedBuffer() {
|
||||||
Result IDisplayController::AcquireCallerAppletCaptureSharedBuffer(
|
Result IDisplayController::AcquireCallerAppletCaptureSharedBuffer(
|
||||||
Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) {
|
Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) {
|
||||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||||
R_RETURN(applet->system_buffer_manager.WriteAppletCaptureBuffer(out_was_written,
|
R_RETURN(applet->display_layer_manager.WriteAppletCaptureBuffer(out_was_written,
|
||||||
out_fbshare_layer_index));
|
out_fbshare_layer_index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ Result IDisplayController::ReleaseCallerAppletCaptureSharedBuffer() {
|
||||||
Result IDisplayController::AcquireLastApplicationCaptureSharedBuffer(
|
Result IDisplayController::AcquireLastApplicationCaptureSharedBuffer(
|
||||||
Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) {
|
Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) {
|
||||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||||
R_RETURN(applet->system_buffer_manager.WriteAppletCaptureBuffer(out_was_written,
|
R_RETURN(applet->display_layer_manager.WriteAppletCaptureBuffer(out_was_written,
|
||||||
out_fbshare_layer_index));
|
out_fbshare_layer_index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system,
|
||||||
case LibraryAppletMode::AllForegroundInitiallyHidden:
|
case LibraryAppletMode::AllForegroundInitiallyHidden:
|
||||||
applet->hid_registration.EnableAppletToGetInput(false);
|
applet->hid_registration.EnableAppletToGetInput(false);
|
||||||
applet->focus_state = FocusState::NotInFocus;
|
applet->focus_state = FocusState::NotInFocus;
|
||||||
applet->system_buffer_manager.SetWindowVisibility(false);
|
applet->display_layer_manager.SetWindowVisibility(false);
|
||||||
applet->message_queue.PushMessage(AppletMessage::ChangeIntoBackground);
|
applet->message_queue.PushMessage(AppletMessage::ChangeIntoBackground);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,8 @@ namespace Service::AM {
|
||||||
|
|
||||||
ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet> applet,
|
ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet> applet,
|
||||||
Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger)
|
Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger)
|
||||||
: ServiceFramework{system_, "ISelfController"},
|
: ServiceFramework{system_, "ISelfController"}, m_nvnflinger{nvnflinger}, m_process{process},
|
||||||
m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} {
|
m_applet{std::move(applet)} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, D<&ISelfController::Exit>, "Exit"},
|
{0, D<&ISelfController::Exit>, "Exit"},
|
||||||
|
@ -72,9 +72,16 @@ ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet>
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
|
|
||||||
|
std::scoped_lock lk{m_applet->lock};
|
||||||
|
m_applet->display_layer_manager.Initialize(&m_nvnflinger, m_process, m_applet->applet_id,
|
||||||
|
m_applet->library_applet_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
ISelfController::~ISelfController() = default;
|
ISelfController::~ISelfController() {
|
||||||
|
std::scoped_lock lk{m_applet->lock};
|
||||||
|
m_applet->display_layer_manager.Finalize();
|
||||||
|
}
|
||||||
|
|
||||||
Result ISelfController::Exit() {
|
Result ISelfController::Exit() {
|
||||||
LOG_DEBUG(Service_AM, "called");
|
LOG_DEBUG(Service_AM, "called");
|
||||||
|
@ -212,48 +219,42 @@ Result ISelfController::SetAlbumImageOrientation(
|
||||||
|
|
||||||
Result ISelfController::IsSystemBufferSharingEnabled() {
|
Result ISelfController::IsSystemBufferSharingEnabled() {
|
||||||
LOG_INFO(Service_AM, "called");
|
LOG_INFO(Service_AM, "called");
|
||||||
R_SUCCEED_IF(m_applet->system_buffer_manager.Initialize(
|
|
||||||
&m_nvnflinger, m_process, m_applet->applet_id, m_applet->library_applet_mode));
|
std::scoped_lock lk{m_applet->lock};
|
||||||
R_THROW(VI::ResultOperationFailed);
|
R_RETURN(m_applet->display_layer_manager.IsSystemBufferSharingEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ISelfController::GetSystemSharedBufferHandle(Out<u64> out_buffer_id) {
|
Result ISelfController::GetSystemSharedBufferHandle(Out<u64> out_buffer_id) {
|
||||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
LOG_INFO(Service_AM, "called");
|
||||||
|
|
||||||
R_TRY(this->IsSystemBufferSharingEnabled());
|
|
||||||
|
|
||||||
u64 layer_id;
|
u64 layer_id;
|
||||||
m_applet->system_buffer_manager.GetSystemSharedLayerHandle(out_buffer_id, &layer_id);
|
|
||||||
R_SUCCEED();
|
std::scoped_lock lk{m_applet->lock};
|
||||||
|
R_RETURN(m_applet->display_layer_manager.GetSystemSharedLayerHandle(out_buffer_id, &layer_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ISelfController::GetSystemSharedLayerHandle(Out<u64> out_buffer_id, Out<u64> out_layer_id) {
|
Result ISelfController::GetSystemSharedLayerHandle(Out<u64> out_buffer_id, Out<u64> out_layer_id) {
|
||||||
LOG_INFO(Service_AM, "(STUBBED) called");
|
LOG_INFO(Service_AM, "called");
|
||||||
|
|
||||||
R_TRY(this->IsSystemBufferSharingEnabled());
|
std::scoped_lock lk{m_applet->lock};
|
||||||
|
R_RETURN(
|
||||||
m_applet->system_buffer_manager.GetSystemSharedLayerHandle(out_buffer_id, out_layer_id);
|
m_applet->display_layer_manager.GetSystemSharedLayerHandle(out_buffer_id, out_layer_id));
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ISelfController::CreateManagedDisplayLayer(Out<u64> out_layer_id) {
|
Result ISelfController::CreateManagedDisplayLayer(Out<u64> out_layer_id) {
|
||||||
LOG_INFO(Service_AM, "called");
|
LOG_INFO(Service_AM, "called");
|
||||||
|
|
||||||
m_applet->managed_layer_holder.Initialize(&m_nvnflinger);
|
std::scoped_lock lk{m_applet->lock};
|
||||||
m_applet->managed_layer_holder.CreateManagedDisplayLayer(out_layer_id);
|
R_RETURN(m_applet->display_layer_manager.CreateManagedDisplayLayer(out_layer_id));
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ISelfController::CreateManagedDisplaySeparableLayer(Out<u64> out_layer_id,
|
Result ISelfController::CreateManagedDisplaySeparableLayer(Out<u64> out_layer_id,
|
||||||
Out<u64> out_recording_layer_id) {
|
Out<u64> out_recording_layer_id) {
|
||||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||||
|
|
||||||
m_applet->managed_layer_holder.Initialize(&m_nvnflinger);
|
std::scoped_lock lk{m_applet->lock};
|
||||||
m_applet->managed_layer_holder.CreateManagedDisplaySeparableLayer(out_layer_id,
|
R_RETURN(m_applet->display_layer_manager.CreateManagedDisplaySeparableLayer(
|
||||||
out_recording_layer_id);
|
out_layer_id, out_recording_layer_id));
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ISelfController::SetHandlesRequestToDisplay(bool enable) {
|
Result ISelfController::SetHandlesRequestToDisplay(bool enable) {
|
||||||
|
|
|
@ -63,7 +63,7 @@ Result IWindowController::RejectToChangeIntoBackground() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IWindowController::SetAppletWindowVisibility(bool visible) {
|
Result IWindowController::SetAppletWindowVisibility(bool visible) {
|
||||||
m_applet->system_buffer_manager.SetWindowVisibility(visible);
|
m_applet->display_layer_manager.SetWindowVisibility(visible);
|
||||||
m_applet->hid_registration.EnableAppletToGetInput(visible);
|
m_applet->hid_registration.EnableAppletToGetInput(visible);
|
||||||
|
|
||||||
if (visible) {
|
if (visible) {
|
||||||
|
|
|
@ -1,80 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include "core/hle/service/am/system_buffer_manager.h"
|
|
||||||
#include "core/hle/service/nvnflinger/fb_share_buffer_manager.h"
|
|
||||||
#include "core/hle/service/nvnflinger/nvnflinger.h"
|
|
||||||
#include "core/hle/service/vi/vi_results.h"
|
|
||||||
|
|
||||||
namespace Service::AM {
|
|
||||||
|
|
||||||
SystemBufferManager::SystemBufferManager() = default;
|
|
||||||
|
|
||||||
SystemBufferManager::~SystemBufferManager() {
|
|
||||||
if (!m_nvnflinger) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up shared layers.
|
|
||||||
if (m_buffer_sharing_enabled) {
|
|
||||||
m_nvnflinger->GetSystemBufferManager().Finalize(m_process);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SystemBufferManager::Initialize(Nvnflinger::Nvnflinger* nvnflinger, Kernel::KProcess* process,
|
|
||||||
AppletId applet_id, LibraryAppletMode mode) {
|
|
||||||
if (m_nvnflinger) {
|
|
||||||
return m_buffer_sharing_enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_process = process;
|
|
||||||
m_nvnflinger = nvnflinger;
|
|
||||||
m_buffer_sharing_enabled = false;
|
|
||||||
m_system_shared_buffer_id = 0;
|
|
||||||
m_system_shared_layer_id = 0;
|
|
||||||
|
|
||||||
if (applet_id <= AppletId::Application) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Nvnflinger::LayerBlending blending = Nvnflinger::LayerBlending::None;
|
|
||||||
if (mode == LibraryAppletMode::PartialForeground ||
|
|
||||||
mode == LibraryAppletMode::PartialForegroundIndirectDisplay) {
|
|
||||||
blending = Nvnflinger::LayerBlending::Coverage;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto display_id = m_nvnflinger->OpenDisplay("Default").value();
|
|
||||||
const auto res = m_nvnflinger->GetSystemBufferManager().Initialize(
|
|
||||||
m_process, &m_system_shared_buffer_id, &m_system_shared_layer_id, display_id, blending);
|
|
||||||
|
|
||||||
if (res.IsSuccess()) {
|
|
||||||
m_buffer_sharing_enabled = true;
|
|
||||||
m_nvnflinger->SetLayerVisibility(m_system_shared_layer_id, m_visible);
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_buffer_sharing_enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SystemBufferManager::SetWindowVisibility(bool visible) {
|
|
||||||
if (m_visible == visible) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_visible = visible;
|
|
||||||
|
|
||||||
if (m_nvnflinger) {
|
|
||||||
m_nvnflinger->SetLayerVisibility(m_system_shared_layer_id, m_visible);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Result SystemBufferManager::WriteAppletCaptureBuffer(bool* out_was_written,
|
|
||||||
s32* out_fbshare_layer_index) {
|
|
||||||
if (!m_buffer_sharing_enabled) {
|
|
||||||
return VI::ResultPermissionDenied;
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_nvnflinger->GetSystemBufferManager().WriteAppletCaptureBuffer(out_was_written,
|
|
||||||
out_fbshare_layer_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Service::AM
|
|
|
@ -1,52 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
#include "common/common_funcs.h"
|
|
||||||
#include "common/common_types.h"
|
|
||||||
|
|
||||||
#include "core/hle/service/am/am_types.h"
|
|
||||||
|
|
||||||
namespace Kernel {
|
|
||||||
class KProcess;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Service::Nvnflinger {
|
|
||||||
class Nvnflinger;
|
|
||||||
}
|
|
||||||
|
|
||||||
union Result;
|
|
||||||
|
|
||||||
namespace Service::AM {
|
|
||||||
|
|
||||||
class SystemBufferManager {
|
|
||||||
public:
|
|
||||||
SystemBufferManager();
|
|
||||||
~SystemBufferManager();
|
|
||||||
|
|
||||||
bool Initialize(Nvnflinger::Nvnflinger* flinger, Kernel::KProcess* process, AppletId applet_id,
|
|
||||||
LibraryAppletMode mode);
|
|
||||||
|
|
||||||
void GetSystemSharedLayerHandle(u64* out_system_shared_buffer_id,
|
|
||||||
u64* out_system_shared_layer_id) {
|
|
||||||
*out_system_shared_buffer_id = m_system_shared_buffer_id;
|
|
||||||
*out_system_shared_layer_id = m_system_shared_layer_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetWindowVisibility(bool visible);
|
|
||||||
|
|
||||||
Result WriteAppletCaptureBuffer(bool* out_was_written, s32* out_fbshare_layer_index);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Kernel::KProcess* m_process{};
|
|
||||||
Nvnflinger::Nvnflinger* m_nvnflinger{};
|
|
||||||
bool m_buffer_sharing_enabled{};
|
|
||||||
bool m_visible{true};
|
|
||||||
u64 m_system_shared_buffer_id{};
|
|
||||||
u64 m_system_shared_layer_id{};
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Service::AM
|
|
Loading…
Reference in a new issue