How do the pieces of Android’s (2D) Canvas drawing pipeline fit together?

Like Romain Guy said, “This question is difficult to answer on StackOverflow”. There wasn’t really any complete documentation, and complete documentation would be kind of large to include here.

I ended up reading through the source and doing a bunch of experiments. I took notes along the way, and ended up turning them into a document which you can see here:

  • Android’s 2D Canvas Rendering Pipeline

as well as this diagram:

enter image description here

It’s “unofficial”, obviously, so the normal caveats apply.

Based on the above, here are answers to some of the “sub-questions”:

It’s also not entirely clear to me how
drawing operations that have intrinsic
colors (eg: drawBitmap, versus the
“vector” primitives like drawRect)
fit into all of this — do they always
ignore the Paint‘s color and use use
their intrinsic color instead?

The “source colors” come from the Shader. In drawBitmap the Shader is temporarily replaced by a BitmapShader if a non-ALPHA_8 Bitmap is used. In other cases, if no Shader is specified a Shader that just generates a solid color, the Paint‘s color, is used.

I was also surprised by the fact that
one can do something like this:

Paint eraser = new Paint();
eraser.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawOval(rectF, eraser);

This erases an oval. Before I noticed
this my mental-model was that drawing
to a canvas (conceptually) draws to a
separate “layer” and then that layer
is composed with the Canvas’s Bitmap
using the Paint’s transfer mode. If it
were as simple as that then the above
code would erase the entire Bitmap
(within the clipping region) as CLEAR
always sets the color (and alpha) to 0 regardless of the source’s alpha. So
this implies that there’s an
additional sort of masking going on to
constrain the erasing to an oval.

The XferMode applies to the “source colors” (from the Shader) and the “destination colors” (from the Canvas‘s Bitmap). The result is then blended with the destination using the mask computed in Rasterization. See the Transfer phase in the above document for more details.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)