diff options
| author | 2020-05-08 18:03:12 -0700 | |
|---|---|---|
| committer | 2020-05-11 13:19:59 -0700 | |
| commit | eb53e523957de8967b0c391166b63fa7835c9833 (patch) | |
| tree | 1b10a3ca8e2dcb72bc853821bd310dd5fc57a6d8 | |
| parent | 5d92729cbc864cdc2534d10d79dc6be7fe9b09b1 (diff) | |
Provide a fixed transform hint if the layer is in a fixed orientation 2/2
The transform hint is used to prevent allocating a buffer of a
different size when a layer is rotated. The producer can choose to
consume the hint and allocate the buffer with the same size.
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.
Bug: 152919661
Test: atest VulkanPreTransformTest
Test: confirm with winscope trace, buffers are allocated taking into
account the transform hint in fixed orientation scenarios
Test: go/wm-smoke
Change-Id: I2ccc21ed8af015716e6cdfde1e3cec67c99f3339
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; + } } |