Merge "SurfaceView: Make surfaceRedrawNeededAsync work with WM bypass." into oc-dev

This commit is contained in:
Rob Carr
2017-03-29 16:44:36 +00:00
committed by Android (Google) Code Review
2 changed files with 65 additions and 7 deletions

View File

@@ -137,7 +137,10 @@ public class SurfaceView extends View {
} break; } break;
case DRAW_FINISHED_MSG: { case DRAW_FINISHED_MSG: {
mDrawFinished = true; mDrawFinished = true;
invalidate(); if (mAttachedToWindow) {
notifyDrawFinished();
invalidate();
}
} break; } break;
} }
} }
@@ -188,9 +191,12 @@ public class SurfaceView extends View {
private Translator mTranslator; private Translator mTranslator;
private boolean mGlobalListenersAdded; private boolean mGlobalListenersAdded;
private boolean mAttachedToWindow;
private int mSurfaceFlags = SurfaceControl.HIDDEN; private int mSurfaceFlags = SurfaceControl.HIDDEN;
private int mPendingReportDraws;
public SurfaceView(Context context) { public SurfaceView(Context context) {
this(context, null); this(context, null);
} }
@@ -227,6 +233,7 @@ public class SurfaceView extends View {
mViewVisibility = getVisibility() == VISIBLE; mViewVisibility = getVisibility() == VISIBLE;
mRequestedVisible = mViewVisibility && mWindowVisibility; mRequestedVisible = mViewVisibility && mWindowVisibility;
mAttachedToWindow = true;
if (!mGlobalListenersAdded) { if (!mGlobalListenersAdded) {
ViewTreeObserver observer = getViewTreeObserver(); ViewTreeObserver observer = getViewTreeObserver();
observer.addOnScrollChangedListener(mScrollChangedListener); observer.addOnScrollChangedListener(mScrollChangedListener);
@@ -261,8 +268,17 @@ public class SurfaceView extends View {
updateSurface(); updateSurface();
} }
void notifyDrawFinished() {
ViewRootImpl viewRoot = getViewRootImpl();
if (viewRoot != null) {
viewRoot.pendingDrawFinished();
}
mPendingReportDraws--;
}
@Override @Override
protected void onDetachedFromWindow() { protected void onDetachedFromWindow() {
mAttachedToWindow = false;
if (mGlobalListenersAdded) { if (mGlobalListenersAdded) {
ViewTreeObserver observer = getViewTreeObserver(); ViewTreeObserver observer = getViewTreeObserver();
observer.removeOnScrollChangedListener(mScrollChangedListener); observer.removeOnScrollChangedListener(mScrollChangedListener);
@@ -270,6 +286,10 @@ public class SurfaceView extends View {
mGlobalListenersAdded = false; mGlobalListenersAdded = false;
} }
while (mPendingReportDraws > 0) {
notifyDrawFinished();
}
mRequestedVisible = false; mRequestedVisible = false;
updateSurface(); updateSurface();
@@ -618,6 +638,9 @@ public class SurfaceView extends View {
if (callbacks == null) { if (callbacks == null) {
callbacks = getSurfaceCallbacks(); callbacks = getSurfaceCallbacks();
} }
mPendingReportDraws++;
viewRoot.drawPending();
SurfaceCallbackHelper sch = SurfaceCallbackHelper sch =
new SurfaceCallbackHelper(this::onDrawFinished); new SurfaceCallbackHelper(this::onDrawFinished);
sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks); sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);

View File

@@ -2704,8 +2704,40 @@ public final class ViewRootImpl implements ViewParent,
} }
} }
private void onDrawFinished() { /**
* A count of the number of calls to pendingDrawFinished we
* require to notify the WM drawing is complete.
*
* This starts at 1, for the ViewRootImpl surface itself.
* Subsurfaces may debt the value with drawPending.
*/
int mDrawsNeededToReport = 1;
/**
* Delay notifying WM of draw finished until
* a balanced call to pendingDrawFinished.
*/
void drawPending() {
mDrawsNeededToReport++;
}
void pendingDrawFinished() {
if (mDrawsNeededToReport == 0) {
throw new RuntimeException("Unbalanced drawPending/pendingDrawFinished calls");
}
mDrawsNeededToReport--;
if (mDrawsNeededToReport == 0) {
reportDrawFinished();
}
}
private void postDrawFinished() {
mHandler.sendEmptyMessage(MSG_DRAW_FINISHED);
}
private void reportDrawFinished() {
try { try {
mDrawsNeededToReport = 1;
mWindowSession.finishDrawing(mWindow); mWindowSession.finishDrawing(mWindow);
} catch (RemoteException e) { } catch (RemoteException e) {
// Have fun! // Have fun!
@@ -2762,15 +2794,12 @@ public final class ViewRootImpl implements ViewParent,
} }
if (mSurfaceHolder != null && mSurface.isValid()) { if (mSurfaceHolder != null && mSurface.isValid()) {
SurfaceCallbackHelper sch = new SurfaceCallbackHelper(this::onDrawFinished); SurfaceCallbackHelper sch = new SurfaceCallbackHelper(this::postDrawFinished);
SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks(); SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks); sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
} else { } else {
try { pendingDrawFinished();
mWindowSession.finishDrawing(mWindow);
} catch (RemoteException e) {
}
} }
} }
} }
@@ -3576,6 +3605,7 @@ public final class ViewRootImpl implements ViewParent,
private final static int MSG_REQUEST_KEYBOARD_SHORTCUTS = 26; private final static int MSG_REQUEST_KEYBOARD_SHORTCUTS = 26;
private final static int MSG_UPDATE_POINTER_ICON = 27; private final static int MSG_UPDATE_POINTER_ICON = 27;
private final static int MSG_POINTER_CAPTURE_CHANGED = 28; private final static int MSG_POINTER_CAPTURE_CHANGED = 28;
private final static int MSG_DRAW_FINISHED = 29;
final class ViewRootHandler extends Handler { final class ViewRootHandler extends Handler {
@Override @Override
@@ -3627,6 +3657,8 @@ public final class ViewRootImpl implements ViewParent,
return "MSG_UPDATE_POINTER_ICON"; return "MSG_UPDATE_POINTER_ICON";
case MSG_POINTER_CAPTURE_CHANGED: case MSG_POINTER_CAPTURE_CHANGED:
return "MSG_POINTER_CAPTURE_CHANGED"; return "MSG_POINTER_CAPTURE_CHANGED";
case MSG_DRAW_FINISHED:
return "MSG_DRAW_FINISHED";
} }
return super.getMessageName(message); return super.getMessageName(message);
} }
@@ -3902,6 +3934,9 @@ public final class ViewRootImpl implements ViewParent,
final boolean hasCapture = msg.arg1 != 0; final boolean hasCapture = msg.arg1 != 0;
handlePointerCaptureChanged(hasCapture); handlePointerCaptureChanged(hasCapture);
} break; } break;
case MSG_DRAW_FINISHED: {
pendingDrawFinished();
} break;
} }
} }
} }