Merge "Add some client side logging for interrupted draws to the dump" into tm-qpr-dev am: 5f7ead346d
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19533074 Change-Id: I59a509a87399d36612c518648a4288d8e3ad7882 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -422,7 +422,7 @@ public class SurfaceControlViewHost {
|
||||
public void relayout(WindowManager.LayoutParams attrs,
|
||||
WindowlessWindowManager.ResizeCompleteCallback callback) {
|
||||
mViewRoot.setLayoutParams(attrs, false);
|
||||
mViewRoot.setReportNextDraw(true /* syncBuffer */);
|
||||
mViewRoot.setReportNextDraw(true /* syncBuffer */, "scvh_relayout");
|
||||
mWm.setCompletionCallback(mViewRoot.mWindow.asBinder(), callback);
|
||||
}
|
||||
|
||||
|
||||
@@ -586,8 +586,21 @@ public final class ViewRootImpl implements ViewParent,
|
||||
int mContentCaptureEnabled = CONTENT_CAPTURE_ENABLED_NOT_CHECKED;
|
||||
boolean mPerformContentCapture;
|
||||
|
||||
|
||||
boolean mReportNextDraw;
|
||||
/** Set only while mReportNextDraw=true, indicating the last reason that was triggered */
|
||||
String mLastReportNextDrawReason;
|
||||
/** The reaason the last call to performDraw() returned false */
|
||||
String mLastPerformDrawSkippedReason;
|
||||
/** The reason the last call to performTraversals() returned without drawing */
|
||||
String mLastPerformTraversalsSkipDrawReason;
|
||||
/** The state of the local sync, if one is in progress. Can be one of the states below. */
|
||||
int mLocalSyncState;
|
||||
|
||||
// The possible states of the local sync, see createSyncIfNeeded()
|
||||
private final int LOCAL_SYNC_NONE = 0;
|
||||
private final int LOCAL_SYNC_PENDING = 1;
|
||||
private final int LOCAL_SYNC_RETURNED = 2;
|
||||
private final int LOCAL_SYNC_MERGED = 3;
|
||||
|
||||
/**
|
||||
* Set whether the draw should send the buffer to system server. When set to true, VRI will
|
||||
@@ -1813,7 +1826,7 @@ public final class ViewRootImpl implements ViewParent,
|
||||
mSyncSeqId = args.argi4 > mSyncSeqId ? args.argi4 : mSyncSeqId;
|
||||
|
||||
if (msg == MSG_RESIZED_REPORT) {
|
||||
reportNextDraw();
|
||||
reportNextDraw("resized");
|
||||
}
|
||||
|
||||
if (mView != null && (frameChanged || configChanged)) {
|
||||
@@ -2718,6 +2731,8 @@ public final class ViewRootImpl implements ViewParent,
|
||||
}
|
||||
|
||||
private void performTraversals() {
|
||||
mLastPerformTraversalsSkipDrawReason = null;
|
||||
|
||||
// cache mView since it is used so much below...
|
||||
final View host = mView;
|
||||
if (DBG) {
|
||||
@@ -2727,12 +2742,14 @@ public final class ViewRootImpl implements ViewParent,
|
||||
}
|
||||
|
||||
if (host == null || !mAdded) {
|
||||
mLastPerformTraversalsSkipDrawReason = host == null ? "no_host" : "not_added";
|
||||
return;
|
||||
}
|
||||
|
||||
mIsInTraversal = true;
|
||||
mWillDrawSoon = true;
|
||||
boolean cancelDraw = false;
|
||||
String cancelReason = null;
|
||||
boolean isSyncRequest = false;
|
||||
|
||||
boolean windowSizeMayChange = false;
|
||||
@@ -3015,13 +3032,14 @@ public final class ViewRootImpl implements ViewParent,
|
||||
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
|
||||
cancelDraw = (relayoutResult & RELAYOUT_RES_CANCEL_AND_REDRAW)
|
||||
== RELAYOUT_RES_CANCEL_AND_REDRAW;
|
||||
cancelReason = "relayout";
|
||||
final boolean dragResizing = mPendingDragResizing;
|
||||
if (mSyncSeqId > mLastSyncSeqId) {
|
||||
mLastSyncSeqId = mSyncSeqId;
|
||||
if (DEBUG_BLAST) {
|
||||
Log.d(mTag, "Relayout called with blastSync");
|
||||
}
|
||||
reportNextDraw();
|
||||
reportNextDraw("relayout");
|
||||
mSyncBuffer = true;
|
||||
isSyncRequest = true;
|
||||
if (!cancelDraw) {
|
||||
@@ -3119,6 +3137,7 @@ public final class ViewRootImpl implements ViewParent,
|
||||
}
|
||||
} catch (OutOfResourcesException e) {
|
||||
handleOutOfResourcesException(e);
|
||||
mLastPerformTraversalsSkipDrawReason = "oom_initialize_renderer";
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -3156,6 +3175,7 @@ public final class ViewRootImpl implements ViewParent,
|
||||
mAttachInfo.mThreadedRenderer.updateSurface(mSurface);
|
||||
} catch (OutOfResourcesException e) {
|
||||
handleOutOfResourcesException(e);
|
||||
mLastPerformTraversalsSkipDrawReason = "oom_update_surface";
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -3321,6 +3341,7 @@ public final class ViewRootImpl implements ViewParent,
|
||||
if (mCheckIfCanDraw) {
|
||||
try {
|
||||
cancelDraw = mWindowSession.cancelDraw(mWindow);
|
||||
cancelReason = "wm_sync";
|
||||
if (DEBUG_BLAST) {
|
||||
Log.d(mTag, "cancelDraw returned " + cancelDraw);
|
||||
}
|
||||
@@ -3543,19 +3564,21 @@ public final class ViewRootImpl implements ViewParent,
|
||||
mImeFocusController.onTraversal(hasWindowFocus, mWindowAttributes);
|
||||
|
||||
if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
|
||||
reportNextDraw();
|
||||
reportNextDraw("first_relayout");
|
||||
}
|
||||
|
||||
mCheckIfCanDraw = isSyncRequest || cancelDraw;
|
||||
|
||||
boolean cancelAndRedraw =
|
||||
mAttachInfo.mTreeObserver.dispatchOnPreDraw() || (cancelDraw && mDrewOnceForSync);
|
||||
boolean cancelDueToPreDrawListener = mAttachInfo.mTreeObserver.dispatchOnPreDraw();
|
||||
boolean cancelAndRedraw = cancelDueToPreDrawListener
|
||||
|| (cancelDraw && mDrewOnceForSync);
|
||||
if (!cancelAndRedraw) {
|
||||
createSyncIfNeeded();
|
||||
mDrewOnceForSync = true;
|
||||
}
|
||||
|
||||
if (!isViewVisible) {
|
||||
mLastPerformTraversalsSkipDrawReason = "view_not_visible";
|
||||
if (mPendingTransitions != null && mPendingTransitions.size() > 0) {
|
||||
for (int i = 0; i < mPendingTransitions.size(); ++i) {
|
||||
mPendingTransitions.get(i).endChangingAnimations();
|
||||
@@ -3567,6 +3590,9 @@ public final class ViewRootImpl implements ViewParent,
|
||||
mSyncBufferCallback.onBufferReady(null);
|
||||
}
|
||||
} else if (cancelAndRedraw) {
|
||||
mLastPerformTraversalsSkipDrawReason = cancelDueToPreDrawListener
|
||||
? "predraw_" + mAttachInfo.mTreeObserver.getLastDispatchOnPreDrawCanceledReason()
|
||||
: "cancel_" + cancelReason;
|
||||
// Try again
|
||||
scheduleTraversals();
|
||||
} else {
|
||||
@@ -3590,11 +3616,13 @@ public final class ViewRootImpl implements ViewParent,
|
||||
|
||||
if (!cancelAndRedraw) {
|
||||
mReportNextDraw = false;
|
||||
mLastReportNextDrawReason = null;
|
||||
mSyncBufferCallback = null;
|
||||
mSyncBuffer = false;
|
||||
if (isInLocalSync()) {
|
||||
mSurfaceSyncer.markSyncReady(mSyncId);
|
||||
mSyncId = UNSET_SYNC_ID;
|
||||
mLocalSyncState = LOCAL_SYNC_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3606,9 +3634,12 @@ public final class ViewRootImpl implements ViewParent,
|
||||
}
|
||||
|
||||
final int seqId = mSyncSeqId;
|
||||
mLocalSyncState = LOCAL_SYNC_PENDING;
|
||||
mSyncId = mSurfaceSyncer.setupSync(transaction -> {
|
||||
mLocalSyncState = LOCAL_SYNC_RETURNED;
|
||||
// Callback will be invoked on executor thread so post to main thread.
|
||||
mHandler.postAtFrontOfQueue(() -> {
|
||||
mLocalSyncState = LOCAL_SYNC_MERGED;
|
||||
mSurfaceChangedTransaction.merge(transaction);
|
||||
reportDrawFinished(seqId);
|
||||
});
|
||||
@@ -4323,9 +4354,12 @@ public final class ViewRootImpl implements ViewParent,
|
||||
}
|
||||
|
||||
private boolean performDraw() {
|
||||
mLastPerformDrawSkippedReason = null;
|
||||
if (mAttachInfo.mDisplayState == Display.STATE_OFF && !mReportNextDraw) {
|
||||
mLastPerformDrawSkippedReason = "screen_off";
|
||||
return false;
|
||||
} else if (mView == null) {
|
||||
mLastPerformDrawSkippedReason = "no_root_view";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -8392,6 +8426,21 @@ public final class ViewRootImpl implements ViewParent,
|
||||
if (mTraversalScheduled) {
|
||||
writer.println(innerPrefix + " (barrier=" + mTraversalBarrier + ")");
|
||||
}
|
||||
writer.println(innerPrefix + "mReportNextDraw=" + mReportNextDraw);
|
||||
if (mReportNextDraw) {
|
||||
writer.println(innerPrefix + " (reason=" + mLastReportNextDrawReason + ")");
|
||||
}
|
||||
if (mLastPerformTraversalsSkipDrawReason != null) {
|
||||
writer.println(innerPrefix + "mLastPerformTraversalsFailedReason="
|
||||
+ mLastPerformTraversalsSkipDrawReason);
|
||||
}
|
||||
if (mLastPerformDrawSkippedReason != null) {
|
||||
writer.println(innerPrefix + "mLastPerformDrawFailedReason="
|
||||
+ mLastPerformDrawSkippedReason);
|
||||
}
|
||||
if (mLocalSyncState != LOCAL_SYNC_NONE) {
|
||||
writer.println(innerPrefix + "mLocalSyncState=" + mLocalSyncState);
|
||||
}
|
||||
writer.println(innerPrefix + "mIsAmbientMode=" + mIsAmbientMode);
|
||||
writer.println(innerPrefix + "mUnbufferedInputSource="
|
||||
+ Integer.toHexString(mUnbufferedInputSource));
|
||||
@@ -9892,11 +9941,12 @@ public final class ViewRootImpl implements ViewParent,
|
||||
}
|
||||
}
|
||||
|
||||
private void reportNextDraw() {
|
||||
private void reportNextDraw(String reason) {
|
||||
if (DEBUG_BLAST) {
|
||||
Log.d(mTag, "reportNextDraw " + Debug.getCallers(5));
|
||||
}
|
||||
mReportNextDraw = true;
|
||||
mLastReportNextDrawReason = reason;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -9909,11 +9959,12 @@ public final class ViewRootImpl implements ViewParent,
|
||||
* @param syncBuffer If true, the transaction that contains the buffer from the draw should be
|
||||
* sent to system to be synced. If false, VRI will not try to sync the buffer,
|
||||
* but only report back that a buffer was drawn.
|
||||
* @param reason A debug string indicating the reason for reporting the next draw
|
||||
* @hide
|
||||
*/
|
||||
public void setReportNextDraw(boolean syncBuffer) {
|
||||
public void setReportNextDraw(boolean syncBuffer, String reason) {
|
||||
mSyncBuffer = syncBuffer;
|
||||
reportNextDraw();
|
||||
reportNextDraw(reason);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +74,9 @@ public final class ViewTreeObserver {
|
||||
* that the listener will be immediately called. */
|
||||
private boolean mWindowShown;
|
||||
|
||||
// The reason that the last call to dispatchOnPreDraw() returned true to cancel and redraw
|
||||
private String mLastDispatchOnPreDrawCanceledReason;
|
||||
|
||||
private boolean mAlive = true;
|
||||
|
||||
/**
|
||||
@@ -1167,6 +1170,7 @@ public final class ViewTreeObserver {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public final boolean dispatchOnPreDraw() {
|
||||
mLastDispatchOnPreDrawCanceledReason = null;
|
||||
boolean cancelDraw = false;
|
||||
final CopyOnWriteArray<OnPreDrawListener> listeners = mOnPreDrawListeners;
|
||||
if (listeners != null && listeners.size() > 0) {
|
||||
@@ -1174,7 +1178,11 @@ public final class ViewTreeObserver {
|
||||
try {
|
||||
int count = access.size();
|
||||
for (int i = 0; i < count; i++) {
|
||||
cancelDraw |= !(access.get(i).onPreDraw());
|
||||
final OnPreDrawListener preDrawListener = access.get(i);
|
||||
cancelDraw |= !(preDrawListener.onPreDraw());
|
||||
if (cancelDraw) {
|
||||
mLastDispatchOnPreDrawCanceledReason = preDrawListener.getClass().getName();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
listeners.end();
|
||||
@@ -1183,6 +1191,15 @@ public final class ViewTreeObserver {
|
||||
return cancelDraw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the reason that the last call to dispatchOnPreDraw() returned true to cancel the
|
||||
* current draw, or null if the last call did not cancel.
|
||||
* @hide
|
||||
*/
|
||||
final String getLastDispatchOnPreDrawCanceledReason() {
|
||||
return mLastDispatchOnPreDrawCanceledReason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies registered listeners that the window is now shown
|
||||
* @hide
|
||||
|
||||
Reference in New Issue
Block a user