Loading core/java/android/view/SurfaceView.java +11 −2 Original line number Diff line number Diff line Loading @@ -1061,6 +1061,15 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall } } /** * @hide */ public String getName() { ViewRootImpl viewRoot = getViewRootImpl(); String viewRootName = viewRoot == null ? "detached" : viewRoot.getTitle().toString(); return "SurfaceView[" + viewRootName + "]"; } /** * If SV is trying to be part of the VRI sync, we need to add SV to the VRI sync before * invoking the redrawNeeded call to the owner. This is to ensure we can set up the SV in Loading @@ -1073,7 +1082,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall private void handleSyncBufferCallback(SurfaceHolder.Callback[] callbacks, SyncBufferTransactionCallback syncBufferTransactionCallback) { final SurfaceSyncGroup surfaceSyncGroup = new SurfaceSyncGroup(); final SurfaceSyncGroup surfaceSyncGroup = new SurfaceSyncGroup(getName()); getViewRootImpl().addToSync(surfaceSyncGroup); redrawNeededAsync(callbacks, () -> { Transaction t = null; Loading @@ -1088,7 +1097,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall } private void handleSyncNoBuffer(SurfaceHolder.Callback[] callbacks) { final SurfaceSyncGroup surfaceSyncGroup = new SurfaceSyncGroup(); final SurfaceSyncGroup surfaceSyncGroup = new SurfaceSyncGroup(getName()); synchronized (mSyncGroups) { mSyncGroups.add(surfaceSyncGroup); } Loading core/java/android/view/ViewRootImpl.java +20 −9 Original line number Diff line number Diff line Loading @@ -3726,15 +3726,18 @@ public final class ViewRootImpl implements ViewParent, final int seqId = mSyncSeqId; mWmsRequestSyncGroupState = WMS_SYNC_PENDING; mWmsRequestSyncGroup = new SurfaceSyncGroup(t -> { mWmsRequestSyncGroup = new SurfaceSyncGroup("wmsSync-" + mTag, t -> { mWmsRequestSyncGroupState = WMS_SYNC_MERGED; reportDrawFinished(t, seqId); }); Trace.traceBegin(Trace.TRACE_TAG_VIEW, "create WMS Sync group=" + mWmsRequestSyncGroup.getName()); if (DEBUG_BLAST) { Log.d(mTag, "Setup new sync id=" + mWmsRequestSyncGroup); Log.d(mTag, "Setup new sync=" + mWmsRequestSyncGroup.getName()); } mWmsRequestSyncGroup.addToSync(this); Trace.traceEnd(Trace.TRACE_TAG_VIEW); notifySurfaceSyncStarted(); } Loading Loading @@ -11328,20 +11331,28 @@ public final class ViewRootImpl implements ViewParent, @Override public SurfaceSyncGroup getOrCreateSurfaceSyncGroup() { boolean newSyncGroup = false; if (mActiveSurfaceSyncGroup == null) { mActiveSurfaceSyncGroup = new SurfaceSyncGroup(); mActiveSurfaceSyncGroup = new SurfaceSyncGroup(mTag); updateSyncInProgressCount(mActiveSurfaceSyncGroup); if (!mIsInTraversal && !mTraversalScheduled) { scheduleTraversals(); } if (DEBUG_BLAST) { Log.d(mTag, "Creating new active sync group " + mActiveSurfaceSyncGroup); newSyncGroup = true; } } else { Trace.instant(Trace.TRACE_TAG_VIEW, "getOrCreateSurfaceSyncGroup isNew=" + newSyncGroup + " " + mTag); if (DEBUG_BLAST) { Log.d(mTag, "Return already created active sync group " + mActiveSurfaceSyncGroup); if (newSyncGroup) { Log.d(mTag, "Creating new active sync group " + mActiveSurfaceSyncGroup.getName()); } else { Log.d(mTag, "Return already created active sync group " + mActiveSurfaceSyncGroup.getName()); } } return mActiveSurfaceSyncGroup; }; Loading core/java/android/window/SurfaceSyncGroup.java +67 −19 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.window; import android.annotation.Nullable; import android.annotation.UiThread; import android.os.Debug; import android.os.Trace; import android.util.ArraySet; import android.util.Log; import android.util.Pair; Loading @@ -30,6 +31,7 @@ import com.android.internal.annotations.GuardedBy; import java.util.Set; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.function.Supplier; Loading Loading @@ -75,6 +77,10 @@ public class SurfaceSyncGroup { private static final String TAG = "SurfaceSyncGroup"; private static final boolean DEBUG = false; private static final int MAX_COUNT = 100; private static final AtomicInteger sCounter = new AtomicInteger(0); private static Supplier<Transaction> sTransactionFactory = Transaction::new; /** Loading @@ -83,6 +89,8 @@ public class SurfaceSyncGroup { */ private final Object mLock = new Object(); private final String mName; @GuardedBy("mLock") private final Set<TransactionReadyCallback> mPendingSyncs = new ArraySet<>(); @GuardedBy("mLock") Loading Loading @@ -112,8 +120,8 @@ public class SurfaceSyncGroup { /** * Starts a sync and will automatically apply the final, merged transaction. */ public SurfaceSyncGroup() { this(transaction -> { public SurfaceSyncGroup(String name) { this(name, transaction -> { if (transaction != null) { if (DEBUG) { Log.d(TAG, "Applying transaction " + transaction); Loading @@ -134,12 +142,24 @@ public class SurfaceSyncGroup { * NOTE: Only should be used by ViewRootImpl * @hide */ public SurfaceSyncGroup(Consumer<Transaction> transactionReadyCallback) { public SurfaceSyncGroup(String name, Consumer<Transaction> transactionReadyCallback) { // sCounter is a way to give the SurfaceSyncGroup a unique name even if the name passed in // is not. // Avoid letting the count get too big so just reset to 0. It's unlikely that we'll have // more than MAX_COUNT active syncs that have overlapping names if (sCounter.get() >= MAX_COUNT) { sCounter.set(0); } mName = name + "#" + sCounter.getAndIncrement(); mTransactionReadyCallback = transaction -> { if (DEBUG && transaction != null) { Log.d(TAG, "Sending non null transaction " + transaction + " to callback for " + this); Log.d(TAG, "Sending non null transaction " + transaction + " to callback for " + mName); } Trace.instant(Trace.TRACE_TAG_VIEW, "Final TransactionCallback with " + transaction + " for " + mName); transactionReadyCallback.accept(transaction); synchronized (mLock) { for (Pair<Executor, Runnable> callback : mSyncCompleteCallbacks) { Loading @@ -148,8 +168,10 @@ public class SurfaceSyncGroup { } }; Trace.instant(Trace.TRACE_TAG_VIEW, "new SurfaceSyncGroup " + mName); if (DEBUG) { Log.d(TAG, "setupSync " + this + " " + Debug.getCallers(2)); Log.d(TAG, "setupSync " + mName + " " + Debug.getCallers(2)); } } Loading Loading @@ -178,9 +200,11 @@ public class SurfaceSyncGroup { /** * Similar to {@link #markSyncReady()}, but a transaction is passed in to merge with the * SurfaceSyncGroup. * * @param t The transaction that merges into the main Transaction for the SurfaceSyncGroup. */ public void onTransactionReady(@Nullable Transaction t) { Trace.traceBegin(Trace.TRACE_TAG_VIEW, "markSyncReady " + mName); synchronized (mLock) { mSyncReady = true; if (t != null) { Loading @@ -188,6 +212,7 @@ public class SurfaceSyncGroup { } checkIfSyncIsComplete(); } Trace.traceEnd(Trace.TRACE_TAG_VIEW); } /** Loading @@ -205,7 +230,7 @@ public class SurfaceSyncGroup { @UiThread public boolean addToSync(SurfaceView surfaceView, Consumer<SurfaceViewFrameCallback> frameCallbackConsumer) { SurfaceSyncGroup surfaceSyncGroup = new SurfaceSyncGroup(); SurfaceSyncGroup surfaceSyncGroup = new SurfaceSyncGroup(surfaceView.getName()); if (addToSync(surfaceSyncGroup, false /* parentSyncGroupMerge */)) { frameCallbackConsumer.accept( () -> surfaceView.syncNextFrame(surfaceSyncGroup::onTransactionReady)); Loading Loading @@ -242,12 +267,14 @@ public class SurfaceSyncGroup { * otherwise. */ public boolean addToSync(SurfaceSyncGroup surfaceSyncGroup, boolean parentSyncGroupMerge) { Trace.traceBegin(Trace.TRACE_TAG_VIEW, "addToSync child=" + surfaceSyncGroup.mName + " parent=" + mName); TransactionReadyCallback transactionReadyCallback = new TransactionReadyCallback() { @Override public void onTransactionReady(Transaction t) { if (DEBUG) { Log.d(TAG, "onTransactionReady called for" + surfaceSyncGroup + " and sent to " + this); Log.d(TAG, "onTransactionReady called for" + surfaceSyncGroup.mName + " and sent to " + mName); } synchronized (mLock) { if (t != null) { Loading @@ -261,6 +288,9 @@ public class SurfaceSyncGroup { mTransaction.merge(t); } mPendingSyncs.remove(this); Trace.instant(Trace.TRACE_TAG_VIEW, "onTransactionReady child=" + surfaceSyncGroup.mName + " parent=" + mName); checkIfSyncIsComplete(); } } Loading @@ -268,18 +298,20 @@ public class SurfaceSyncGroup { synchronized (mLock) { if (mSyncReady) { Log.e(TAG, "Sync " + this + " was already marked as ready. No more " Log.e(TAG, "Sync " + mName + " was already marked as ready. No more " + "SurfaceSyncGroups can be added."); Trace.traceEnd(Trace.TRACE_TAG_VIEW); return false; } mPendingSyncs.add(transactionReadyCallback); if (DEBUG) { Log.d(TAG, "addToSync " + surfaceSyncGroup + " to " + this + " mSyncReady=" Log.d(TAG, "addToSync " + surfaceSyncGroup.mName + " to " + mName + " mSyncReady=" + mSyncReady + " mPendingSyncs=" + mPendingSyncs.size()); } } surfaceSyncGroup.onAddedToSyncGroup(this, transactionReadyCallback); Trace.traceEnd(Trace.TRACE_TAG_VIEW); return true; } Loading @@ -297,21 +329,25 @@ public class SurfaceSyncGroup { private void checkIfSyncIsComplete() { if (mFinished) { if (DEBUG) { Log.d(TAG, "SurfaceSyncGroup=" + this + " is already complete"); Log.d(TAG, "SurfaceSyncGroup=" + mName + " is already complete"); } return; } Trace.instant(Trace.TRACE_TAG_VIEW, "checkIfSyncIsComplete " + mName + " mSyncReady=" + mSyncReady + " mPendingSyncs=" + mPendingSyncs.size()); if (!mSyncReady || !mPendingSyncs.isEmpty()) { if (DEBUG) { Log.d(TAG, "SurfaceSyncGroup=" + this + " is not complete. mSyncReady=" + mSyncReady + " mPendingSyncs=" + mPendingSyncs.size()); Log.d(TAG, "SurfaceSyncGroup=" + mName + " is not complete. mSyncReady=" + mSyncReady + " mPendingSyncs=" + mPendingSyncs.size()); } return; } if (DEBUG) { Log.d(TAG, "Successfully finished sync id=" + this); Log.d(TAG, "Successfully finished sync id=" + mName); } mTransactionReadyCallback.onTransactionReady(mTransaction); mFinished = true; Loading @@ -319,6 +355,8 @@ public class SurfaceSyncGroup { private void onAddedToSyncGroup(SurfaceSyncGroup parentSyncGroup, TransactionReadyCallback transactionReadyCallback) { Trace.traceBegin(Trace.TRACE_TAG_VIEW, "onAddedToSyncGroup child=" + mName + " parent=" + parentSyncGroup.mName); boolean finished = false; synchronized (mLock) { if (mFinished) { Loading @@ -332,9 +370,9 @@ public class SurfaceSyncGroup { // from the original parent are also combined with the new parent SurfaceSyncGroup. if (mParentSyncGroup != null && mParentSyncGroup != parentSyncGroup) { if (DEBUG) { Log.d(TAG, "Trying to add to " + parentSyncGroup + " but already part of sync group " + mParentSyncGroup + " " + this); Log.d(TAG, "Trying to add to " + parentSyncGroup.mName + " but already part of sync group " + mParentSyncGroup.mName + " " + mName); } parentSyncGroup.addToSync(mParentSyncGroup, true /* parentSyncGroupMerge */); } Loading @@ -347,8 +385,12 @@ public class SurfaceSyncGroup { mParentSyncGroup = parentSyncGroup; final TransactionReadyCallback lastCallback = mTransactionReadyCallback; mTransactionReadyCallback = t -> { Trace.traceBegin(Trace.TRACE_TAG_VIEW, "transactionReadyCallback " + mName + " parent=" + parentSyncGroup.mName); lastCallback.onTransactionReady(null); transactionReadyCallback.onTransactionReady(t); Trace.traceEnd(Trace.TRACE_TAG_VIEW); }; } } Loading @@ -358,7 +400,13 @@ public class SurfaceSyncGroup { if (finished) { transactionReadyCallback.onTransactionReady(null); } Trace.traceEnd(Trace.TRACE_TAG_VIEW); } public String getName() { return mName; } /** * Interface so the SurfaceSyncer can know when it's safe to start and when everything has been * completed. The caller should invoke the calls when the rendering has started and finished a Loading core/java/android/window/SurfaceSyncGroup.md +2 −2 Original line number Diff line number Diff line Loading @@ -59,7 +59,7 @@ As mentioned above, SurfaceViews are a special case because the buffers produced A simple example where you want to sync two windows and also include a transaction in the sync ```java SurfaceSyncGroup syncGroup = new SurfaceSyncGroup(); SurfaceSyncGroup syncGroup = new SurfaceSyncGroup(NAME); SyncGroup.addSyncCompleteCallback(mMainThreadExecutor, () -> { Log.d(TAG, "syncComplete"); }; Loading @@ -73,7 +73,7 @@ A SurfaceView example: See `frameworks/base/tests/SurfaceViewSyncTest` for a working example ```java SurfaceSyncGroup syncGroup = new SurfaceSyncGroup(); SurfaceSyncGroup syncGroup = new SurfaceSyncGroup(NAME); syncGroup.addSyncCompleteCallback(mMainThreadExecutor, () -> { Log.d(TAG, "syncComplete"); }; Loading packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt +1 −1 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ object ViewRootSync { return } val syncGroup = SurfaceSyncGroup() val syncGroup = SurfaceSyncGroup("SysUIAnimation") syncGroup.addSyncCompleteCallback(view.context.mainExecutor) { then() } syncGroup.addToSync(view.rootSurfaceControl) syncGroup.addToSync(otherView.rootSurfaceControl) Loading Loading
core/java/android/view/SurfaceView.java +11 −2 Original line number Diff line number Diff line Loading @@ -1061,6 +1061,15 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall } } /** * @hide */ public String getName() { ViewRootImpl viewRoot = getViewRootImpl(); String viewRootName = viewRoot == null ? "detached" : viewRoot.getTitle().toString(); return "SurfaceView[" + viewRootName + "]"; } /** * If SV is trying to be part of the VRI sync, we need to add SV to the VRI sync before * invoking the redrawNeeded call to the owner. This is to ensure we can set up the SV in Loading @@ -1073,7 +1082,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall private void handleSyncBufferCallback(SurfaceHolder.Callback[] callbacks, SyncBufferTransactionCallback syncBufferTransactionCallback) { final SurfaceSyncGroup surfaceSyncGroup = new SurfaceSyncGroup(); final SurfaceSyncGroup surfaceSyncGroup = new SurfaceSyncGroup(getName()); getViewRootImpl().addToSync(surfaceSyncGroup); redrawNeededAsync(callbacks, () -> { Transaction t = null; Loading @@ -1088,7 +1097,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall } private void handleSyncNoBuffer(SurfaceHolder.Callback[] callbacks) { final SurfaceSyncGroup surfaceSyncGroup = new SurfaceSyncGroup(); final SurfaceSyncGroup surfaceSyncGroup = new SurfaceSyncGroup(getName()); synchronized (mSyncGroups) { mSyncGroups.add(surfaceSyncGroup); } Loading
core/java/android/view/ViewRootImpl.java +20 −9 Original line number Diff line number Diff line Loading @@ -3726,15 +3726,18 @@ public final class ViewRootImpl implements ViewParent, final int seqId = mSyncSeqId; mWmsRequestSyncGroupState = WMS_SYNC_PENDING; mWmsRequestSyncGroup = new SurfaceSyncGroup(t -> { mWmsRequestSyncGroup = new SurfaceSyncGroup("wmsSync-" + mTag, t -> { mWmsRequestSyncGroupState = WMS_SYNC_MERGED; reportDrawFinished(t, seqId); }); Trace.traceBegin(Trace.TRACE_TAG_VIEW, "create WMS Sync group=" + mWmsRequestSyncGroup.getName()); if (DEBUG_BLAST) { Log.d(mTag, "Setup new sync id=" + mWmsRequestSyncGroup); Log.d(mTag, "Setup new sync=" + mWmsRequestSyncGroup.getName()); } mWmsRequestSyncGroup.addToSync(this); Trace.traceEnd(Trace.TRACE_TAG_VIEW); notifySurfaceSyncStarted(); } Loading Loading @@ -11328,20 +11331,28 @@ public final class ViewRootImpl implements ViewParent, @Override public SurfaceSyncGroup getOrCreateSurfaceSyncGroup() { boolean newSyncGroup = false; if (mActiveSurfaceSyncGroup == null) { mActiveSurfaceSyncGroup = new SurfaceSyncGroup(); mActiveSurfaceSyncGroup = new SurfaceSyncGroup(mTag); updateSyncInProgressCount(mActiveSurfaceSyncGroup); if (!mIsInTraversal && !mTraversalScheduled) { scheduleTraversals(); } if (DEBUG_BLAST) { Log.d(mTag, "Creating new active sync group " + mActiveSurfaceSyncGroup); newSyncGroup = true; } } else { Trace.instant(Trace.TRACE_TAG_VIEW, "getOrCreateSurfaceSyncGroup isNew=" + newSyncGroup + " " + mTag); if (DEBUG_BLAST) { Log.d(mTag, "Return already created active sync group " + mActiveSurfaceSyncGroup); if (newSyncGroup) { Log.d(mTag, "Creating new active sync group " + mActiveSurfaceSyncGroup.getName()); } else { Log.d(mTag, "Return already created active sync group " + mActiveSurfaceSyncGroup.getName()); } } return mActiveSurfaceSyncGroup; }; Loading
core/java/android/window/SurfaceSyncGroup.java +67 −19 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.window; import android.annotation.Nullable; import android.annotation.UiThread; import android.os.Debug; import android.os.Trace; import android.util.ArraySet; import android.util.Log; import android.util.Pair; Loading @@ -30,6 +31,7 @@ import com.android.internal.annotations.GuardedBy; import java.util.Set; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.function.Supplier; Loading Loading @@ -75,6 +77,10 @@ public class SurfaceSyncGroup { private static final String TAG = "SurfaceSyncGroup"; private static final boolean DEBUG = false; private static final int MAX_COUNT = 100; private static final AtomicInteger sCounter = new AtomicInteger(0); private static Supplier<Transaction> sTransactionFactory = Transaction::new; /** Loading @@ -83,6 +89,8 @@ public class SurfaceSyncGroup { */ private final Object mLock = new Object(); private final String mName; @GuardedBy("mLock") private final Set<TransactionReadyCallback> mPendingSyncs = new ArraySet<>(); @GuardedBy("mLock") Loading Loading @@ -112,8 +120,8 @@ public class SurfaceSyncGroup { /** * Starts a sync and will automatically apply the final, merged transaction. */ public SurfaceSyncGroup() { this(transaction -> { public SurfaceSyncGroup(String name) { this(name, transaction -> { if (transaction != null) { if (DEBUG) { Log.d(TAG, "Applying transaction " + transaction); Loading @@ -134,12 +142,24 @@ public class SurfaceSyncGroup { * NOTE: Only should be used by ViewRootImpl * @hide */ public SurfaceSyncGroup(Consumer<Transaction> transactionReadyCallback) { public SurfaceSyncGroup(String name, Consumer<Transaction> transactionReadyCallback) { // sCounter is a way to give the SurfaceSyncGroup a unique name even if the name passed in // is not. // Avoid letting the count get too big so just reset to 0. It's unlikely that we'll have // more than MAX_COUNT active syncs that have overlapping names if (sCounter.get() >= MAX_COUNT) { sCounter.set(0); } mName = name + "#" + sCounter.getAndIncrement(); mTransactionReadyCallback = transaction -> { if (DEBUG && transaction != null) { Log.d(TAG, "Sending non null transaction " + transaction + " to callback for " + this); Log.d(TAG, "Sending non null transaction " + transaction + " to callback for " + mName); } Trace.instant(Trace.TRACE_TAG_VIEW, "Final TransactionCallback with " + transaction + " for " + mName); transactionReadyCallback.accept(transaction); synchronized (mLock) { for (Pair<Executor, Runnable> callback : mSyncCompleteCallbacks) { Loading @@ -148,8 +168,10 @@ public class SurfaceSyncGroup { } }; Trace.instant(Trace.TRACE_TAG_VIEW, "new SurfaceSyncGroup " + mName); if (DEBUG) { Log.d(TAG, "setupSync " + this + " " + Debug.getCallers(2)); Log.d(TAG, "setupSync " + mName + " " + Debug.getCallers(2)); } } Loading Loading @@ -178,9 +200,11 @@ public class SurfaceSyncGroup { /** * Similar to {@link #markSyncReady()}, but a transaction is passed in to merge with the * SurfaceSyncGroup. * * @param t The transaction that merges into the main Transaction for the SurfaceSyncGroup. */ public void onTransactionReady(@Nullable Transaction t) { Trace.traceBegin(Trace.TRACE_TAG_VIEW, "markSyncReady " + mName); synchronized (mLock) { mSyncReady = true; if (t != null) { Loading @@ -188,6 +212,7 @@ public class SurfaceSyncGroup { } checkIfSyncIsComplete(); } Trace.traceEnd(Trace.TRACE_TAG_VIEW); } /** Loading @@ -205,7 +230,7 @@ public class SurfaceSyncGroup { @UiThread public boolean addToSync(SurfaceView surfaceView, Consumer<SurfaceViewFrameCallback> frameCallbackConsumer) { SurfaceSyncGroup surfaceSyncGroup = new SurfaceSyncGroup(); SurfaceSyncGroup surfaceSyncGroup = new SurfaceSyncGroup(surfaceView.getName()); if (addToSync(surfaceSyncGroup, false /* parentSyncGroupMerge */)) { frameCallbackConsumer.accept( () -> surfaceView.syncNextFrame(surfaceSyncGroup::onTransactionReady)); Loading Loading @@ -242,12 +267,14 @@ public class SurfaceSyncGroup { * otherwise. */ public boolean addToSync(SurfaceSyncGroup surfaceSyncGroup, boolean parentSyncGroupMerge) { Trace.traceBegin(Trace.TRACE_TAG_VIEW, "addToSync child=" + surfaceSyncGroup.mName + " parent=" + mName); TransactionReadyCallback transactionReadyCallback = new TransactionReadyCallback() { @Override public void onTransactionReady(Transaction t) { if (DEBUG) { Log.d(TAG, "onTransactionReady called for" + surfaceSyncGroup + " and sent to " + this); Log.d(TAG, "onTransactionReady called for" + surfaceSyncGroup.mName + " and sent to " + mName); } synchronized (mLock) { if (t != null) { Loading @@ -261,6 +288,9 @@ public class SurfaceSyncGroup { mTransaction.merge(t); } mPendingSyncs.remove(this); Trace.instant(Trace.TRACE_TAG_VIEW, "onTransactionReady child=" + surfaceSyncGroup.mName + " parent=" + mName); checkIfSyncIsComplete(); } } Loading @@ -268,18 +298,20 @@ public class SurfaceSyncGroup { synchronized (mLock) { if (mSyncReady) { Log.e(TAG, "Sync " + this + " was already marked as ready. No more " Log.e(TAG, "Sync " + mName + " was already marked as ready. No more " + "SurfaceSyncGroups can be added."); Trace.traceEnd(Trace.TRACE_TAG_VIEW); return false; } mPendingSyncs.add(transactionReadyCallback); if (DEBUG) { Log.d(TAG, "addToSync " + surfaceSyncGroup + " to " + this + " mSyncReady=" Log.d(TAG, "addToSync " + surfaceSyncGroup.mName + " to " + mName + " mSyncReady=" + mSyncReady + " mPendingSyncs=" + mPendingSyncs.size()); } } surfaceSyncGroup.onAddedToSyncGroup(this, transactionReadyCallback); Trace.traceEnd(Trace.TRACE_TAG_VIEW); return true; } Loading @@ -297,21 +329,25 @@ public class SurfaceSyncGroup { private void checkIfSyncIsComplete() { if (mFinished) { if (DEBUG) { Log.d(TAG, "SurfaceSyncGroup=" + this + " is already complete"); Log.d(TAG, "SurfaceSyncGroup=" + mName + " is already complete"); } return; } Trace.instant(Trace.TRACE_TAG_VIEW, "checkIfSyncIsComplete " + mName + " mSyncReady=" + mSyncReady + " mPendingSyncs=" + mPendingSyncs.size()); if (!mSyncReady || !mPendingSyncs.isEmpty()) { if (DEBUG) { Log.d(TAG, "SurfaceSyncGroup=" + this + " is not complete. mSyncReady=" + mSyncReady + " mPendingSyncs=" + mPendingSyncs.size()); Log.d(TAG, "SurfaceSyncGroup=" + mName + " is not complete. mSyncReady=" + mSyncReady + " mPendingSyncs=" + mPendingSyncs.size()); } return; } if (DEBUG) { Log.d(TAG, "Successfully finished sync id=" + this); Log.d(TAG, "Successfully finished sync id=" + mName); } mTransactionReadyCallback.onTransactionReady(mTransaction); mFinished = true; Loading @@ -319,6 +355,8 @@ public class SurfaceSyncGroup { private void onAddedToSyncGroup(SurfaceSyncGroup parentSyncGroup, TransactionReadyCallback transactionReadyCallback) { Trace.traceBegin(Trace.TRACE_TAG_VIEW, "onAddedToSyncGroup child=" + mName + " parent=" + parentSyncGroup.mName); boolean finished = false; synchronized (mLock) { if (mFinished) { Loading @@ -332,9 +370,9 @@ public class SurfaceSyncGroup { // from the original parent are also combined with the new parent SurfaceSyncGroup. if (mParentSyncGroup != null && mParentSyncGroup != parentSyncGroup) { if (DEBUG) { Log.d(TAG, "Trying to add to " + parentSyncGroup + " but already part of sync group " + mParentSyncGroup + " " + this); Log.d(TAG, "Trying to add to " + parentSyncGroup.mName + " but already part of sync group " + mParentSyncGroup.mName + " " + mName); } parentSyncGroup.addToSync(mParentSyncGroup, true /* parentSyncGroupMerge */); } Loading @@ -347,8 +385,12 @@ public class SurfaceSyncGroup { mParentSyncGroup = parentSyncGroup; final TransactionReadyCallback lastCallback = mTransactionReadyCallback; mTransactionReadyCallback = t -> { Trace.traceBegin(Trace.TRACE_TAG_VIEW, "transactionReadyCallback " + mName + " parent=" + parentSyncGroup.mName); lastCallback.onTransactionReady(null); transactionReadyCallback.onTransactionReady(t); Trace.traceEnd(Trace.TRACE_TAG_VIEW); }; } } Loading @@ -358,7 +400,13 @@ public class SurfaceSyncGroup { if (finished) { transactionReadyCallback.onTransactionReady(null); } Trace.traceEnd(Trace.TRACE_TAG_VIEW); } public String getName() { return mName; } /** * Interface so the SurfaceSyncer can know when it's safe to start and when everything has been * completed. The caller should invoke the calls when the rendering has started and finished a Loading
core/java/android/window/SurfaceSyncGroup.md +2 −2 Original line number Diff line number Diff line Loading @@ -59,7 +59,7 @@ As mentioned above, SurfaceViews are a special case because the buffers produced A simple example where you want to sync two windows and also include a transaction in the sync ```java SurfaceSyncGroup syncGroup = new SurfaceSyncGroup(); SurfaceSyncGroup syncGroup = new SurfaceSyncGroup(NAME); SyncGroup.addSyncCompleteCallback(mMainThreadExecutor, () -> { Log.d(TAG, "syncComplete"); }; Loading @@ -73,7 +73,7 @@ A SurfaceView example: See `frameworks/base/tests/SurfaceViewSyncTest` for a working example ```java SurfaceSyncGroup syncGroup = new SurfaceSyncGroup(); SurfaceSyncGroup syncGroup = new SurfaceSyncGroup(NAME); syncGroup.addSyncCompleteCallback(mMainThreadExecutor, () -> { Log.d(TAG, "syncComplete"); }; Loading
packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt +1 −1 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ object ViewRootSync { return } val syncGroup = SurfaceSyncGroup() val syncGroup = SurfaceSyncGroup("SysUIAnimation") syncGroup.addSyncCompleteCallback(view.context.mainExecutor) { then() } syncGroup.addToSync(view.rootSurfaceControl) syncGroup.addToSync(otherView.rootSurfaceControl) Loading