more on masking
01:36 pm
Yesterday I talked about creating a mask to speed up your drawing with Cairo. I mentioned that I had a bug where, unlike my test case, my real code was running slower rather than faster. As I suspected, this is because my operations weren't pixel aligned (I had floor(x), not x = floor(x), whoops!). Fixing this bug gave me my 10x speedup that I'd measured in my test case, but revealed the other edge of the sword, all of my markers were now pixel aligned.


The solution I came up with was to create a series of subpixel aligned masks that would give the same effect as the old antialiasing code.

First up is to create the masks:
int i;
for (i = 0; i < NSUBPX; i++)
{
	int j;

	for (j = 0; j < NSUBPX; j++)
	{
		cairo_t *cr2;

		mask[i][j] = cairo_surface_create_similar (
					cairo_get_target (cr),
					CAIRO_CONTENT_ALPHA, 16, 16);
		cairo_surface_set_device_offset (mask[i][j], 8, 8);

		cr2 = cairo_create (mask[i][j]);

		/* add a certain amount of subpixel offset for this mask */
		cairo_translate (cr2, 1. / NSUBPX * i, 1. / NSUBPX * j);
			
		draw_func (cr2) /* draw onto the mask */;
		cairo_destroy (cr2);
	}
}
Now we need to remove the transformation matrix from our target surface so that our compositing operations are fast:
cairo_get_matrix (cr, &matrix);
cairo_save (cr);
cairo_identity_matrix (cr);
Now for each point, we can work out it's location on the canvas, choose a mask to use and a pixel to align to:
/* transform the point from plot space to device space */
x = point->x; y = point->y;
cairo_matrix_transform_point (&matrix, &x, &y);

/* choose an appropriate subpixel mask */
xi = CLAMP (((int) (x * NSUBPX + 0.5)) % NSUBPX, 0, NSUBPX - 1);
yi = CLAMP (((int) (y * NSUBPX + 0.5)) % NSUBPX, 0, NSUBPX - 1);

x = ((int) (x * NSUBPX + 0.5)) / NSUBPX;
y = ((int) (y * NSUBPX + 0.5)) / NSUBPX;

cairo_mask_surface (cr, mask[xi][yi], x, y);
Don't forget to destroy your mask surfaces when you're done or you'll find yourself leaking video card memory.

I've currently put NSUBPX at 3 for this result:

(posted on Tuesday May 6th, 2008 at 01:36 pm)

Livejournal

Navigation

Related Links

Syndication

RSS 2.0 Atom FOAF

Planetarium

Web Presence

Hacking Life   UCC   GNOME

Contact Me

License

Creative Commons License