summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorTreeHugger Robot <treehugger-gerrit@google.com>2021-09-22 23:55:07 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2021-09-22 23:55:07 +0000
commitdedfe23d543b98605a509a5e6071d98aa89c2e44 (patch)
tree0fe3ec8fac41fc6434ab3cc2c49815f10dd0af78 /core/java/android
parentb5d43be7029fb2a18ed059ae4c470daf509da3bd (diff)
parent1f19e1141e3f40f2f5af0c6b750bde7f13047eaf (diff)
Merge "Expose getSurfaceTransformHint API" into sc-v2-dev
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/view/AttachedSurfaceControl.java68
-rw-r--r--core/java/android/view/ViewRootImpl.java42
2 files changed, 109 insertions, 1 deletions
diff --git a/core/java/android/view/AttachedSurfaceControl.java b/core/java/android/view/AttachedSurfaceControl.java
index bcc5b56459bb..b2fc9a0c85fc 100644
--- a/core/java/android/view/AttachedSurfaceControl.java
+++ b/core/java/android/view/AttachedSurfaceControl.java
@@ -53,4 +53,72 @@ public interface AttachedSurfaceControl {
* to the View hierarchy you may need to call {@link android.view.View#invalidate}
*/
boolean applyTransactionOnDraw(@NonNull SurfaceControl.Transaction t);
+
+ /**
+ * The transform hint can be used by a buffer producer to pre-rotate the rendering such that the
+ * final transformation in the system composer is identity. This can be very useful when used in
+ * conjunction with the h/w composer HAL in situations where it cannot handle rotations or
+ * handle them with an additional power cost.
+ *
+ * The transform hint should be used with ASurfaceControl APIs when submitting buffers.
+ * Example usage:
+ *
+ * 1. After a configuration change, before dequeuing a buffer, the buffer producer queries the
+ * function for the transform hint.
+ *
+ * 2. The desired buffer width and height is rotated by the transform hint.
+ *
+ * 3. The producer dequeues a buffer of the new pre-rotated size.
+ *
+ * 4. The producer renders to the buffer such that the image is already transformed, that is
+ * applying the transform hint to the rendering.
+ *
+ * 5. The producer applies the inverse transform hint to the buffer it just rendered.
+ *
+ * 6. The producer queues the pre-transformed buffer with the buffer transform.
+ *
+ * 7. The composer combines the buffer transform with the display transform. If the buffer
+ * transform happens to cancel out the display transform then no rotation is needed and there
+ * will be no performance penalties.
+ *
+ * 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.
+ */
+ default @Surface.Rotation int getSurfaceTransformHint() {
+ return Surface.ROTATION_0;
+ }
+
+ /**
+ * Surface transform hint change listener.
+ * @see #getSurfaceTransformHint
+ */
+ @UiThread
+ interface OnSurfaceTransformHintChangedListener {
+ /**
+ * @param hint new surface transform hint
+ * @see #getSurfaceTransformHint
+ */
+ void onSurfaceTransformHintChanged(@Surface.Rotation int hint);
+ }
+
+ /**
+ * Registers a surface transform hint changed listener to receive notifications about when
+ * the transform hint changes.
+ *
+ * @see #getSurfaceTransformHint
+ * @see #removeOnSurfaceTransformHintChangedListener
+ */
+ default void addOnSurfaceTransformHintChangedListener(
+ @NonNull OnSurfaceTransformHintChangedListener listener) {
+ }
+
+ /**
+ * Unregisters a surface transform hint changed listener.
+ *
+ * @see #addOnSurfaceTransformHintChangedListener
+ */
+ default void removeOnSurfaceTransformHintChangedListener(
+ @NonNull OnSurfaceTransformHintChangedListener listener) {
+ }
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index b54b251de80f..e38b8838586a 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -312,6 +312,9 @@ public final class ViewRootImpl implements ViewParent,
static final ArrayList<Runnable> sFirstDrawHandlers = new ArrayList<>();
static boolean sFirstDrawComplete = false;
+ private ArrayList<OnSurfaceTransformHintChangedListener> mTransformHintListeners =
+ new ArrayList<>();
+ private @Surface.Rotation int mPreviousTransformHint = Surface.ROTATION_0;
/**
* Callback for notifying about global configuration changes.
*/
@@ -7840,6 +7843,11 @@ public final class ViewRootImpl implements ViewParent,
}
mAttachInfo.mThreadedRenderer.setSurfaceControl(mSurfaceControl);
}
+ int transformHint = mSurfaceControl.getTransformHint();
+ if (mPreviousTransformHint != transformHint) {
+ mPreviousTransformHint = transformHint;
+ dispatchTransformHintChanged(transformHint);
+ }
} else {
destroySurface();
}
@@ -10463,7 +10471,39 @@ public final class ViewRootImpl implements ViewParent,
return true;
}
- int getSurfaceTransformHint() {
+ @Override
+ public @Surface.Rotation int getSurfaceTransformHint() {
return mSurfaceControl.getTransformHint();
}
+
+ @Override
+ public void addOnSurfaceTransformHintChangedListener(
+ OnSurfaceTransformHintChangedListener listener) {
+ Objects.requireNonNull(listener);
+ if (mTransformHintListeners.contains(listener)) {
+ throw new IllegalArgumentException(
+ "attempt to call addOnSurfaceTransformHintChangedListener() "
+ + "with a previously registered listener");
+ }
+ mTransformHintListeners.add(listener);
+ }
+
+ @Override
+ public void removeOnSurfaceTransformHintChangedListener(
+ OnSurfaceTransformHintChangedListener listener) {
+ Objects.requireNonNull(listener);
+ mTransformHintListeners.remove(listener);
+ }
+
+ private void dispatchTransformHintChanged(@Surface.Rotation int hint) {
+ if (mTransformHintListeners.isEmpty()) {
+ return;
+ }
+ ArrayList<OnSurfaceTransformHintChangedListener> listeners =
+ (ArrayList<OnSurfaceTransformHintChangedListener>) mTransformHintListeners.clone();
+ for (int i = 0; i < listeners.size(); i++) {
+ OnSurfaceTransformHintChangedListener listener = listeners.get(i);
+ listener.onSurfaceTransformHintChanged(hint);
+ }
+ }
}