diff options
| author | TreeHugger Robot <treehugger-gerrit@google.com> | 2017-03-10 05:15:18 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2017-03-10 05:15:21 +0000 |
| commit | cfdfd997bd3aa8e32d9d1eefddb1d5921c1db5ee (patch) | |
| tree | a4a072ac5836189adcb9afc572142abaf9822165 /core/java/android | |
| parent | 6698ff30c41a6142bcc08149bd3169859ea638fc (diff) | |
| parent | d5c7dd6da810a6b89151b337bea79fd817e6b72a (diff) | |
Merge "Modify SurfaceView to use SurfaceFlinger child surfaces."
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/view/SurfaceControl.java | 23 | ||||
| -rw-r--r-- | core/java/android/view/SurfaceSession.java | 5 | ||||
| -rw-r--r-- | core/java/android/view/SurfaceView.java | 451 | ||||
| -rw-r--r-- | core/java/android/view/ViewRootImpl.java | 10 |
4 files changed, 220 insertions, 269 deletions
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index b718696b2202..519c1e2454df 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -95,6 +95,11 @@ public class SurfaceControl { IBinder displayToken, int mode); private static native void nativeDeferTransactionUntil(long nativeObject, IBinder handle, long frame); + private static native void nativeDeferTransactionUntilSurface(long nativeObject, + long surfaceObject, long frame); + private static native void nativeReparentChildren(long nativeObject, + IBinder handle); + private static native void nativeSeverChildren(long nativeObject); private static native void nativeSetOverrideScalingMode(long nativeObject, int scalingMode); private static native IBinder nativeGetHandle(long nativeObject); @@ -418,7 +423,23 @@ public class SurfaceControl { } public void deferTransactionUntil(IBinder handle, long frame) { - nativeDeferTransactionUntil(mNativeObject, handle, frame); + if (frame > 0) { + nativeDeferTransactionUntil(mNativeObject, handle, frame); + } + } + + public void deferTransactionUntil(Surface barrier, long frame) { + if (frame > 0) { + nativeDeferTransactionUntilSurface(mNativeObject, barrier.mNativeObject, frame); + } + } + + public void reparentChildren(IBinder newParentHandle) { + nativeReparentChildren(mNativeObject, newParentHandle); + } + + public void detachChildren() { + nativeSeverChildren(mNativeObject); } public void setOverrideScalingMode(int scalingMode) { diff --git a/core/java/android/view/SurfaceSession.java b/core/java/android/view/SurfaceSession.java index 3cf5af484625..b5912bc1e1c8 100644 --- a/core/java/android/view/SurfaceSession.java +++ b/core/java/android/view/SurfaceSession.java @@ -27,6 +27,7 @@ public final class SurfaceSession { private long mNativeClient; // SurfaceComposerClient* private static native long nativeCreate(); + private static native long nativeCreateScoped(long surfacePtr); private static native void nativeDestroy(long ptr); private static native void nativeKill(long ptr); @@ -35,6 +36,10 @@ public final class SurfaceSession { mNativeClient = nativeCreate(); } + public SurfaceSession(Surface root) { + mNativeClient = nativeCreateScoped(root.mNativeObject); + } + /* no user serviceable parts here ... */ @Override protected void finalize() throws Throwable { diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index d2577d48c3d1..61b12475d542 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -16,6 +16,10 @@ package android.view; +import static android.view.WindowManagerPolicy.APPLICATION_MEDIA_SUBLAYER; +import static android.view.WindowManagerPolicy.APPLICATION_MEDIA_OVERLAY_SUBLAYER; +import static android.view.WindowManagerPolicy.APPLICATION_PANEL_SUBLAYER; + import android.content.Context; import android.content.res.CompatibilityInfo.Translator; import android.content.res.Configuration; @@ -26,16 +30,12 @@ import android.graphics.Rect; import android.graphics.Region; import android.os.Handler; import android.os.Message; -import android.os.ParcelFileDescriptor; -import android.os.RemoteException; import android.os.SystemClock; import android.util.AttributeSet; import android.util.Log; -import com.android.internal.view.BaseIWindow; import com.android.internal.view.SurfaceCallbackHelper; -import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.concurrent.locks.ReentrantLock; @@ -92,8 +92,8 @@ import java.util.concurrent.locks.ReentrantLock; * positioned asynchronously.</p> */ public class SurfaceView extends View { - static private final String TAG = "SurfaceView"; - static private final boolean DEBUG = false; + private static final String TAG = "SurfaceView"; + private static final boolean DEBUG = false; final ArrayList<SurfaceHolder.Callback> mCallbacks = new ArrayList<SurfaceHolder.Callback>(); @@ -102,28 +102,23 @@ public class SurfaceView extends View { final ReentrantLock mSurfaceLock = new ReentrantLock(); final Surface mSurface = new Surface(); // Current surface in use - final Surface mNewSurface = new Surface(); // New surface we are switching to boolean mDrawingStopped = true; + // We use this to track if the application has produced a frame + // in to the Surface. Up until that point, we should be careful not to punch + // holes. + boolean mDrawFinished = false; + + final Rect mScreenRect = new Rect(); + SurfaceSession mSurfaceSession; - final WindowManager.LayoutParams mLayout - = new WindowManager.LayoutParams(); - IWindowSession mSession; - MyWindow mWindow; - final Rect mVisibleInsets = new Rect(); - final Rect mWinFrame = new Rect(); - final Rect mOverscanInsets = new Rect(); - final Rect mContentInsets = new Rect(); - final Rect mStableInsets = new Rect(); - final Rect mOutsets = new Rect(); - final Rect mBackdropFrame = new Rect(); + SurfaceControl mSurfaceControl; final Rect mTmpRect = new Rect(); final Configuration mConfiguration = new Configuration(); static final int KEEP_SCREEN_ON_MSG = 1; - static final int GET_NEW_SURFACE_MSG = 2; - static final int UPDATE_WINDOW_MSG = 3; + static final int DRAW_FINISHED_MSG = 2; - int mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA; + int mSubLayer = APPLICATION_MEDIA_SUBLAYER; boolean mIsCreating = false; private volatile boolean mRtHandlingPositionUpdates = false; @@ -135,11 +130,9 @@ public class SurfaceView extends View { case KEEP_SCREEN_ON_MSG: { setKeepScreenOn(msg.arg1 != 0); } break; - case GET_NEW_SURFACE_MSG: { - handleGetNewSurface(); - } break; - case UPDATE_WINDOW_MSG: { - updateWindow(); + case DRAW_FINISHED_MSG: { + mDrawFinished = true; + invalidate(); } break; } } @@ -149,7 +142,7 @@ public class SurfaceView extends View { = new ViewTreeObserver.OnScrollChangedListener() { @Override public void onScrollChanged() { - updateWindow(); + updateSurface(); } }; @@ -159,13 +152,14 @@ public class SurfaceView extends View { public boolean onPreDraw() { // reposition ourselves where the surface is mHaveFrame = getWidth() > 0 && getHeight() > 0; - updateWindow(); + updateSurface(); return true; } }; boolean mRequestedVisible = false; boolean mWindowVisibility = false; + boolean mLastWindowVisibility = false; boolean mViewVisibility = false; int mRequestedWidth = -1; int mRequestedHeight = -1; @@ -181,19 +175,17 @@ public class SurfaceView extends View { boolean mVisible = false; int mWindowSpaceLeft = -1; int mWindowSpaceTop = -1; - int mWindowSpaceWidth = -1; - int mWindowSpaceHeight = -1; + int mSurfaceWidth = -1; + int mSurfaceHeight = -1; int mFormat = -1; final Rect mSurfaceFrame = new Rect(); int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1; - boolean mUpdateWindowNeeded; - boolean mReportDrawNeeded; private Translator mTranslator; - private int mWindowInsetLeft; - private int mWindowInsetTop; private boolean mGlobalListenersAdded; + private int mSurfaceFlags = SurfaceControl.HIDDEN; + public SurfaceView(Context context) { this(context, null); } @@ -227,11 +219,8 @@ public class SurfaceView extends View { protected void onAttachedToWindow() { super.onAttachedToWindow(); mParent.requestTransparentRegion(this); - mSession = getWindowSession(); - mLayout.token = getWindowToken(); - mLayout.setTitle("SurfaceView - " + getViewRootImpl().getTitle()); - mLayout.packageName = mContext.getOpPackageName(); mViewVisibility = getVisibility() == VISIBLE; + mRequestedVisible = mViewVisibility && mWindowVisibility; if (!mGlobalListenersAdded) { ViewTreeObserver observer = getViewTreeObserver(); @@ -246,7 +235,7 @@ public class SurfaceView extends View { super.onWindowVisibilityChanged(visibility); mWindowVisibility = visibility == VISIBLE; mRequestedVisible = mWindowVisibility && mViewVisibility; - updateWindow(); + updateSurface(); } @Override @@ -264,7 +253,7 @@ public class SurfaceView extends View { requestLayout(); } mRequestedVisible = newRequestedVisible; - updateWindow(); + updateSurface(); } @Override @@ -277,19 +266,14 @@ public class SurfaceView extends View { } mRequestedVisible = false; - updateWindow(); - mHaveFrame = false; - if (mWindow != null) { - try { - mSession.remove(mWindow); - } catch (RemoteException ex) { - // Not much we can do here... - } - mWindow = null; + + updateSurface(); + if (mSurfaceControl != null) { + mSurfaceControl.destroy(); } - mSession = null; - mLayout.token = null; + mSurfaceControl = null; + mHaveFrame = false; super.onDetachedFromWindow(); } @@ -308,13 +292,13 @@ public class SurfaceView extends View { @Override protected boolean setFrame(int left, int top, int right, int bottom) { boolean result = super.setFrame(left, top, right, bottom); - updateWindow(); + updateSurface(); return result; } @Override public boolean gatherTransparentRegion(Region region) { - if (mWindowType == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) { + if (isAboveParent()) { return super.gatherTransparentRegion(region); } @@ -341,7 +325,7 @@ public class SurfaceView extends View { @Override public void draw(Canvas canvas) { - if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) { + if (mDrawFinished && !isAboveParent()) { // draw() is not called when SKIP_DRAW is set if ((mPrivateFlags & PFLAG_SKIP_DRAW) == 0) { // punch a whole in the view-hierarchy below us @@ -353,8 +337,8 @@ public class SurfaceView extends View { @Override protected void dispatchDraw(Canvas canvas) { - if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) { - // if SKIP_DRAW is cleared, draw() has already punched a hole + if (mDrawFinished && !isAboveParent()) { + // draw() is not called when SKIP_DRAW is set if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) { // punch a whole in the view-hierarchy below us canvas.drawColor(0, PorterDuff.Mode.CLEAR); @@ -375,9 +359,8 @@ public class SurfaceView extends View { * <p>Calling this overrides any previous call to {@link #setZOrderOnTop}. */ public void setZOrderMediaOverlay(boolean isMediaOverlay) { - mWindowType = isMediaOverlay - ? WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY - : WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA; + mSubLayer = isMediaOverlay + ? APPLICATION_MEDIA_OVERLAY_SUBLAYER : APPLICATION_MEDIA_SUBLAYER; } /** @@ -395,12 +378,9 @@ public class SurfaceView extends View { */ public void setZOrderOnTop(boolean onTop) { if (onTop) { - mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; - // ensures the surface is placed below the IME - mLayout.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; + mSubLayer = APPLICATION_PANEL_SUBLAYER; } else { - mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA; - mLayout.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; + mSubLayer = APPLICATION_MEDIA_SUBLAYER; } } @@ -418,31 +398,32 @@ public class SurfaceView extends View { */ public void setSecure(boolean isSecure) { if (isSecure) { - mLayout.flags |= WindowManager.LayoutParams.FLAG_SECURE; + mSurfaceFlags |= SurfaceControl.SECURE; } else { - mLayout.flags &= ~WindowManager.LayoutParams.FLAG_SECURE; + mSurfaceFlags &= ~SurfaceControl.SECURE; } } - /** - * Hack to allow special layering of windows. The type is one of the - * types in WindowManager.LayoutParams. This is a hack so: - * @hide - */ - public void setWindowType(int type) { - mWindowType = type; + private Rect getParentSurfaceInsets() { + final ViewRootImpl root = getViewRootImpl(); + if (root == null) { + return null; + } else { + return root.mWindowAttributes.surfaceInsets; + } } /** @hide */ - protected void updateWindow() { + protected void updateSurface() { if (!mHaveFrame) { return; } ViewRootImpl viewRoot = getViewRootImpl(); - if (viewRoot != null) { - mTranslator = viewRoot.mTranslator; + if (viewRoot == null || viewRoot.mSurface == null || !viewRoot.mSurface.isValid()) { + return; } + mTranslator = viewRoot.mTranslator; if (mTranslator != null) { mSurface.setCompatibilityTranslator(mTranslator); } @@ -452,17 +433,15 @@ public class SurfaceView extends View { int myHeight = mRequestedHeight; if (myHeight <= 0) myHeight = getHeight(); - final boolean creating = mWindow == null; final boolean formatChanged = mFormat != mRequestedFormat; - final boolean sizeChanged = mWindowSpaceWidth != myWidth || mWindowSpaceHeight != myHeight; + final boolean creating = (mSurfaceControl == null || formatChanged) + && mRequestedVisible; + final boolean sizeChanged = mSurfaceWidth != myWidth || mSurfaceHeight != myHeight; final boolean visibleChanged = mVisible != mRequestedVisible; - final boolean layoutSizeChanged = getWidth() != mLayout.width - || getHeight() != mLayout.height; - + final boolean windowVisibleChanged = mWindowVisibility != mLastWindowVisibility; boolean redrawNeeded = false; - if (creating || formatChanged || sizeChanged || visibleChanged - || mUpdateWindowNeeded || mReportDrawNeeded) { + if (creating || formatChanged || sizeChanged || visibleChanged || windowVisibleChanged) { getLocationInWindow(mLocation); if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " @@ -476,93 +455,77 @@ public class SurfaceView extends View { final boolean visible = mVisible = mRequestedVisible; mWindowSpaceLeft = mLocation[0]; mWindowSpaceTop = mLocation[1]; - mWindowSpaceWidth = myWidth; - mWindowSpaceHeight = myHeight; + mSurfaceWidth = myWidth; + mSurfaceHeight = myHeight; mFormat = mRequestedFormat; + mLastWindowVisibility = mWindowVisibility; - // Scaling/Translate window's layout here because mLayout is not used elsewhere. - - // Places the window relative - mLayout.x = mWindowSpaceLeft; - mLayout.y = mWindowSpaceTop; - mLayout.width = getWidth(); - mLayout.height = getHeight(); + mScreenRect.left = mWindowSpaceLeft; + mScreenRect.top = mWindowSpaceTop; + mScreenRect.right = mWindowSpaceLeft + getWidth(); + mScreenRect.bottom = mWindowSpaceTop + getHeight(); if (mTranslator != null) { - mTranslator.translateLayoutParamsInAppWindowToScreen(mLayout); + mTranslator.translateRectInAppWindowToScreen(mScreenRect); } - mLayout.format = mRequestedFormat; - mLayout.flags |=WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE - | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE - | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS - | WindowManager.LayoutParams.FLAG_SCALED - | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE - | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE - ; - if (!creating && !sizeChanged) { - mLayout.privateFlags |= - WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY; - } else { - mLayout.privateFlags &= - ~WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY; - } + final Rect surfaceInsets = getParentSurfaceInsets(); + mScreenRect.offset(surfaceInsets.left, surfaceInsets.top); - if (!getContext().getResources().getCompatibilityInfo().supportsScreen()) { - mLayout.privateFlags |= - WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; - } - mLayout.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION - | WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME; - - if (mWindow == null) { - Display display = getDisplay(); - mWindow = new MyWindow(this); - mLayout.type = mWindowType; - mLayout.gravity = Gravity.START|Gravity.TOP; - mSession.addToDisplayWithoutInputChannel(mWindow, mWindow.mSeq, mLayout, - mVisible ? VISIBLE : GONE, display.getDisplayId(), mContentInsets, - mStableInsets); + if (creating) { + mSurfaceSession = new SurfaceSession(viewRoot.mSurface); + mSurfaceControl = new SurfaceControl(mSurfaceSession, + "SurfaceView - " + viewRoot.getTitle().toString(), + mSurfaceWidth, mSurfaceHeight, mFormat, + mSurfaceFlags); } - boolean realSizeChanged; - boolean reportDrawNeeded; - - int relayoutResult; + boolean realSizeChanged = false; mSurfaceLock.lock(); try { - mUpdateWindowNeeded = false; - reportDrawNeeded = mReportDrawNeeded; - mReportDrawNeeded = false; mDrawingStopped = !visible; if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " + "Cur surface: " + mSurface); - relayoutResult = mSession.relayout( - mWindow, mWindow.mSeq, mLayout, mWindowSpaceWidth, mWindowSpaceHeight, - visible ? VISIBLE : GONE, - WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY, - mWinFrame, mOverscanInsets, mContentInsets, - mVisibleInsets, mStableInsets, mOutsets, mBackdropFrame, - mConfiguration, mNewSurface); - if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) { - reportDrawNeeded = true; + SurfaceControl.openTransaction(); + try { + mSurfaceControl.setLayer(mSubLayer); + if (mViewVisibility) { + mSurfaceControl.show(); + } else { + mSurfaceControl.hide(); + } + + // While creating the surface, we will set it's initial + // geometry. Outside of that though, we should generally + // leave it to the RenderThread. + if (creating || !mRtHandlingPositionUpdates) { + mSurfaceControl.setPosition(mScreenRect.left, mScreenRect.top); + mSurfaceControl.setMatrix(mScreenRect.width() / (float) mSurfaceWidth, + 0.0f, 0.0f, + mScreenRect.height() / (float) mSurfaceHeight); + } + if (sizeChanged) { + mSurfaceControl.setSize(mSurfaceWidth, mSurfaceHeight); + } + } finally { + SurfaceControl.closeTransaction(); } - if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " - + "New surface: " + mNewSurface - + ", vis=" + visible + ", frame=" + mWinFrame); + if (sizeChanged || creating) { + redrawNeeded = true; + } mSurfaceFrame.left = 0; mSurfaceFrame.top = 0; if (mTranslator == null) { - mSurfaceFrame.right = mWinFrame.width(); - mSurfaceFrame.bottom = mWinFrame.height(); + mSurfaceFrame.right = mSurfaceWidth; + mSurfaceFrame.bottom = mSurfaceHeight; } else { float appInvertedScale = mTranslator.applicationInvertedScale; - mSurfaceFrame.right = (int) (mWinFrame.width() * appInvertedScale + 0.5f); - mSurfaceFrame.bottom = (int) (mWinFrame.height() * appInvertedScale + 0.5f); + mSurfaceFrame.right = (int) (mSurfaceWidth * appInvertedScale + 0.5f); + mSurfaceFrame.bottom = (int) (mSurfaceHeight * appInvertedScale + 0.5f); } final int surfaceWidth = mSurfaceFrame.right; @@ -576,12 +539,11 @@ public class SurfaceView extends View { } try { - redrawNeeded |= creating | reportDrawNeeded; + redrawNeeded |= visible && !mDrawFinished; SurfaceHolder.Callback callbacks[] = null; - final boolean surfaceChanged = (relayoutResult - & WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED) != 0; + final boolean surfaceChanged = creating; if (mSurfaceCreated && (surfaceChanged || (!visible && visibleChanged))) { mSurfaceCreated = false; if (mSurface.isValid()) { @@ -608,7 +570,10 @@ public class SurfaceView extends View { } } - mSurface.transferFrom(mNewSurface); + if (creating) { + mSurface.copyFrom(mSurfaceControl); + } + if (visible && mSurface.isValid()) { if (!mSurfaceCreated && (surfaceChanged || visibleChanged)) { mSurfaceCreated = true; @@ -641,53 +606,55 @@ public class SurfaceView extends View { callbacks = getSurfaceCallbacks(); } SurfaceCallbackHelper sch = - new SurfaceCallbackHelper(mSession, mWindow); + new SurfaceCallbackHelper(this::onDrawFinished); sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks); } } } finally { mIsCreating = false; - mSession.performDeferredDestroy(mWindow); + if (mSurfaceControl != null && !mSurfaceCreated) { + mSurfaceControl.destroy(); + mSurfaceControl = null; + } } - } catch (RemoteException ex) { + } catch (Exception ex) { Log.e(TAG, "Exception from relayout", ex); } if (DEBUG) Log.v( - TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y + - " w=" + mLayout.width + " h=" + mLayout.height + - ", frame=" + mSurfaceFrame); + TAG, "Layout: x=" + mScreenRect.left + " y=" + mScreenRect.top + + " w=" + mScreenRect.width() + " h=" + mScreenRect.height() + + ", frame=" + mSurfaceFrame); } 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); + getLocationInSurface(mLocation); final boolean positionChanged = mWindowSpaceLeft != mLocation[0] || mWindowSpaceTop != mLocation[1]; + final boolean layoutSizeChanged = getWidth() != mScreenRect.width() + || getHeight() != mScreenRect.height(); if (positionChanged || layoutSizeChanged) { // Only the position has changed mWindowSpaceLeft = mLocation[0]; mWindowSpaceTop = mLocation[1]; - // For our size changed check, we keep mLayout.width and mLayout.height + // For our size changed check, we keep mScreenRect.width() and mScreenRect.height() // in view local space. - mLocation[0] = mLayout.width = getWidth(); - mLocation[1] = mLayout.height = getHeight(); - - transformFromViewToWindowSpace(mLocation); + mLocation[0] = getWidth(); + mLocation[1] = getHeight(); - mTmpRect.set(mWindowSpaceLeft, mWindowSpaceTop, + mScreenRect.set(mWindowSpaceLeft, mWindowSpaceTop, mLocation[0], mLocation[1]); if (mTranslator != null) { - mTranslator.translateRectInAppWindowToScreen(mTmpRect); + mTranslator.translateRectInAppWindowToScreen(mScreenRect); } if (!isHardwareAccelerated() || !mRtHandlingPositionUpdates) { try { - if (DEBUG) Log.d(TAG, String.format("%d updateWindowPosition UI, " + + if (DEBUG) Log.d(TAG, String.format("%d updateSurfacePosition UI, " + "postion = [%d, %d, %d, %d]", System.identityHashCode(this), - mTmpRect.left, mTmpRect.top, - mTmpRect.right, mTmpRect.bottom)); - mSession.repositionChild(mWindow, mTmpRect.left, mTmpRect.top, - mTmpRect.right, mTmpRect.bottom, -1, mTmpRect); - } catch (RemoteException ex) { + mScreenRect.left, mScreenRect.top, + mScreenRect.right, mScreenRect.bottom)); + setParentSpaceRectangle(mScreenRect, -1); + } catch (Exception ex) { Log.e(TAG, "Exception from relayout", ex); } } @@ -695,20 +662,43 @@ public class SurfaceView extends View { } } + private void onDrawFinished() { + if (DEBUG) { + Log.i(TAG, System.identityHashCode(this) + " " + + "finishedDrawing"); + } + mHandler.sendEmptyMessage(DRAW_FINISHED_MSG); + } + + private void setParentSpaceRectangle(Rect position, long frameNumber) { + ViewRootImpl viewRoot = getViewRootImpl(); + + SurfaceControl.openTransaction(); + try { + if (frameNumber > 0) { + mSurfaceControl.deferTransactionUntil(viewRoot.mSurface, frameNumber); + } + mSurfaceControl.setPosition(position.left, position.top); + mSurfaceControl.setMatrix(position.width() / (float) mSurfaceWidth, + 0.0f, 0.0f, + position.height() / (float) mSurfaceHeight); + } finally { + SurfaceControl.closeTransaction(); + } + } + private Rect mRTLastReportedPosition = new Rect(); /** * Called by native by a Rendering Worker thread to update the window position * @hide */ - public final void updateWindowPosition_renderWorker(long frameNumber, + public final void updateSurfacePosition_renderWorker(long frameNumber, int left, int top, int right, int bottom) { - IWindowSession session = mSession; - MyWindow window = mWindow; - if (session == null || window == null) { - // Guess we got detached, that sucks + if (mSurfaceControl == null) { 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 @@ -726,35 +716,29 @@ public class SurfaceView extends View { } try { if (DEBUG) { - Log.d(TAG, String.format("%d updateWindowPosition RenderWorker, frameNr = %d, " + + Log.d(TAG, String.format("%d updateSurfacePosition RenderWorker, frameNr = %d, " + "postion = [%d, %d, %d, %d]", System.identityHashCode(this), frameNumber, left, top, right, bottom)); } - // Just using mRTLastReportedPosition as a dummy rect here - session.repositionChild(window, left, top, right, bottom, - frameNumber, - mRTLastReportedPosition); - // Now overwrite mRTLastReportedPosition with our values mRTLastReportedPosition.set(left, top, right, bottom); - } catch (RemoteException ex) { + setParentSpaceRectangle(mRTLastReportedPosition, frameNumber); + // Now overwrite mRTLastReportedPosition with our values + } catch (Exception ex) { Log.e(TAG, "Exception from repositionChild", ex); } } /** - * Called by native on RenderThread to notify that the window is no longer in the + * Called by native on RenderThread to notify that the view is no longer in the * draw tree. UI thread is blocked at this point. * @hide */ - public final void windowPositionLost_uiRtSync(long frameNumber) { + public final void surfacePositionLost_uiRtSync(long frameNumber) { if (DEBUG) { Log.d(TAG, String.format("%d windowPositionLost, frameNr = %d", System.identityHashCode(this), frameNumber)); } - IWindowSession session = mSession; - MyWindow window = mWindow; - if (session == null || window == null) { - // We got detached prior to receiving this, abort + if (mSurfaceControl == null) { return; } if (mRtHandlingPositionUpdates) { @@ -763,19 +747,14 @@ public class SurfaceView extends View { // safely access other member variables at this time. // So do what the UI thread would have done if RT wasn't handling position // updates. - mTmpRect.set(mLayout.x, mLayout.y, - mLayout.x + mLayout.width, - mLayout.y + mLayout.height); - - if (!mTmpRect.isEmpty() && !mTmpRect.equals(mRTLastReportedPosition)) { + if (!mScreenRect.isEmpty() && !mScreenRect.equals(mRTLastReportedPosition)) { try { - if (DEBUG) Log.d(TAG, String.format("%d updateWindowPosition, " + + if (DEBUG) Log.d(TAG, String.format("%d updateSurfacePosition, " + "postion = [%d, %d, %d, %d]", System.identityHashCode(this), - mTmpRect.left, mTmpRect.top, - mTmpRect.right, mTmpRect.bottom)); - session.repositionChild(window, mTmpRect.left, mTmpRect.top, - mTmpRect.right, mTmpRect.bottom, frameNumber, mWinFrame); - } catch (RemoteException ex) { + mScreenRect.left, mScreenRect.top, + mScreenRect.right, mScreenRect.bottom)); + setParentSpaceRectangle(mScreenRect, frameNumber); + } catch (Exception ex) { Log.e(TAG, "Exception from relayout", ex); } } @@ -792,10 +771,6 @@ public class SurfaceView extends View { return callbacks; } - void handleGetNewSurface() { - updateWindow(); - } - /** * Check to see if the surface has fixed size dimensions or if the surface's * dimensions are dimensions are dependent on its current layout. @@ -807,65 +782,8 @@ public class SurfaceView extends View { return (mRequestedWidth != -1 || mRequestedHeight != -1); } - private static class MyWindow extends BaseIWindow { - private final WeakReference<SurfaceView> mSurfaceView; - - public MyWindow(SurfaceView surfaceView) { - mSurfaceView = new WeakReference<SurfaceView>(surfaceView); - } - - @Override - public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, - Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, - Configuration newConfig, Rect backDropRect, boolean forceLayout, - boolean alwaysConsumeNavBar, int displayId) { - SurfaceView surfaceView = mSurfaceView.get(); - if (surfaceView != null) { - if (DEBUG) Log.v(TAG, surfaceView + " got resized: w=" + frame.width() - + " h=" + frame.height() + ", cur w=" + mCurWidth + " h=" + mCurHeight); - surfaceView.mSurfaceLock.lock(); - try { - if (reportDraw) { - surfaceView.mUpdateWindowNeeded = true; - surfaceView.mReportDrawNeeded = true; - surfaceView.mHandler.sendEmptyMessage(UPDATE_WINDOW_MSG); - } else if (surfaceView.mWinFrame.width() != frame.width() - || surfaceView.mWinFrame.height() != frame.height() - || forceLayout) { - surfaceView.mUpdateWindowNeeded = true; - surfaceView.mHandler.sendEmptyMessage(UPDATE_WINDOW_MSG); - } - } finally { - surfaceView.mSurfaceLock.unlock(); - } - } - } - - @Override - public void dispatchAppVisibility(boolean visible) { - // The point of SurfaceView is to let the app control the surface. - } - - @Override - public void dispatchGetNewSurface() { - SurfaceView surfaceView = mSurfaceView.get(); - if (surfaceView != null) { - Message msg = surfaceView.mHandler.obtainMessage(GET_NEW_SURFACE_MSG); - surfaceView.mHandler.sendMessage(msg); - } - } - - @Override - public void windowFocusChanged(boolean hasFocus, boolean touchEnabled) { - Log.w("SurfaceView", "Unexpected focus in surface: focus=" + hasFocus + ", touchEnabled=" + touchEnabled); - } - - @Override - public void executeCommand(String command, String parameters, ParcelFileDescriptor out) { - } - - int mCurWidth = -1; - int mCurHeight = -1; + private boolean isAboveParent() { + return mSubLayer >= 0; } private final SurfaceHolder mSurfaceHolder = new SurfaceHolder() { @@ -913,15 +831,14 @@ public class SurfaceView extends View { @Override public void setFormat(int format) { - // for backward compatibility reason, OPAQUE always // means 565 for SurfaceView if (format == PixelFormat.OPAQUE) format = PixelFormat.RGB_565; mRequestedFormat = format; - if (mWindow != null) { - updateWindow(); + if (mSurfaceControl != null) { + updateSurface(); } } @@ -982,10 +899,10 @@ public class SurfaceView extends View { mSurfaceLock.lock(); if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " + "Locking canvas... stopped=" - + mDrawingStopped + ", win=" + mWindow); + + mDrawingStopped + ", surfaceControl=" + mSurfaceControl); Canvas c = null; - if (!mDrawingStopped && mWindow != null) { + if (!mDrawingStopped && mSurfaceControl != null) { try { if (hardware) { c = mSurface.lockHardwareCanvas(); diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 20d960fff661..f9863b0a6761 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -2632,6 +2632,14 @@ public final class ViewRootImpl implements ViewParent, } } + private void onDrawFinished() { + try { + mWindowSession.finishDrawing(mWindow); + } catch (RemoteException e) { + // Have fun! + } + } + private void performDraw() { if (mAttachInfo.mDisplayState == Display.STATE_OFF && !mReportNextDraw) { return; @@ -2682,7 +2690,7 @@ public final class ViewRootImpl implements ViewParent, } if (mSurfaceHolder != null && mSurface.isValid()) { - SurfaceCallbackHelper sch = new SurfaceCallbackHelper(mWindowSession, mWindow); + SurfaceCallbackHelper sch = new SurfaceCallbackHelper(this::onDrawFinished); SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks(); sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks); |
