Loading core/java/android/view/SurfaceView.java +44 −17 Original line number Original line Diff line number Diff line Loading @@ -124,6 +124,7 @@ public class SurfaceView extends View { int mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA; int mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA; boolean mIsCreating = false; boolean mIsCreating = false; private volatile boolean mRtHandlingPositionUpdates = false; final Handler mHandler = new Handler() { final Handler mHandler = new Handler() { @Override @Override Loading Loading @@ -649,7 +650,9 @@ public class SurfaceView extends View { TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y + TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y + " w=" + mLayout.width + " h=" + mLayout.height + " w=" + mLayout.width + " h=" + mLayout.height + ", frame=" + mSurfaceFrame); ", frame=" + mSurfaceFrame); } else if (!isHardwareAccelerated()) { } else { // Calculate the window position in case RT loses the window // and we need to fallback to a UI-thread driven position update getLocationInWindow(mLocation); getLocationInWindow(mLocation); final boolean positionChanged = mWindowSpaceLeft != mLocation[0] final boolean positionChanged = mWindowSpaceLeft != mLocation[0] || mWindowSpaceTop != mLocation[1]; || mWindowSpaceTop != mLocation[1]; Loading @@ -670,8 +673,9 @@ public class SurfaceView extends View { mTranslator.translateRectInAppWindowToScreen(mWinFrame); mTranslator.translateRectInAppWindowToScreen(mWinFrame); } } if (!isHardwareAccelerated() || !mRtHandlingPositionUpdates) { try { try { Log.d(TAG, String.format("%d updateWindowPosition UI, " + if (DEBUG) Log.d(TAG, String.format("%d updateWindowPosition UI, " + "postion = [%d, %d, %d, %d]", System.identityHashCode(this), "postion = [%d, %d, %d, %d]", System.identityHashCode(this), mWinFrame.left, mWinFrame.top, mWinFrame.left, mWinFrame.top, mWinFrame.right, mWinFrame.bottom)); mWinFrame.right, mWinFrame.bottom)); Loading @@ -683,6 +687,7 @@ public class SurfaceView extends View { } } } } } } } private Rect mRTLastReportedPosition = new Rect(); private Rect mRTLastReportedPosition = new Rect(); Loading @@ -698,6 +703,15 @@ public class SurfaceView extends View { // Guess we got detached, that sucks // Guess we got detached, that sucks return; return; } } // TODO: This is teensy bit racey in that a brand new SurfaceView moving on // its 2nd frame if RenderThread is running slowly could potentially see // this as false, enter the branch, get pre-empted, then this comes along // and reports a new position, then the UI thread resumes and reports // its position. This could therefore be de-sync'd in that interval, but // the synchronization would violate the rule that RT must never block // on the UI thread which would open up potential deadlocks. The risk of // a single-frame desync is therefore preferable for now. mRtHandlingPositionUpdates = true; if (mRTLastReportedPosition.left == left if (mRTLastReportedPosition.left == left && mRTLastReportedPosition.top == top && mRTLastReportedPosition.top == top && mRTLastReportedPosition.right == right && mRTLastReportedPosition.right == right Loading Loading @@ -731,13 +745,26 @@ public class SurfaceView extends View { Log.d(TAG, String.format("%d windowPositionLostRT RT, frameNr = %d", Log.d(TAG, String.format("%d windowPositionLostRT RT, frameNr = %d", System.identityHashCode(this), frameNumber)); System.identityHashCode(this), frameNumber)); } } // TODO: This is a bit of a hack as we don't have an API to report to WM if (mRtHandlingPositionUpdates) { // to hide a window with a frameNumber, so just shift the window very far into mRtHandlingPositionUpdates = false; // negative space which will do effectively the same thing. // This callback will happen while the UI thread is blocked, so we can // Use the last reported size to avoid influencing the size of the bufferqueue // safely access other member variables at this time. int x = -1000 - mRTLastReportedPosition.width(); // So do what the UI thread would have done if RT wasn't handling position int y = -1000 - mRTLastReportedPosition.height(); // updates. updateWindowPositionRT(frameNumber, x, y, -1000, -1000); if (!mWinFrame.isEmpty() && !mWinFrame.equals(mRTLastReportedPosition)) { try { if (DEBUG) Log.d(TAG, String.format("%d updateWindowPosition, " + "postion = [%d, %d, %d, %d]", System.identityHashCode(this), mWinFrame.left, mWinFrame.top, mWinFrame.right, mWinFrame.bottom)); mSession.repositionChild(mWindow, mWinFrame.left, mWinFrame.top, mWinFrame.right, mWinFrame.bottom, frameNumber, mWinFrame); } catch (RemoteException ex) { Log.e(TAG, "Exception from relayout", ex); } } mRTLastReportedPosition.setEmpty(); } } } private SurfaceHolder.Callback[] getSurfaceCallbacks() { private SurfaceHolder.Callback[] getSurfaceCallbacks() { Loading Loading
core/java/android/view/SurfaceView.java +44 −17 Original line number Original line Diff line number Diff line Loading @@ -124,6 +124,7 @@ public class SurfaceView extends View { int mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA; int mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA; boolean mIsCreating = false; boolean mIsCreating = false; private volatile boolean mRtHandlingPositionUpdates = false; final Handler mHandler = new Handler() { final Handler mHandler = new Handler() { @Override @Override Loading Loading @@ -649,7 +650,9 @@ public class SurfaceView extends View { TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y + TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y + " w=" + mLayout.width + " h=" + mLayout.height + " w=" + mLayout.width + " h=" + mLayout.height + ", frame=" + mSurfaceFrame); ", frame=" + mSurfaceFrame); } else if (!isHardwareAccelerated()) { } else { // Calculate the window position in case RT loses the window // and we need to fallback to a UI-thread driven position update getLocationInWindow(mLocation); getLocationInWindow(mLocation); final boolean positionChanged = mWindowSpaceLeft != mLocation[0] final boolean positionChanged = mWindowSpaceLeft != mLocation[0] || mWindowSpaceTop != mLocation[1]; || mWindowSpaceTop != mLocation[1]; Loading @@ -670,8 +673,9 @@ public class SurfaceView extends View { mTranslator.translateRectInAppWindowToScreen(mWinFrame); mTranslator.translateRectInAppWindowToScreen(mWinFrame); } } if (!isHardwareAccelerated() || !mRtHandlingPositionUpdates) { try { try { Log.d(TAG, String.format("%d updateWindowPosition UI, " + if (DEBUG) Log.d(TAG, String.format("%d updateWindowPosition UI, " + "postion = [%d, %d, %d, %d]", System.identityHashCode(this), "postion = [%d, %d, %d, %d]", System.identityHashCode(this), mWinFrame.left, mWinFrame.top, mWinFrame.left, mWinFrame.top, mWinFrame.right, mWinFrame.bottom)); mWinFrame.right, mWinFrame.bottom)); Loading @@ -683,6 +687,7 @@ public class SurfaceView extends View { } } } } } } } private Rect mRTLastReportedPosition = new Rect(); private Rect mRTLastReportedPosition = new Rect(); Loading @@ -698,6 +703,15 @@ public class SurfaceView extends View { // Guess we got detached, that sucks // Guess we got detached, that sucks return; return; } } // TODO: This is teensy bit racey in that a brand new SurfaceView moving on // its 2nd frame if RenderThread is running slowly could potentially see // this as false, enter the branch, get pre-empted, then this comes along // and reports a new position, then the UI thread resumes and reports // its position. This could therefore be de-sync'd in that interval, but // the synchronization would violate the rule that RT must never block // on the UI thread which would open up potential deadlocks. The risk of // a single-frame desync is therefore preferable for now. mRtHandlingPositionUpdates = true; if (mRTLastReportedPosition.left == left if (mRTLastReportedPosition.left == left && mRTLastReportedPosition.top == top && mRTLastReportedPosition.top == top && mRTLastReportedPosition.right == right && mRTLastReportedPosition.right == right Loading Loading @@ -731,13 +745,26 @@ public class SurfaceView extends View { Log.d(TAG, String.format("%d windowPositionLostRT RT, frameNr = %d", Log.d(TAG, String.format("%d windowPositionLostRT RT, frameNr = %d", System.identityHashCode(this), frameNumber)); System.identityHashCode(this), frameNumber)); } } // TODO: This is a bit of a hack as we don't have an API to report to WM if (mRtHandlingPositionUpdates) { // to hide a window with a frameNumber, so just shift the window very far into mRtHandlingPositionUpdates = false; // negative space which will do effectively the same thing. // This callback will happen while the UI thread is blocked, so we can // Use the last reported size to avoid influencing the size of the bufferqueue // safely access other member variables at this time. int x = -1000 - mRTLastReportedPosition.width(); // So do what the UI thread would have done if RT wasn't handling position int y = -1000 - mRTLastReportedPosition.height(); // updates. updateWindowPositionRT(frameNumber, x, y, -1000, -1000); if (!mWinFrame.isEmpty() && !mWinFrame.equals(mRTLastReportedPosition)) { try { if (DEBUG) Log.d(TAG, String.format("%d updateWindowPosition, " + "postion = [%d, %d, %d, %d]", System.identityHashCode(this), mWinFrame.left, mWinFrame.top, mWinFrame.right, mWinFrame.bottom)); mSession.repositionChild(mWindow, mWinFrame.left, mWinFrame.top, mWinFrame.right, mWinFrame.bottom, frameNumber, mWinFrame); } catch (RemoteException ex) { Log.e(TAG, "Exception from relayout", ex); } } mRTLastReportedPosition.setEmpty(); } } } private SurfaceHolder.Callback[] getSurfaceCallbacks() { private SurfaceHolder.Callback[] getSurfaceCallbacks() { Loading