Android drawBitmap 5x performance difference

Viewed 8183

I've been fighting with android performance all night and possibly solved the issue I've been dealing with, however I'm still very confused and could use some help. Consider the timing differences between these two samples.

The first sample loads in a drawable bitmap and creates a mutable copy of it

Bitmap cacheBitmap;
Canvas cacheCanvas;
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    if (cacheBitmap != null) {
        cacheBitmap.recycle();
    }
    Resources res = getContext().getResources();
    Bitmap blankImage = BitmapFactory.decodeResource(res, R.drawable.blank);

    /* copy existing bitmap */
    cacheBitmap = Bitmap.createScaledBitmap(blankImage, w, h, false);
    /* copy existing bitmap */

    cacheCanvas = new Canvas();
    cacheCanvas.setBitmap(cacheBitmap);
    cacheCanvas.drawRGB(255, 255, 255);
}
public void onDraw(Canvas canvas) {
    canvas.drawBitmap(cacheBitmap, 0, 0, null); // draws in 7-8 ms
}

The second sample creates a new bitmap without copying the original blank image.

Bitmap cacheBitmap;
Canvas cacheCanvas;
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    if (cacheBitmap != null) {
        cacheBitmap.recycle();
    }
    Resources res = getContext().getResources();
    Bitmap blankImage = BitmapFactory.decodeResource(res, R.drawable.blank);

    /* create fresh bitmap */
    cacheBitmap = Bitmap.createBitmap(w, h, blankImage.getConfig());
    /* create fresh bitmap */

    cacheCanvas = new Canvas();
    cacheCanvas.setBitmap(cacheBitmap);
    cacheCanvas.drawRGB(255, 255, 255);
}
public void onDraw(Canvas canvas) {
    canvas.drawBitmap(cacheBitmap, 0, 0, null); // draws in 40 ms
}

The first sample draws 5-6 times faster then the second sample, why is this? I'd like to be able to write this code in some way that doesn't even rely on the blank image, but no matter what I do I end up with a slow bitmap draw without having it available to copy initially.

2 Answers

Couldn't it be that the createScaledBitmap() actually creates a new bitmap with exactly the proportions needed for the screen, giving a 1:1 pixel draw internally and probably allowing for a faster drawing routine, where the second just creates a new bitmap which contains ALL of the information for the original resource (probably a lot of extra pixels) and each call to draw the bitmap results in an internal scaling between the pixels in the internal bitmap and the canvas that is being drawn to?

Related