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

Commit 108e5394 authored by Alan Viverette's avatar Alan Viverette Committed by Android Git Automerger
Browse files

am 6dfa60f3: Avoid extra saveLayer calls in RippleDrawable, fix docs

* commit '6dfa60f3':
  Avoid extra saveLayer calls in RippleDrawable, fix docs
parents ed068f7c 6dfa60f3
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -21,9 +21,10 @@
       android:insetTop="@dimen/button_inset_vertical_material"
       android:insetRight="@dimen/button_inset_horizontal_material"
       android:insetBottom="@dimen/button_inset_vertical_material">
    <shape android:shape="rectangle">
    <shape android:shape="rectangle"
           android:tint="?attr/colorButtonNormal">
        <corners android:radius="@dimen/control_corner_material" />
        <solid android:color="?attr/colorButtonNormal" />
        <solid android:color="@color/white" />
        <padding android:left="@dimen/button_padding_horizontal_material"
                 android:top="@dimen/button_padding_vertical_material"
                 android:right="@dimen/button_padding_horizontal_material"
+8 −1
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Insets;
import android.graphics.Outline;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.graphics.Rect;
import android.util.AttributeSet;
@@ -317,7 +318,13 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {

    @Override
    public int getOpacity() {
        return mState.mDrawable.getOpacity();
        final InsetState state = mState;
        final int opacity = state.mDrawable.getOpacity();
        if (opacity == PixelFormat.OPAQUE && (state.mInsetLeft > 0 || state.mInsetTop > 0
                || state.mInsetRight > 0 || state.mInsetBottom > 0)) {
            return PixelFormat.TRANSLUCENT;
        }
        return opacity;
    }

    @Override
+43 −55
Original line number Diff line number Diff line
@@ -22,11 +22,8 @@ import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.graphics.Canvas;
import android.graphics.CanvasProperty;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.Xfermode;
import android.util.MathUtils;
import android.view.HardwareCanvas;
import android.view.RenderNodeAnimator;
@@ -51,19 +48,12 @@ class Ripple {
    // Hardware animators.
    private final ArrayList<RenderNodeAnimator> mRunningAnimations =
            new ArrayList<RenderNodeAnimator>();
    private final ArrayList<RenderNodeAnimator> mPendingAnimations =
            new ArrayList<RenderNodeAnimator>();

    private final RippleDrawable mOwner;

    /** Bounds used for computing max radius. */
    private final Rect mBounds;

    /** ARGB color for drawing this ripple. */
    private int mColor;

    private Xfermode mXfermode;

    /** Maximum ripple radius. */
    private float mOuterRadius;

@@ -112,6 +102,10 @@ class Ripple {
    /** Whether we were canceled externally and should avoid self-removal. */
    private boolean mCanceled;

    private boolean mHasPendingHardwareExit;
    private int mPendingRadiusDuration;
    private int mPendingOpacityDuration;

    /**
     * Creates a new ripple.
     */
@@ -217,10 +211,6 @@ class Ripple {
     * Draws the ripple centered at (0,0) using the specified paint.
     */
    public boolean draw(Canvas c, Paint p) {
        // Store the color and xfermode, we might need them later.
        mColor = p.getColor();
        mXfermode = p.getXfermode();

        final boolean canUseHardware = c.isHardwareAccelerated();
        if (mCanUseHardware != canUseHardware && mCanUseHardware) {
            // We've switched from hardware to non-hardware mode. Panic.
@@ -229,8 +219,8 @@ class Ripple {
        mCanUseHardware = canUseHardware;

        final boolean hasContent;
        if (canUseHardware && mHardwareAnimating) {
            hasContent = drawHardware((HardwareCanvas) c);
        if (canUseHardware && (mHardwareAnimating || mHasPendingHardwareExit)) {
            hasContent = drawHardware((HardwareCanvas) c, p);
        } else {
            hasContent = drawSoftware(c, p);
        }
@@ -238,24 +228,10 @@ class Ripple {
        return hasContent;
    }

    private boolean drawHardware(HardwareCanvas c) {
        // If we have any pending hardware animations, cancel any running
        // animations and start those now.
        final ArrayList<RenderNodeAnimator> pendingAnimations = mPendingAnimations;
        final int N = pendingAnimations.size();
        if (N > 0) {
    private boolean drawHardware(HardwareCanvas c, Paint p) {
        if (mHasPendingHardwareExit) {
            cancelHardwareAnimations(false);

            // We canceled old animations, but we're about to run new ones.
            mHardwareAnimating = true;

            for (int i = 0; i < N; i++) {
                pendingAnimations.get(i).setTarget(c);
                pendingAnimations.get(i).start();
            }

            mRunningAnimations.addAll(pendingAnimations);
            pendingAnimations.clear();
            startPendingHardwareExit(c, p);
        }

        c.drawCircle(mPropX, mPropY, mPropRadius, mPropPaint);
@@ -347,8 +323,6 @@ class Ripple {
     * Starts the exit animation.
     */
    public void exit() {
        cancel();

        final float radius = MathUtils.lerp(0, mOuterRadius, mTweenRadius);
        final float remaining;
        if (mAnimRadius != null && mAnimRadius.isRunning()) {
@@ -357,19 +331,33 @@ class Ripple {
            remaining = mOuterRadius;
        }

        cancel();

        final int radiusDuration = (int) (1000 * Math.sqrt(remaining / (WAVE_TOUCH_UP_ACCELERATION
                + WAVE_TOUCH_DOWN_ACCELERATION) * mDensity) + 0.5);
        final int opacityDuration = (int) (1000 * mOpacity / WAVE_OPACITY_DECAY_VELOCITY + 0.5f);

        if (mCanUseHardware) {
            exitHardware(radiusDuration, opacityDuration);
            createPendingHardwareExit(radiusDuration, opacityDuration);
        } else {
            exitSoftware(radiusDuration, opacityDuration);
        }
    }

    private void exitHardware(int radiusDuration, int opacityDuration) {
        mPendingAnimations.clear();
    private void createPendingHardwareExit(int radiusDuration, int opacityDuration) {
        mHasPendingHardwareExit = true;
        mPendingRadiusDuration = radiusDuration;
        mPendingOpacityDuration = opacityDuration;

        // The animation will start on the next draw().
        invalidateSelf();
    }

    private void startPendingHardwareExit(HardwareCanvas c, Paint p) {
        mHasPendingHardwareExit = false;

        final int radiusDuration = mPendingRadiusDuration;
        final int opacityDuration = mPendingOpacityDuration;

        final float startX = MathUtils.lerp(
                mClampedStartingX - mBounds.exactCenterX(), mOuterX, mTweenX);
@@ -377,12 +365,8 @@ class Ripple {
                mClampedStartingY - mBounds.exactCenterY(), mOuterY, mTweenY);

        final float startRadius = MathUtils.lerp(0, mOuterRadius, mTweenRadius);
        final Paint paint = getTempPaint();
        paint.setAntiAlias(true);
        paint.setColor(mColor);
        paint.setXfermode(mXfermode);
        paint.setAlpha((int) (Color.alpha(mColor) * mOpacity + 0.5f));
        paint.setStyle(Style.FILL);
        final Paint paint = getTempPaint(p);
        paint.setAlpha((int) (paint.getAlpha() * mOpacity + 0.5f));
        mPropPaint = CanvasProperty.createPaint(paint);
        mPropRadius = CanvasProperty.createFloat(startRadius);
        mPropX = CanvasProperty.createFloat(startX);
@@ -391,25 +375,33 @@ class Ripple {
        final RenderNodeAnimator radiusAnim = new RenderNodeAnimator(mPropRadius, mOuterRadius);
        radiusAnim.setDuration(radiusDuration);
        radiusAnim.setInterpolator(DECEL_INTERPOLATOR);
        radiusAnim.setTarget(c);
        radiusAnim.start();

        final RenderNodeAnimator xAnim = new RenderNodeAnimator(mPropX, mOuterX);
        xAnim.setDuration(radiusDuration);
        xAnim.setInterpolator(DECEL_INTERPOLATOR);
        xAnim.setTarget(c);
        xAnim.start();

        final RenderNodeAnimator yAnim = new RenderNodeAnimator(mPropY, mOuterY);
        yAnim.setDuration(radiusDuration);
        yAnim.setInterpolator(DECEL_INTERPOLATOR);
        yAnim.setTarget(c);
        yAnim.start();

        final RenderNodeAnimator opacityAnim = new RenderNodeAnimator(mPropPaint,
                RenderNodeAnimator.PAINT_ALPHA, 0);
        opacityAnim.setDuration(opacityDuration);
        opacityAnim.setInterpolator(LINEAR_INTERPOLATOR);
        opacityAnim.addListener(mAnimationListener);
        opacityAnim.setTarget(c);
        opacityAnim.start();

        mPendingAnimations.add(radiusAnim);
        mPendingAnimations.add(opacityAnim);
        mPendingAnimations.add(xAnim);
        mPendingAnimations.add(yAnim);
        mRunningAnimations.add(radiusAnim);
        mRunningAnimations.add(opacityAnim);
        mRunningAnimations.add(xAnim);
        mRunningAnimations.add(yAnim);

        mHardwareAnimating = true;

@@ -418,8 +410,6 @@ class Ripple {
        mTweenX = 1;
        mTweenY = 1;
        mTweenRadius = 1;

        invalidateSelf();
    }

    /**
@@ -455,10 +445,11 @@ class Ripple {
        }
    }

    private Paint getTempPaint() {
    private Paint getTempPaint(Paint original) {
        if (mTempPaint == null) {
            mTempPaint = new Paint();
        }
        mTempPaint.set(original);
        return mTempPaint;
    }

@@ -539,10 +530,7 @@ class Ripple {
        }
        runningAnimations.clear();

        if (cancelPending && !mPendingAnimations.isEmpty()) {
            mPendingAnimations.clear();
        }

        mHasPendingHardwareExit = false;
        mHardwareAnimating = false;
    }

+40 −45
Original line number Diff line number Diff line
@@ -24,9 +24,7 @@ import android.graphics.Canvas;
import android.graphics.CanvasProperty;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.Xfermode;
import android.util.MathUtils;
import android.view.HardwareCanvas;
import android.view.RenderNodeAnimator;
@@ -53,8 +51,6 @@ class RippleBackground {
    // Hardware animators.
    private final ArrayList<RenderNodeAnimator> mRunningAnimations =
            new ArrayList<RenderNodeAnimator>();
    private final ArrayList<RenderNodeAnimator> mPendingAnimations =
            new ArrayList<RenderNodeAnimator>();

    private final RippleDrawable mOwner;

@@ -64,8 +60,6 @@ class RippleBackground {
    /** ARGB color for drawing this ripple. */
    private int mColor;

    private Xfermode mXfermode;

    /** Maximum ripple radius. */
    private float mOuterRadius;

@@ -98,6 +92,11 @@ class RippleBackground {
    /** Whether we have an explicit maximum radius. */
    private boolean mHasMaxRadius;

    private boolean mHasPendingHardwareExit;
    private int mPendingOpacityDuration;
    private int mPendingInflectionDuration;
    private int mPendingInflectionOpacity;

    /**
     * Creates a new ripple.
     */
@@ -144,9 +143,7 @@ class RippleBackground {
     * Draws the ripple centered at (0,0) using the specified paint.
     */
    public boolean draw(Canvas c, Paint p) {
        // Store the color and xfermode, we might need them later.
        mColor = p.getColor();
        mXfermode = p.getXfermode();

        final boolean canUseHardware = c.isHardwareAccelerated();
        if (mCanUseHardware != canUseHardware && mCanUseHardware) {
@@ -156,8 +153,8 @@ class RippleBackground {
        mCanUseHardware = canUseHardware;

        final boolean hasContent;
        if (canUseHardware && mHardwareAnimating) {
            hasContent = drawHardware((HardwareCanvas) c);
        if (canUseHardware && (mHardwareAnimating || mHasPendingHardwareExit)) {
            hasContent = drawHardware((HardwareCanvas) c, p);
        } else {
            hasContent = drawSoftware(c, p);
        }
@@ -169,24 +166,10 @@ class RippleBackground {
        return (mCanUseHardware && mHardwareAnimating) || (mOuterOpacity > 0 && mOuterRadius > 0);
    }

    private boolean drawHardware(HardwareCanvas c) {
        // If we have any pending hardware animations, cancel any running
        // animations and start those now.
        final ArrayList<RenderNodeAnimator> pendingAnimations = mPendingAnimations;
        final int N = pendingAnimations.size();
        if (N > 0) {
    private boolean drawHardware(HardwareCanvas c, Paint p) {
        if (mHasPendingHardwareExit) {
            cancelHardwareAnimations(false);

            // We canceled old animations, but we're about to run new ones.
            mHardwareAnimating = true;

            for (int i = 0; i < N; i++) {
                pendingAnimations.get(i).setTarget(c);
                pendingAnimations.get(i).start();
            }

            mRunningAnimations.addAll(pendingAnimations);
            pendingAnimations.clear();
            startPendingHardwareExit(c, p);
        }

        c.drawCircle(mPropOuterX, mPropOuterY, mPropOuterRadius, mPropOuterPaint);
@@ -263,21 +246,32 @@ class RippleBackground {
                + inflectionDuration * outerOpacityVelocity * outerSizeInfluence / 1000) + 0.5f);

        if (mCanUseHardware) {
            exitHardware(opacityDuration, inflectionDuration, inflectionOpacity);
            createPendingHardwareExit(opacityDuration, inflectionDuration, inflectionOpacity);
        } else {
            exitSoftware(opacityDuration, inflectionDuration, inflectionOpacity);
        }
    }

    private void exitHardware(int opacityDuration, int inflectionDuration, int inflectionOpacity) {
        mPendingAnimations.clear();
    private void createPendingHardwareExit(
            int opacityDuration, int inflectionDuration, int inflectionOpacity) {
        mHasPendingHardwareExit = true;
        mPendingOpacityDuration = opacityDuration;
        mPendingInflectionDuration = inflectionDuration;
        mPendingInflectionOpacity = inflectionOpacity;

        final Paint outerPaint = getTempPaint();
        outerPaint.setAntiAlias(true);
        outerPaint.setXfermode(mXfermode);
        outerPaint.setColor(mColor);
        outerPaint.setAlpha((int) (Color.alpha(mColor) * mOuterOpacity + 0.5f));
        outerPaint.setStyle(Style.FILL);
        // The animation will start on the next draw().
        invalidateSelf();
    }

    private void startPendingHardwareExit(HardwareCanvas c, Paint p) {
        mHasPendingHardwareExit = false;

        final int opacityDuration = mPendingOpacityDuration;
        final int inflectionDuration = mPendingInflectionDuration;
        final int inflectionOpacity = mPendingInflectionOpacity;

        final Paint outerPaint = getTempPaint(p);
        outerPaint.setAlpha((int) (outerPaint.getAlpha() * mOuterOpacity + 0.5f));
        mPropOuterPaint = CanvasProperty.createPaint(outerPaint);
        mPropOuterRadius = CanvasProperty.createFloat(mOuterRadius);
        mPropOuterX = CanvasProperty.createFloat(mOuterX);
@@ -301,8 +295,10 @@ class RippleBackground {
                outerFadeOutAnim.setStartDelay(inflectionDuration);
                outerFadeOutAnim.setStartValue(inflectionOpacity);
                outerFadeOutAnim.addListener(mAnimationListener);
                outerFadeOutAnim.setTarget(c);
                outerFadeOutAnim.start();

                mPendingAnimations.add(outerFadeOutAnim);
                mRunningAnimations.add(outerFadeOutAnim);
            } else {
                outerOpacityAnim.addListener(mAnimationListener);
            }
@@ -314,14 +310,15 @@ class RippleBackground {
            outerOpacityAnim.addListener(mAnimationListener);
        }

        mPendingAnimations.add(outerOpacityAnim);
        outerOpacityAnim.setTarget(c);
        outerOpacityAnim.start();

        mRunningAnimations.add(outerOpacityAnim);

        mHardwareAnimating = true;

        // Set up the software values to match the hardware end values.
        mOuterOpacity = 0;

        invalidateSelf();
    }

    /**
@@ -340,10 +337,11 @@ class RippleBackground {
        }
    }

    private Paint getTempPaint() {
    private Paint getTempPaint(Paint original) {
        if (mTempPaint == null) {
            mTempPaint = new Paint();
        }
        mTempPaint.set(original);
        return mTempPaint;
    }

@@ -422,10 +420,7 @@ class RippleBackground {
        }
        runningAnimations.clear();

        if (cancelPending && !mPendingAnimations.isEmpty()) {
            mPendingAnimations.clear();
        }

        mHasPendingHardwareExit = false;
        mHardwareAnimating = false;
    }

+162 −95

File changed.

Preview size limit exceeded, changes collapsed.