Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 78a45f2b authored by Robert Carr's avatar Robert Carr
Browse files

Clarify geometry management for SurfaceView

In the hardware accelerated case, RenderThread needs
to be the authority of information on the geometry of
the SurfaceView (this will occur via moving the
repositionWindow call to RenderThread). In order
to support this we have to enable calling relayoutWindow
without geometry (so that it will not fight with
repositionWindow). Add such a mode to relayoutWindow
and use it from SurfaceView. Add size to repositionChild
while we are here.

Change-Id: I12f85f586a38bf86367f3d964cb49f19003d441f
parent a76bafdc
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -101,16 +101,24 @@ interface IWindowSession {
     *  for the parent window appears. This allows for synchronizing movement of a child
     *  to repainting the contents of the parent.
     *
     *  "width" and "height" correspond to the width and height members of
     *  WindowManager.LayoutParams in the {@link #relayout relayout()} case.
     *  This may differ from the surface buffer size in the
     *  case of {@link LayoutParams#FLAG_SCALED} and {@link #relayout relayout()}
     *  must be used with requestedWidth/height if this must be changed.
     *
     *  @param window The window being modified. Must be attached to a parent window
     *  or this call will fail.
     *  @param x The new x position
     *  @param y The new y position
     *  @param width The new width
     *  @param height The new height
     *  @param deferTransactionUntilFrame Frame number from our parent (attached) to
     *  defer this action until.
     *  @param outFrame Rect in which is placed the new position/size on screen.
     */
    void repositionChild(IWindow childWindow, int x, int y, long deferTransactionUntilFrame,
            out Rect outFrame);
    void repositionChild(IWindow childWindow, int left, int top, int right, int bottom,
            long deferTransactionUntilFrame, out Rect outFrame);

    /**
     * If a call to relayout() asked to have the surface destroy deferred,
+38 −21
Original line number Diff line number Diff line
@@ -157,10 +157,10 @@ public class SurfaceView extends View {
    long mLastLockTime = 0;

    boolean mVisible = false;
    int mLeft = -1;
    int mTop = -1;
    int mWidth = -1;
    int mHeight = -1;
    int mWindowSpaceLeft = -1;
    int mWindowSpaceTop = -1;
    int mWindowSpaceWidth = -1;
    int mWindowSpaceHeight = -1;
    int mFormat = -1;
    final Rect mSurfaceFrame = new Rect();
    int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1;
@@ -445,32 +445,33 @@ public class SurfaceView extends View {
        getLocationInWindow(mLocation);
        final boolean creating = mWindow == null;
        final boolean formatChanged = mFormat != mRequestedFormat;
        final boolean sizeChanged = mWidth != myWidth || mHeight != myHeight;
        final boolean sizeChanged = mWindowSpaceWidth != myWidth || mWindowSpaceHeight != myHeight;
        final boolean visibleChanged = mVisible != mRequestedVisible;
        final boolean layoutSizeChanged = getWidth() != mLayout.width || getHeight() != mLayout.height;
        final boolean positionChanged = mLeft != mLocation[0] || mTop != mLocation[1];
        final boolean layoutSizeChanged = getWidth() != mLayout.width
                || getHeight() != mLayout.height;
        final boolean positionChanged = mWindowSpaceLeft != mLocation[0] || mWindowSpaceTop != mLocation[1];

        if (force || creating || formatChanged || sizeChanged || visibleChanged
            || mUpdateWindowNeeded || mReportDrawNeeded || redrawNeeded || layoutSizeChanged) {
            || mUpdateWindowNeeded || mReportDrawNeeded || redrawNeeded) {
            if (DEBUG) Log.i(TAG, "Changes: creating=" + creating
                    + " format=" + formatChanged + " size=" + sizeChanged
                    + " visible=" + visibleChanged
                    + " left=" + (mLeft != mLocation[0])
                    + " top=" + (mTop != mLocation[1]));
                    + " left=" + (mWindowSpaceLeft != mLocation[0])
                    + " top=" + (mWindowSpaceTop != mLocation[1]));

            try {
                final boolean visible = mVisible = mRequestedVisible;
                mLeft = mLocation[0];
                mTop = mLocation[1];
                mWidth = myWidth;
                mHeight = myHeight;
                mWindowSpaceLeft = mLocation[0];
                mWindowSpaceTop = mLocation[1];
                mWindowSpaceWidth = myWidth;
                mWindowSpaceHeight = myHeight;
                mFormat = mRequestedFormat;

                // Scaling/Translate window's layout here because mLayout is not used elsewhere.

                // Places the window relative
                mLayout.x = mLeft;
                mLayout.y = mTop;
                mLayout.x = mWindowSpaceLeft;
                mLayout.y = mWindowSpaceTop;
                mLayout.width = getWidth();
                mLayout.height = getHeight();
                if (mTranslator != null) {
@@ -485,6 +486,14 @@ public class SurfaceView extends View {
                              | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                              | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                              ;
                if (!creating && !force && !mUpdateWindowNeeded) {
                    mLayout.privateFlags |=
                            WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY;
                } else {
                    mLayout.privateFlags &=
                            ~WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY;
                }

                if (!getContext().getResources().getCompatibilityInfo().supportsScreen()) {
                    mLayout.privateFlags |=
                            WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
@@ -516,7 +525,7 @@ public class SurfaceView extends View {
                    if (DEBUG) Log.i(TAG, "Cur surface: " + mSurface);

                    relayoutResult = mSession.relayout(
                        mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
                        mWindow, mWindow.mSeq, mLayout, mWindowSpaceWidth, mWindowSpaceHeight,
                            visible ? VISIBLE : GONE,
                            WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY,
                            mWinFrame, mOverscanInsets, mContentInsets,
@@ -621,11 +630,19 @@ public class SurfaceView extends View {
                TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y +
                " w=" + mLayout.width + " h=" + mLayout.height +
                ", frame=" + mSurfaceFrame);
        } else if (positionChanged) { // Only the position has changed
            mLeft = mLocation[0];
            mTop = mLocation[1];
        } else 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
            // in view local space.
            mLocation[0] = mLayout.width = getWidth();
            mLocation[1] = mLayout.height = getHeight();

            transformFromViewToWindowSpace(mLocation);

            try {
                mSession.repositionChild(mWindow, mLeft, mTop,
                mSession.repositionChild(mWindow, mWindowSpaceLeft, mWindowSpaceTop,
                        mLocation[0], mLocation[1],
                        viewRoot != null ? viewRoot.getNextFrameNumber() : -1,
                        mWinFrame);
            } catch (RemoteException ex) {
+16 −8
Original line number Diff line number Diff line
@@ -18500,19 +18500,27 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     *
     * @param location an array of two integers in which to hold the coordinates
     */
    public void getLocationInWindow(@Size(2) int[] location) {
        if (location == null || location.length < 2) {
            throw new IllegalArgumentException("location must be an array of two integers");
    public void getLocationInWindow(@Size(2) int[] outWindowSpace) {
        outWindowSpace[0] = 0;
        outWindowSpace[1] = 0;
        transformFromViewToWindowSpace(outWindowSpace);
    }
    void transformFromViewToWindowSpace(@Size(2) int[] inOutLocation) {
        if (inOutLocation == null || inOutLocation.length < 2) {
            throw new IllegalArgumentException("inOutLocation must be an array of two integers");
        }
        if (mAttachInfo == null) {
            // When the view is not attached to a window, this method does not make sense
            location[0] = location[1] = 0;
            inOutLocation[0] = inOutLocation[1] = 0;
            return;
        }
        float[] position = mAttachInfo.mTmpTransformLocation;
        position[0] = position[1] = 0.0f;
        float position[] = mAttachInfo.mTmpTransformLocation;
        position[0] = inOutLocation[0];
        position[1] = inOutLocation[1];
        if (!hasIdentityMatrix()) {
            getMatrix().mapPoints(position);
@@ -18544,8 +18552,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            position[1] -= vr.mCurScrollY;
        }
        location[0] = (int) (position[0] + 0.5f);
        location[1] = (int) (position[1] + 0.5f);
        inOutLocation[0] = (int) (position[0] + 0.5f);
        inOutLocation[1] = (int) (position[1] + 0.5f);
    }
    /**
+10 −0
Original line number Diff line number Diff line
@@ -1135,6 +1135,16 @@ public interface WindowManager extends ViewManager {
         */
        public static final int PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT = 0x00001000;

        /**
         * Flag indicating that the x, y, width, and height members should be
         * ignored (and thus their previous value preserved). For example 
         * because they are being managed externally through repositionChild.
         *
         * {@hide}
         */
        public static final int PRIVATE_FLAG_PRESERVE_GEOMETRY = 0x00002000;


        /**
         * Control flags that are private to the platform.
         * @hide
+4 −3
Original line number Diff line number Diff line
@@ -188,9 +188,10 @@ final class Session extends IWindowSession.Stub
    }

    @Override
    public void repositionChild(IWindow window, int x, int y, long deferTransactionUntilFrame,
             Rect outFrame) {
        mService.repositionChild(this, window, x, y, deferTransactionUntilFrame, outFrame);
    public void repositionChild(IWindow window, int left, int top, int right, int bottom,
             long deferTransactionUntilFrame, Rect outFrame) {
        mService.repositionChild(this, window, left, top, right, bottom,
                deferTransactionUntilFrame, outFrame);
    }

    public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
Loading