From 8eb0c64cf4c8450fb4ef33ab28c6431611a62369 Mon Sep 17 00:00:00 2001 From: Vishnu Nair Date: Tue, 5 Oct 2021 13:48:46 -0700 Subject: [PATCH] Rename getSurfaceTransformHint API and switch to using NDK transform constants NDK exposes ANativeWindowTransform/NATIVE_WINDOW_TRANSFORM_*. These constants are aligned with HAL definitions and are used internally to specify buffer transforms. Native consumers of the transform hint are expected to generate ANativeWindowTransform from the hint. Aligning the SDK and the NDK transform values will make the API less confusing. Bug: 196167822 Test: atest AttachedSurfaceControlTest Change-Id: Ib20be045f6c8c6d7befef93a839a27098da55ffa --- core/api/current.txt | 16 +++-- .../android/view/AttachedSurfaceControl.java | 35 +++++----- core/java/android/view/SurfaceControl.java | 70 +++++++++++++++++++ core/java/android/view/SurfaceView.java | 6 +- core/java/android/view/ViewRootImpl.java | 29 ++++---- 5 files changed, 118 insertions(+), 38 deletions(-) diff --git a/core/api/current.txt b/core/api/current.txt index 1d03370e698d8..bc34292ac936b 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -46905,15 +46905,15 @@ package android.view { } @UiThread public interface AttachedSurfaceControl { - method public default void addOnSurfaceTransformHintChangedListener(@NonNull android.view.AttachedSurfaceControl.OnSurfaceTransformHintChangedListener); + method public default void addOnBufferTransformHintChangedListener(@NonNull android.view.AttachedSurfaceControl.OnBufferTransformHintChangedListener); method public boolean applyTransactionOnDraw(@NonNull android.view.SurfaceControl.Transaction); method @Nullable public android.view.SurfaceControl.Transaction buildReparentTransaction(@NonNull android.view.SurfaceControl); - method public default int getSurfaceTransformHint(); - method public default void removeOnSurfaceTransformHintChangedListener(@NonNull android.view.AttachedSurfaceControl.OnSurfaceTransformHintChangedListener); + method public default int getBufferTransformHint(); + method public default void removeOnBufferTransformHintChangedListener(@NonNull android.view.AttachedSurfaceControl.OnBufferTransformHintChangedListener); } - @UiThread public static interface AttachedSurfaceControl.OnSurfaceTransformHintChangedListener { - method public void onSurfaceTransformHintChanged(int); + @UiThread public static interface AttachedSurfaceControl.OnBufferTransformHintChangedListener { + method public void onBufferTransformHintChanged(int); } public final class Choreographer { @@ -48403,6 +48403,12 @@ package android.view { method public void readFromParcel(android.os.Parcel); method public void release(); method public void writeToParcel(android.os.Parcel, int); + field public static final int BUFFER_TRANSFORM_IDENTITY = 0; // 0x0 + field public static final int BUFFER_TRANSFORM_MIRROR_HORIZONTAL = 1; // 0x1 + field public static final int BUFFER_TRANSFORM_MIRROR_VERTICAL = 2; // 0x2 + field public static final int BUFFER_TRANSFORM_ROTATE_180 = 3; // 0x3 + field public static final int BUFFER_TRANSFORM_ROTATE_270 = 7; // 0x7 + field public static final int BUFFER_TRANSFORM_ROTATE_90 = 4; // 0x4 field @NonNull public static final android.os.Parcelable.Creator CREATOR; } diff --git a/core/java/android/view/AttachedSurfaceControl.java b/core/java/android/view/AttachedSurfaceControl.java index b2fc9a0c85fc5..69af2a5ce7fb4 100644 --- a/core/java/android/view/AttachedSurfaceControl.java +++ b/core/java/android/view/AttachedSurfaceControl.java @@ -18,6 +18,7 @@ package android.view; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UiThread; +import android.hardware.HardwareBuffer; /** * Provides an interface to the root-Surface of a View Hierarchy or Window. This @@ -84,41 +85,43 @@ public interface AttachedSurfaceControl { * Note, when using ANativeWindow APIs in conjunction with a NativeActivity Surface or * SurfaceView Surface, the buffer producer will already have access to the transform hint and * no additional work is needed. + * + * @see HardwareBuffer */ - default @Surface.Rotation int getSurfaceTransformHint() { - return Surface.ROTATION_0; + default @SurfaceControl.BufferTransform int getBufferTransformHint() { + return SurfaceControl.BUFFER_TRANSFORM_IDENTITY; } /** - * Surface transform hint change listener. - * @see #getSurfaceTransformHint + * Buffer transform hint change listener. + * @see #getBufferTransformHint */ @UiThread - interface OnSurfaceTransformHintChangedListener { + interface OnBufferTransformHintChangedListener { /** * @param hint new surface transform hint - * @see #getSurfaceTransformHint + * @see #getBufferTransformHint */ - void onSurfaceTransformHintChanged(@Surface.Rotation int hint); + void onBufferTransformHintChanged(@SurfaceControl.BufferTransform int hint); } /** - * Registers a surface transform hint changed listener to receive notifications about when + * Registers a {@link OnBufferTransformHintChangedListener} to receive notifications about when * the transform hint changes. * - * @see #getSurfaceTransformHint - * @see #removeOnSurfaceTransformHintChangedListener + * @see #getBufferTransformHint + * @see #removeOnBufferTransformHintChangedListener */ - default void addOnSurfaceTransformHintChangedListener( - @NonNull OnSurfaceTransformHintChangedListener listener) { + default void addOnBufferTransformHintChangedListener( + @NonNull OnBufferTransformHintChangedListener listener) { } /** - * Unregisters a surface transform hint changed listener. + * Unregisters a {@link OnBufferTransformHintChangedListener}. * - * @see #addOnSurfaceTransformHintChangedListener + * @see #addOnBufferTransformHintChangedListener */ - default void removeOnSurfaceTransformHintChangedListener( - @NonNull OnSurfaceTransformHintChangedListener listener) { + default void removeOnBufferTransformHintChangedListener( + @NonNull OnBufferTransformHintChangedListener listener) { } } diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 5b8dc4055509f..d743ec80fe97a 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -243,6 +243,76 @@ public final class SurfaceControl implements Parcelable { private static native void nativeSetTransformHint(long nativeObject, int transformHint); private static native int nativeGetTransformHint(long nativeObject); + /** + * Transforms that can be applied to buffers as they are displayed to a window. + * + * Supported transforms are any combination of horizontal mirror, vertical mirror, and + * clock-wise 90 degree rotation, in that order. Rotations of 180 and 270 degrees are made up + * of those basic transforms. + * Mirrors {@code ANativeWindowTransform} definitions. + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"BUFFER_TRANSFORM_"}, + value = {BUFFER_TRANSFORM_IDENTITY, BUFFER_TRANSFORM_MIRROR_HORIZONTAL, + BUFFER_TRANSFORM_MIRROR_VERTICAL, BUFFER_TRANSFORM_ROTATE_90, + BUFFER_TRANSFORM_ROTATE_180, BUFFER_TRANSFORM_ROTATE_270, + BUFFER_TRANSFORM_MIRROR_HORIZONTAL | BUFFER_TRANSFORM_ROTATE_90, + BUFFER_TRANSFORM_MIRROR_VERTICAL | BUFFER_TRANSFORM_ROTATE_90}) + public @interface BufferTransform { + } + + /** + * Identity transform. + * + * These transforms that can be applied to buffers as they are displayed to a window. + * @see HardwareBuffer + * + * Supported transforms are any combination of horizontal mirror, vertical mirror, and + * clock-wise 90 degree rotation, in that order. Rotations of 180 and 270 degrees are + * made up of those basic transforms. + */ + public static final int BUFFER_TRANSFORM_IDENTITY = 0x00; + /** + * Mirror horizontally. Can be combined with {@link #BUFFER_TRANSFORM_MIRROR_VERTICAL} + * and {@link #BUFFER_TRANSFORM_ROTATE_90}. + */ + public static final int BUFFER_TRANSFORM_MIRROR_HORIZONTAL = 0x01; + /** + * Mirror vertically. Can be combined with {@link #BUFFER_TRANSFORM_MIRROR_HORIZONTAL} + * and {@link #BUFFER_TRANSFORM_ROTATE_90}. + */ + public static final int BUFFER_TRANSFORM_MIRROR_VERTICAL = 0x02; + /** + * Rotate 90 degrees clock-wise. Can be combined with {@link + * #BUFFER_TRANSFORM_MIRROR_HORIZONTAL} and {@link #BUFFER_TRANSFORM_MIRROR_VERTICAL}. + */ + public static final int BUFFER_TRANSFORM_ROTATE_90 = 0x04; + /** + * Rotate 180 degrees clock-wise. Cannot be combined with other transforms. + */ + public static final int BUFFER_TRANSFORM_ROTATE_180 = + BUFFER_TRANSFORM_MIRROR_HORIZONTAL | BUFFER_TRANSFORM_MIRROR_VERTICAL; + /** + * Rotate 270 degrees clock-wise. Cannot be combined with other transforms. + */ + public static final int BUFFER_TRANSFORM_ROTATE_270 = + BUFFER_TRANSFORM_ROTATE_180 | BUFFER_TRANSFORM_ROTATE_90; + + /** + * @hide + */ + public static @BufferTransform int rotationToBufferTransform(@Surface.Rotation int rotation) { + switch (rotation) { + case Surface.ROTATION_0: return BUFFER_TRANSFORM_IDENTITY; + case Surface.ROTATION_90: return BUFFER_TRANSFORM_ROTATE_90; + case Surface.ROTATION_180: return BUFFER_TRANSFORM_ROTATE_180; + case Surface.ROTATION_270: return BUFFER_TRANSFORM_ROTATE_270; + } + Log.e(TAG, "Trying to convert unknown rotation=" + rotation); + return BUFFER_TRANSFORM_IDENTITY; + } + @Nullable @GuardedBy("mLock") private ArrayList mReparentListeners; diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 60bb99d37c399..63757e373795e 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -1104,7 +1104,7 @@ 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) + final boolean hintChanged = (viewRoot.getBufferTransformHint() != mTransformHint) && mRequestedVisible; if (creating || formatChanged || sizeChanged || visibleChanged || @@ -1130,7 +1130,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall mSurfaceHeight = myHeight; mFormat = mRequestedFormat; mLastWindowVisibility = mWindowVisibility; - mTransformHint = viewRoot.getSurfaceTransformHint(); + mTransformHint = viewRoot.getBufferTransformHint(); mScreenRect.left = mWindowSpaceLeft; mScreenRect.top = mWindowSpaceTop; @@ -1362,7 +1362,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall if (mBlastBufferQueue != null) { mBlastBufferQueue.destroy(); } - mTransformHint = viewRoot.getSurfaceTransformHint(); + mTransformHint = viewRoot.getBufferTransformHint(); mBlastSurfaceControl.setTransformHint(mTransformHint); mBlastBufferQueue = new BLASTBufferQueue(name, mBlastSurfaceControl, mSurfaceWidth, mSurfaceHeight, mFormat); diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index c45b27a8a2c20..8b791a4941f44 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -312,7 +312,7 @@ public final class ViewRootImpl implements ViewParent, static final ArrayList sFirstDrawHandlers = new ArrayList<>(); static boolean sFirstDrawComplete = false; - private ArrayList mTransformHintListeners = + private ArrayList mTransformHintListeners = new ArrayList<>(); private @Surface.Rotation int mPreviousTransformHint = Surface.ROTATION_0; /** @@ -7872,7 +7872,8 @@ public final class ViewRootImpl implements ViewParent, int transformHint = mSurfaceControl.getTransformHint(); if (mPreviousTransformHint != transformHint) { mPreviousTransformHint = transformHint; - dispatchTransformHintChanged(transformHint); + dispatchTransformHintChanged( + SurfaceControl.rotationToBufferTransform(transformHint)); } } else { destroySurface(); @@ -10499,38 +10500,38 @@ public final class ViewRootImpl implements ViewParent, } @Override - public @Surface.Rotation int getSurfaceTransformHint() { - return mSurfaceControl.getTransformHint(); + public @SurfaceControl.BufferTransform int getBufferTransformHint() { + return SurfaceControl.rotationToBufferTransform(mSurfaceControl.getTransformHint()); } @Override - public void addOnSurfaceTransformHintChangedListener( - OnSurfaceTransformHintChangedListener listener) { + public void addOnBufferTransformHintChangedListener( + OnBufferTransformHintChangedListener listener) { Objects.requireNonNull(listener); if (mTransformHintListeners.contains(listener)) { throw new IllegalArgumentException( - "attempt to call addOnSurfaceTransformHintChangedListener() " + "attempt to call addOnBufferTransformHintChangedListener() " + "with a previously registered listener"); } mTransformHintListeners.add(listener); } @Override - public void removeOnSurfaceTransformHintChangedListener( - OnSurfaceTransformHintChangedListener listener) { + public void removeOnBufferTransformHintChangedListener( + OnBufferTransformHintChangedListener listener) { Objects.requireNonNull(listener); mTransformHintListeners.remove(listener); } - private void dispatchTransformHintChanged(@Surface.Rotation int hint) { + private void dispatchTransformHintChanged(@SurfaceControl.BufferTransform int hint) { if (mTransformHintListeners.isEmpty()) { return; } - ArrayList listeners = - (ArrayList) mTransformHintListeners.clone(); + ArrayList listeners = + (ArrayList) mTransformHintListeners.clone(); for (int i = 0; i < listeners.size(); i++) { - OnSurfaceTransformHintChangedListener listener = listeners.get(i); - listener.onSurfaceTransformHintChanged(hint); + OnBufferTransformHintChangedListener listener = listeners.get(i); + listener.onBufferTransformHintChanged(hint); } } }