Commit graph

4478 commits

Author SHA1 Message Date
Chris Wilson
33ef32af4e [clip] Use the rectangular tessellator to extract boxes 2009-08-29 08:08:38 +01:00
Chris Wilson
ab035ab2c7 [tessellate] Rectangular special case
Add an even simpler sweep-line tessellator for rectangular trapezoids (as
produced by the rectilinear stoker and box filler).

This is so simple it even outperforms pixman's region validation code for the
purposes of path-to-region conversion.
2009-08-29 08:08:38 +01:00
Chris Wilson
d7b0c3b784 [script] Track scaled-font
Instead of emitting the (font-face, matrix and options) elements when
setting up the desired font on the matrix, simply restore the scaled-font.
2009-08-29 08:08:38 +01:00
Chris Wilson
7306305cc8 [script] Emit surface content
Include the desired content with the creation info.
2009-08-29 08:08:37 +01:00
Chris Wilson
052211b072 [script] Garbage collect contexts on context switch
Previously the contexts were permanently associated with the surface and
only destroyed along with the final reference to the surface. This meant
that we kept a large number of unwanted contexts in memory. Most
applications only have a few contexts active at any time, so remove
inactive contexts from the operand stack every time we perform an
operation on a different context.
2009-08-29 08:08:37 +01:00
Chris Wilson
8f8b91d904 [script] Wrap snapshot.
Use the snapshot of our target surface if available.
2009-08-29 08:08:37 +01:00
Chris Wilson
a9d997fecd [script] Introduce cairo_script_context_t
cairo_script_context_t is an encapsulation object for interfacing with the
output - multiple surfaces can share the same context, meaning that they
write to the same destination file/stream.
2009-08-29 08:08:36 +01:00
Chris Wilson
dbd9438f5d [stroke] Only mark traps as having intersection if non-empty.
We were hitting an assertion attempting to eliminate intersections inside
the rectilinear tessellator for empty strokes. We can avoid this
assertion, by only marking the traps as having potential intersections iff
it is non-empty.
2009-08-29 08:08:36 +01:00
Chris Wilson
60d73da9f2 [clip] Cache intermediate clip masks.
As we now superimpose a per-operation clip, this defeats the current
top-level caching mechanism. Instead we need to cache the mask for
each path. This still seems quite wasteful, and an avenue would be to
avoid caching if the path is rectilinear and reduce the number of
required composite operations. (However, first find test case...)
2009-08-29 08:08:36 +01:00
Chris Wilson
3a483c2896 [gstate] Convert simple mask() into a paint()
As using mask() prevents various optimisations in the backends (for
example the use of geometric clips) and for some may trigger fallbacks,
perform the simplifications usually done (too late) by the pattern layer
in the generic gstate layer. This allows us on the odd occasion to
transform a mask() into a paint() but perhaps more importantly removes the
need for identical transformations in each backend.
2009-08-29 08:08:35 +01:00
Chris Wilson
4f129863df [script] Store the current stroke matrix
We can skip re-emitting stroke parameters if the values are unchanged and
the scaling matrix is unaltered.
2009-08-29 08:08:35 +01:00
Chris Wilson
858211f394 [script] Suppress resetting stroke-style elements after matrix switch
If the user is just using the default values, there is no point re-emitting
them.
2009-08-29 08:08:35 +01:00
Chris Wilson
b6db3053dc [script] Hide the implicit CLEAR for similar surfaces
Do emit the clear that is performed by the surface layer on similar
surfaces.
2009-08-29 08:08:34 +01:00
Chris Wilson
005b195f06 [pattern] Ignore matrix/filter/extend when comparing solids
Solid patterns do not use their matrices, filter or extend properties so
ignore them for the purposes of comparing and hashing.
2009-08-29 08:08:34 +01:00
Chris Wilson
bb919584c0 [script] Use a compact representation for horizontal offsets between glyphs
Kerning is quite frequent, that is to apply a horizontal but no vertical
offset to a glyph. For instance by discarding the vertical coordinate
where it remains the same and only encoding the horizontal offset we
reduce the file size by ~12.5% when tracing poppler.
2009-08-29 08:08:34 +01:00
Chris Wilson
24b2320002 [script] Fix list handling during font destruction
Use cairo_list to unhook the font correctly during the fini callback.
2009-08-29 08:08:34 +01:00
Chris Wilson
4032438625 [path] Eliminate redundant line-to before a close
As the close implicitly issues a line-to to the initial point, remove an
identical line-to if present.
2009-08-29 08:08:34 +01:00
Chris Wilson
111f2be71b [path] Discard redundant line-to
Eliminate repeated line-to to the current point.
2009-08-29 08:08:33 +01:00
Chris Wilson
a2d5f59e21 [debug] Path printer 2009-08-29 08:08:33 +01:00
Chris Wilson
4bf96bad96 [fill] Use trivial rectilinear_to_traps
Avoid a small amount of unnecessary overhead by performing a simple
conversion of the path to traps when it consists solely of simple boxes.
2009-08-29 08:08:33 +01:00
Chris Wilson
30e5fa0ce0 [polygon] Return status from path ops
This tidies the common case which was to call, for example,
_cairo_polygon_line_to(); _cairo_polygon_status();
2009-08-29 08:08:33 +01:00
Chris Wilson
3fcac1ef21 [slope] Inline _cairo_slope_init()
Move the definition to a separate header file and allow callers to inline
the simple function.
2009-08-29 08:08:33 +01:00
Chris Wilson
a1e0c4b309 [clip] Combine directly onto target
Where it is unlikely that we will reuse the temporary clip surface,
combine the clip directly with the mask.
2009-08-29 08:08:33 +01:00
Chris Wilson
3f12d9ec5d [clip] Use geometric clipping for unaligned clips
For the simple cases where the clip is an unaligned box (or boxes), apply
the clip directly to the geometry and avoid having to use an intermediate
clip-mask.
2009-08-29 08:08:33 +01:00
Chris Wilson
2457c4bede traps-as-spans
Add an interface to spans that accepts trapezoids. This allows backends
that have an efficient span-line interface but lack efficient handling
of boxes (partly due to the current poor compositor interface) to
redirect composite_trapezoids() to composite_polygon() and the
span-renderer.
2009-08-29 08:08:32 +01:00
Chris Wilson
3023330706 [fill] Early check for empty path/polygon 2009-08-29 08:08:32 +01:00
Chris Wilson
9ba37a85d2 [gstate] Discard trivial all-clipped regions
Avoid assertion failures later that we have a valid region.
2009-08-29 08:08:32 +01:00
Chris Wilson
85094c4eee [clip] Eliminate redundant clips
First perform a simple geometric clip to catch the majority of cases where
an unaligned clip has been set outside the operation extents that can be
discarded without having to use an image surface.

