Having added a specialised scan converter on the premise that it should
be better at handling rounded rectangles, ensure that they are indeed
rendered correctly.
Enable origin tracking by default for make check-valgrind. This is
slower and consumes more memory than regular valgrind, but the
additional information provided about the source of the uninitialised
data is often invaluable.
This is a highly specialised scan converter for the relatively common
case of where the input geometry is known to be a series of rectangles.
Generally not device aligned (or else we would most likely have chosen
an even higher performance path that does not require a coverage mask),
this optimised converter can simply compute the analytical coverage by
utilising a special case Bentley-Ottmann intersection finder.
This variant uses the Bentley-Ottmann algorithm to only maintain the
active edge list upon edge events and so can efficiently skip areas
where no change occurs. This means that it can be much quicker than the
Tor algorithm (which is still used to compute the coverages from the
active edges) for geometries consisting of long straight lines with few
intersections. However due to the computational overhead of the
Bentley-Ottmann event processing, for dense curvy paths, simply updating
the active edge list in sync with computing the coverages is a win. Due
to advantageous adaptive step size, the scan converter can be run at a
much higher subsampling with little extra overhead compared with Tor,
currently it uses a 256x256 subsampling grid to avoid any impedance
mismatch with path precision.
Given the current status of implementations, this scan converter [botor]
is likely to be advantage where detecting large regions of unchanged
span data will result in improved performance, for instance the drm
backends which convert the scan data into rectangles.
Currently we use cairo_traps_t to also pass around arrays of boxes. This
is woefully inefficient in terms of storage, but also means that we
repeatedly have to verify that the traps are a set of boxes. By
explicitly passing around a cairo_boxes_t we avoid the semantic loss.
This will be heavily used in pending commits.
This is a more useful definition that is able to individually track the
rectangles that compose the composite operation. This will be used by
the specialist compositors as a means to perform the common extents
determination for an operation.
It is quite common amongst our geometry to have rows of repeated span
data, for example a rounded rectangle will have repeating data between
the top and bottom rounded corners. By passing the repeat length to the
renderers, they may be able to use that information more efficiently,
and the scan converters can avoid recomputing the same span data.
Add a gl-window boilerplate target to exercise using GL to render to a
visible Drawable -- for instance, a window has a different coordinate
system to a framebuffer...
The device is a generic method for accessing the underlying interface
with the native graphics subsystem, typically the X connection or
perhaps the GL context. By exposing a cairo_device_t on a surface and
its various methods we enable finer control over interoperability with
external interactions of the device by applications. The use case in
mind is, for example, a multi-threaded gstreamer which needs to serialise
its own direct access to the device along with Cairo's across many
threads.
Secondly, the cairo_device_t is a unifying API for the mismash of
backend specific methods for controlling creation of surfaces with
explicit devices and a convenient hook for debugging and introspection.
The principal components of the API are the memory management of:
cairo_device_reference(),
cairo_device_finish() and
cairo_device_destroy();
along with a pair of routines for serialising interaction:
cairo_device_acquire() and
cairo_device_release()
and a method to flush any outstanding accesses:
cairo_device_flush().
The device for a particular surface may be retrieved using:
cairo_surface_get_device().
The device returned is owned by the surface.
Implement a recursive mutex which will be needed for cairo_device_t.
In particular only pthreads by default is a non-recursive mutex (to my
knowledge) - both win32 critical sections and mutexes on Quartz are
recursive.
We were using _GNU_SOURCE throughout the codebase, so simply define it
once during configure. This is the easiest method to enable recursive
mutexes using pthreads, as required in a pending patch.
The first iteration of COW snapshotting always made an initial copy when
the snapshot was requested (and reused that copy until the surface was
modified). However, in a few circumstances we can avoid even that copy
so long as the surface is still alive and unmodified between the
snapshotting and its use. In order to do so, we need a new proxy surface
that can automatically perform the copy if the target should disappear
prior to use.
A subsurface is a region of another surface that may be used either to
restrict the writable area of a context or the readable extents of a
source. Whilst writing, access to the exterior of the subsurface is
prevented via clipping and when used as a source reads from the exterior
of the subsurface are governed via the extend mechanism of the pattern.
This is a simplified version of the wrapping surface where the target
surface is just a subsurface onto which we wish to draw the current
operation. In particular this is useful for the subsurface API as well
as fallbacks.
As a simple step to ensure that we do not inadvertently modify (or at least
generate compiler warns if we try) user data, mark the incoming style
and matrices as constant.
This test does various operations with a clear source surface with
various content types.
The idea is to make sure optimizations done when surface->is_clear ==
TRUE only happen in the proper cases.
By implicitly reference the target of the context instead, i.e.
this reduces the use of:
/target get (example.png) write-to-png pop
as a common idiom where the context is kept on the stack and the surface
forgotten.
Real applications that control their Drawable externally to Cairo are
'disadvantaged' by cairo-perf-trace when it creates a similar surface
for each new instance of the same Drawable. The difficulty in
maintaining one perf surface for every application surface is that the
traces do not track lifetimes for the application surfaces, so we would
just accumulate stale surfaces. The surface cache takes a different
approach and returns the same surface for each active Drawable, and
maintains a hold-over of the MRU 16 surfaces. This achieves 60-80% hit
rate with firefox, which is probably as good as can be expected.
Obviously for double-buffered applications we only every draw to freshly
created surfaces (and Gtk+ bypasses cairo to do the final copy -- the
ideal application would just use a push-group for double buffering, in
which case we would capture and replay the entire expose event).
To enable use of the surface cache whilst replaying use -c:
./cairo-perf-trace -c firefox-talos-gfx
An older variant of the fixes for moving the device transformation out
of the surface layer, but languished in a side branch. The only benefit
of this patch is that it avoids the copy where possible.
When the texture is GL_RGB, GL_CLAMP_TO_BORDER (EXTEND_NONE) fills the
border color alpha channel with 1, when the whole reason we were using
the border color was to get a color and alpha of 0. We're forced to
use GL_RGBA textures and do extra work to fill in the alpha channel of
them to 1 to get cairo's desired behavior.
This fixes a failure in rotate-image-surface-paint and 4 other
testcases. No performance difference in firefox-talos-gfx.
Hanno Meyer-Thurow reported in
http://bugs.freedesktop.org/show_bug.cgi?id=26063
[PATCH] various fixes to cairo-qt
a few issues related to _cairo_qt_surface_flush() where firefox was
crashing after being built to use cairo-qt.
This is an amalgam of those patches that hopefully address the issue.
Fixes: test/linear-uniform
https://bugzilla.mozilla.org/show_bug.cgi?id=539165
Bug 539165 - gradients with a single stop do not have their color
multiplied by the alpha.
As reported by Jeff Muizelaar, we regressed in 2d790daa as the
color-stops are not premultiplied and so could not be treated as an
ordinary cairo_color_t. Instead we have to create a intermediate
cairo_color_t from the original values in order for the
premultiplication to be performed.
Jeff reported a regression found by Mozilla whereby a uniform gradient
was not being premultiplied on conversion to a solid pattern.
https://bugzilla.mozilla.org/show_bug.cgi?id=539165
[Bug 539165] gradients with a single stop do not have their color
multiplied by the alpha.
Quartz doesn't try to approximate dash pattern even if they are well
beyond suface sampling frequency. Approximating dash patterns when their
density is too high avoids looping indefinitely in these degenerate cases.