[cairo] Slow painting of images
Haakon Riiser
haakon.riiser at fys.uio.no
Wed Oct 26 05:12:26 PDT 2005
I've recently started experimenting with the Cairo library, and I
think I'm doing something wrong. I'm trying to display some PNG
images, and although it works, it is _extremely_ slow. Take a look
at the test program shown below (btw, it is based on some sample code
I found in the cairo-demo package). At first I thought it was slow
because the PNG image is reloaded every time the picture is drawn,
but I tried moving the loading of the PNG image away so that it was
only done once, and it didn't appear to make things faster. Thanks
in advance for any help!
/* ------------------------------------------------------------------------ */
#include <stdio.h>
#include <stdlib.h>
#include <cairo.h>
#include <cairo-xlib.h>
typedef struct win {
Display *dpy;
int scr;
Window win;
GC gc;
int width, height;
KeyCode quit_code;
} win_t;
static void win_init(win_t *win);
static void win_draw(win_t *win);
static void win_handle_events(win_t *win);
int
main(int argc, char *argv[])
{
win_t win;
win.dpy = XOpenDisplay(0);
if (win.dpy == NULL) {
fprintf(stderr, "failed to open display\n");
return 1;
}
win_init(&win);
win_handle_events(&win);
XDestroyWindow(win.dpy, win.win);
XCloseDisplay(win.dpy);
return 0;
}
static void
win_init(win_t *win)
{
Window root;
win->width = 800;
win->height = 800;
root = DefaultRootWindow(win->dpy);
win->scr = DefaultScreen(win->dpy);
win->win = XCreateSimpleWindow(win->dpy, root, 0, 0,
win->width, win->height, 0,
BlackPixel(win->dpy, win->scr),
BlackPixel(win->dpy, win->scr));
win->quit_code = XKeysymToKeycode(win->dpy, XStringToKeysym("Q"));
XSelectInput(win->dpy, win->win, KeyPressMask |
StructureNotifyMask |
ExposureMask);
XMapWindow(win->dpy, win->win);
}
Visual *visual;
cairo_t *cr;
cairo_surface_t *surface;
cairo_surface_t *surface_xlib;
static void
win_draw(win_t *win)
{
int w, h;
visual = DefaultVisual(win->dpy, DefaultScreen(win->dpy));
XClearWindow(win->dpy, win->win);
surface_xlib = cairo_xlib_surface_create(win->dpy, win->win, visual,
win->width, win->height);
cr = cairo_create(surface_xlib);
surface = cairo_image_surface_create_from_png("image.png");
w = cairo_image_surface_get_width(surface);
h = cairo_image_surface_get_height(surface);
cairo_scale(cr, (double) win->width / w, (double) win->height / h);
cairo_set_source_surface(cr, surface, 0, 0);
cairo_paint(cr);
if (cairo_status(cr)) {
printf("Cairo is unhappy: %s\n",
cairo_status_to_string (cairo_status (cr)));
exit(0);
}
cairo_surface_destroy(surface);
cairo_destroy(cr);
}
static void
win_handle_events(win_t *win)
{
XEvent xev;
for (;;) {
XNextEvent(win->dpy, &xev);
switch(xev.type) {
case KeyPress:
{
XKeyEvent *kev = &xev.xkey;
if (kev->keycode == win->quit_code) {
return;
}
break;
}
case ConfigureNotify:
{
XConfigureEvent *cev = &xev.xconfigure;
win->width = cev->width;
win->height = cev->height;
break;
}
case Expose:
{
XExposeEvent *eev = &xev.xexpose;
if (eev->count == 0)
win_draw(win);
break;
}
}
}
}
/* ------------------------------------------------------------------------ */
--
Haakon
More information about the cairo
mailing list