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

Commit 11a249be authored by Derek Sollenberger's avatar Derek Sollenberger Committed by Android (Google) Code Review
Browse files

Merge "Reland "Enforce that RuntimeShader is only hardware accelerated""

parents ebab4fe0 2474c831
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -1896,7 +1896,7 @@ public class ViewDebug {

        private Canvas mCanvas;
        private Bitmap mBitmap;
        private boolean mEnabledHwBitmapsInSwMode;
        private boolean mEnabledHwFeaturesInSwMode;

        @Override
        public Canvas getCanvas(View view, int width, int height) {
@@ -1913,7 +1913,7 @@ public class ViewDebug {
            if (mCanvas == null) {
                mCanvas = new Canvas();
            }
            mEnabledHwBitmapsInSwMode = mCanvas.isHwBitmapsInSwModeEnabled();
            mEnabledHwFeaturesInSwMode = mCanvas.isHwFeaturesInSwModeEnabled();
            mCanvas.setBitmap(mBitmap);
            return mCanvas;
        }
@@ -1921,7 +1921,7 @@ public class ViewDebug {
        @Override
        public Bitmap createBitmap() {
            mCanvas.setBitmap(null);
            mCanvas.setHwBitmapsInSwModeEnabled(mEnabledHwBitmapsInSwMode);
            mCanvas.setHwFeaturesInSwModeEnabled(mEnabledHwFeaturesInSwMode);
            return mBitmap;
        }
    }
+60 −57
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ public abstract class BaseCanvas {
     * @hide
     */
    protected int mDensity = Bitmap.DENSITY_NONE;
    private boolean mAllowHwBitmapsInSwMode = false;
    private boolean mAllowHwFeaturesInSwMode = false;

    protected void throwIfCannotDraw(Bitmap bitmap) {
        if (bitmap.isRecycled()) {
@@ -101,14 +101,14 @@ public abstract class BaseCanvas {

    public void drawArc(float left, float top, float right, float bottom, float startAngle,
            float sweepAngle, boolean useCenter, @NonNull Paint paint) {
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        nDrawArc(mNativeCanvasWrapper, left, top, right, bottom, startAngle, sweepAngle,
                useCenter, paint.getNativeInstance());
    }

    public void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter,
            @NonNull Paint paint) {
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        drawArc(oval.left, oval.top, oval.right, oval.bottom, startAngle, sweepAngle, useCenter,
                paint);
    }
@@ -119,14 +119,14 @@ public abstract class BaseCanvas {

    public void drawBitmap(@NonNull Bitmap bitmap, float left, float top, @Nullable Paint paint) {
        throwIfCannotDraw(bitmap);
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        nDrawBitmap(mNativeCanvasWrapper, bitmap.getNativeInstance(), left, top,
                paint != null ? paint.getNativeInstance() : 0, mDensity, mScreenDensity,
                bitmap.mDensity);
    }

    public void drawBitmap(@NonNull Bitmap bitmap, @NonNull Matrix matrix, @Nullable Paint paint) {
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        nDrawBitmapMatrix(mNativeCanvasWrapper, bitmap.getNativeInstance(), matrix.ni(),
                paint != null ? paint.getNativeInstance() : 0);
    }
@@ -137,7 +137,7 @@ public abstract class BaseCanvas {
            throw new NullPointerException();
        }
        throwIfCannotDraw(bitmap);
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        final long nativePaint = paint == null ? 0 : paint.getNativeInstance();

        int left, top, right, bottom;
@@ -163,7 +163,7 @@ public abstract class BaseCanvas {
            throw new NullPointerException();
        }
        throwIfCannotDraw(bitmap);
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        final long nativePaint = paint == null ? 0 : paint.getNativeInstance();

        float left, top, right, bottom;
@@ -202,7 +202,7 @@ public abstract class BaseCanvas {
                || (lastScanline + width > length)) {
            throw new ArrayIndexOutOfBoundsException();
        }
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        // quick escape if there's nothing to draw
        if (width == 0 || height == 0) {
            return;
@@ -226,7 +226,7 @@ public abstract class BaseCanvas {
        if ((meshWidth | meshHeight | vertOffset | colorOffset) < 0) {
            throw new ArrayIndexOutOfBoundsException();
        }
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        if (meshWidth == 0 || meshHeight == 0) {
            return;
        }
@@ -243,7 +243,7 @@ public abstract class BaseCanvas {
    }

    public void drawCircle(float cx, float cy, float radius, @NonNull Paint paint) {
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        nDrawCircle(mNativeCanvasWrapper, cx, cy, radius, paint.getNativeInstance());
    }

@@ -275,23 +275,23 @@ public abstract class BaseCanvas {

    public void drawLine(float startX, float startY, float stopX, float stopY,
            @NonNull Paint paint) {
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        nDrawLine(mNativeCanvasWrapper, startX, startY, stopX, stopY, paint.getNativeInstance());
    }

    public void drawLines(@Size(multiple = 4) @NonNull float[] pts, int offset, int count,
            @NonNull Paint paint) {
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        nDrawLines(mNativeCanvasWrapper, pts, offset, count, paint.getNativeInstance());
    }

    public void drawLines(@Size(multiple = 4) @NonNull float[] pts, @NonNull Paint paint) {
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        drawLines(pts, 0, pts.length, paint);
    }

    public void drawOval(float left, float top, float right, float bottom, @NonNull Paint paint) {
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        nDrawOval(mNativeCanvasWrapper, left, top, right, bottom, paint.getNativeInstance());
    }

@@ -299,18 +299,19 @@ public abstract class BaseCanvas {
        if (oval == null) {
            throw new NullPointerException();
        }
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        drawOval(oval.left, oval.top, oval.right, oval.bottom, paint);
    }

    public void drawPaint(@NonNull Paint paint) {
        throwIfHasHwFeaturesInSwMode(paint);
        nDrawPaint(mNativeCanvasWrapper, paint.getNativeInstance());
    }

    public void drawPatch(@NonNull NinePatch patch, @NonNull Rect dst, @Nullable Paint paint) {
        Bitmap bitmap = patch.getBitmap();
        throwIfCannotDraw(bitmap);
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
        nDrawNinePatch(mNativeCanvasWrapper, bitmap.getNativeInstance(), patch.mNativeChunk,
                dst.left, dst.top, dst.right, dst.bottom, nativePaint,
@@ -320,7 +321,7 @@ public abstract class BaseCanvas {
    public void drawPatch(@NonNull NinePatch patch, @NonNull RectF dst, @Nullable Paint paint) {
        Bitmap bitmap = patch.getBitmap();
        throwIfCannotDraw(bitmap);
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
        nDrawNinePatch(mNativeCanvasWrapper, bitmap.getNativeInstance(), patch.mNativeChunk,
                dst.left, dst.top, dst.right, dst.bottom, nativePaint,
@@ -328,7 +329,7 @@ public abstract class BaseCanvas {
    }

    public void drawPath(@NonNull Path path, @NonNull Paint paint) {
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        if (path.isSimplePath && path.rects != null) {
            nDrawRegion(mNativeCanvasWrapper, path.rects.mNativeRegion, paint.getNativeInstance());
        } else {
@@ -337,18 +338,18 @@ public abstract class BaseCanvas {
    }

    public void drawPoint(float x, float y, @NonNull Paint paint) {
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        nDrawPoint(mNativeCanvasWrapper, x, y, paint.getNativeInstance());
    }

    public void drawPoints(@Size(multiple = 2) float[] pts, int offset, int count,
            @NonNull Paint paint) {
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        nDrawPoints(mNativeCanvasWrapper, pts, offset, count, paint.getNativeInstance());
    }

    public void drawPoints(@Size(multiple = 2) @NonNull float[] pts, @NonNull Paint paint) {
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        drawPoints(pts, 0, pts.length, paint);
    }

@@ -359,7 +360,7 @@ public abstract class BaseCanvas {
        if (index < 0 || index + count > text.length || count * 2 > pos.length) {
            throw new IndexOutOfBoundsException();
        }
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        for (int i = 0; i < count; i++) {
            drawText(text, index + i, 1, pos[i * 2], pos[i * 2 + 1], paint);
        }
@@ -368,22 +369,22 @@ public abstract class BaseCanvas {
    @Deprecated
    public void drawPosText(@NonNull String text, @NonNull @Size(multiple = 2) float[] pos,
            @NonNull Paint paint) {
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        drawPosText(text.toCharArray(), 0, text.length(), pos, paint);
    }

    public void drawRect(float left, float top, float right, float bottom, @NonNull Paint paint) {
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        nDrawRect(mNativeCanvasWrapper, left, top, right, bottom, paint.getNativeInstance());
    }

    public void drawRect(@NonNull Rect r, @NonNull Paint paint) {
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        drawRect(r.left, r.top, r.right, r.bottom, paint);
    }

    public void drawRect(@NonNull RectF rect, @NonNull Paint paint) {
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        nDrawRect(mNativeCanvasWrapper,
                rect.left, rect.top, rect.right, rect.bottom, paint.getNativeInstance());
    }
@@ -394,13 +395,13 @@ public abstract class BaseCanvas {

    public void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,
            @NonNull Paint paint) {
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        nDrawRoundRect(mNativeCanvasWrapper, left, top, right, bottom, rx, ry,
                paint.getNativeInstance());
    }

    public void drawRoundRect(@NonNull RectF rect, float rx, float ry, @NonNull Paint paint) {
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        drawRoundRect(rect.left, rect.top, rect.right, rect.bottom, rx, ry, paint);
    }

@@ -410,7 +411,7 @@ public abstract class BaseCanvas {
     */
    public void drawDoubleRoundRect(@NonNull RectF outer, float outerRx, float outerRy,
            @NonNull RectF inner, float innerRx, float innerRy, @NonNull Paint paint) {
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        float outerLeft = outer.left;
        float outerTop = outer.top;
        float outerRight = outer.right;
@@ -431,7 +432,7 @@ public abstract class BaseCanvas {
     */
    public void drawDoubleRoundRect(@NonNull RectF outer, @NonNull float[] outerRadii,
            @NonNull RectF inner, @NonNull float[] innerRadii, @NonNull Paint paint) {
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        if (innerRadii == null || outerRadii == null
                || innerRadii.length != 8 || outerRadii.length != 8) {
            throw new IllegalArgumentException("Both inner and outer radii arrays must contain "
@@ -509,7 +510,7 @@ public abstract class BaseCanvas {
                (text.length - index - count)) < 0) {
            throw new IndexOutOfBoundsException();
        }
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        nDrawText(mNativeCanvasWrapper, text, index, count, x, y, paint.mBidiFlags,
                paint.getNativeInstance());
    }
@@ -519,7 +520,7 @@ public abstract class BaseCanvas {
        if ((start | end | (end - start) | (text.length() - end)) < 0) {
            throw new IndexOutOfBoundsException();
        }
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        if (text instanceof String || text instanceof SpannedString ||
                text instanceof SpannableString) {
            nDrawText(mNativeCanvasWrapper, text.toString(), start, end, x, y,
@@ -537,7 +538,7 @@ public abstract class BaseCanvas {
    }

    public void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) {
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        nDrawText(mNativeCanvasWrapper, text, 0, text.length(), x, y, paint.mBidiFlags,
                paint.getNativeInstance());
    }
@@ -547,7 +548,7 @@ public abstract class BaseCanvas {
        if ((start | end | (end - start) | (text.length() - end)) < 0) {
            throw new IndexOutOfBoundsException();
        }
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        nDrawText(mNativeCanvasWrapper, text, start, end, x, y, paint.mBidiFlags,
                paint.getNativeInstance());
    }
@@ -557,7 +558,7 @@ public abstract class BaseCanvas {
        if (index < 0 || index + count > text.length) {
            throw new ArrayIndexOutOfBoundsException();
        }
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        nDrawTextOnPath(mNativeCanvasWrapper, text, index, count,
                path.readOnlyNI(), hOffset, vOffset,
                paint.mBidiFlags, paint.getNativeInstance());
@@ -566,7 +567,7 @@ public abstract class BaseCanvas {
    public void drawTextOnPath(@NonNull String text, @NonNull Path path, float hOffset,
            float vOffset, @NonNull Paint paint) {
        if (text.length() > 0) {
            throwIfHasHwBitmapInSwMode(paint);
            throwIfHasHwFeaturesInSwMode(paint);
            nDrawTextOnPath(mNativeCanvasWrapper, text, path.readOnlyNI(), hOffset, vOffset,
                    paint.mBidiFlags, paint.getNativeInstance());
        }
@@ -587,7 +588,7 @@ public abstract class BaseCanvas {
            throw new IndexOutOfBoundsException();
        }

        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        nDrawTextRun(mNativeCanvasWrapper, text, index, count, contextIndex, contextCount,
                x, y, isRtl, paint.getNativeInstance(), 0 /* measured text */);
    }
@@ -606,7 +607,7 @@ public abstract class BaseCanvas {
            throw new IndexOutOfBoundsException();
        }

        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        if (text instanceof String || text instanceof SpannedString ||
                text instanceof SpannableString) {
            nDrawTextRun(mNativeCanvasWrapper, text.toString(), start, end, contextStart,
@@ -664,7 +665,7 @@ public abstract class BaseCanvas {
        if (indices != null) {
            checkRange(indices.length, indexOffset, indexCount);
        }
        throwIfHasHwBitmapInSwMode(paint);
        throwIfHasHwFeaturesInSwMode(paint);
        nDrawVertices(mNativeCanvasWrapper, mode.nativeInt, vertexCount, verts,
                vertOffset, texs, texOffset, colors, colorOffset,
                indices, indexOffset, indexCount, paint.getNativeInstance());
@@ -680,50 +681,52 @@ public abstract class BaseCanvas {
    /**
     * @hide
     */
    public void setHwBitmapsInSwModeEnabled(boolean enabled) {
        mAllowHwBitmapsInSwMode = enabled;
    public void setHwFeaturesInSwModeEnabled(boolean enabled) {
        mAllowHwFeaturesInSwMode = enabled;
    }

    /**
     * @hide
     */
    public boolean isHwBitmapsInSwModeEnabled() {
        return mAllowHwBitmapsInSwMode;
    public boolean isHwFeaturesInSwModeEnabled() {
        return mAllowHwFeaturesInSwMode;
    }

    /**
     * If true throw an exception
     * @hide
     */
    protected void onHwBitmapInSwMode() {
        if (!mAllowHwBitmapsInSwMode) {
            throw new IllegalArgumentException(
                    "Software rendering doesn't support hardware bitmaps");
        }
    protected boolean onHwFeatureInSwMode() {
        return !mAllowHwFeaturesInSwMode;
    }

    private void throwIfHwBitmapInSwMode(Bitmap bitmap) {
        if (!isHardwareAccelerated() && bitmap.getConfig() == Bitmap.Config.HARDWARE) {
            onHwBitmapInSwMode();
        if (!isHardwareAccelerated() && bitmap.getConfig() == Bitmap.Config.HARDWARE
                && onHwFeatureInSwMode()) {
            throw new IllegalArgumentException(
                    "Software rendering doesn't support hardware bitmaps");
        }
    }

    private void throwIfHasHwBitmapInSwMode(Paint p) {
    private void throwIfHasHwFeaturesInSwMode(Paint p) {
        if (isHardwareAccelerated() || p == null) {
            return;
        }
        throwIfHasHwBitmapInSwMode(p.getShader());
        throwIfHasHwFeaturesInSwMode(p.getShader());
    }

    private void throwIfHasHwBitmapInSwMode(Shader shader) {
    private void throwIfHasHwFeaturesInSwMode(Shader shader) {
        if (shader == null) {
            return;
        }
        if (shader instanceof BitmapShader) {
            throwIfHwBitmapInSwMode(((BitmapShader) shader).mBitmap);
        }
        if (shader instanceof ComposeShader) {
            throwIfHasHwBitmapInSwMode(((ComposeShader) shader).mShaderA);
            throwIfHasHwBitmapInSwMode(((ComposeShader) shader).mShaderB);
        } else if (shader instanceof RuntimeShader && onHwFeatureInSwMode()) {
            throw new IllegalArgumentException(
                    "Software rendering doesn't support RuntimeShader");
        } else if (shader instanceof ComposeShader) {
            throwIfHasHwFeaturesInSwMode(((ComposeShader) shader).mShaderA);
            throwIfHasHwFeaturesInSwMode(((ComposeShader) shader).mShaderB);
        }
    }

+9 −6
Original line number Diff line number Diff line
@@ -124,7 +124,7 @@ public class Picture {
    public void endRecording() {
        verifyValid();
        if (mRecordingCanvas != null) {
            mRequiresHwAcceleration = mRecordingCanvas.mHoldsHwBitmap;
            mRequiresHwAcceleration = mRecordingCanvas.mUsesHwFeature;
            mRecordingCanvas = null;
            nativeEndRecording(mNativePicture);
        }
@@ -182,8 +182,10 @@ public class Picture {
        if (mRecordingCanvas != null) {
            endRecording();
        }
        if (mRequiresHwAcceleration && !canvas.isHardwareAccelerated()) {
            canvas.onHwBitmapInSwMode();
        if (mRequiresHwAcceleration && !canvas.isHardwareAccelerated()
                && canvas.onHwFeatureInSwMode()) {
            throw new IllegalArgumentException("Software rendering not supported for Pictures that"
                    + " require hardware acceleration");
        }
        nativeDraw(canvas.getNativeCanvasWrapper(), mNativePicture);
    }
@@ -242,7 +244,7 @@ public class Picture {

    private static class PictureCanvas extends Canvas {
        private final Picture mPicture;
        boolean mHoldsHwBitmap;
        boolean mUsesHwFeature;

        public PictureCanvas(Picture pict, long nativeCanvas) {
            super(nativeCanvas);
@@ -265,8 +267,9 @@ public class Picture {
        }

        @Override
        protected void onHwBitmapInSwMode() {
            mHoldsHwBitmap = true;
        protected boolean onHwFeatureInSwMode() {
            mUsesHwFeature = true;
            return false;
        }
    }
}
+6 −6
Original line number Diff line number Diff line
@@ -868,7 +868,7 @@ public class RippleDrawable extends LayerDrawable {
    private void drawPatterned(@NonNull Canvas canvas) {
        final Rect bounds = mHotspotBounds;
        final int saveCount = canvas.save(Canvas.CLIP_SAVE_FLAG);
        boolean useCanvasProps = shouldUseCanvasProps(canvas);
        boolean useCanvasProps = !mForceSoftware;
        if (isBounded()) {
            canvas.clipRect(getDirtyBounds());
        }
@@ -914,7 +914,11 @@ public class RippleDrawable extends LayerDrawable {
        }
        for (int i = 0; i < mRunningAnimations.size(); i++) {
            RippleAnimationSession s = mRunningAnimations.get(i);
            if (useCanvasProps) {
            if (!canvas.isHardwareAccelerated()) {
                Log.e(TAG, "The RippleDrawable.STYLE_PATTERNED animation is not supported for a "
                        + "non-hardware accelerated Canvas. Skipping animation.");
                break;
            } else if (useCanvasProps) {
                RippleAnimationSession.AnimationProperties<CanvasProperty<Float>,
                        CanvasProperty<Paint>>
                        p = s.getCanvasProperties();
@@ -1002,10 +1006,6 @@ public class RippleDrawable extends LayerDrawable {
        return color;
    }

    private boolean shouldUseCanvasProps(Canvas c) {
        return !mForceSoftware && c.isHardwareAccelerated();
    }

    @Override
    public void invalidateSelf() {
        invalidateSelf(true);