mirror of
https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
synced 2025-12-19 01:52:40 +00:00
vi: manage resources independently of nvnflinger and refactor
This commit is contained in:
@@ -3,11 +3,12 @@
|
||||
|
||||
#include "core/core.h"
|
||||
#include "core/hle/service/am/display_layer_manager.h"
|
||||
#include "core/hle/service/nvnflinger/hos_binder_driver.h"
|
||||
#include "core/hle/service/sm/sm.h"
|
||||
#include "core/hle/service/vi/application_display_service.h"
|
||||
#include "core/hle/service/vi/fbshare_buffer_manager.h"
|
||||
#include "core/hle/service/vi/container.h"
|
||||
#include "core/hle/service/vi/manager_display_service.h"
|
||||
#include "core/hle/service/vi/manager_root_service.h"
|
||||
#include "core/hle/service/vi/shared_buffer_manager.h"
|
||||
#include "core/hle/service/vi/vi_results.h"
|
||||
#include "core/hle/service/vi/vi_types.h"
|
||||
|
||||
@@ -20,12 +21,10 @@ DisplayLayerManager::~DisplayLayerManager() {
|
||||
|
||||
void DisplayLayerManager::Initialize(Core::System& system, Kernel::KProcess* process,
|
||||
AppletId applet_id, LibraryAppletMode mode) {
|
||||
m_surface_flinger = system.ServiceManager()
|
||||
.GetService<Nvnflinger::IHOSBinderDriver>("dispdrv", true)
|
||||
->GetSurfaceFlinger();
|
||||
R_ASSERT(system.ServiceManager()
|
||||
.GetService<VI::IManagerRootService>("vi:m", true)
|
||||
->GetDisplayService(&m_display_service, VI::Policy::Compositor));
|
||||
R_ASSERT(m_display_service->GetManagerDisplayService(&m_manager_display_service));
|
||||
|
||||
m_process = process;
|
||||
m_system_shared_buffer_id = 0;
|
||||
@@ -37,46 +36,47 @@ void DisplayLayerManager::Initialize(Core::System& system, Kernel::KProcess* pro
|
||||
}
|
||||
|
||||
void DisplayLayerManager::Finalize() {
|
||||
if (!m_surface_flinger) {
|
||||
if (!m_manager_display_service) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Clean up managed layers.
|
||||
for (const auto& layer : m_managed_display_layers) {
|
||||
m_surface_flinger->DestroyLayer(layer);
|
||||
m_manager_display_service->DestroyManagedLayer(layer);
|
||||
}
|
||||
|
||||
for (const auto& layer : m_managed_display_recording_layers) {
|
||||
m_surface_flinger->DestroyLayer(layer);
|
||||
m_manager_display_service->DestroyManagedLayer(layer);
|
||||
}
|
||||
|
||||
// Clean up shared layers.
|
||||
if (m_buffer_sharing_enabled) {
|
||||
m_display_service->GetSharedBufferManager()->Finalize(m_process);
|
||||
m_manager_display_service->DestroySharedLayerSession(m_process);
|
||||
}
|
||||
|
||||
m_surface_flinger = nullptr;
|
||||
m_manager_display_service = nullptr;
|
||||
m_display_service = nullptr;
|
||||
}
|
||||
|
||||
Result DisplayLayerManager::CreateManagedDisplayLayer(u64* out_layer) {
|
||||
R_UNLESS(m_surface_flinger != nullptr, VI::ResultOperationFailed);
|
||||
Result DisplayLayerManager::CreateManagedDisplayLayer(u64* out_layer_id) {
|
||||
R_UNLESS(m_manager_display_service != 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_surface_flinger->OpenDisplay("Default");
|
||||
const auto layer_id = m_surface_flinger->CreateLayer(*display_id);
|
||||
u64 display_id;
|
||||
R_TRY(m_display_service->OpenDisplay(&display_id, VI::DisplayName{"Default"}));
|
||||
R_TRY(m_manager_display_service->CreateManagedLayer(
|
||||
out_layer_id, 0, display_id, Service::AppletResourceUserId{m_process->GetProcessId()}));
|
||||
|
||||
m_surface_flinger->SetLayerVisibility(*layer_id, m_visible);
|
||||
m_managed_display_layers.emplace(*layer_id);
|
||||
|
||||
*out_layer = *layer_id;
|
||||
m_manager_display_service->SetLayerVisibility(m_visible, *out_layer_id);
|
||||
m_managed_display_layers.emplace(*out_layer_id);
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result DisplayLayerManager::CreateManagedDisplaySeparableLayer(u64* out_layer,
|
||||
u64* out_recording_layer) {
|
||||
R_UNLESS(m_surface_flinger != nullptr, VI::ResultOperationFailed);
|
||||
Result DisplayLayerManager::CreateManagedDisplaySeparableLayer(u64* out_layer_id,
|
||||
u64* out_recording_layer_id) {
|
||||
R_UNLESS(m_manager_display_service != nullptr, VI::ResultOperationFailed);
|
||||
|
||||
// TODO(Subv): Find out how AM determines the display to use, for now just
|
||||
// create the layer in the Default display.
|
||||
@@ -84,17 +84,8 @@ Result DisplayLayerManager::CreateManagedDisplaySeparableLayer(u64* out_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_surface_flinger->OpenDisplay("Default");
|
||||
const auto layer_id = m_surface_flinger->CreateLayer(*display_id);
|
||||
|
||||
m_surface_flinger->SetLayerVisibility(*layer_id, m_visible);
|
||||
m_managed_display_layers.emplace(*layer_id);
|
||||
|
||||
*out_layer = *layer_id;
|
||||
*out_recording_layer = 0;
|
||||
|
||||
R_SUCCEED();
|
||||
*out_recording_layer_id = 0;
|
||||
R_RETURN(this->CreateManagedDisplayLayer(out_layer_id));
|
||||
}
|
||||
|
||||
Result DisplayLayerManager::IsSystemBufferSharingEnabled() {
|
||||
@@ -102,19 +93,19 @@ Result DisplayLayerManager::IsSystemBufferSharingEnabled() {
|
||||
R_SUCCEED_IF(m_buffer_sharing_enabled);
|
||||
|
||||
// Ensure we can access shared layers.
|
||||
R_UNLESS(m_surface_flinger != nullptr, VI::ResultOperationFailed);
|
||||
R_UNLESS(m_manager_display_service != 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_surface_flinger->OpenDisplay("Default").value();
|
||||
R_TRY(m_display_service->GetSharedBufferManager()->Initialize(
|
||||
m_process, &m_system_shared_buffer_id, &m_system_shared_layer_id, display_id, blend));
|
||||
u64 display_id;
|
||||
R_TRY(m_display_service->OpenDisplay(&display_id, VI::DisplayName{"Default"}));
|
||||
R_TRY(m_manager_display_service->CreateSharedLayerSession(m_process, &m_system_shared_buffer_id,
|
||||
&m_system_shared_layer_id, display_id,
|
||||
m_blending_enabled));
|
||||
|
||||
// We succeeded, so set up remaining state.
|
||||
m_buffer_sharing_enabled = true;
|
||||
m_surface_flinger->SetLayerVisibility(m_system_shared_layer_id, m_visible);
|
||||
m_manager_display_service->SetLayerVisibility(m_visible, m_system_shared_layer_id);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
@@ -135,13 +126,13 @@ void DisplayLayerManager::SetWindowVisibility(bool visible) {
|
||||
|
||||
m_visible = visible;
|
||||
|
||||
if (m_surface_flinger) {
|
||||
if (m_manager_display_service) {
|
||||
if (m_system_shared_layer_id) {
|
||||
m_surface_flinger->SetLayerVisibility(m_system_shared_layer_id, m_visible);
|
||||
m_manager_display_service->SetLayerVisibility(m_visible, m_system_shared_layer_id);
|
||||
}
|
||||
|
||||
for (const auto layer_id : m_managed_display_layers) {
|
||||
m_surface_flinger->SetLayerVisibility(layer_id, m_visible);
|
||||
m_manager_display_service->SetLayerVisibility(m_visible, layer_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,7 +144,7 @@ bool DisplayLayerManager::GetWindowVisibility() const {
|
||||
Result DisplayLayerManager::WriteAppletCaptureBuffer(bool* out_was_written,
|
||||
s32* out_fbshare_layer_index) {
|
||||
R_UNLESS(m_buffer_sharing_enabled, VI::ResultPermissionDenied);
|
||||
R_RETURN(m_display_service->GetSharedBufferManager()->WriteAppletCaptureBuffer(
|
||||
R_RETURN(m_display_service->GetContainer()->GetSharedBufferManager()->WriteAppletCaptureBuffer(
|
||||
out_was_written, out_fbshare_layer_index));
|
||||
}
|
||||
|
||||
|
||||
@@ -17,13 +17,10 @@ namespace Kernel {
|
||||
class KProcess;
|
||||
}
|
||||
|
||||
namespace Service::Nvnflinger {
|
||||
class Nvnflinger;
|
||||
}
|
||||
|
||||
namespace Service::VI {
|
||||
class IApplicationDisplayService;
|
||||
}
|
||||
class IManagerDisplayService;
|
||||
} // namespace Service::VI
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
@@ -36,8 +33,8 @@ public:
|
||||
LibraryAppletMode mode);
|
||||
void Finalize();
|
||||
|
||||
Result CreateManagedDisplayLayer(u64* out_layer);
|
||||
Result CreateManagedDisplaySeparableLayer(u64* out_layer, u64* out_recording_layer);
|
||||
Result CreateManagedDisplayLayer(u64* out_layer_id);
|
||||
Result CreateManagedDisplaySeparableLayer(u64* out_layer_id, u64* out_recording_layer_id);
|
||||
|
||||
Result IsSystemBufferSharingEnabled();
|
||||
Result GetSystemSharedLayerHandle(u64* out_system_shared_buffer_id,
|
||||
@@ -50,8 +47,8 @@ public:
|
||||
|
||||
private:
|
||||
Kernel::KProcess* m_process{};
|
||||
std::shared_ptr<Nvnflinger::Nvnflinger> m_surface_flinger{};
|
||||
std::shared_ptr<VI::IApplicationDisplayService> m_display_service{};
|
||||
std::shared_ptr<VI::IManagerDisplayService> m_manager_display_service{};
|
||||
std::set<u64> m_managed_display_layers{};
|
||||
std::set<u64> m_managed_display_recording_layers{};
|
||||
u64 m_system_shared_buffer_id{};
|
||||
|
||||
Reference in New Issue
Block a user