From 06cff30935710246784ffb3a66fbd743f8a678fb Mon Sep 17 00:00:00 2001 From: Vishnu Nair Date: Fri, 29 May 2020 14:39:20 -0700 Subject: [PATCH] Remove additional sf transaction when constructing a leash The leash needs to be visible on creation otherwise when reparenting the leash, the leashed layer may be hidden for a moment. This is because Transaction#show can be deferred but Transaction#reparent cannot. This change adds a layer flag to allow creating effect layers without a color fill so we can avoid an additional sf transaction. Fixes: 157646690 Test: go/wm-smoke Test: atest SurfaceFlinger_test Change-Id: I3d8a4f4820d7b8fb05daab697c25cff8def612c1 --- core/java/android/view/SurfaceControl.java | 37 ++++++++++++++++--- .../android/server/wm/SurfaceAnimator.java | 19 ++++------ .../core/java/com/android/server/wm/Task.java | 8 +--- 3 files changed, 40 insertions(+), 24 deletions(-) diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 9109f50247e0a..6f73e8985a8a3 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -322,6 +322,14 @@ public final class SurfaceControl implements Parcelable { */ public static final int CURSOR_WINDOW = 0x00002000; + /** + * Surface creation flag: Indicates the effect layer will not have a color fill on + * creation. + * + * @hide + */ + public static final int NO_COLOR_FILL = 0x00004000; + /** * Surface creation flag: Creates a normal surface. * This is the default. @@ -577,7 +585,7 @@ public final class SurfaceControl implements Parcelable { throw new IllegalStateException( "width and height must be positive or unset"); } - if ((mWidth > 0 || mHeight > 0) && (isColorLayerSet() || isContainerLayerSet())) { + if ((mWidth > 0 || mHeight > 0) && (isEffectLayer() || isContainerLayer())) { throw new IllegalStateException( "Only buffer layers can set a valid buffer size."); } @@ -749,10 +757,27 @@ public final class SurfaceControl implements Parcelable { } /** - * Indicate whether a 'ColorLayer' is to be constructed. + * Indicate whether an 'EffectLayer' is to be constructed. * - * Color layers will not have an associated BufferQueue and will instead always render a - * solid color (that is, solid before plane alpha). Currently that color is black. + * An effect layer behaves like a container layer by default but it can support + * color fill, shadows and/or blur. These layers will not have an associated buffer. + * When created, this layer has no effects set and will be transparent but the caller + * can render an effect by calling: + * - {@link Transaction#setColor(SurfaceControl, float[])} + * - {@link Transaction#setBackgroundBlurRadius(SurfaceControl, int)} + * - {@link Transaction#setShadowRadius(SurfaceControl, float)} + * + * @hide + */ + public Builder setEffectLayer() { + mFlags |= NO_COLOR_FILL; + unsetBufferSize(); + return setFlags(FX_SURFACE_EFFECT, FX_SURFACE_MASK); + } + + /** + * A convenience function to create an effect layer with a default color fill + * applied to it. Currently that color is black. * * @hide */ @@ -761,7 +786,7 @@ public final class SurfaceControl implements Parcelable { return setFlags(FX_SURFACE_EFFECT, FX_SURFACE_MASK); } - private boolean isColorLayerSet() { + private boolean isEffectLayer() { return (mFlags & FX_SURFACE_EFFECT) == FX_SURFACE_EFFECT; } @@ -786,7 +811,7 @@ public final class SurfaceControl implements Parcelable { return setFlags(FX_SURFACE_CONTAINER, FX_SURFACE_MASK); } - private boolean isContainerLayerSet() { + private boolean isContainerLayer() { return (mFlags & FX_SURFACE_CONTAINER) == FX_SURFACE_CONTAINER; } diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java index 0143eb1abe032..1b77fd2e87820 100644 --- a/services/core/java/com/android/server/wm/SurfaceAnimator.java +++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java @@ -388,18 +388,15 @@ class SurfaceAnimator { final SurfaceControl.Builder builder = animatable.makeAnimationLeash() .setParent(animatable.getAnimationLeashParent()) .setName(surface + " - animation-leash") - .setColorLayer(); + // TODO(b/151665759) Defer reparent calls + // We want the leash to be visible immediately because the transaction which shows + // the leash may be deferred but the reparent will not. This will cause the leashed + // surface to be invisible until the deferred transaction is applied. If this + // doesn't work, you will can see the 2/3 button nav bar flicker during seamless + // rotation. + .setHidden(hidden) + .setEffectLayer(); final SurfaceControl leash = builder.build(); - if (!hidden) { - // TODO(b/151665759) Defer reparent calls - // We want the leash to be visible immediately but we want to set the effects on - // the layer. Since the transaction used in this function may be deferred, we apply - // another transaction immediately with the correct visibility and effects. - // If this doesn't work, you will can see the 2/3 button nav bar flicker during - // seamless rotation. - transactionFactory.get().unsetColor(leash).show(leash).apply(); - } - t.unsetColor(leash); t.setWindowCrop(leash, width, height); t.setPosition(leash, x, y); t.show(leash); diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 7113a15da1bfb..cb2df851a8b32 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -3202,15 +3202,9 @@ class Task extends WindowContainer { return true; } - @Override - void onSurfaceShown(SurfaceControl.Transaction t) { - super.onSurfaceShown(t); - t.unsetColor(mSurfaceControl); - } - @Override void setInitialSurfaceControlProperties(SurfaceControl.Builder b) { - b.setColorLayer().setMetadata(METADATA_TASK_ID, mTaskId); + b.setEffectLayer().setMetadata(METADATA_TASK_ID, mTaskId); super.setInitialSurfaceControlProperties(b); }