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

Commit 599913d6 authored by Chet Haase's avatar Chet Haase
Browse files

Account for static child transformations correctly

Optimizations in drawing and invalidation in JB did not correctly
account for static child transforms
(View.getChildStaticTransformation()).
For the invalidation part, this meant that views were not properly
setting the invalidation bounds (which should be transformed by
the static transform), so the affected area of the invalidation
was potentially incorrect. For the drawing part, this meant that
views outside of their parent's bounds were being incorrectly
rejected when the static transform would, in fact, place the views
inside of those bounds.

The fix is in two parts:
- drawing: avoid the early quickReject() logic for containers that
have static transformations set on them
(ViewGroup.setStaticTransformationsEnabled()).
- invalidation: Include the static transform in the invalidation
area propagated up the view hierarchy.

Issue #6864203 The child position outside of parent is not drawn
even it will be drawn inside of the parent after applying static
transformation

Change-Id: I73bea01feab250bdcae2d575313be355a4a3c8f5
parent 9169b558
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -12877,7 +12877,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        // to call invalidate() successfully when doing animations
        mPrivateFlags |= DRAWN;
        if (!concatMatrix && canvas.quickReject(mLeft, mTop, mRight, mBottom, Canvas.EdgeType.BW) &&
        if (!concatMatrix && (flags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) == 0 &&
                canvas.quickReject(mLeft, mTop, mRight, mBottom, Canvas.EdgeType.BW) &&
                (mPrivateFlags & DRAW_ANIMATION) == 0) {
            mPrivateFlags2 |= VIEW_QUICK_REJECTED;
            return more;
@@ -17295,6 +17296,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
         */
        final RectF mTmpTransformRect = new RectF();
        /**
         * Temporary for use in transforming invalidation rect
         */
        final Matrix mTmpMatrix = new Matrix();
        /**
         * Temporary for use in transforming invalidation rect
         */
        final Transformation mTmpTransformation = new Transformation();
        /**
         * Temporary list for use in collecting focusable descendents of a view.
         */
+22 −5
Original line number Diff line number Diff line
@@ -2988,7 +2988,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
     *
     * @param enabled True to enable static transformations on children, false otherwise.
     *
     * @see #FLAG_SUPPORT_STATIC_TRANSFORMATIONS
     * @see #getChildStaticTransformation(View, android.view.animation.Transformation)
     */
    protected void setStaticTransformationsEnabled(boolean enabled) {
        setBooleanFlag(FLAG_SUPPORT_STATIC_TRANSFORMATIONS, enabled);
@@ -2998,7 +2998,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
     * Sets  <code>t</code> to be the static transformation of the child, if set, returning a
     * boolean to indicate whether a static transform was set. The default implementation
     * simply returns <code>false</code>; subclasses may override this method for different
     * behavior.
     * behavior. {@link #setStaticTransformationsEnabled(boolean)} must be set to true
     * for this method to be called.
     *
     * @param child The child view whose static transform is being requested
     * @param t The Transformation which will hold the result
@@ -3962,11 +3963,27 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
            final int[] location = attachInfo.mInvalidateChildLocation;
            location[CHILD_LEFT_INDEX] = child.mLeft;
            location[CHILD_TOP_INDEX] = child.mTop;
            if (!childMatrix.isIdentity()) {
            if (!childMatrix.isIdentity() ||
                    (mGroupFlags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
                RectF boundingRect = attachInfo.mTmpTransformRect;
                boundingRect.set(dirty);
                //boundingRect.inset(-0.5f, -0.5f);
                childMatrix.mapRect(boundingRect);
                Matrix transformMatrix;
                if ((mGroupFlags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
                    Transformation t = attachInfo.mTmpTransformation;
                    boolean transformed = getChildStaticTransformation(child, t);
                    if (transformed) {
                        transformMatrix = attachInfo.mTmpMatrix;
                        transformMatrix.set(t.getMatrix());
                        if (!childMatrix.isIdentity()) {
                            transformMatrix.preConcat(childMatrix);
                        }
                    } else {
                        transformMatrix = childMatrix;
                    }
                } else {
                    transformMatrix = childMatrix;
                }
                transformMatrix.mapRect(boundingRect);
                dirty.set((int) (boundingRect.left - 0.5f),
                        (int) (boundingRect.top - 0.5f),
                        (int) (boundingRect.right + 0.5f),