diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2009-08-06 23:17:06 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2009-08-06 23:19:52 +0100 |
commit | af392f7e45edcbf101ca7c91fc1ee372d283e8b9 (patch) | |
tree | aa435f3353c4075bec68a3adf0cf810313f2c1a4 /util | |
parent | b7639a5f79eaecfbaf1710fc679c7be375638efd (diff) |
[script] Extend csi-replay to show how to use a single surface
Currently the replay creates a fresh surface for every new surface. Whilst
using it to view replays (such as with --xlib) this is often not what is
desired so add a mode (compile-time only for now) to use similar surfaces
and blits to the front buffer instead.
Diffstat (limited to 'util')
-rw-r--r-- | util/cairo-script/csi-replay.c | 73 |
1 files changed, 72 insertions, 1 deletions
diff --git a/util/cairo-script/csi-replay.c b/util/cairo-script/csi-replay.c index 16b733cc..297f16c8 100644 --- a/util/cairo-script/csi-replay.c +++ b/util/cairo-script/csi-replay.c @@ -7,6 +7,58 @@ static const cairo_user_data_key_t _key; +#define SINGLE_SURFACE 1 + +#if SINGLE_SURFACE +static cairo_surface_t * +_similar_surface_create (void *closure, + cairo_content_t content, + double width, double height) +{ + return cairo_surface_create_similar (closure, content, width, height); +} + +static struct list { + struct list *next; + cairo_t *context; + cairo_surface_t *surface; +} *list; + +static cairo_t * +_context_create (void *closure, cairo_surface_t *surface) +{ + cairo_t *cr = cairo_create (surface); + struct list *l = malloc (sizeof (*l)); + l->next = list; + l->context = cr; + l->surface = cairo_surface_reference (surface); + list = l; + return cr; +} + +static void +_context_destroy (void *closure, void *ptr) +{ + struct list *l, **prev = &list; + while ((l = *prev) != NULL) { + if (l->context == ptr) { + if (cairo_surface_status (l->surface) == CAIRO_STATUS_SUCCESS) { + cairo_t *cr = cairo_create (closure); + cairo_set_source_surface (cr, l->surface, 0, 0); + cairo_paint (cr); + cairo_destroy (cr); + } + + cairo_surface_destroy (l->surface); + *prev = l->next; + free (l); + return; + } + prev = &l->next; + } +} +#endif + #if CAIRO_HAS_XLIB_SURFACE #include <cairo-xlib.h> static Display * @@ -216,7 +268,11 @@ main (int argc, char **argv) { cairo_script_interpreter_t *csi; cairo_script_interpreter_hooks_t hooks = { -#if CAIRO_HAS_XLIB_XRENDER_SURFACE +#if SINGLE_SURFACE + .surface_create = _similar_surface_create, + .context_create = _context_create, + .context_destroy = _context_destroy +#elif CAIRO_HAS_XLIB_XRENDER_SURFACE .surface_create = _xrender_surface_create #elif CAIRO_HAS_XLIB_SURFACE .surface_create = _xlib_surface_create @@ -257,6 +313,13 @@ main (int argc, char **argv) { NULL, NULL } }; +#if SINGLE_SURFACE + hooks.closure = backends[0].create (NULL, + CAIRO_CONTENT_COLOR_ALPHA, + 512, 512); +#endif + + csi = cairo_script_interpreter_create (); cairo_script_interpreter_install_hooks (csi, &hooks); @@ -265,7 +328,14 @@ main (int argc, char **argv) for (b = backends; b->name != NULL; b++) { if (strcmp (b->name, argv[i]) == 0) { +#if SINGLE_SURFACE + cairo_surface_destroy (hooks.closure); + hooks.closure = b->create (NULL, + CAIRO_CONTENT_COLOR_ALPHA, + 512, 512); +#else hooks.surface_create = b->create; +#endif cairo_script_interpreter_install_hooks (csi, &hooks); break; } @@ -274,6 +344,7 @@ main (int argc, char **argv) if (b->name == NULL) cairo_script_interpreter_run (csi, argv[i]); } + cairo_surface_destroy (hooks.closure); return cairo_script_interpreter_destroy (csi); } |