Loading core/java/android/view/SurfaceControl.java +35 −0 Original line number Diff line number Diff line Loading @@ -220,6 +220,8 @@ public final class SurfaceControl implements Parcelable { private static native long nativeAcquireFrameRateFlexibilityToken(); private static native void nativeReleaseFrameRateFlexibilityToken(long token); private static native void nativeSetFixedTransformHint(long transactionObj, long nativeObject, int transformHint); private final CloseGuard mCloseGuard = CloseGuard.get(); private String mName; Loading Loading @@ -2306,6 +2308,39 @@ public final class SurfaceControl implements Parcelable { return this; } /** * Provide the graphic producer a transform hint if the layer and its children are * in an orientation different from the display's orientation. The caller is responsible * for clearing this transform hint if the layer is no longer in a fixed orientation. * * The transform hint is used to prevent allocating a buffer of different size when a * layer is rotated. The producer can choose to consume the hint and allocate the buffer * with the same size. * * @return This Transaction. * @hide */ @NonNull public Transaction setFixedTransformHint(@NonNull SurfaceControl sc, @Surface.Rotation int transformHint) { checkPreconditions(sc); nativeSetFixedTransformHint(mNativeObject, sc.mNativeObject, transformHint); return this; } /** * Clearing any transform hint if set on this layer. * * @return This Transaction. * @hide */ @NonNull public Transaction unsetFixedTransformHint(@NonNull SurfaceControl sc) { checkPreconditions(sc); nativeSetFixedTransformHint(mNativeObject, sc.mNativeObject, -1/* INVALID_ROTATION */); return this; } /** * Set the Z-order for a given SurfaceControl, relative to it's siblings. * If two siblings share the same Z order the ordering is undefined. Surfaces Loading core/jni/android_view_SurfaceControl.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -645,6 +645,14 @@ static void nativeReleaseFrameRateFlexibilityToken(JNIEnv* env, jclass clazz, jl token->decStrong((void*)nativeAcquireFrameRateFlexibilityToken); } static void nativeSetFixedTransformHint(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject, jint transformHint) { auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj); SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject); transaction->setFixedTransformHint(ctrl, transformHint); } static jlongArray nativeGetPhysicalDisplayIds(JNIEnv* env, jclass clazz) { const auto displayIds = SurfaceComposerClient::getPhysicalDisplayIds(); jlongArray array = env->NewLongArray(displayIds.size()); Loading Loading @@ -1644,6 +1652,7 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeSetGlobalShadowSettings }, {"nativeGetHandle", "(J)J", (void*)nativeGetHandle }, {"nativeSetFixedTransformHint", "(JJI)V", (void*)nativeSetFixedTransformHint}, }; int register_android_view_SurfaceControl(JNIEnv* env) Loading services/core/java/com/android/server/wm/SeamlessRotator.java +19 −2 Original line number Diff line number Diff line Loading @@ -45,11 +45,22 @@ public class SeamlessRotator { private final float[] mFloat9 = new float[9]; private final int mOldRotation; private final int mNewRotation; /* If the seamless rotator is used to rotate part of the hierarchy, then provide a transform * hint based on the display orientation if the entire display was rotated. When the display * orientation matches the hierarchy orientation, the fixed transform hint will be removed. * This will prevent allocating different buffer sizes by the graphic producers when the * orientation of a layer changes. */ private final boolean mApplyFixedTransformHint; private final int mFixedTransformHint; public SeamlessRotator(@Rotation int oldRotation, @Rotation int newRotation, DisplayInfo info) { public SeamlessRotator(@Rotation int oldRotation, @Rotation int newRotation, DisplayInfo info, boolean applyFixedTransformationHint) { mOldRotation = oldRotation; mNewRotation = newRotation; mApplyFixedTransformHint = applyFixedTransformationHint; mFixedTransformHint = oldRotation; final boolean flipped = info.rotation == ROTATION_90 || info.rotation == ROTATION_270; final int pH = flipped ? info.logicalWidth : info.logicalHeight; final int pW = flipped ? info.logicalHeight : info.logicalWidth; Loading @@ -70,6 +81,9 @@ public class SeamlessRotator { final float[] winSurfacePos = {win.mLastSurfacePosition.x, win.mLastSurfacePosition.y}; mTransform.mapPoints(winSurfacePos); transaction.setPosition(win.getSurfaceControl(), winSurfacePos[0], winSurfacePos[1]); if (mApplyFixedTransformHint) { transaction.setFixedTransformHint(win.mSurfaceControl, mFixedTransformHint); } } /** Loading Loading @@ -109,6 +123,9 @@ public class SeamlessRotator { mTransform.reset(); t.setMatrix(win.mSurfaceControl, mTransform, mFloat9); t.setPosition(win.mSurfaceControl, win.mLastSurfacePosition.x, win.mLastSurfacePosition.y); if (mApplyFixedTransformHint) { t.unsetFixedTransformHint(win.mSurfaceControl); } } public void dump(PrintWriter pw) { Loading services/core/java/com/android/server/wm/WindowState.java +2 −1 Original line number Diff line number Diff line Loading @@ -741,7 +741,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (mControllableInsetProvider != null) { mControllableInsetProvider.startSeamlessRotation(); } mPendingSeamlessRotate = new SeamlessRotator(oldRotation, rotation, getDisplayInfo()); mPendingSeamlessRotate = new SeamlessRotator(oldRotation, rotation, getDisplayInfo(), false /* applyFixedTransformationHint */); mPendingSeamlessRotate.unrotate(transaction, this); getDisplayContent().getDisplayRotation().markForSeamlessRotation(this, true /* seamlesslyRotated */); Loading services/core/java/com/android/server/wm/WindowToken.java +1 −1 Original line number Diff line number Diff line Loading @@ -141,7 +141,7 @@ class WindowToken extends WindowContainer<WindowState> { mRotatedOverrideConfiguration = rotatedConfig; // This will use unrotate as rotate, so the new and old rotation are inverted. mRotator = new SeamlessRotator(rotatedDisplayInfo.rotation, currentRotation, rotatedDisplayInfo); rotatedDisplayInfo, true /* applyFixedTransformationHint */); } /** Loading Loading
core/java/android/view/SurfaceControl.java +35 −0 Original line number Diff line number Diff line Loading @@ -220,6 +220,8 @@ public final class SurfaceControl implements Parcelable { private static native long nativeAcquireFrameRateFlexibilityToken(); private static native void nativeReleaseFrameRateFlexibilityToken(long token); private static native void nativeSetFixedTransformHint(long transactionObj, long nativeObject, int transformHint); private final CloseGuard mCloseGuard = CloseGuard.get(); private String mName; Loading Loading @@ -2306,6 +2308,39 @@ public final class SurfaceControl implements Parcelable { return this; } /** * Provide the graphic producer a transform hint if the layer and its children are * in an orientation different from the display's orientation. The caller is responsible * for clearing this transform hint if the layer is no longer in a fixed orientation. * * The transform hint is used to prevent allocating a buffer of different size when a * layer is rotated. The producer can choose to consume the hint and allocate the buffer * with the same size. * * @return This Transaction. * @hide */ @NonNull public Transaction setFixedTransformHint(@NonNull SurfaceControl sc, @Surface.Rotation int transformHint) { checkPreconditions(sc); nativeSetFixedTransformHint(mNativeObject, sc.mNativeObject, transformHint); return this; } /** * Clearing any transform hint if set on this layer. * * @return This Transaction. * @hide */ @NonNull public Transaction unsetFixedTransformHint(@NonNull SurfaceControl sc) { checkPreconditions(sc); nativeSetFixedTransformHint(mNativeObject, sc.mNativeObject, -1/* INVALID_ROTATION */); return this; } /** * Set the Z-order for a given SurfaceControl, relative to it's siblings. * If two siblings share the same Z order the ordering is undefined. Surfaces Loading
core/jni/android_view_SurfaceControl.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -645,6 +645,14 @@ static void nativeReleaseFrameRateFlexibilityToken(JNIEnv* env, jclass clazz, jl token->decStrong((void*)nativeAcquireFrameRateFlexibilityToken); } static void nativeSetFixedTransformHint(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject, jint transformHint) { auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj); SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject); transaction->setFixedTransformHint(ctrl, transformHint); } static jlongArray nativeGetPhysicalDisplayIds(JNIEnv* env, jclass clazz) { const auto displayIds = SurfaceComposerClient::getPhysicalDisplayIds(); jlongArray array = env->NewLongArray(displayIds.size()); Loading Loading @@ -1644,6 +1652,7 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeSetGlobalShadowSettings }, {"nativeGetHandle", "(J)J", (void*)nativeGetHandle }, {"nativeSetFixedTransformHint", "(JJI)V", (void*)nativeSetFixedTransformHint}, }; int register_android_view_SurfaceControl(JNIEnv* env) Loading
services/core/java/com/android/server/wm/SeamlessRotator.java +19 −2 Original line number Diff line number Diff line Loading @@ -45,11 +45,22 @@ public class SeamlessRotator { private final float[] mFloat9 = new float[9]; private final int mOldRotation; private final int mNewRotation; /* If the seamless rotator is used to rotate part of the hierarchy, then provide a transform * hint based on the display orientation if the entire display was rotated. When the display * orientation matches the hierarchy orientation, the fixed transform hint will be removed. * This will prevent allocating different buffer sizes by the graphic producers when the * orientation of a layer changes. */ private final boolean mApplyFixedTransformHint; private final int mFixedTransformHint; public SeamlessRotator(@Rotation int oldRotation, @Rotation int newRotation, DisplayInfo info) { public SeamlessRotator(@Rotation int oldRotation, @Rotation int newRotation, DisplayInfo info, boolean applyFixedTransformationHint) { mOldRotation = oldRotation; mNewRotation = newRotation; mApplyFixedTransformHint = applyFixedTransformationHint; mFixedTransformHint = oldRotation; final boolean flipped = info.rotation == ROTATION_90 || info.rotation == ROTATION_270; final int pH = flipped ? info.logicalWidth : info.logicalHeight; final int pW = flipped ? info.logicalHeight : info.logicalWidth; Loading @@ -70,6 +81,9 @@ public class SeamlessRotator { final float[] winSurfacePos = {win.mLastSurfacePosition.x, win.mLastSurfacePosition.y}; mTransform.mapPoints(winSurfacePos); transaction.setPosition(win.getSurfaceControl(), winSurfacePos[0], winSurfacePos[1]); if (mApplyFixedTransformHint) { transaction.setFixedTransformHint(win.mSurfaceControl, mFixedTransformHint); } } /** Loading Loading @@ -109,6 +123,9 @@ public class SeamlessRotator { mTransform.reset(); t.setMatrix(win.mSurfaceControl, mTransform, mFloat9); t.setPosition(win.mSurfaceControl, win.mLastSurfacePosition.x, win.mLastSurfacePosition.y); if (mApplyFixedTransformHint) { t.unsetFixedTransformHint(win.mSurfaceControl); } } public void dump(PrintWriter pw) { Loading
services/core/java/com/android/server/wm/WindowState.java +2 −1 Original line number Diff line number Diff line Loading @@ -741,7 +741,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (mControllableInsetProvider != null) { mControllableInsetProvider.startSeamlessRotation(); } mPendingSeamlessRotate = new SeamlessRotator(oldRotation, rotation, getDisplayInfo()); mPendingSeamlessRotate = new SeamlessRotator(oldRotation, rotation, getDisplayInfo(), false /* applyFixedTransformationHint */); mPendingSeamlessRotate.unrotate(transaction, this); getDisplayContent().getDisplayRotation().markForSeamlessRotation(this, true /* seamlesslyRotated */); Loading
services/core/java/com/android/server/wm/WindowToken.java +1 −1 Original line number Diff line number Diff line Loading @@ -141,7 +141,7 @@ class WindowToken extends WindowContainer<WindowState> { mRotatedOverrideConfiguration = rotatedConfig; // This will use unrotate as rotate, so the new and old rotation are inverted. mRotator = new SeamlessRotator(rotatedDisplayInfo.rotation, currentRotation, rotatedDisplayInfo); rotatedDisplayInfo, true /* applyFixedTransformationHint */); } /** Loading