Synchronize future unsync transactions to last sync.

This ensures we don't push through an unsynchronized
update while a synchronized one is pending. If the
synchronized one is no longer pending, then our
transaction is applied anyway and things continue as normal.

Bug: 27098060
Change-Id: I08fe8f848848d25d01b1696e0340fcce61ac554f
This commit is contained in:
Robert Carr
2016-04-07 15:51:48 -07:00
parent 78740add9b
commit 679c807210
3 changed files with 43 additions and 5 deletions

View File

@@ -2555,7 +2555,7 @@ public class WindowManagerService extends IWindowManager.Stub
void repositionChild(Session session, IWindow client,
int left, int top, int right, int bottom,
long deferTransactionUntilFrame, Rect outFrame) {
long frameNumber, Rect outFrame) {
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "repositionChild");
long origId = Binder.clearCallingIdentity();
@@ -2591,10 +2591,8 @@ public class WindowManagerService extends IWindowManager.Stub
win.mWinAnimator.setSurfaceBoundariesLocked(false);
if (deferTransactionUntilFrame > 0) {
win.mWinAnimator.mSurfaceController.deferTransactionUntil(
win.mAttachedWindow.mWinAnimator.mSurfaceController.getHandle(),
deferTransactionUntilFrame);
if (frameNumber > 0) {
win.mWinAnimator.deferTransactionUntilParentFrame(frameNumber);
}
} finally {

View File

@@ -219,6 +219,10 @@ class WindowStateAnimator {
int mAttrType;
static final long PENDING_TRANSACTION_FINISH_WAIT_TIME = 100;
long mDeferTransactionUntilFrame = -1;
long mDeferTransactionTime = -1;
private final Rect mTmpSize = new Rect();
WindowStateAnimator(final WindowState win) {
@@ -1865,4 +1869,36 @@ class WindowStateAnimator {
mAnimDy = mWin.mLastFrame.top - top;
mAnimateMove = true;
}
void deferTransactionUntilParentFrame(long frameNumber) {
if (!mWin.isChildWindow()) {
return;
}
mDeferTransactionUntilFrame = frameNumber;
mDeferTransactionTime = System.currentTimeMillis();
mSurfaceController.deferTransactionUntil(
mWin.mAttachedWindow.mWinAnimator.mSurfaceController.getHandle(),
frameNumber);
}
// Defer the current transaction to the frame number of the last saved transaction.
// We do this to avoid shooting through an unsynchronized transaction while something is
// pending. This is generally fine, as either we will get in on the synchronization,
// or SurfaceFlinger will see that the frame has already occured. The only
// potential problem is in frame number resets so we reset things with a timeout
// every so often to be careful.
void deferToPendingTransaction() {
if (mDeferTransactionUntilFrame < 0) {
return;
}
long time = System.currentTimeMillis();
if (time > mDeferTransactionTime + PENDING_TRANSACTION_FINISH_WAIT_TIME) {
mDeferTransactionTime = -1;
mDeferTransactionUntilFrame = -1;
} else {
mSurfaceController.deferTransactionUntil(
mWin.mAttachedWindow.mWinAnimator.mSurfaceController.getHandle(),
mDeferTransactionUntilFrame);
}
}
}

View File

@@ -721,6 +721,10 @@ class WindowSurfacePlacer {
// Moved from updateWindowsAndWallpaperLocked().
if (w.mHasSurface) {
// If we have recently synchronized a previous transaction for this
// window ensure we don't push through an unsynchronized one now.
winAnimator.deferToPendingTransaction();
// Take care of the window being ready to display.
final boolean committed = winAnimator.commitFinishDrawingLocked();
if (isDefaultDisplay && committed) {