service: am: Implement shared buffer

Co-authored-by: Liam <byteslice@airmail.cc>
This commit is contained in:
Narr the Reg 2023-09-29 00:13:56 -06:00
parent 35f25882e0
commit 2687a83f6a
2 changed files with 125 additions and 10 deletions

View File

@ -35,11 +35,13 @@
#include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/ipc_helpers.h" #include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/ns/ns.h" #include "core/hle/service/ns/ns.h"
#include "core/hle/service/nvnflinger/fb_share_buffer_manager.h"
#include "core/hle/service/nvnflinger/nvnflinger.h" #include "core/hle/service/nvnflinger/nvnflinger.h"
#include "core/hle/service/pm/pm.h" #include "core/hle/service/pm/pm.h"
#include "core/hle/service/server_manager.h" #include "core/hle/service/server_manager.h"
#include "core/hle/service/sm/sm.h" #include "core/hle/service/sm/sm.h"
#include "core/hle/service/vi/vi.h" #include "core/hle/service/vi/vi.h"
#include "core/hle/service/vi/vi_results.h"
#include "core/memory.h" #include "core/memory.h"
namespace Service::AM { namespace Service::AM {
@ -192,7 +194,7 @@ IDisplayController::IDisplayController(Core::System& system_)
{4, nullptr, "UpdateCallerAppletCaptureImage"}, {4, nullptr, "UpdateCallerAppletCaptureImage"},
{5, nullptr, "GetLastForegroundCaptureImageEx"}, {5, nullptr, "GetLastForegroundCaptureImageEx"},
{6, nullptr, "GetLastApplicationCaptureImageEx"}, {6, nullptr, "GetLastApplicationCaptureImageEx"},
{7, nullptr, "GetCallerAppletCaptureImageEx"}, {7, &IDisplayController::GetCallerAppletCaptureImageEx, "GetCallerAppletCaptureImageEx"},
{8, &IDisplayController::TakeScreenShotOfOwnLayer, "TakeScreenShotOfOwnLayer"}, {8, &IDisplayController::TakeScreenShotOfOwnLayer, "TakeScreenShotOfOwnLayer"},
{9, nullptr, "CopyBetweenCaptureBuffers"}, {9, nullptr, "CopyBetweenCaptureBuffers"},
{10, nullptr, "AcquireLastApplicationCaptureBuffer"}, {10, nullptr, "AcquireLastApplicationCaptureBuffer"},
@ -210,8 +212,8 @@ IDisplayController::IDisplayController(Core::System& system_)
{23, nullptr, "ReleaseLastApplicationCaptureSharedBuffer"}, {23, nullptr, "ReleaseLastApplicationCaptureSharedBuffer"},
{24, nullptr, "AcquireLastForegroundCaptureSharedBuffer"}, {24, nullptr, "AcquireLastForegroundCaptureSharedBuffer"},
{25, nullptr, "ReleaseLastForegroundCaptureSharedBuffer"}, {25, nullptr, "ReleaseLastForegroundCaptureSharedBuffer"},
{26, nullptr, "AcquireCallerAppletCaptureSharedBuffer"}, {26, &IDisplayController::AcquireCallerAppletCaptureSharedBuffer, "AcquireCallerAppletCaptureSharedBuffer"},
{27, nullptr, "ReleaseCallerAppletCaptureSharedBuffer"}, {27, &IDisplayController::ReleaseCallerAppletCaptureSharedBuffer, "ReleaseCallerAppletCaptureSharedBuffer"},
{28, nullptr, "TakeScreenShotOfOwnLayerEx"}, {28, nullptr, "TakeScreenShotOfOwnLayerEx"},
}; };
// clang-format on // clang-format on
@ -221,6 +223,15 @@ IDisplayController::IDisplayController(Core::System& system_)
IDisplayController::~IDisplayController() = default; IDisplayController::~IDisplayController() = default;
void IDisplayController::GetCallerAppletCaptureImageEx(HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
rb.Push(1u);
rb.Push(0);
}
void IDisplayController::TakeScreenShotOfOwnLayer(HLERequestContext& ctx) { void IDisplayController::TakeScreenShotOfOwnLayer(HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called"); LOG_WARNING(Service_AM, "(STUBBED) called");
@ -228,6 +239,22 @@ void IDisplayController::TakeScreenShotOfOwnLayer(HLERequestContext& ctx) {
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
} }
void IDisplayController::AcquireCallerAppletCaptureSharedBuffer(HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
rb.Push(1U);
rb.Push(0);
}
void IDisplayController::ReleaseCallerAppletCaptureSharedBuffer(HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
IDebugFunctions::IDebugFunctions(Core::System& system_) IDebugFunctions::IDebugFunctions(Core::System& system_)
: ServiceFramework{system_, "IDebugFunctions"} { : ServiceFramework{system_, "IDebugFunctions"} {
// clang-format off // clang-format off
@ -287,14 +314,14 @@ ISelfController::ISelfController(Core::System& system_, Nvnflinger::Nvnflinger&
{20, nullptr, "SetDesirableKeyboardLayout"}, {20, nullptr, "SetDesirableKeyboardLayout"},
{21, nullptr, "GetScreenShotProgramId"}, {21, nullptr, "GetScreenShotProgramId"},
{40, &ISelfController::CreateManagedDisplayLayer, "CreateManagedDisplayLayer"}, {40, &ISelfController::CreateManagedDisplayLayer, "CreateManagedDisplayLayer"},
{41, nullptr, "IsSystemBufferSharingEnabled"}, {41, &ISelfController::IsSystemBufferSharingEnabled, "IsSystemBufferSharingEnabled"},
{42, nullptr, "GetSystemSharedLayerHandle"}, {42, &ISelfController::GetSystemSharedLayerHandle, "GetSystemSharedLayerHandle"},
{43, nullptr, "GetSystemSharedBufferHandle"}, {43, &ISelfController::GetSystemSharedBufferHandle, "GetSystemSharedBufferHandle"},
{44, &ISelfController::CreateManagedDisplaySeparableLayer, "CreateManagedDisplaySeparableLayer"}, {44, &ISelfController::CreateManagedDisplaySeparableLayer, "CreateManagedDisplaySeparableLayer"},
{45, nullptr, "SetManagedDisplayLayerSeparationMode"}, {45, nullptr, "SetManagedDisplayLayerSeparationMode"},
{46, nullptr, "SetRecordingLayerCompositionEnabled"}, {46, nullptr, "SetRecordingLayerCompositionEnabled"},
{50, &ISelfController::SetHandlesRequestToDisplay, "SetHandlesRequestToDisplay"}, {50, &ISelfController::SetHandlesRequestToDisplay, "SetHandlesRequestToDisplay"},
{51, nullptr, "ApproveToDisplay"}, {51, &ISelfController::ApproveToDisplay, "ApproveToDisplay"},
{60, nullptr, "OverrideAutoSleepTimeAndDimmingTime"}, {60, nullptr, "OverrideAutoSleepTimeAndDimmingTime"},
{61, nullptr, "SetMediaPlaybackState"}, {61, nullptr, "SetMediaPlaybackState"},
{62, &ISelfController::SetIdleTimeDetectionExtension, "SetIdleTimeDetectionExtension"}, {62, &ISelfController::SetIdleTimeDetectionExtension, "SetIdleTimeDetectionExtension"},
@ -493,6 +520,50 @@ void ISelfController::CreateManagedDisplayLayer(HLERequestContext& ctx) {
rb.Push(*layer_id); rb.Push(*layer_id);
} }
void ISelfController::IsSystemBufferSharingEnabled(HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(this->EnsureBufferSharingEnabled());
}
void ISelfController::GetSystemSharedLayerHandle(HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(this->EnsureBufferSharingEnabled());
rb.Push<s64>(system_shared_buffer_id);
rb.Push<s64>(system_shared_layer_id);
}
void ISelfController::GetSystemSharedBufferHandle(HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(this->EnsureBufferSharingEnabled());
rb.Push<s64>(system_shared_buffer_id);
}
Result ISelfController::EnsureBufferSharingEnabled() {
if (buffer_sharing_enabled) {
return ResultSuccess;
}
if (system.GetAppletManager().GetCurrentAppletId() <= Applets::AppletId::Application) {
return VI::ResultOperationFailed;
}
const auto display_id = nvnflinger.OpenDisplay("Default");
const auto result = nvnflinger.GetSystemBufferManager().Initialize(
&system_shared_buffer_id, &system_shared_layer_id, *display_id);
if (result.IsSuccess()) {
buffer_sharing_enabled = true;
}
return result;
}
void ISelfController::CreateManagedDisplaySeparableLayer(HLERequestContext& ctx) { void ISelfController::CreateManagedDisplaySeparableLayer(HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called"); LOG_WARNING(Service_AM, "(STUBBED) called");
@ -518,6 +589,13 @@ void ISelfController::SetHandlesRequestToDisplay(HLERequestContext& ctx) {
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
} }
void ISelfController::ApproveToDisplay(HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void ISelfController::SetIdleTimeDetectionExtension(HLERequestContext& ctx) { void ISelfController::SetIdleTimeDetectionExtension(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
idle_time_detection_extension = rp.Pop<u32>(); idle_time_detection_extension = rp.Pop<u32>();
@ -688,7 +766,8 @@ void AppletMessageQueue::OperationModeChanged() {
ICommonStateGetter::ICommonStateGetter(Core::System& system_, ICommonStateGetter::ICommonStateGetter(Core::System& system_,
std::shared_ptr<AppletMessageQueue> msg_queue_) std::shared_ptr<AppletMessageQueue> msg_queue_)
: ServiceFramework{system_, "ICommonStateGetter"}, msg_queue{std::move(msg_queue_)} { : ServiceFramework{system_, "ICommonStateGetter"}, msg_queue{std::move(msg_queue_)},
service_context{system_, "ICommonStateGetter"} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"}, {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"},
@ -701,10 +780,10 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_,
{7, nullptr, "GetCradleStatus"}, {7, nullptr, "GetCradleStatus"},
{8, &ICommonStateGetter::GetBootMode, "GetBootMode"}, {8, &ICommonStateGetter::GetBootMode, "GetBootMode"},
{9, &ICommonStateGetter::GetCurrentFocusState, "GetCurrentFocusState"}, {9, &ICommonStateGetter::GetCurrentFocusState, "GetCurrentFocusState"},
{10, nullptr, "RequestToAcquireSleepLock"}, {10, &ICommonStateGetter::RequestToAcquireSleepLock, "RequestToAcquireSleepLock"},
{11, nullptr, "ReleaseSleepLock"}, {11, nullptr, "ReleaseSleepLock"},
{12, nullptr, "ReleaseSleepLockTransiently"}, {12, nullptr, "ReleaseSleepLockTransiently"},
{13, nullptr, "GetAcquiredSleepLockEvent"}, {13, &ICommonStateGetter::GetAcquiredSleepLockEvent, "GetAcquiredSleepLockEvent"},
{14, nullptr, "GetWakeupCount"}, {14, nullptr, "GetWakeupCount"},
{20, nullptr, "PushToGeneralChannel"}, {20, nullptr, "PushToGeneralChannel"},
{30, nullptr, "GetHomeButtonReaderLockAccessor"}, {30, nullptr, "GetHomeButtonReaderLockAccessor"},
@ -747,6 +826,8 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_,
RegisterHandlers(functions); RegisterHandlers(functions);
sleep_lock_event = service_context.CreateEvent("ICommonStateGetter::SleepLockEvent");
// Configure applets to be in foreground state // Configure applets to be in foreground state
msg_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged); msg_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
msg_queue->PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground); msg_queue->PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground);
@ -795,6 +876,24 @@ void ICommonStateGetter::GetCurrentFocusState(HLERequestContext& ctx) {
rb.Push(static_cast<u8>(FocusState::InFocus)); rb.Push(static_cast<u8>(FocusState::InFocus));
} }
void ICommonStateGetter::RequestToAcquireSleepLock(HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
// Sleep lock is acquired immediately.
sleep_lock_event->Signal();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void ICommonStateGetter::GetAcquiredSleepLockEvent(HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "called");
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
rb.PushCopyObjects(sleep_lock_event->GetReadableEvent());
}
void ICommonStateGetter::IsVrModeEnabled(HLERequestContext& ctx) { void ICommonStateGetter::IsVrModeEnabled(HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");

View File

@ -122,7 +122,10 @@ public:
~IDisplayController() override; ~IDisplayController() override;
private: private:
void GetCallerAppletCaptureImageEx(HLERequestContext& ctx);
void TakeScreenShotOfOwnLayer(HLERequestContext& ctx); void TakeScreenShotOfOwnLayer(HLERequestContext& ctx);
void AcquireCallerAppletCaptureSharedBuffer(HLERequestContext& ctx);
void ReleaseCallerAppletCaptureSharedBuffer(HLERequestContext& ctx);
}; };
class IDebugFunctions final : public ServiceFramework<IDebugFunctions> { class IDebugFunctions final : public ServiceFramework<IDebugFunctions> {
@ -150,9 +153,13 @@ private:
void SetRestartMessageEnabled(HLERequestContext& ctx); void SetRestartMessageEnabled(HLERequestContext& ctx);
void SetOutOfFocusSuspendingEnabled(HLERequestContext& ctx); void SetOutOfFocusSuspendingEnabled(HLERequestContext& ctx);
void SetAlbumImageOrientation(HLERequestContext& ctx); void SetAlbumImageOrientation(HLERequestContext& ctx);
void IsSystemBufferSharingEnabled(HLERequestContext& ctx);
void GetSystemSharedBufferHandle(HLERequestContext& ctx);
void GetSystemSharedLayerHandle(HLERequestContext& ctx);
void CreateManagedDisplayLayer(HLERequestContext& ctx); void CreateManagedDisplayLayer(HLERequestContext& ctx);
void CreateManagedDisplaySeparableLayer(HLERequestContext& ctx); void CreateManagedDisplaySeparableLayer(HLERequestContext& ctx);
void SetHandlesRequestToDisplay(HLERequestContext& ctx); void SetHandlesRequestToDisplay(HLERequestContext& ctx);
void ApproveToDisplay(HLERequestContext& ctx);
void SetIdleTimeDetectionExtension(HLERequestContext& ctx); void SetIdleTimeDetectionExtension(HLERequestContext& ctx);
void GetIdleTimeDetectionExtension(HLERequestContext& ctx); void GetIdleTimeDetectionExtension(HLERequestContext& ctx);
void ReportUserIsActive(HLERequestContext& ctx); void ReportUserIsActive(HLERequestContext& ctx);
@ -164,6 +171,8 @@ private:
void SaveCurrentScreenshot(HLERequestContext& ctx); void SaveCurrentScreenshot(HLERequestContext& ctx);
void SetRecordVolumeMuted(HLERequestContext& ctx); void SetRecordVolumeMuted(HLERequestContext& ctx);
Result EnsureBufferSharingEnabled();
enum class ScreenshotPermission : u32 { enum class ScreenshotPermission : u32 {
Inherit = 0, Inherit = 0,
Enable = 1, Enable = 1,
@ -179,7 +188,10 @@ private:
u32 idle_time_detection_extension = 0; u32 idle_time_detection_extension = 0;
u64 num_fatal_sections_entered = 0; u64 num_fatal_sections_entered = 0;
u64 system_shared_buffer_id = 0;
u64 system_shared_layer_id = 0;
bool is_auto_sleep_disabled = false; bool is_auto_sleep_disabled = false;
bool buffer_sharing_enabled = false;
ScreenshotPermission screenshot_permission = ScreenshotPermission::Inherit; ScreenshotPermission screenshot_permission = ScreenshotPermission::Inherit;
}; };
@ -223,6 +235,8 @@ private:
void GetEventHandle(HLERequestContext& ctx); void GetEventHandle(HLERequestContext& ctx);
void ReceiveMessage(HLERequestContext& ctx); void ReceiveMessage(HLERequestContext& ctx);
void GetCurrentFocusState(HLERequestContext& ctx); void GetCurrentFocusState(HLERequestContext& ctx);
void RequestToAcquireSleepLock(HLERequestContext& ctx);
void GetAcquiredSleepLockEvent(HLERequestContext& ctx);
void GetDefaultDisplayResolutionChangeEvent(HLERequestContext& ctx); void GetDefaultDisplayResolutionChangeEvent(HLERequestContext& ctx);
void GetOperationMode(HLERequestContext& ctx); void GetOperationMode(HLERequestContext& ctx);
void GetPerformanceMode(HLERequestContext& ctx); void GetPerformanceMode(HLERequestContext& ctx);
@ -240,6 +254,8 @@ private:
std::shared_ptr<AppletMessageQueue> msg_queue; std::shared_ptr<AppletMessageQueue> msg_queue;
bool vr_mode_state{}; bool vr_mode_state{};
Kernel::KEvent* sleep_lock_event;
KernelHelpers::ServiceContext service_context;
}; };
class IStorageImpl { class IStorageImpl {