Răsfoiți Sursa

service: am: Implement shared buffer

Co-authored-by: Liam <byteslice@airmail.cc>
Narr the Reg 2 ani în urmă
părinte
comite
2687a83f6a
2 a modificat fișierele cu 125 adăugiri și 10 ștergeri
  1. 109 10
      src/core/hle/service/am/am.cpp
  2. 16 0
      src/core/hle/service/am/am.h

+ 109 - 10
src/core/hle/service/am/am.cpp

@@ -35,11 +35,13 @@
 #include "core/hle/service/filesystem/filesystem.h"
 #include "core/hle/service/ipc_helpers.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/pm/pm.h"
 #include "core/hle/service/server_manager.h"
 #include "core/hle/service/sm/sm.h"
 #include "core/hle/service/vi/vi.h"
+#include "core/hle/service/vi/vi_results.h"
 #include "core/memory.h"
 
 namespace Service::AM {
@@ -192,7 +194,7 @@ IDisplayController::IDisplayController(Core::System& system_)
         {4, nullptr, "UpdateCallerAppletCaptureImage"},
         {5, nullptr, "GetLastForegroundCaptureImageEx"},
         {6, nullptr, "GetLastApplicationCaptureImageEx"},
-        {7, nullptr, "GetCallerAppletCaptureImageEx"},
+        {7, &IDisplayController::GetCallerAppletCaptureImageEx, "GetCallerAppletCaptureImageEx"},
         {8, &IDisplayController::TakeScreenShotOfOwnLayer, "TakeScreenShotOfOwnLayer"},
         {9, nullptr, "CopyBetweenCaptureBuffers"},
         {10, nullptr, "AcquireLastApplicationCaptureBuffer"},
@@ -210,8 +212,8 @@ IDisplayController::IDisplayController(Core::System& system_)
         {23, nullptr, "ReleaseLastApplicationCaptureSharedBuffer"},
         {24, nullptr, "AcquireLastForegroundCaptureSharedBuffer"},
         {25, nullptr, "ReleaseLastForegroundCaptureSharedBuffer"},
-        {26, nullptr, "AcquireCallerAppletCaptureSharedBuffer"},
-        {27, nullptr, "ReleaseCallerAppletCaptureSharedBuffer"},
+        {26, &IDisplayController::AcquireCallerAppletCaptureSharedBuffer, "AcquireCallerAppletCaptureSharedBuffer"},
+        {27, &IDisplayController::ReleaseCallerAppletCaptureSharedBuffer, "ReleaseCallerAppletCaptureSharedBuffer"},
         {28, nullptr, "TakeScreenShotOfOwnLayerEx"},
     };
     // clang-format on
@@ -221,6 +223,15 @@ IDisplayController::IDisplayController(Core::System& system_)
 
 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) {
     LOG_WARNING(Service_AM, "(STUBBED) called");
 
@@ -228,6 +239,22 @@ void IDisplayController::TakeScreenShotOfOwnLayer(HLERequestContext& ctx) {
     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_)
     : ServiceFramework{system_, "IDebugFunctions"} {
     // clang-format off
@@ -287,14 +314,14 @@ ISelfController::ISelfController(Core::System& system_, Nvnflinger::Nvnflinger&
         {20, nullptr, "SetDesirableKeyboardLayout"},
         {21, nullptr, "GetScreenShotProgramId"},
         {40, &ISelfController::CreateManagedDisplayLayer, "CreateManagedDisplayLayer"},
-        {41, nullptr, "IsSystemBufferSharingEnabled"},
-        {42, nullptr, "GetSystemSharedLayerHandle"},
-        {43, nullptr, "GetSystemSharedBufferHandle"},
+        {41, &ISelfController::IsSystemBufferSharingEnabled, "IsSystemBufferSharingEnabled"},
+        {42, &ISelfController::GetSystemSharedLayerHandle, "GetSystemSharedLayerHandle"},
+        {43, &ISelfController::GetSystemSharedBufferHandle, "GetSystemSharedBufferHandle"},
         {44, &ISelfController::CreateManagedDisplaySeparableLayer, "CreateManagedDisplaySeparableLayer"},
         {45, nullptr, "SetManagedDisplayLayerSeparationMode"},
         {46, nullptr, "SetRecordingLayerCompositionEnabled"},
         {50, &ISelfController::SetHandlesRequestToDisplay, "SetHandlesRequestToDisplay"},
-        {51, nullptr, "ApproveToDisplay"},
+        {51, &ISelfController::ApproveToDisplay, "ApproveToDisplay"},
         {60, nullptr, "OverrideAutoSleepTimeAndDimmingTime"},
         {61, nullptr, "SetMediaPlaybackState"},
         {62, &ISelfController::SetIdleTimeDetectionExtension, "SetIdleTimeDetectionExtension"},
@@ -493,6 +520,50 @@ void ISelfController::CreateManagedDisplayLayer(HLERequestContext& ctx) {
     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) {
     LOG_WARNING(Service_AM, "(STUBBED) called");
 
@@ -518,6 +589,13 @@ void ISelfController::SetHandlesRequestToDisplay(HLERequestContext& ctx) {
     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) {
     IPC::RequestParser rp{ctx};
     idle_time_detection_extension = rp.Pop<u32>();
@@ -688,7 +766,8 @@ void AppletMessageQueue::OperationModeChanged() {
 
 ICommonStateGetter::ICommonStateGetter(Core::System& system_,
                                        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
     static const FunctionInfo functions[] = {
         {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"},
@@ -701,10 +780,10 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_,
         {7, nullptr, "GetCradleStatus"},
         {8, &ICommonStateGetter::GetBootMode, "GetBootMode"},
         {9, &ICommonStateGetter::GetCurrentFocusState, "GetCurrentFocusState"},
-        {10, nullptr, "RequestToAcquireSleepLock"},
+        {10, &ICommonStateGetter::RequestToAcquireSleepLock, "RequestToAcquireSleepLock"},
         {11, nullptr, "ReleaseSleepLock"},
         {12, nullptr, "ReleaseSleepLockTransiently"},
-        {13, nullptr, "GetAcquiredSleepLockEvent"},
+        {13, &ICommonStateGetter::GetAcquiredSleepLockEvent, "GetAcquiredSleepLockEvent"},
         {14, nullptr, "GetWakeupCount"},
         {20, nullptr, "PushToGeneralChannel"},
         {30, nullptr, "GetHomeButtonReaderLockAccessor"},
@@ -747,6 +826,8 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_,
 
     RegisterHandlers(functions);
 
+    sleep_lock_event = service_context.CreateEvent("ICommonStateGetter::SleepLockEvent");
+
     // Configure applets to be in foreground state
     msg_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
     msg_queue->PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground);
@@ -795,6 +876,24 @@ void ICommonStateGetter::GetCurrentFocusState(HLERequestContext& ctx) {
     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) {
     LOG_DEBUG(Service_AM, "called");
 

+ 16 - 0
src/core/hle/service/am/am.h

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