summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/SurfaceControl.java35
-rw-r--r--core/jni/android_view_SurfaceControl.cpp9
-rw-r--r--services/core/java/com/android/server/wm/SeamlessRotator.java21
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java3
-rw-r--r--services/core/java/com/android/server/wm/WindowToken.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/StubTransaction.java12
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;
+ }
}