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

Commit 6701a601 authored by Nader Jawad's avatar Nader Jawad
Browse files

Wire SKSL based stretch shader to HWUI

--Ported SKSL based stretch shader from OpenGL prototype
--Hooked up the stretch APIs in RenderNode to the stretch
shader.
--Updated RenderNode layer logic to promote the RenderNode to
a layer if there is a stretch to be applied to it in order
to feed the layer as input to the stretch shader

Bug: 179047472
Test: builds + sample overscroll stretches + updated CTS test
Change-Id: I744ff70099fe251ce07f23d067bf13444a468c08
parent b5b5aa24
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -22188,9 +22188,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     * and hardware acceleration.
     */
    boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) {
        // Clear the overscroll effect:
        // TODO: Use internal API instead of overriding the existing RenderEffect
        setRenderEffect(null);
        final boolean hardwareAcceleratedCanvas = canvas.isHardwareAccelerated();
        /* If an attached view draws to a HW canvas, it may use its RenderNode + DisplayList.
+80 −11
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@ import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RecordingCanvas;
import android.graphics.Rect;
import android.graphics.RenderEffect;
import android.graphics.RenderNode;
import android.os.Build;
import android.util.AttributeSet;
@@ -83,6 +82,8 @@ public class EdgeEffect {
    public @interface EdgeEffectType {
    }

    private static final float DEFAULT_MAX_STRETCH_INTENSITY = 1.5f;

    @SuppressWarnings("UnusedDeclaration")
    private static final String TAG = "EdgeEffect";

@@ -128,6 +129,8 @@ public class EdgeEffect {

    private long mStartTime;
    private float mDuration;
    private float mStretchIntensity = DEFAULT_MAX_STRETCH_INTENSITY;
    private float mStretchDistance = -1f;

    private final Interpolator mInterpolator;

@@ -146,6 +149,8 @@ public class EdgeEffect {
    private float mPullDistance;

    private final Rect mBounds = new Rect();
    private float mWidth;
    private float mHeight;
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769450)
    private final Paint mPaint = new Paint();
    private float mRadius;
@@ -202,6 +207,19 @@ public class EdgeEffect {
        mBaseGlowScale = h > 0 ? Math.min(oh / h, 1.f) : 1.f;

        mBounds.set(mBounds.left, mBounds.top, width, (int) Math.min(height, h));

        mWidth = width;
        mHeight = height;
    }

    /**
     * Configure the distance in pixels to stretch the content. This is only consumed as part
     * if {@link #setType(int)} is set to {@link #TYPE_STRETCH}
     * @param stretchDistance Stretch distance in pixels when the target View is overscrolled
     * @hide
     */
    public void setStretchDistance(float stretchDistance) {
        mStretchDistance = stretchDistance;
    }

    /**
@@ -436,6 +454,13 @@ public class EdgeEffect {
        mEdgeEffectType = type;
    }

    /**
     * @hide
     */
    public void setMaxStretchIntensity(float stretchIntensity) {
        mStretchIntensity = stretchIntensity;
    }

    /**
     * Set or clear the blend mode. A blend mode defines how source pixels
     * (generated by a drawing command) are composited with the destination pixels
@@ -520,23 +545,55 @@ public class EdgeEffect {
            RecordingCanvas recordingCanvas = (RecordingCanvas) canvas;
            if (mTmpMatrix == null) {
                mTmpMatrix = new Matrix();
                mTmpPoints = new float[4];
                mTmpPoints = new float[12];
            }
            //noinspection deprecation
            recordingCanvas.getMatrix(mTmpMatrix);
            mTmpPoints[0] = mBounds.width() * mDisplacement;
            mTmpPoints[1] = mDistance * mBounds.height();
            mTmpPoints[2] = mTmpPoints[0];
            mTmpPoints[3] = 0;

            mTmpPoints[0] = 0;
            mTmpPoints[1] = 0; // top-left
            mTmpPoints[2] = mWidth;
            mTmpPoints[3] = 0; // top-right
            mTmpPoints[4] = mWidth;
            mTmpPoints[5] = mHeight; // bottom-right
            mTmpPoints[6] = 0;
            mTmpPoints[7] = mHeight; // bottom-left
            mTmpPoints[8] = mWidth * mDisplacement;
            mTmpPoints[9] = 0; // drag start point
            mTmpPoints[10] = mWidth * mDisplacement;
            mTmpPoints[11] = mHeight * mDistance; // drag point
            mTmpMatrix.mapPoints(mTmpPoints);
            float x = mTmpPoints[0] - mTmpPoints[2];
            float y = mTmpPoints[1] - mTmpPoints[3];

            RenderNode renderNode = recordingCanvas.mNode;

            // TODO: use stretchy RenderEffect and use internal API when it is ready
            // TODO: wrap existing RenderEffect
            renderNode.setRenderEffect(RenderEffect.createOffsetEffect(x, y));
            float left = renderNode.getLeft()
                    + min(mTmpPoints[0], mTmpPoints[2], mTmpPoints[4], mTmpPoints[6]);
            float top = renderNode.getTop()
                    + min(mTmpPoints[1], mTmpPoints[3], mTmpPoints[5], mTmpPoints[7]);
            float right = renderNode.getLeft()
                    + max(mTmpPoints[0], mTmpPoints[2], mTmpPoints[4], mTmpPoints[6]);
            float bottom = renderNode.getTop()
                    + max(mTmpPoints[1], mTmpPoints[3], mTmpPoints[5], mTmpPoints[7]);
            // assume rotations of increments of 90 degrees
            float x = mTmpPoints[10] - mTmpPoints[8];
            float width = right - left;
            float vecX = Math.max(-1f, Math.min(1f, x / width));
            float y = mTmpPoints[11] - mTmpPoints[9];
            float height = bottom - top;
            float vecY = Math.max(-1f, Math.min(1f, y / height));
            renderNode.stretch(
                    left,
                    top,
                    right,
                    bottom,
                    vecX * mStretchIntensity,
                    vecY * mStretchIntensity,
                    // TODO (njawad/mount) figure out proper stretch distance from UX
                    //  for now leverage placeholder logic if no stretch distance is provided to
                    //  consume the displacement ratio times the minimum of the width or height
                    mStretchDistance > 0 ? mStretchDistance :
                            (mDisplacement * Math.min(mWidth, mHeight))
            );
        }

        boolean oneLastFrame = false;
@@ -548,6 +605,18 @@ public class EdgeEffect {
        return mState != STATE_IDLE || oneLastFrame;
    }

    private float min(float f1, float f2, float f3, float f4) {
        float min = Math.min(f1, f2);
        min = Math.min(min, f3);
        return Math.min(min, f4);
    }

    private float max(float f1, float f2, float f3, float f4) {
        float max = Math.max(f1, f2);
        max = Math.max(max, f3);
        return Math.max(max, f4);
    }

    /**
     * Return the maximum height that the edge effect will be drawn at given the original
     * {@link #setSize(int, int) input size}.
+20 −0
Original line number Diff line number Diff line
@@ -248,6 +248,26 @@ public class HorizontalScrollView extends FrameLayout {
        setRightEdgeEffectColor(color);
    }

    /**
     * API used for prototyping stretch effect parameters in framework sample apps
     * @hide
     */
    public void setEdgeEffectIntensity(float intensity) {
        mEdgeGlowLeft.setMaxStretchIntensity(intensity);
        mEdgeGlowRight.setMaxStretchIntensity(intensity);
        invalidate();
    }

    /**
     * API used for prototyping stretch effect parameters in the framework sample apps
     * @hide
     */
    public void setStretchDistance(float distance) {
        mEdgeGlowLeft.setStretchDistance(distance);
        mEdgeGlowRight.setStretchDistance(distance);
        invalidate();
    }

    /**
     * Sets the right edge effect color.
     *
+20 −0
Original line number Diff line number Diff line
@@ -280,6 +280,26 @@ public class ScrollView extends FrameLayout {
        setBottomEdgeEffectColor(color);
    }

    /**
     * API used for prototyping stretch effect parameters in framework sample apps
     * @hide
     */
    public void setEdgeEffectIntensity(float intensity) {
        mEdgeGlowTop.setMaxStretchIntensity(intensity);
        mEdgeGlowBottom.setMaxStretchIntensity(intensity);
        invalidate();
    }

    /**
     * API used for prototyping stretch effect parameters in the framework sample apps
     * @hide
     */
    public void setStretchDistance(float distance) {
        mEdgeGlowTop.setStretchDistance(distance);
        mEdgeGlowBottom.setStretchDistance(distance);
        invalidate();
    }

    /**
     * Sets the bottom edge effect color.
     *
+14 −5
Original line number Diff line number Diff line
@@ -719,11 +719,11 @@ public final class RenderNode {
    /** @hide */
    public boolean stretch(float left, float top, float right, float bottom,
            float vecX, float vecY, float maxStretchAmount) {
        if (1.0 < vecX || vecX < -1.0) {
            throw new IllegalArgumentException("vecX must be in the range [-1, 1], was " + vecX);
        if (Float.isInfinite(vecX) || Float.isNaN(vecX)) {
            throw new IllegalArgumentException("vecX must be a finite, non-NaN value " + vecX);
        }
        if (1.0 < vecY || vecY < -1.0) {
            throw new IllegalArgumentException("vecY must be in the range [-1, 1], was " + vecY);
        if (Float.isInfinite(vecY) || Float.isNaN(vecY)) {
            throw new IllegalArgumentException("vecY must be a finite, non-NaN value " + vecY);
        }
        if (top >= bottom || left >= right) {
            throw new IllegalArgumentException(
@@ -734,7 +734,16 @@ public final class RenderNode {
            throw new IllegalArgumentException(
                    "The max stretch amount must be >0, got " + maxStretchAmount);
        }
        return nStretch(mNativeRenderNode, left, top, right, bottom, vecX, vecY, maxStretchAmount);
        return nStretch(
                mNativeRenderNode,
                left,
                top,
                right,
                bottom,
                vecX,
                vecY,
                maxStretchAmount
        );
    }

    /**
Loading