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

Commit 1de566b5 authored by Diego Perez's avatar Diego Perez Committed by android-build-merger
Browse files

Merge "Separate measure so it can only run inflate if needed" into nyc-dev

am: 38745971

* commit '38745971':
  Separate measure so it can only run inflate if needed

Change-Id: Id52cf5e5c211d8c0f2363e0e349669a1c1f4ca40
parents 48b8d147 38745971
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -192,8 +192,10 @@ public class BridgeRenderSession extends RenderSession {

    @Override
    public void setElapsedFrameTimeNanos(long nanos) {
        if (mSession != null) {
            mSession.setElapsedFrameTimeNanos(nanos);
        }
    }

    @Override
    public void dispose() {
+95 −76
Original line number Diff line number Diff line
@@ -134,6 +134,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
    private List<ViewInfo> mViewInfoList;
    private List<ViewInfo> mSystemViewInfoList;
    private Layout.Builder mLayoutBuilder;
    private boolean mNewRenderSize;

    private static final class PostInflateException extends Exception {
        private static final long serialVersionUID = 1L;
@@ -199,6 +200,88 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
        return SUCCESS.createResult();
    }

    /**
     * Measures the the current layout if needed (see {@link #invalidateRenderingSize}).
     */
    private void measure(@NonNull SessionParams params) {
        // only do the screen measure when needed.
        if (mMeasuredScreenWidth != -1) {
            return;
        }

        RenderingMode renderingMode = params.getRenderingMode();
        HardwareConfig hardwareConfig = params.getHardwareConfig();

        mNewRenderSize = true;
        mMeasuredScreenWidth = hardwareConfig.getScreenWidth();
        mMeasuredScreenHeight = hardwareConfig.getScreenHeight();

        if (renderingMode != RenderingMode.NORMAL) {
            int widthMeasureSpecMode = renderingMode.isHorizExpand() ?
                    MeasureSpec.UNSPECIFIED // this lets us know the actual needed size
                    : MeasureSpec.EXACTLY;
            int heightMeasureSpecMode = renderingMode.isVertExpand() ?
                    MeasureSpec.UNSPECIFIED // this lets us know the actual needed size
                    : MeasureSpec.EXACTLY;

            // We used to compare the measured size of the content to the screen size but
            // this does not work anymore due to the 2 following issues:
            // - If the content is in a decor (system bar, title/action bar), the root view
            //   will not resize even with the UNSPECIFIED because of the embedded layout.
            // - If there is no decor, but a dialog frame, then the dialog padding prevents
            //   comparing the size of the content to the screen frame (as it would not
            //   take into account the dialog padding).

            // The solution is to first get the content size in a normal rendering, inside
            // the decor or the dialog padding.
            // Then measure only the content with UNSPECIFIED to see the size difference
            // and apply this to the screen size.

            // first measure the full layout, with EXACTLY to get the size of the
            // content as it is inside the decor/dialog
            @SuppressWarnings("deprecation")
            Pair<Integer, Integer> exactMeasure = measureView(
                    mViewRoot, mContentRoot.getChildAt(0),
                    mMeasuredScreenWidth, MeasureSpec.EXACTLY,
                    mMeasuredScreenHeight, MeasureSpec.EXACTLY);

            // now measure the content only using UNSPECIFIED (where applicable, based on
            // the rendering mode). This will give us the size the content needs.
            @SuppressWarnings("deprecation")
            Pair<Integer, Integer> result = measureView(
                    mContentRoot, mContentRoot.getChildAt(0),
                    mMeasuredScreenWidth, widthMeasureSpecMode,
                    mMeasuredScreenHeight, heightMeasureSpecMode);

            // now look at the difference and add what is needed.
            if (renderingMode.isHorizExpand()) {
                int measuredWidth = exactMeasure.getFirst();
                int neededWidth = result.getFirst();
                if (neededWidth > measuredWidth) {
                    mMeasuredScreenWidth += neededWidth - measuredWidth;
                }
                if (mMeasuredScreenWidth < measuredWidth) {
                    // If the screen width is less than the exact measured width,
                    // expand to match.
                    mMeasuredScreenWidth = measuredWidth;
                }
            }

            if (renderingMode.isVertExpand()) {
                int measuredHeight = exactMeasure.getSecond();
                int neededHeight = result.getSecond();
                if (neededHeight > measuredHeight) {
                    mMeasuredScreenHeight += neededHeight - measuredHeight;
                }
                if (mMeasuredScreenHeight < measuredHeight) {
                    // If the screen height is less than the exact measured height,
                    // expand to match.
                    mMeasuredScreenHeight = measuredHeight;
                }
            }
        }
    }

    /**
     * Inflates the layout.
     * <p>
@@ -245,6 +328,14 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {

            setActiveToolbar(view, context, params);

            measure(params);
            measureView(mViewRoot, null /*measuredView*/,
                    mMeasuredScreenWidth, MeasureSpec.EXACTLY,
                    mMeasuredScreenHeight, MeasureSpec.EXACTLY);
            mViewRoot.layout(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
            mSystemViewInfoList = visitAllChildren(mViewRoot, 0, params.getExtendedViewInfoMode(),
                    false);

            return SUCCESS.createResult();
        } catch (PostInflateException e) {
            return ERROR_INFLATION.createResult(e.getMessage(), e);
@@ -320,82 +411,9 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
                return ERROR_NOT_INFLATED.createResult();
            }

            RenderingMode renderingMode = params.getRenderingMode();
            HardwareConfig hardwareConfig = params.getHardwareConfig();

            // only do the screen measure when needed.
            boolean newRenderSize = false;
            if (mMeasuredScreenWidth == -1) {
                newRenderSize = true;
                mMeasuredScreenWidth = hardwareConfig.getScreenWidth();
                mMeasuredScreenHeight = hardwareConfig.getScreenHeight();

                if (renderingMode != RenderingMode.NORMAL) {
                    int widthMeasureSpecMode = renderingMode.isHorizExpand() ?
                            MeasureSpec.UNSPECIFIED // this lets us know the actual needed size
                            : MeasureSpec.EXACTLY;
                    int heightMeasureSpecMode = renderingMode.isVertExpand() ?
                            MeasureSpec.UNSPECIFIED // this lets us know the actual needed size
                            : MeasureSpec.EXACTLY;

                    // We used to compare the measured size of the content to the screen size but
                    // this does not work anymore due to the 2 following issues:
                    // - If the content is in a decor (system bar, title/action bar), the root view
                    //   will not resize even with the UNSPECIFIED because of the embedded layout.
                    // - If there is no decor, but a dialog frame, then the dialog padding prevents
                    //   comparing the size of the content to the screen frame (as it would not
                    //   take into account the dialog padding).

                    // The solution is to first get the content size in a normal rendering, inside
                    // the decor or the dialog padding.
                    // Then measure only the content with UNSPECIFIED to see the size difference
                    // and apply this to the screen size.

                    // first measure the full layout, with EXACTLY to get the size of the
                    // content as it is inside the decor/dialog
                    @SuppressWarnings("deprecation")
                    Pair<Integer, Integer> exactMeasure = measureView(
                            mViewRoot, mContentRoot.getChildAt(0),
                            mMeasuredScreenWidth, MeasureSpec.EXACTLY,
                            mMeasuredScreenHeight, MeasureSpec.EXACTLY);

                    // now measure the content only using UNSPECIFIED (where applicable, based on
                    // the rendering mode). This will give us the size the content needs.
                    @SuppressWarnings("deprecation")
                    Pair<Integer, Integer> result = measureView(
                            mContentRoot, mContentRoot.getChildAt(0),
                            mMeasuredScreenWidth, widthMeasureSpecMode,
                            mMeasuredScreenHeight, heightMeasureSpecMode);

                    // now look at the difference and add what is needed.
                    if (renderingMode.isHorizExpand()) {
                        int measuredWidth = exactMeasure.getFirst();
                        int neededWidth = result.getFirst();
                        if (neededWidth > measuredWidth) {
                            mMeasuredScreenWidth += neededWidth - measuredWidth;
                        }
                        if (mMeasuredScreenWidth < measuredWidth) {
                            // If the screen width is less than the exact measured width,
                            // expand to match.
                            mMeasuredScreenWidth = measuredWidth;
                        }
                    }

                    if (renderingMode.isVertExpand()) {
                        int measuredHeight = exactMeasure.getSecond();
                        int neededHeight = result.getSecond();
                        if (neededHeight > measuredHeight) {
                            mMeasuredScreenHeight += neededHeight - measuredHeight;
                        }
                        if (mMeasuredScreenHeight < measuredHeight) {
                            // If the screen height is less than the exact measured height,
                            // expand to match.
                            mMeasuredScreenHeight = measuredHeight;
                        }
                    }
                }
            }
            measure(params);

            HardwareConfig hardwareConfig = params.getHardwareConfig();
            Result renderResult = SUCCESS.createResult();
            if (params.isLayoutOnly()) {
                // delete the canvas and image to reset them on the next full rendering
@@ -412,7 +430,8 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
                // it doesn't get cached.
                boolean disableBitmapCaching = Boolean.TRUE.equals(params.getFlag(
                    RenderParamsFlags.FLAG_KEY_DISABLE_BITMAP_CACHING));
                if (newRenderSize || mCanvas == null || disableBitmapCaching) {
                if (mNewRenderSize || mCanvas == null || disableBitmapCaching) {
                    mNewRenderSize = false;
                    if (params.getImageFactory() != null) {
                        mImage = params.getImageFactory().getImage(
                                mMeasuredScreenWidth,