Update transform hint from relayout window (1/2)
The transform hint is used to prevent allocating a buffer of a different size when a window is rotated. We return the fixed rotation transform and pass it to BLASTBufferQueue so the producer can choose to consume the hint and allocate the buffer with the same size. Bug: 188893403 Bug: 177029197 Test: atest WmTests Test: gfxbenchmark Test: atest libsurfaceflinger_unittest SurfaceFlinger_test Change-Id: If631984cf6b4b74ccdf19547fd6a63e759ed5732
This commit is contained in:
@@ -233,6 +233,7 @@ public final class SurfaceControl implements Parcelable {
|
||||
private static native void nativeRemoveJankDataListener(long nativeListener);
|
||||
private static native long nativeCreateJankDataListenerWrapper(OnJankDataListener listener);
|
||||
private static native int nativeGetGPUContextPriority();
|
||||
private static native void nativeSetTransformHint(long nativeObject, int transformHint);
|
||||
|
||||
@Nullable
|
||||
@GuardedBy("mLock")
|
||||
@@ -348,6 +349,8 @@ public final class SurfaceControl implements Parcelable {
|
||||
@GuardedBy("mLock")
|
||||
private int mHeight;
|
||||
|
||||
private int mTransformHint;
|
||||
|
||||
private WeakReference<View> mLocalOwnerView;
|
||||
|
||||
static GlobalTransactionWrapper sGlobalTransaction;
|
||||
@@ -605,6 +608,7 @@ public final class SurfaceControl implements Parcelable {
|
||||
mName = other.mName;
|
||||
mWidth = other.mWidth;
|
||||
mHeight = other.mHeight;
|
||||
mTransformHint = other.mTransformHint;
|
||||
mLocalOwnerView = other.mLocalOwnerView;
|
||||
assignNativeObject(nativeCopyFromSurfaceControl(other.mNativeObject), callsite);
|
||||
}
|
||||
@@ -1467,6 +1471,7 @@ public final class SurfaceControl implements Parcelable {
|
||||
mName = in.readString8();
|
||||
mWidth = in.readInt();
|
||||
mHeight = in.readInt();
|
||||
mTransformHint = in.readInt();
|
||||
|
||||
long object = 0;
|
||||
if (in.readInt() != 0) {
|
||||
@@ -1485,6 +1490,7 @@ public final class SurfaceControl implements Parcelable {
|
||||
dest.writeString8(mName);
|
||||
dest.writeInt(mWidth);
|
||||
dest.writeInt(mHeight);
|
||||
dest.writeInt(mTransformHint);
|
||||
if (mNativeObject == 0) {
|
||||
dest.writeInt(0);
|
||||
} else {
|
||||
@@ -3602,4 +3608,27 @@ public final class SurfaceControl implements Parcelable {
|
||||
mHeight = h;
|
||||
nativeUpdateDefaultBufferSize(mNativeObject, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public int getTransformHint() {
|
||||
return mTransformHint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the transform hint of current SurfaceControl. Only affect if type is
|
||||
* {@link #FX_SURFACE_BLAST}
|
||||
*
|
||||
* 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.
|
||||
* @hide
|
||||
*/
|
||||
public void setTransformHint(@Surface.Rotation int transformHint) {
|
||||
if (mTransformHint != transformHint) {
|
||||
mTransformHint = transformHint;
|
||||
nativeSetTransformHint(mNativeObject, transformHint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ import android.graphics.BLASTBufferQueue;
|
||||
import android.graphics.BlendMode;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.HardwareRenderer;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PixelFormat;
|
||||
@@ -214,6 +213,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
||||
final Rect mSurfaceFrame = new Rect();
|
||||
int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1;
|
||||
int mTransformHint = 0;
|
||||
|
||||
private boolean mGlobalListenersAdded;
|
||||
private boolean mAttachedToWindow;
|
||||
@@ -944,7 +944,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
}
|
||||
|
||||
private boolean performSurfaceTransaction(ViewRootImpl viewRoot, Translator translator,
|
||||
boolean creating, boolean sizeChanged) {
|
||||
boolean creating, boolean sizeChanged, boolean hintChanged) {
|
||||
boolean realSizeChanged = false;
|
||||
|
||||
mSurfaceLock.lock();
|
||||
@@ -1009,7 +1009,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
}
|
||||
}
|
||||
mTmpTransaction.setCornerRadius(mSurfaceControl, mCornerRadius);
|
||||
if (sizeChanged && !creating) {
|
||||
if ((sizeChanged || hintChanged) && !creating) {
|
||||
setBufferSize(mTmpTransaction);
|
||||
}
|
||||
|
||||
@@ -1081,17 +1081,18 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
|| mWindowSpaceTop != mLocation[1];
|
||||
final boolean layoutSizeChanged = getWidth() != mScreenRect.width()
|
||||
|| getHeight() != mScreenRect.height();
|
||||
|
||||
final boolean hintChanged = viewRoot.getSurfaceTransformHint() != mTransformHint;
|
||||
|
||||
if (creating || formatChanged || sizeChanged || visibleChanged ||
|
||||
(mUseAlpha && alphaChanged) || windowVisibleChanged ||
|
||||
positionChanged || layoutSizeChanged) {
|
||||
positionChanged || layoutSizeChanged || hintChanged) {
|
||||
getLocationInWindow(mLocation);
|
||||
|
||||
if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
|
||||
+ "Changes: creating=" + creating
|
||||
+ " format=" + formatChanged + " size=" + sizeChanged
|
||||
+ " visible=" + visibleChanged + " alpha=" + alphaChanged
|
||||
+ " hint=" + hintChanged
|
||||
+ " mUseAlpha=" + mUseAlpha
|
||||
+ " visible=" + visibleChanged
|
||||
+ " left=" + (mWindowSpaceLeft != mLocation[0])
|
||||
@@ -1105,6 +1106,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
mSurfaceHeight = myHeight;
|
||||
mFormat = mRequestedFormat;
|
||||
mLastWindowVisibility = mWindowVisibility;
|
||||
mTransformHint = viewRoot.getSurfaceTransformHint();
|
||||
|
||||
mScreenRect.left = mWindowSpaceLeft;
|
||||
mScreenRect.top = mWindowSpaceTop;
|
||||
@@ -1130,9 +1132,9 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
}
|
||||
|
||||
final boolean realSizeChanged = performSurfaceTransaction(viewRoot,
|
||||
translator, creating, sizeChanged);
|
||||
final boolean redrawNeeded = sizeChanged || creating ||
|
||||
(mVisible && !mDrawFinished);
|
||||
translator, creating, sizeChanged, hintChanged);
|
||||
final boolean redrawNeeded = sizeChanged || creating || hintChanged
|
||||
|| (mVisible && !mDrawFinished);
|
||||
|
||||
try {
|
||||
SurfaceHolder.Callback[] callbacks = null;
|
||||
@@ -1158,7 +1160,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
c.surfaceCreated(mSurfaceHolder);
|
||||
}
|
||||
}
|
||||
if (creating || formatChanged || sizeChanged
|
||||
if (creating || formatChanged || sizeChanged || hintChanged
|
||||
|| visibleChanged || realSizeChanged) {
|
||||
if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
|
||||
+ "surfaceChanged -- format=" + mFormat
|
||||
@@ -1234,6 +1236,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
|
||||
private void setBufferSize(Transaction transaction) {
|
||||
if (mUseBlastAdapter) {
|
||||
mBlastSurfaceControl.setTransformHint(mTransformHint);
|
||||
mBlastBufferQueue.update(mBlastSurfaceControl, mSurfaceWidth, mSurfaceHeight, mFormat);
|
||||
} else {
|
||||
transaction.setBufferSize(mSurfaceControl, mSurfaceWidth, mSurfaceHeight);
|
||||
@@ -1330,6 +1333,8 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
if (mBlastBufferQueue != null) {
|
||||
mBlastBufferQueue.destroy();
|
||||
}
|
||||
mTransformHint = viewRoot.getSurfaceTransformHint();
|
||||
mBlastSurfaceControl.setTransformHint(mTransformHint);
|
||||
mBlastBufferQueue = new BLASTBufferQueue(name, mBlastSurfaceControl, mSurfaceWidth,
|
||||
mSurfaceHeight, mFormat);
|
||||
}
|
||||
|
||||
@@ -10353,4 +10353,8 @@ public final class ViewRootImpl implements ViewParent,
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
int getSurfaceTransformHint() {
|
||||
return mSurfaceControl.getTransformHint();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1775,6 +1775,16 @@ static jint nativeGetGPUContextPriority(JNIEnv* env, jclass clazz) {
|
||||
return static_cast<jint>(SurfaceComposerClient::getGPUContextPriority());
|
||||
}
|
||||
|
||||
static void nativeSetTransformHint(JNIEnv* env, jclass clazz, jlong nativeSurfaceControl,
|
||||
jint transformHint) {
|
||||
sp<SurfaceControl> surface(reinterpret_cast<SurfaceControl*>(nativeSurfaceControl));
|
||||
if (surface == nullptr) {
|
||||
return;
|
||||
}
|
||||
surface->setTransformHint(
|
||||
ui::Transform::toRotationFlags(static_cast<ui::Rotation>(transformHint)));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static const JNINativeMethod sSurfaceControlMethods[] = {
|
||||
@@ -1962,6 +1972,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
|
||||
(void*)nativeCreateJankDataListenerWrapper },
|
||||
{"nativeGetGPUContextPriority", "()I",
|
||||
(void*)nativeGetGPUContextPriority },
|
||||
{"nativeSetTransformHint", "(JI)V",
|
||||
(void*)nativeSetTransformHint },
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
|
||||
@@ -2463,6 +2463,17 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
configChanged = displayContent.updateOrientation();
|
||||
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
|
||||
|
||||
final DisplayInfo rotatedDisplayInfo =
|
||||
win.mToken.getFixedRotationTransformDisplayInfo();
|
||||
if (rotatedDisplayInfo != null) {
|
||||
outSurfaceControl.setTransformHint(rotatedDisplayInfo.rotation);
|
||||
} else {
|
||||
// We have to update the transform hint of display here, but we need to get if from
|
||||
// SurfaceFlinger, so set it as rotation of display for most cases, then
|
||||
// SurfaceFlinger would still update the transform hint of display in next frame.
|
||||
outSurfaceControl.setTransformHint(displayContent.getDisplayInfo().rotation);
|
||||
}
|
||||
|
||||
if (toBeDisplayed && win.mIsWallpaper) {
|
||||
displayContent.mWallpaperController.updateWallpaperOffset(win, false /* sync */);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user