The status return from _cairo_xlib_screen_put_gc() indicates the failure
to queue a job to free an old GC - the current GC is always transferred
away from the caller, so always nullify it in the surface.
Return the nil object if we encounter any error whilst trying to
generate the path.
Also special case the NO_MEMORY error object to return the nil object.
After consuming the GC we need to unset the clip reset flag, so that
if we try and get a new GC without first putting a fresh one we do not
try to call XSetClipMask on a NULL GC.
(Fixes http://bugs.freedesktop.org/show_bug.cgi?id=10921)
By dropping the top frame from suppression, the XrmGetFileDatabase
suppressions will also match XrmGetStringDatabase leaks which are
starting to occur.
_cairo_truetype_font_create() failed to update the status before
returning after detecting an allocation failure, leaving its callers
none the wishing - and eventually triggering a segmentation fault when
the font was used in anger.
Before attempting to access the cairo_meta_surface_t specific members,
we need to ensure that _cairo_meta_surface_replay() has received a true
meta surface rather than an error surface (e.g. _cairo_surface_nil).
Sun never released a version of Solaris with Xorg with the buggy repeat
problem. This patch was only needed for development versions of Solaris
Nevada (roughly builds 25-30). The latest S10U release and Nevada releases
have a fixed Xorg. So no users should ever encounter this bug.
We need to remove this test because Xsun has the same VendorString and a lower
VendorRelease number so it falsely triggers buggy_repeat to be turned on.
They just added Xrender support recently to Xsun, so this wasn't an issue
before recently.
cairo_scaled_font_create() returns a nil object on failure whereas a few
callers were checking for NULL.
Secondly review the public entry points for cairo_scaled_font_*() to
ensure that all check that they will not attempt to overwrite the
read-only nil object.
cairo_pop_group() checks for a NULL return from
cairo_pattern_create_for_surface() instead of the nil cairo_pattern_t,
and then returns a NULL pattern instead of the nil object.
During the copy, allocation of the gradient may fail and so the callers
need to check for a pattern that returned in an error state. No callers
did so and in order to force all callers to check the error status,
the status return was added to _cairo_pattern_init_copy(). The early
error checking may appear redundant for an object with an embedded
structure, however it does fix an error where an uninitialised pattern
was being used:
==1922== Process terminating with default action of signal 11 (SIGSEGV)
==1922== Access not within mapped region at address 0x55555555
==1922== at 0x402CF6F: _cairo_array_index (cairo-array.c:208)
==1922== by 0x402D4F3: _cairo_user_data_array_fini (cairo-array.c:370)
==1922== by 0x4046464: _cairo_pattern_fini (cairo-pattern.c:188)
==1922== by 0x404992A: _cairo_meta_surface_paint (cairo-meta-surface.c:266)
==1922== by 0x403FCE0: _cairo_surface_paint (cairo-surface.c:1331)
==1922== by 0x405CB5E: _test_meta_surface_paint (test-meta-surface.c:195)
==1922== by 0x403FCE0: _cairo_surface_paint (cairo-surface.c:1331)
==1922== by 0x4032A60: _cairo_gstate_paint (cairo-gstate.c:822)
==1922== by 0x402B2D1: cairo_paint (cairo.c:1879)
==1922== by 0x804A4F7: draw (radial-gradient.c:73)
==1922== by 0x804AFA4: cairo_test_expecting (cairo-test.c:326)
==1922== by 0x804A57C: main (radial-gradient.c:109)
==1922== Injected fault at:
==1922== at 0x4020EA5: malloc (vg_replace_malloc.c:207)
==1922== by 0x404475C: _cairo_pattern_init_copy (cairo-pattern.c:136)
==1922== by 0x403F779: _cairo_surface_copy_pattern_for_destination (cairo-surface.c:2153)
==1922== by 0x403FCC1: _cairo_surface_paint (cairo-surface.c:1328)
==1922== by 0x405CB5E: _test_meta_surface_paint (test-meta-surface.c:195)
==1922== by 0x403FCE0: _cairo_surface_paint (cairo-surface.c:1331)
==1922== by 0x4032A60: _cairo_gstate_paint (cairo-gstate.c:822)
==1922== by 0x402B2D1: cairo_paint (cairo.c:1879)
==1922== by 0x804A4F7: draw (radial-gradient.c:73)
==1922== by 0x804AFA4: cairo_test_expecting (cairo-test.c:326)
==1922== by 0x804A57C: main (radial-gradient.c:109)
The design is for the user to create a cairo_font_options_t object with
cairo_font_options_create() and then is free to use it with any Cairo
operation. This requires us to check when we may be about to overwrite
the read-only nil object.
Simply return without writing to potentially read-only members of an
invalid pattern rather than assert. This is cleaner than tracking down
all the error paths that may call into cairo_pattern_transform()...
Check for an allocation failure during _cairo_analysis_surface_create()
and propagate to caller - where we discover that the callers themselves
missed the status checks...
_cairo_surface_create_similar_solid() may return an image surface,
should the backend not support the required content or should it
encounter an error whilst creating the surface. In those circumstances
we choose not to cache the fallback surface.
Original work by Jorn Baayen <jorn@openedhand.com>,
2715f20981
We use a small cache of size 16 for surfaces created for solid patterns.
This mainly helps with the X backends where we don't have to create a
pattern for every operation, so we save a lot on X traffic. Xft uses a
similar cache, so cairo's text rendering traffic with the xlib backend
now completely matches that of Xft.
The cache uses an static index variable, which itself acts like a cache of
size 1, remembering the most recently used solid pattern. So repeated
lookups for the same pattern hit immediately. If that fails, the cache is
searched linearly, and if that fails too, a new surface is created and a
random member of the cache is evicted.
A cached surface can only be reused if it is similar to the destination.
In order to check for similar surfaces a new test is introduced for the
backends to determine that the cached surface is as would be returned by
a _create_similar() call for the destination and content.
As surfaces are in general complex encapsulation of graphics state we
only return unshared cached surfaces and reset them (to clear any error
conditions and graphics state). In practice this makes little difference
to the efficacy of the cache during various benchmarks. However, in order
to transparently share solid surfaces it would be possible to implement a
COW scheme.
Cache hit rates: (hit same index + hit in cache) / lookups
cairo-perf: (42346 + 28480) / 159600 = 44.38%
gtk-theme-torturer: (3023 + 3502) / 6528 = 99.95%
gtk-perf: (8270 + 3190) / 21504 = 53.29%
This translates into a reduction of about 25% of the XRENDER traffic during
cairo-perf.
By deferring the issuing of the X requests to set the clip mask we can
theoretically avoid some redundant requests, but primarily we remove
another path where X requests are emitted.