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).
This commit is contained in:
PixelyIon 2021-07-06 00:19:53 +05:30
parent 0e02f1900f
commit e7aa439029
7 changed files with 37 additions and 24 deletions

View File

@ -23,7 +23,7 @@ namespace skyline::gpu {
std::mutex mutex; //!< Synchronizes access to the surface objects std::mutex mutex; //!< Synchronizes access to the surface objects
std::condition_variable surfaceCondition; //!< Allows us to efficiently wait for Vulkan surface to be initialized std::condition_variable surfaceCondition; //!< Allows us to efficiently wait for Vulkan surface to be initialized
jobject jSurface{}; //!< The Java Surface object backing the ANativeWindow 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::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::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 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 * @param frameId The ID of this frame for correlating it with presentation timing readouts
* @note The texture **must** be locked prior to calling this * @note The texture **must** be locked prior to calling this
*/ */
void Present(const std::shared_ptr<Texture> &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> &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 * @return A transform that the application should render with to elide costly transforms later

View File

@ -364,10 +364,23 @@ namespace skyline::service::hosbinder {
throw exception("Application attempting to perform unknown transformation: {:#b}", static_cast<u32>(transform)); throw exception("Application attempting to perform unknown transformation: {:#b}", static_cast<u32>(transform));
} }
if (stickyTransform != NativeWindowTransform::Identity) switch (stickyTransform) {
// We do not support sticky transforms as they are only used by the LEGACY camera mode // 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
// Note: This is used on HOS to signal that the frame number should be returned but it's unimplemented // 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
throw exception("Any non-identity sticky transform is not supported: '{}' ({:#b})", ToString(stickyTransform), static_cast<u32>(stickyTransform)); 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<u32>(stickyTransform));
}
fence.Wait(state.soc->host1x); fence.Wait(state.soc->host1x);

View File

@ -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/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 * @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 * @note Nintendo has added an additional field for swap interval which sets the swap interval of the compositor

View File

@ -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 * @return A pointer to an optional flattenable from the top of data, nullptr will be returned if the object doesn't exist
*/ */
template<typename ValueType> template<typename ValueType>
ValueType* PopOptionalFlattenable() { ValueType *PopOptionalFlattenable() {
bool hasObject{static_cast<bool>(Pop<u32>())}; bool hasObject{static_cast<bool>(Pop<u32>())};
if (hasObject) { if (hasObject) {
auto size{Pop<u64>()}; auto size{Pop<u64>()};
@ -72,7 +72,7 @@ namespace skyline::service::hosbinder {
void Push(const ValueType &value) { void Push(const ValueType &value) {
auto offset{data.size()}; auto offset{data.size()};
data.resize(offset + sizeof(ValueType)); data.resize(offset + sizeof(ValueType));
*(reinterpret_cast<ValueType*>(data.data() + offset)) = value; *(reinterpret_cast<ValueType *>(data.data() + offset)) = value;
} }
/** /**
@ -105,7 +105,7 @@ namespace skyline::service::hosbinder {
void PushObject(const ObjectType &object) { void PushObject(const ObjectType &object) {
auto offset{objects.size()}; auto offset{objects.size()};
objects.resize(offset + sizeof(ObjectType)); objects.resize(offset + sizeof(ObjectType));
*(reinterpret_cast<ObjectType*>(objects.data() + offset)) = object; *(reinterpret_cast<ObjectType *>(objects.data() + offset)) = object;
} }
/** /**