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
This commit is contained in:
Vishnu Nair
2020-05-08 18:03:12 -07:00
parent 5d92729cbc
commit eb53e52395
6 changed files with 78 additions and 4 deletions

View File

@@ -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;
@@ -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

View File

@@ -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)

View File

@@ -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) {

View File

@@ -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 */);

View File

@@ -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 */);
}
/**

View File

@@ -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;
}
}