Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eb53e523 authored by Vishnu Nair's avatar Vishnu Nair
Browse files

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
parent 5d92729c
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -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
+9 −0
Original line number Diff line number Diff line
@@ -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)
+19 −2
Original line number Diff line number Diff line
@@ -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) {
+2 −1
Original line number Diff line number Diff line
@@ -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 */);
+1 −1
Original line number Diff line number Diff line
@@ -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 */);
        }

        /**
Loading