This causes a dramatic increase of over 13x for the poppler-bug-12266
trace and little impact elsewhere for more sensible clippers.
2009-08-29 08:08:32 +01:00
Chris Wilson
6dfe050d63 [polygon] Amalgamate collinear edges
Combine sequential collinear edges into a single edge, this benefits
immensely by feeding fewer edges into either the tessellator or spans.
2009-08-29 08:08:31 +01:00
Chris Wilson
0f8af05484 [fallback] Avoid tessellating empty polygons
I added an assert inside the tessellator to ensure that empty polygon were
not being propagated that far...
2009-08-29 08:08:31 +01:00
Chris Wilson
09377a7163 [freelist] Lazy initialisation of pools 2009-08-29 08:08:30 +01:00
Chris Wilson
6f0340e2e5 [clip] Use the rectilinear tessellator
We can ensure that we always produce a clip region when possible by using
the rectilinear tessellator to convert complex, device-aligned polygons to
regions. Prior to using the tessellator, we relied on pixman's region code
which could only handle a union of rectangles.
2009-08-29 08:08:30 +01:00
Chris Wilson
e3820bef20 [fill] Short-circuit extents on an empty path.
If the path is empty, avoid redundant polygonisation and tessellation by
simply returning the empty extents.
2009-08-29 08:08:30 +01:00
Chris Wilson
4051ed328b [tessellator] Special case rectilinear tessellation
For the frequent cases where we know in advance that we are dealing with a
rectilinear path, but can not use the simple region code, implement a
variant of the Bentley-Ottmann tessellator. The advantages here are that
edge comparison is very simple (we only have vertical edges) and there are
no intersection, though possible overlaps. The idea is the same, maintain
a y-x sorted queue of start/stop events that demarcate traps and sweep
through the active edges at each event, looking for completed traps.

The motivation for this was noticing a performance regression in
box-fill-outline with the self-intersection work:

  1.9.2 to HEAD^: 3.66x slowdown
  HEAD^ to HEAD:  5.38x speedup
  1.9.2 to HEAD:  1.57x speedup

