Soeren was the first to report a clipping regression in the xlib backend
with strokes, and provided a test case to exercise the bug. This is an
extension of his test to provide coverage of different clipping and
stroking methods.
This is a simple test that broke with the determination of rectilinearity
during path construction. I forgot the implicit close on fill and so the
ignored the final diagonal edge and failed to draw the triangle.
We refactor the surface fallbacks to convert full strokes and fills to the
intermediate polygon representation (as opposed to before where we
returned the trapezoidal representation). This allow greater flexibility
to choose how then to rasterize the polygon. Where possible we use the
local spans rasteriser for its increased performance, but still have the
option to use the tessellator instead (for example, with the current
Render protocol which does not yet have a polygon image).
In order to accommodate this, the spans interface is tweaked to accept
whole polygons instead of a path and the tessellator is tweaked for speed.
Performance Impact
==================
...
Still measuring, expecting some severe regressions.
...
Remove the intermediate C program that was a nuisance whilst
cross-compiling and replace it with a simple shell script that is just a
combination of cat + sed.
Andrea Canciani (ranma42) found another instance of my broken 'degenerate'
curve-to as line-to optimisation. All I can say is when I do something
wrong, at least I'm consistent!
This test case highlights the bug in the rel-curve-to path.
The stroker code is liable to wedge when passed
dash patterns which don't advance the dash offset
due to limited precision arithmetic. This test
attempts to hit all the places in the stroker where
that can happen.
Reported on the cairo mailing list by Hans Breuer:
http://lists.cairographics.org/archives/cairo/2009-June/017506.html
Andrea Canciani (ranma42) pointed out a second bug in the curve-to as
line-to optimisation, that is a curve starting and finishing on the same
point is not necessarily degenerate. This test case exercises 5 different
curves that start and end on the same point.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
Requires hooking into test-meta-surface currently. Export meta-surface!
The idea is that on detection of an error, we can reconstruct a minimal
trace from the meta-surface. The first step is to simply dump the trace
for the failing meta-surface. Later, we should automatically minimise
this further.
These need to be recorded using an XFAIL reference. In the meantime, as
the poppler output has changed, just remove all the invalid PDF reference
images.
Test case for:
Bug 22441 -- Unexpected shift with push_group and pop_group
https://bugs.freedesktop.org/show_bug.cgi?id=22441
This is a test that demonstrates the error in the pdf backend when using
groups on surfaces with non-integer sizes. In order to create such a
surface, we need to update the boilerplate to use doubles instead of
integers when specifying the surface size.
Sun's make doesn't like conditional assignments to variables
in dependencies in the form of "target: VAR+=VAL". This
construct was used to force the test suite run in the foreground
in the check-valgrind target. It is replaced by a more
explicit set of the CAIRO_TEST_MODE environment variable.
Specify another boilerplate target to use as the reference for this
target. We then use this in cairo-test-trace in preference to using the
image surface. Still not perfect, though the framework is improving.
The configure test for __attribute__((constructor)) succeeds when
compiling with Sun Studio 12 on OpenSolaris but the attribute
is just ignored and has no actual effect. This causes the test
suite to not run any tests at all. With this patch we revert to
always using make-cairo-test-constructors.pl.
cairo-test-trace's shared memory allocation pattern is much simpler than
anticipated as it allocates a bunch of images and then frees them all,
and so only needs a simple linear allocator.