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

Commit f3187b7d authored by Romain Guy's avatar Romain Guy
Browse files

Remove unnecessary Rect, better reuse of NinePatch objects

Cloning drawables (which happens a lot) was creating copies of NinePatch
objects, which would cause the hardware renderer to generate more meshes
than necessary. Also avoid keeping a String we don't need (it was interned
but still.) Last but not least, remove 1 RectF per NinePatch in the system.

Change-Id: If4dbfa0c30892c9b00d68875e334fd5c2bde8b94
parent e50848bf
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -735,6 +735,21 @@ class GLES20Canvas extends HardwareCanvas {
        drawColor((a & 0xFF) << 24 | (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF));
    }

    @Override
    public void drawPatch(NinePatch patch, Rect dst, Paint paint) {
        Bitmap bitmap = patch.getBitmap();
        if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
        // Shaders are ignored when drawing patches
        int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
        try {
            final int nativePaint = paint == null ? 0 : paint.mNativePaint;
            nDrawPatch(mRenderer, bitmap.mNativeBitmap, patch.mChunk,
                    dst.left, dst.top, dst.right, dst.bottom, nativePaint);
        } finally {
            if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
        }
    }

    @Override
    public void drawPatch(NinePatch patch, RectF dst, Paint paint) {
        Bitmap bitmap = patch.getBitmap();
+16 −2
Original line number Diff line number Diff line
@@ -1059,6 +1059,20 @@ public class Canvas {
        }
    }

    /**
     * Draws the specified bitmap as an N-patch (most often, a 9-patches.)
     *
     * Note: Only supported by hardware accelerated canvas at the moment.
     *
     * @param patch The ninepatch object to render
     * @param dst The destination rectangle.
     * @param paint The paint to draw the bitmap with. may be null
     * 
     * @hide
     */
    public void drawPatch(NinePatch patch, Rect dst, Paint paint) {
    }

    /**
     * Draws the specified bitmap as an N-patch (most often, a 9-patches.)
     *
+22 −15
Original line number Diff line number Diff line
@@ -42,7 +42,17 @@ public class NinePatch {
    public final byte[] mChunk;
    private Paint mPaint;
    private String mSrcName;  // Useful for debugging
    private final RectF mRect = new RectF();

    /**
     * Create a drawable projection from a bitmap to nine patches.
     *
     * @param bitmap    The bitmap describing the patches.
     * @param chunk     The 9-patch data chunk describing how the underlying
     *                  bitmap is split apart and drawn.
     */
    public NinePatch(Bitmap bitmap, byte[] chunk) {
        this(bitmap, chunk, null);
    }

    /** 
     * Create a drawable projection from a bitmap to nine patches.
@@ -90,13 +100,13 @@ public class NinePatch {
     * @param location  Where to draw the bitmap.
     */
    public void draw(Canvas canvas, RectF location) {
        if (!canvas.isHardwareAccelerated()) {
        if (canvas.isHardwareAccelerated()) {
            canvas.drawPatch(this, location, mPaint);
        } else {
            nativeDraw(canvas.mNativeCanvas, location,
                       mBitmap.ni(), mChunk,
                       mPaint != null ? mPaint.mNativePaint : 0,
                       canvas.mDensity, mBitmap.mDensity);
        } else {
            canvas.drawPatch(this, location, mPaint);
        }
    }
    
@@ -107,14 +117,13 @@ public class NinePatch {
     * @param location  Where to draw the bitmap.
     */
    public void draw(Canvas canvas, Rect location) {
        if (!canvas.isHardwareAccelerated()) {
        if (canvas.isHardwareAccelerated()) {
            canvas.drawPatch(this, location, mPaint);
        } else {
            nativeDraw(canvas.mNativeCanvas, location,
                        mBitmap.ni(), mChunk,
                        mPaint != null ? mPaint.mNativePaint : 0,
                        canvas.mDensity, mBitmap.mDensity);
        } else {
            mRect.set(location);
            canvas.drawPatch(this, mRect, mPaint);
        }
    }

@@ -126,13 +135,12 @@ public class NinePatch {
     * @param paint     The Paint to draw through.
     */
    public void draw(Canvas canvas, Rect location, Paint paint) {
        if (!canvas.isHardwareAccelerated()) {
        if (canvas.isHardwareAccelerated()) {
            canvas.drawPatch(this, location, paint);
        } else {
            nativeDraw(canvas.mNativeCanvas, location,
                    mBitmap.ni(), mChunk, paint != null ? paint.mNativePaint : 0,
                    canvas.mDensity, mBitmap.mDensity);
        } else {
            mRect.set(location);
            canvas.drawPatch(this, mRect, paint);
        }
    }

@@ -170,6 +178,5 @@ public class NinePatch {
    private static native void nativeDraw(int canvas_instance, Rect loc, int bitmap_instance,
                                          byte[] c, int paint_instance_or_null,
                                          int destDensity, int srcDensity);
    private static native int nativeGetTransparentRegion(
            int bitmap, byte[] chunk, Rect location);
    private static native int nativeGetTransparentRegion(int bitmap, byte[] chunk, Rect location);
}
+8 −10
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@ import java.io.InputStream;
 */
public class NinePatchDrawable extends Drawable {
    // dithering helps a lot, and is pretty cheap, so default is true
    private static final boolean DEFAULT_DITHER = true;
    private static final boolean DEFAULT_DITHER = false;
    private NinePatchState mNinePatchState;
    private NinePatch mNinePatch;
    private Rect mPadding;
@@ -197,10 +197,8 @@ public class NinePatchDrawable extends Drawable {
            mBitmapHeight = mNinePatch.getHeight();
            mOpticalInsets = mNinePatchState.mOpticalInsets;
        } else {
            mBitmapWidth = Bitmap.scaleFromDensity(mNinePatch.getWidth(),
                    sdensity, tdensity);
            mBitmapHeight = Bitmap.scaleFromDensity(mNinePatch.getHeight(),
                    sdensity, tdensity);
            mBitmapWidth = Bitmap.scaleFromDensity(mNinePatch.getWidth(), sdensity, tdensity);
            mBitmapHeight = Bitmap.scaleFromDensity(mNinePatch.getHeight(), sdensity, tdensity);
            if (mNinePatchState.mPadding != null && mPadding != null) {
                Rect dest = mPadding;
                Rect src = mNinePatchState.mPadding;
@@ -271,6 +269,7 @@ public class NinePatchDrawable extends Drawable {

    @Override
    public void setDither(boolean dither) {
        //noinspection PointlessBooleanExpression
        if (mPaint == null && dither == DEFAULT_DITHER) {
            // Fast common case -- leave at default dither.
            return;
@@ -299,8 +298,7 @@ public class NinePatchDrawable extends Drawable {
        }

        final boolean dither = a.getBoolean(
                com.android.internal.R.styleable.NinePatchDrawable_dither,
                DEFAULT_DITHER);
                com.android.internal.R.styleable.NinePatchDrawable_dither, DEFAULT_DITHER);
        final BitmapFactory.Options options = new BitmapFactory.Options();
        if (dither) {
            options.inDither = false;
@@ -330,8 +328,7 @@ public class NinePatchDrawable extends Drawable {
                    ": <nine-patch> requires a valid 9-patch source image");
        }

        setNinePatchState(new NinePatchState(
                new NinePatch(bitmap, bitmap.getNinePatchChunk(), "XML 9-patch"),
        setNinePatchState(new NinePatchState(new NinePatch(bitmap, bitmap.getNinePatchChunk()),
                padding, opticalInsets, dither), r);
        mNinePatchState.mTargetDensity = mTargetDensity;

@@ -429,7 +426,8 @@ public class NinePatchDrawable extends Drawable {
        // Copy constructor

        NinePatchState(NinePatchState state) {
            mNinePatch = new NinePatch(state.mNinePatch);
            // Note we don't copy the nine patch because it is immutable.
            mNinePatch = state.mNinePatch;
            // Note we don't copy the padding because it is immutable.
            mPadding = state.mPadding;
            mOpticalInsets = state.mOpticalInsets;