Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Honeycomb Hardware Acceleration doesn't seem to work with setColorFilter

This code draws a single color (with alpha) shape using a bitmap's alpha channel.

Bitmap alphaMask = bitmap.extractAlpha();
Paint paint = new Paint();
int color = Color.GRAY;
...
paint.setColor(color);
paint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.DST_IN));
...
canvas.drawBitmap(alphaMask, x, y, paint);

For example, it will take the left Bitmap and draw it onto the canvas like it appears on the right:

enter image description here

However, it does not work on Honeycomb (Android 3.0) when hardware acceleration is turned on. It draws the shape as black no matter what. It ignores the color value. However, it works just fine on ICS (Android 4.0) with hardware acceleration on.

I know some API's are not supported with hardware acceleration, as Romain Guy documented here, under What drawing operations are supported?, but I don't appear to be using any of the ones mentioned as not supported.

Additionally, it sounded like he said that setColorFilter should work at this post.

Is there something in my code that is not supported in Honeycomb? Any workarounds? I would love to leave hardware acceleration on in this case.

Thanks

like image 669
cottonBallPaws Avatar asked Mar 26 '12 23:03

cottonBallPaws


2 Answers

There was a bug with how Android 3.0 handled alpha8 bitmaps. I am terribly sorry for this since it was entirely my fault. This issue was however fixed in Android 4.0.

There are two possible workarounds: - Set a software layer type on your view - Or create your own Bitmap and render what you need in it. You can then draw this bitmap on top of the hardware accelerated Canvas.

like image 77
Romain Guy Avatar answered Sep 27 '22 17:09

Romain Guy


I believe the best answer here is going to be from Romain Guy. Quoth he:

However, what you are describing should work just fine. All gradients are supported, as well as all blending modes. Please report bugs with reproducible test cases for any issue you encounter and I'll get them fixed.

Given this statement, the behavior you're experiencing is a bug. This is one of those cases where contacting the primary developer responsible is actually the best technical fix that can be provided.

He did post a workaround, though:

I checked the implementation and the hardware renderer currently supports only shaders of different types inside a ComposeShader. This means you can use a gradient + a bitmap, but not two bitmaps or two gradients. Note that for Views that do things not supported in hardware you can use setLayerType(LAYER_TYPE_SOFTWARE, null) to force them to render in software.

Perhaps he will post here to further enlighten us all. He did. :)

like image 25
MrGomez Avatar answered Sep 27 '22 17:09

MrGomez