[cairo] xtrace, part the second

Behdad Esfahbod behdad at behdad.org
Wed Dec 13 12:23:15 PST 2006

On Wed, 2006-12-13 at 14:04 -0500, Carl Worth wrote:
> On Wed, 13 Dec 2006 11:31:21 +0200, "Xan Lopez" wrote:
> > Assuming a) less X calls = good b) the way xft does things is just
> > fine,
> There's an implicit goal here of trying to get "new" GTK+ to be no
> slower than "old" GTK+. So those assumptions seem quite valid for that
> goal.
> > just before the actual glyph rendering. So, again. What are we exactly
> > doing? Can it be done the way Xft does it?
> What's happening here is that given a source pattern, (the description
> of the "color" for the text in this case), we're creating from that a
> source surface, (a Render picture), to be used by the xlib backend.

What Xft does is to cache the Picture for 16 colors, and evict one
randomly to make room for a new one.  I think this is in fact simple and
efficient enough that we may as well do.  We can even use a static
cursor variable to make repeated lookups of the same color really fast.
In pseudo-code:

  static int i = 0;

  if (cache[i].color == color)
    return cache[i].picture;

  for (i = 0; i < cache_size; i++)
    if (cache[i].color == color)
      return cache[i].picture;

  i = random() % cache_size;

  cache[i].color = color;
  cache[i].picture = create_picture (color);

  return cache[i].picture;

However, to do this correctly, we need to introduce a new object for a
display.  Moreover, we need to do locking around it (right?).  So, maybe
using a pattern-private member is easier.  You just don't get to reuse
them between patterns.

> So to eliminate that, what we would need is some caching of the
> surfaces acquired from patterns. There are a lot of different
> approaches that could be used here, with varying levels of difficulty
> and benefits. Here are a couple of observations:
> * Ideally we'd have a global pattern cache allowing its total size to
>   be managed as a single value. (Note: We'd like to have the same
>   thing for glyph caches, but currently we have separate per-font
>   caches for glyphs. We knew this was not ideal, but we chose this
>   approach for reasons of expedience. The same reasons might apply
>   here.)
> * An easy thing to do is to simply stash any acquired surface in the
>   pattern object itself. This will help for repeated use of the same
>   pattern object, (for example, set_source_rgb then many show_glyph
>   calls). The surface type here would end up being specific to the
>   backend being used. It's probably correct to just have a single slot
>   and let whichever backend gets there first to use it, (since it's
>   much more likely that patterns will be reused with the same backend
>   than across multiple backends). This is similar to the situation of
>   the surface_private field in cairo_scaled_font_t for example.

Honestly I never figured out how that surface_private thing is working.
I mean, a scaled font can be used with two backends, right?  What
happens then?

> * We could implement a small cache of pattern objects, (perhaps
>   limited to solid colors), for use when cairo creates its own
>   patterns, (inside things like set_source_rgb). This would allow for
>   an operation like changing back and forth between two different
>   source colors to benefit from a stashed surface inside the pattern
>   objects, as described above.

Yeah.  But if you do this lazily, it will become the scheme that Xft

> I hope that's helpful,
> -Carl


"Those who would give up Essential Liberty to purchase a little
 Temporary Safety, deserve neither Liberty nor Safety."
        -- Benjamin Franklin, 1759

More information about the cairo mailing list