[cairo] fixing Cairo's FreeType multi-threaded usage

Jan Slupski jslupski at juljas.net
Fri Mar 2 19:23:33 PST 2007

On Sat, 3 Mar 2007, David Turner wrote:

> no, this is not normal at all; I'm running my desktop on this patch and
> haven't seen any regression in performance. Are you sure your merge happened
> without conflicts ?

No, no conflicts. Only few 'fuzz'.

Except makefiles these are:

$ bzcat ../fix-freetype-usage-1.patchset.bz2 | patch -p1
patching file src/cairo-debug.c
Hunk #1 succeeded at 66 with fuzz 2.
patching file src/cairoint.h
Hunk #1 succeeded at 623 (offset 4 lines).
Hunk #3 succeeded at 1214 (offset 2 lines).

Should I try any earlier cairo snapshot?

> the long story is that some of the intermediate commits in the patchset do
> produce correct behaviour and very poor performance, but this is normally
> fixed in later ones.
> In the event your merge didn't work correctly, you could be left in one of
> these hideously slow cases. I've just checked the patchset file, and the
> changes described there seem ok.
> Could you give more details about your test cases ? it may be interesting.

Seems that I am able to reproduce these on my simple cairo threads test case
I used before to hunt previous problems. (attached)

real    0m2.551s
user    0m2.530s
sys     0m0.020s

Cairo-git + fix-freetype-usage-1.patchset:
real    0m12.956s
user    0m12.950s
sys     0m0.010s

Command used: time ./threads 1 10000 
(one thread, 10K loops)

Before I used two samples (against some external library that calls
cairo) on two Linux machines. Slowdown with patch applied was:
- between 2x (x86_64 dual) and 6x (i386) - first sample
- between 6x (x86_64 dual) and 60x+ (i386) really! - another sample

I'm sure about these results, but if you find them unbelivable
and cannot reproduce, I'll repeat tests from scratch to make it 200% sure...

Thanks a lot,

> On Sat, 3 Mar 2007 01:47:49 +0100 (CET), "Jan Slupski" <jslupski at juljas.net> said:
>> On Wed, 28 Feb 2007, David Turner wrote:
>>> Hello,
>>> here's the first version of my patches to fix Cairo's usage of FreeType with multiple
>>> threads. It's rather big, so I'll summarize things here a little:
>> Hi David,
>> I tried your patches against the current git cairo (latest commit
>> fed13e77e1de071ddaaf829aced10b02f6bc8c90).
>> Is it expected that cairo with these patches runs *much* slower
>> than without? I'm running simple test case and it seems to be
>> 8+ times slower even in single thread.
>> Is there anything special I should do (i.e. revert some already
>> merged patches)?
>> I'll try to figure out what exactly caused the slowdown, but any hints
>> are apperciated...
>> I have used default setup (./autogen.sh; make) and
>> fontconfig 2.4.2, freetype 2.1.7 & 2.3.1

    _  _  _  _  _____________________________________________
    | |_| |\ |  S L U P S K I             jslupski at juljas.net
  |_| | | | \|                             http://juljas.net/
-------------- next part --------------
#include <pthread.h>
#include <cairo.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#define MAX_THREAD 2
#define LOOP_COUNT 50

void * Draw(void *p);

int gLoopCount=LOOP_COUNT;

int main(int argc, char **argv) {
	const int nThreads = argc>1?atoi(argv[1]):MAX_THREAD;
	int i;

	pthread_t threads[5000];

	if(argc>2) gLoopCount = atoi(argv[2]);

	//printf("Cairo version: %s\n",cairo_version_string());

	for(i =0; i<nThreads; i++)
		int err = pthread_create(&threads[i],NULL,Draw,(void*)i);
		if(err) printf("error creating thread %d\n",i);

	for(i =0; i<nThreads; i++)
		pthread_join(threads[i], NULL);


	return 0;

void * Draw(void *p)
  int thread_no = (int)p;
	int loop = 0;

	while (loop<=gLoopCount)
			printf("t%03d loop %4d\n",thread_no, loop);

			//char name[200];
			//sprintf(name, "th%03d.img%04d.png", thread_no, loop);

			cairo_surface_t *surface;
			cairo_t *cr;

			char string[] = "Hello";
			cairo_text_extents_t size;
			double fontsize = 100.0;

			surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 400, 300);
			cr = cairo_create (surface);

			cairo_select_font_face (cr, "Serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
			cairo_set_font_size (cr, fontsize);
			cairo_text_extents(cr, string, &size);
			cairo_show_text (cr, string);

			//cairo_surface_write_to_png (surface, "rotlabel.png");
			cairo_destroy (cr);
			cairo_surface_destroy (surface);


	return NULL;


More information about the cairo mailing list