Re: Horribly slow rendering using Quartz surfaces

Andrea Canciani <[email protected]>
Newsgroups gmane.comp.lib.cairo
Message-ID <CAN_5=BBZZYX=m+7y_QPW_Z8rvZXbF2tTzfHyW3fC=LXeA-6bZQ@mail.gmail.com>
On my system, running your code on image 10000 times takes ~ 0.3 seconds,
while on a quartz surface it takes about 3 seconds.
If I completely disable the gradient evaluation (ComputeGradientValue
always returns [0,0,0,0] without performing any computation at all), quartz
improves a little, as it only takes about 2 seconds, but it is still much
slower than pixman, apparently because it spends a lot of time in
colorspace conversion.

I started to port the pixman gradient evaluation code (the REFLECT case,
which is the one hit by your code), but the improvement I got is less than
10%, which might not be worth the additional complexity.

Andrea



On Wed, Aug 21, 2013 at 4:40 PM, Andrea Canciani <[email protected]> wrote:

> 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.