The cause of which was choosing to use spans instead of the region handling
code, as the complex polygon was no longer being tessellated.
2009-08-29 08:08:29 +01:00
Chris Wilson
82ccb4c70c [clip] Use special-purpose fill_to_region()
Avoid the creation of temporary traps when generating a region, by calling
the to_region() directly.
2009-08-29 08:08:29 +01:00
Chris Wilson
41adeac988 [fallback] Avoid going through traps for trivial regions. 2009-08-29 08:08:29 +01:00
Chris Wilson
55bd590561 [tessellator] Use a priority queue for the events
The skip list was suffering from severe overhead, so though the search was
quick, the extra copies during insertion and deletion were slow.
2009-08-29 08:08:29 +01:00
Chris Wilson
ebfcc2ce8f [tessellator] Remove the skiplist for the active edges
The active edge list is typically short, and the skiplist adds significant
overhead that far outweigh the benefit of the O(n lg n) sort. Instead we
track the position of the last insertion edge, knowing that the start
events are lexicographically sorted, and begin a linear search from there.
2009-08-29 08:08:29 +01:00
Chris Wilson
36480fe531 [traps] Increase exponential expansion factor.
Grow the traps more rapidly, as the allocations are very short-lived so
the over-allocation is less of an issue.
2009-08-29 08:08:28 +01:00
Chris Wilson
9d51c03bad [traps] Compute extents on demand. 2009-08-29 08:08:28 +01:00
Chris Wilson
f8bb3617c3 Eliminate self-intersecting strokes.
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.
...
2009-08-29 08:08:28 +01:00
Benjamin Otte
40aefac5d7 [xlib] DO_XCOPYAREA and DO_XTILE optimizations break with Window source
Cairo should include the contents of subwindows when using a Window as a
source but will clip to subwindows when using a Window as a destination.
This can be set using the GC's subwindow_mode.

XCopyArea and XFillRectangle can however only use one GC for both source
and destination. Cairo's mode is set to (the default) ClipByChildren.
This means that copying from a Window is broken, so we only allow the
optimization when we know that the source is a Pixmap.

The performance impact of this change has not been tested. It should be
small, as the code will use XRender otherwise.

If it turns out to be a bigger impact, the optimizations could be
improved by doing a two-step copy process:
1) Copy to an intermediate Pixmap with IncludeInferiors
2) Copy to the destination with ClipByChildren
(potentially omitting one one of the steps if source or destination are
known to be Pixmaps).

references:
commit 0c5d28a4e5
https://bugs.freedesktop.org/show_bug.cgi?id=12996
2009-08-26 21:22:52 +02:00
Chris Wilson
d1b8e260d4 [qt] Fix compilation
Enabling 'FAST CLIP' appears to trigger an infinite loop so disable.

Enabling 'FAST FILL' has limited effect on performance, so disable whilst
the basic QT surface is improved.
2009-08-10 21:31:10 +01:00
Chris Wilson
dff0a91742 [xlib] Rewrite UNSUPPORTED() avoiding gcc-ism
Behdad pointed out that fprintf() returns a value so that we could simply
use the comma operator to return the correct value instead of the
expression-block gcc-ism.
2009-08-10 18:01:14 +01:00
Andrea Canciani
d4d0fcb4a8 [quartz] Compile fix for show_glyphs
Correct the prototype for _cairo_quartz_surface_show_glyphs().
2009-08-10 17:44:31 +01:00
Chris Wilson
2a2a19457b [surface] Check for a NULL snapshot
The backend is permitted to return a NULL surface when snapshotting to
indicate that it cannot (or choses not to) implement the method.
2009-08-10 17:44:25 +01:00
Chris Wilson
2e8ce34454 [quartz] Use the implementation font-face not the associated
As the associated is now explicitly the font-face used to create the font
by the user, whereas what we require is the current implementation
(quartz) font.
2009-08-10 17:20:00 +01:00
Chris Wilson
a4dc372bab [scaled-font] Update API documentation
Now that the toy-font-face is exposed to the user, it is expected to be
returned when the user queries the font face associated with a scaled font.
2009-08-10 17:19:53 +01:00
Andrea Canciani
3487049195 [quartz] Fix one more compile error 2009-08-09 21:47:40 +01:00
Chris Wilson
c2e75b9993 [quartz] Attempt to fix compile errors
ranma42 spotted that the quartz-backend no longer compiled after bed270,
so once again attempt to blindly fix those errors...
2009-08-09 21:12:36 +01:00