diff options
6 files changed, 78 insertions, 4 deletions
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index c0c29eba41d1..9109f50247e0 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -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; @@ -2307,6 +2309,39 @@ public final class SurfaceControl implements Parcelable { } /** + * 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 * with a negative Z will be placed below the parent surface. diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 36b4b6aad4b4..e553a786da96 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -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()); @@ -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) diff --git a/services/core/java/com/android/server/wm/SeamlessRotator.java b/services/core/java/com/android/server/wm/SeamlessRotator.java index c79cb04a824f..3d305e4d852d 100644 --- a/services/core/java/com/android/server/wm/SeamlessRotator.java +++ b/services/core/java/com/android/server/wm/SeamlessRotator.java @@ -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; @@ -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); + } } /** @@ -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) { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index f6473fd8acd1..49d6889b95f9 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -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 */); diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index 472773e1bb1a..96d8124e2793 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -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 */); } /** diff --git a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java index 851b0523b058..d7eedd990f04 100644 --- a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java +++ b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java @@ -16,6 +16,7 @@ package com.android.server.wm; +import android.annotation.NonNull; import android.graphics.Matrix; import android.graphics.Rect; import android.graphics.Region; @@ -265,4 +266,15 @@ public class StubTransaction extends SurfaceControl.Transaction { public SurfaceControl.Transaction setShadowRadius(SurfaceControl sc, float shadowRadius) { return this; } + + @Override + public SurfaceControl.Transaction setFixedTransformHint(SurfaceControl sc, + @Surface.Rotation int transformHint) { + return this; + } + + @Override + public SurfaceControl.Transaction unsetFixedTransformHint(@NonNull SurfaceControl sc) { + return this; + } } |