From e7aa43902926cfc035245639391128601d4f69da Mon Sep 17 00:00:00 2001 From: PixelyIon Date: Tue, 6 Jul 2021 00:19:53 +0530 Subject: [PATCH] Support Sticky Transforms + Minor Formatting Fixes Sticky transforms have been stubbed, as they are on HOS/Android. Certain titles like Xenoblade Chronicles end up setting the sticky transform even if it doesn't do anything, as a result of this we cannot throw an exception for it and stub it without an exception (Aside from the cases where the value isn't recognized). --- .../cpp/skyline/gpu/presentation_engine.h | 4 ++-- .../hosbinder/GraphicBufferProducer.cpp | 21 +++++++++++++++---- .../hosbinder/GraphicBufferProducer.h | 2 +- .../cpp/skyline/services/hosbinder/parcel.h | 6 +++--- .../services/visrv/IApplicationRootService.h | 8 +++---- .../services/visrv/IManagerDisplayService.h | 12 +++++------ .../services/visrv/ISystemDisplayService.h | 8 +++---- 7 files changed, 37 insertions(+), 24 deletions(-) diff --git a/app/src/main/cpp/skyline/gpu/presentation_engine.h b/app/src/main/cpp/skyline/gpu/presentation_engine.h index d1b7994e..fbaa1ac5 100644 --- a/app/src/main/cpp/skyline/gpu/presentation_engine.h +++ b/app/src/main/cpp/skyline/gpu/presentation_engine.h @@ -23,7 +23,7 @@ namespace skyline::gpu { std::mutex mutex; //!< Synchronizes access to the surface objects std::condition_variable surfaceCondition; //!< Allows us to efficiently wait for Vulkan surface to be initialized jobject jSurface{}; //!< The Java Surface object backing the ANativeWindow - ANativeWindow* window{}; //!< A pointer to an Android Native Window which is the surface we draw to + ANativeWindow *window{}; //!< A pointer to an Android Native Window which is the surface we draw to service::hosbinder::AndroidRect windowCrop{}; //!< A rectangle with the bounds of the current crop performed on the image prior to presentation service::hosbinder::NativeWindowScalingMode windowScalingMode{service::hosbinder::NativeWindowScalingMode::ScaleToWindow}; //!< The mode in which the cropped image is scaled up to the surface service::hosbinder::NativeWindowTransform windowTransform{}; //!< The transformation performed on the image prior to presentation @@ -87,7 +87,7 @@ namespace skyline::gpu { * @param frameId The ID of this frame for correlating it with presentation timing readouts * @note The texture **must** be locked prior to calling this */ - void Present(const std::shared_ptr &texture, u64 timestamp, u64 swapInterval, service::hosbinder::AndroidRect crop, service::hosbinder::NativeWindowScalingMode scalingMode, service::hosbinder::NativeWindowTransform transform, u64& frameId); + void Present(const std::shared_ptr &texture, u64 timestamp, u64 swapInterval, service::hosbinder::AndroidRect crop, service::hosbinder::NativeWindowScalingMode scalingMode, service::hosbinder::NativeWindowTransform transform, u64 &frameId); /** * @return A transform that the application should render with to elide costly transforms later diff --git a/app/src/main/cpp/skyline/services/hosbinder/GraphicBufferProducer.cpp b/app/src/main/cpp/skyline/services/hosbinder/GraphicBufferProducer.cpp index 478ee166..1f83b9d9 100644 --- a/app/src/main/cpp/skyline/services/hosbinder/GraphicBufferProducer.cpp +++ b/app/src/main/cpp/skyline/services/hosbinder/GraphicBufferProducer.cpp @@ -364,10 +364,23 @@ namespace skyline::service::hosbinder { throw exception("Application attempting to perform unknown transformation: {:#b}", static_cast(transform)); } - if (stickyTransform != NativeWindowTransform::Identity) - // We do not support sticky transforms as they are only used by the LEGACY camera mode - // Note: This is used on HOS to signal that the frame number should be returned but it's unimplemented - throw exception("Any non-identity sticky transform is not supported: '{}' ({:#b})", ToString(stickyTransform), static_cast(stickyTransform)); + switch (stickyTransform) { + // Note: Sticky transforms are a legacy feature and aren't implemented in HOS nor the Android version it is based on, they are effectively inert + // Certain games will still pass in values for sticky transforms (even if they don't do anything), we should not assert on these and verify their validity + case NativeWindowTransform::Identity: + case NativeWindowTransform::MirrorHorizontal: + case NativeWindowTransform::MirrorVertical: + case NativeWindowTransform::Rotate90: + case NativeWindowTransform::Rotate180: + case NativeWindowTransform::Rotate270: + case NativeWindowTransform::MirrorHorizontalRotate90: + case NativeWindowTransform::MirrorVerticalRotate90: + case NativeWindowTransform::InvertDisplay: + break; + + default: + throw exception("Application attempting to perform unknown sticky transformation: {:#b}", static_cast(stickyTransform)); + } fence.Wait(state.soc->host1x); diff --git a/app/src/main/cpp/skyline/services/hosbinder/GraphicBufferProducer.h b/app/src/main/cpp/skyline/services/hosbinder/GraphicBufferProducer.h index 7bcfa6a9..343f3fab 100644 --- a/app/src/main/cpp/skyline/services/hosbinder/GraphicBufferProducer.h +++ b/app/src/main/cpp/skyline/services/hosbinder/GraphicBufferProducer.h @@ -112,7 +112,7 @@ namespace skyline::service::hosbinder { * @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/include/gui/BufferQueueProducer.h;l=106-107 * @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/BufferQueueProducer.cpp;l=466-510 */ - AndroidStatus AttachBuffer(i32& slot, const GraphicBuffer &graphicBuffer); + AndroidStatus AttachBuffer(i32 &slot, const GraphicBuffer &graphicBuffer); /** * @note Nintendo has added an additional field for swap interval which sets the swap interval of the compositor diff --git a/app/src/main/cpp/skyline/services/hosbinder/parcel.h b/app/src/main/cpp/skyline/services/hosbinder/parcel.h index 09dce4da..00c8ba26 100644 --- a/app/src/main/cpp/skyline/services/hosbinder/parcel.h +++ b/app/src/main/cpp/skyline/services/hosbinder/parcel.h @@ -53,7 +53,7 @@ namespace skyline::service::hosbinder { * @return A pointer to an optional flattenable from the top of data, nullptr will be returned if the object doesn't exist */ template - ValueType* PopOptionalFlattenable() { + ValueType *PopOptionalFlattenable() { bool hasObject{static_cast(Pop())}; if (hasObject) { auto size{Pop()}; @@ -72,7 +72,7 @@ namespace skyline::service::hosbinder { void Push(const ValueType &value) { auto offset{data.size()}; data.resize(offset + sizeof(ValueType)); - *(reinterpret_cast(data.data() + offset)) = value; + *(reinterpret_cast(data.data() + offset)) = value; } /** @@ -105,7 +105,7 @@ namespace skyline::service::hosbinder { void PushObject(const ObjectType &object) { auto offset{objects.size()}; objects.resize(offset + sizeof(ObjectType)); - *(reinterpret_cast(objects.data() + offset)) = object; + *(reinterpret_cast(objects.data() + offset)) = object; } /** diff --git a/app/src/main/cpp/skyline/services/visrv/IApplicationRootService.h b/app/src/main/cpp/skyline/services/visrv/IApplicationRootService.h index d4ee4b25..81cc6644 100644 --- a/app/src/main/cpp/skyline/services/visrv/IApplicationRootService.h +++ b/app/src/main/cpp/skyline/services/visrv/IApplicationRootService.h @@ -9,12 +9,12 @@ namespace skyline::service::visrv { /** * @url https://switchbrew.org/wiki/Display_services#vi:u */ - class IApplicationRootService : public IRootService { + class IApplicationRootService : public IRootService { public: IApplicationRootService(const DeviceState &state, ServiceManager &manager) : IRootService(state, manager, PrivilegeLevel::Application) {} - SERVICE_DECL( - SFUNC_BASE(0x0, IApplicationRootService, IRootService, GetDisplayService) - ) + SERVICE_DECL( + SFUNC_BASE(0x0, IApplicationRootService, IRootService, GetDisplayService) + ) }; } diff --git a/app/src/main/cpp/skyline/services/visrv/IManagerDisplayService.h b/app/src/main/cpp/skyline/services/visrv/IManagerDisplayService.h index e4f2b2bd..c7b074fa 100644 --- a/app/src/main/cpp/skyline/services/visrv/IManagerDisplayService.h +++ b/app/src/main/cpp/skyline/services/visrv/IManagerDisplayService.h @@ -29,11 +29,11 @@ namespace skyline::service::visrv { */ Result AddToLayerStack(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); - SERVICE_DECL( - SFUNC(0x7DA, IManagerDisplayService, CreateManagedLayer), - SFUNC(0x7DB, IManagerDisplayService, DestroyManagedLayer), - SFUNC_BASE(0x7DC, IManagerDisplayService, IDisplayService, CreateStrayLayer), - SFUNC(0x1770, IManagerDisplayService, AddToLayerStack) - ) + SERVICE_DECL( + SFUNC(0x7DA, IManagerDisplayService, CreateManagedLayer), + SFUNC(0x7DB, IManagerDisplayService, DestroyManagedLayer), + SFUNC_BASE(0x7DC, IManagerDisplayService, IDisplayService, CreateStrayLayer), + SFUNC(0x1770, IManagerDisplayService, AddToLayerStack) + ) }; } diff --git a/app/src/main/cpp/skyline/services/visrv/ISystemDisplayService.h b/app/src/main/cpp/skyline/services/visrv/ISystemDisplayService.h index 8ffbc05d..b5ba1bc0 100644 --- a/app/src/main/cpp/skyline/services/visrv/ISystemDisplayService.h +++ b/app/src/main/cpp/skyline/services/visrv/ISystemDisplayService.h @@ -19,9 +19,9 @@ namespace skyline::service::visrv { */ Result SetLayerZ(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); - SERVICE_DECL( - SFUNC(0x89D, ISystemDisplayService, SetLayerZ), - SFUNC_BASE(0x908, ISystemDisplayService, IDisplayService, CreateStrayLayer) - ) + SERVICE_DECL( + SFUNC(0x89D, ISystemDisplayService, SetLayerZ), + SFUNC_BASE(0x908, ISystemDisplayService, IDisplayService, CreateStrayLayer) + ) }; }