Re: Horribly slow rendering using Quartz surfaces
Andrea Canciani <[email protected]>
| Newsgroups | gmane.comp.lib.cairo |
|---|---|
| Message-ID | <CAN_5=BDT8exAa61XTfDDsNUnAyftL1RZJ56sBg7FNmHYnO9vAg@mail.gmail.com> |
On Tue, Aug 6, 2013 at 4:34 PM, Bobby Salazar <[email protected]> wrote: > I am testing some code on iOS and have run into a rendering problem > using Quartz surfaces that does not happen by merely switching the > surface out to an image surface. Here is the code: > > void TestRadialRender() > { > cairo_surface_t* pSurface; > cairo_t* pContext; > cairo_matrix_t Matrix; > > // Setup surface > //pSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 640, > 1136); > pSurface = cairo_quartz_surface_create(CAIRO_FORMAT_ARGB32, 640, > 1136); > pContext = cairo_create(pSurface); > > // Setup matrix > cairo_matrix_init(&Matrix, 3.6, 0.0, 0.0, 1.35, 568, 66); > cairo_set_matrix(pContext, &Matrix); > > // Setup path > cairo_new_path(pContext); > double cx = -45.84799; > double cy = 7.394; > double rx = 3; > double ry = 3; > > cairo_move_to (pContext, cx + rx, cy); > cairo_curve_to (pContext, cx + rx, cy + ry * 0.5522847498, cx + rx > * > 0.5522847498, cy + ry, cx, cy + ry); > cairo_curve_to (pContext, cx - rx * 0.5522847498, cy + ry, cx - rx, > cy + ry * 0.5522847498, cx - rx, cy); > cairo_curve_to (pContext, cx - rx, cy - ry * 0.5522847498, cx - rx > * > 0.5522847498, cy - ry, cx, cy - ry); > cairo_curve_to (pContext, cx + rx * 0.5522847498, cy - ry, cx + rx, > cy - ry * 0.5522847498, cx + rx, cy); > cairo_close_path (pContext); > > > // Setup pattern > cairo_pattern_t* pat; > pat = cairo_pattern_create_radial(-45.84799, 7.394, 0, -45.84799, > 7.394, 3); > cairo_pattern_set_extend(pat, CAIRO_EXTEND_REFLECT); > > // Setup brush color > cairo_pattern_add_color_stop_rgba(pat, 0, 0.00, 0.00, 1.00, 0.125); > > // Setup color stops > cairo_pattern_add_color_stop_rgba(pat, 0.0000, 0.54, 0.55, 0.56, > 1.00); > cairo_pattern_add_color_stop_rgba(pat, 0.1272, 0.67, 0.68, 0.69, > 1.00); > cairo_pattern_add_color_stop_rgba(pat, 0.2750, 0.78, 0.79, 0.80, > 1.00); > cairo_pattern_add_color_stop_rgba(pat, 0.4307, 0.88, 0.88, 0.89, > 0.50); > cairo_pattern_add_color_stop_rgba(pat, 0.5955, 0.95, 0.95, 0.95, > 0.25); > cairo_pattern_add_color_stop_rgba(pat, 0.7757, 0.98, 0.98, 0.98, > 0.125); > cairo_pattern_add_color_stop_rgba(pat, 1.0000, 1.00, 1.00, 1.00, > 0.00); > > // Render it > cairo_set_source(pContext, pat); > > //// START TIMER //// > cairo_fill_preserve(pContext); > //// END TIMER //// > > cairo_pattern_destroy(pat); > > // Cleanup > cairo_surface_destroy(pSurface); > cairo_destroy(pContext); > } > > > In that test function above, if the code is using > cairo_quartz_surface_create() then the call to cairo_fill_preserve() > takes around 600ms to complete. If you comment out > cairo_quartz_surface_create() and use cairo_image_surface_create() > instead, then the call to cairo_fill_preserve() takes around 2ms to > complete. > > In the case where it renders really slow, it is usually stuck down in > the Pixman code calculating radial gradient information. My profiling seems to show that the code path for the Quartz rendering does not involve Pixman. > However, I > would expect that it uses the same Pixman code for the image surface > as it does for the Quartz surface type. Does anyone have any ideas > what could be going wrong here? > Instead of using Pixman, cairo-quartz is using the native Quartz radial gradient implementation. The radial gradient implementation in Pixman has been tuned quite a lot to achieve high performance. > > This testing was done on an iPod touch 5th generation device (ARM > based processor) using Cairo v1.8.0 and Pixman v0.24.0. I realize this > version of Cairo may be a little old now, is anyone able to test this > function using a newer build to see if it may have already been fixed? > > As I type this I realize it may be helpful to get numbers on an x86 > processor. I ran the same function under the iPhone simulator on a > Core i7 MacBook Pro and it produced 74ms for the Quartz surface and > less than 1 millisecond for the image surface. As you can see, the > Quartz surface is still an order of magnitude slower. > > Any ideas? > Apparently the main slow-down comes from the evaluation of ComputeGradientValue. It should be possible to improve its performance by precomputing some more information (example: the 1/bx coefficient), by caching the current position with respect to the gradient stops (to reduce the lookup time for the correct position) and by avoiding calls to fmod/floor/... function when it is not actually needed (this is hit by your gradient, in particular). As you might have noticed, recently I did not have much time to work on cairo. I will try to prepare a patch in the next days, but if my guess is incorrect (that is, if the slowdown does not just depends on the things I pointed out above), I might be unable to get it done before September. Andrea > -- > cairo mailing list > [email protected] > http://lists.cairographics.org/mailman/listinfo/cairo > -- cairo mailing list [email protected] http://lists.cairographics.org/mailman/listinfo/cairo