diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-08-17 22:20:18 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-08-17 22:20:18 +0100 |
commit | 6f000c3538e7fe1faf669104d120f76d8cc6f154 (patch) | |
tree | 7b2f70419d1a7fc54f0e937127b637e120e7d52f | |
parent | e5bac9de50fe2f6bd241e78b2838c4893abecbff (diff) |
Rename ximage to xshm and create a new demo based on similar-image
-rw-r--r-- | Makefile | 7 | ||||
-rw-r--r-- | demo.c | 8 | ||||
-rw-r--r-- | demo.h | 6 | ||||
-rw-r--r-- | ximage.c | 122 | ||||
-rw-r--r-- | xlib.c | 2 | ||||
-rw-r--r-- | xshm.c | 200 |
6 files changed, 243 insertions, 102 deletions
@@ -12,11 +12,11 @@ endif XLIB:=$(shell pkg-config --exists cairo-xlib && echo 1 || echo 0) ifneq ($(XLIB),0) -DEFINES+=-DHAVE_XLIB=1 -DHAVE_XIMAGE=1 -SOURCES+=xlib.c ximage.c +DEFINES+=-DHAVE_XLIB=1 -DHAVE_XIMAGE=1 -DHAVE_XSHM=1 +SOURCES+=xlib.c ximage.c xshm.c REQUIRES+=cairo-xlib xext else -DEFINES+=-DHAVE_XLIB=0 +DEFINES+=-DHAVE_XLIB=0 -DHAVE_XIMAGE=0 -DHAVE_XSHM=0 endif XCB:=$(shell pkg-config --exists cairo-xcb && echo 1 || echo 0) @@ -29,6 +29,7 @@ DEFINES+=-DHAVE_XCB=0 endif GLX:=$(shell pkg-config --exists cairo-gl && echo 1 || echo 0) +GLX:=0 ifneq ($(GLX),0) DEFINES+=-DHAVE_GLX=1 SOURCES+=glx.c @@ -145,6 +145,7 @@ struct device *device_open(int argc, char **argv) AUTO, XLIB, XIMAGE, + XSHM, SKIA, XCB, GLX, @@ -160,6 +161,8 @@ struct device *device_open(int argc, char **argv) backend = XCB; } else if (strcmp (argv[n], "--ximage") == 0) { backend = XIMAGE; + } else if (strcmp (argv[n], "--xshm") == 0) { + backend = XSHM; } else if (strcmp (argv[n], "--drm") == 0) { backend = DRM; } else if (strcmp (argv[n], "--glx") == 0) { @@ -184,6 +187,8 @@ struct device *device_open(int argc, char **argv) device = cogl_open (argc, argv); if (device == 0 && HAVE_XIMAGE) device = ximage_open (argc, argv); + if (device == 0 && HAVE_XSHM) + device = xshm_open (argc, argv); if (device == 0 && HAVE_SKIA) device = skia_open (argc, argv); } else switch (backend) { @@ -197,6 +202,9 @@ struct device *device_open(int argc, char **argv) case XIMAGE: device = ximage_open (argc, argv); break; + case XSHM: + device = xshm_open (argc, argv); + break; case SKIA: device = skia_open (argc, argv); break; @@ -89,6 +89,12 @@ struct device *ximage_open (int argc, char **argv); static inline struct device *ximage_open (int argc, char **argv) { return 0; } #endif +#if HAVE_XSHM +struct device *xshm_open (int argc, char **argv); +#else +static inline struct device *xshm_open (int argc, char **argv) { return 0; } +#endif + #if HAVE_DRM struct device *drm_open (int argc, char **argv); #else @@ -12,14 +12,6 @@ struct ximage_device { struct device base; struct framebuffer fb; - - Display *display; - Window drawable; - - int stride; - Pixmap pixmap; - GC gc; - XShmSegmentInfo shm; }; static void @@ -27,51 +19,15 @@ destroy (struct framebuffer *abstract_framebuffer) { } -static cairo_bool_t -_native_byte_order_lsb (void) -{ - int x = 1; - - return *((char *) &x) == 1; -} - static void show (struct framebuffer *fb) { struct ximage_device *device = (struct ximage_device *) fb->device; - - if (device->pixmap) { - XCopyArea (device->display, device->pixmap, device->drawable, device->gc, - 0, 0, - device->base.width, device->base.height, - 0, 0); - } else { - XImage ximage; - int native_byte_order = _native_byte_order_lsb () ? LSBFirst : MSBFirst; - - ximage.width = device->base.width; - ximage.height = device->base.height; - ximage.format = ZPixmap; - ximage.byte_order = native_byte_order; - ximage.bitmap_unit = 32; /* always for libpixman */ - ximage.bitmap_bit_order = native_byte_order; - ximage.bitmap_pad = 32; /* always for libpixman */ - ximage.depth = 24; - ximage.red_mask = 0xff; - ximage.green_mask = 0xff00; - ximage.blue_mask = 0xff000; - ximage.xoffset = 0; - ximage.bits_per_pixel = 32; - ximage.data = device->shm.shmaddr; - ximage.obdata = (char *) &device->shm; - ximage.bytes_per_line = device->stride; - - XShmPutImage (device->display, device->drawable, device->gc, &ximage, - 0, 0, 0, 0, device->base.width, device->base.height, - False); - } - - XSync (device->display, True); + cairo_t *cr = cairo_create (device->base.scanout); + cairo_set_source_surface (cr, fb->surface, 0, 0); + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); + cairo_paint (cr); + cairo_destroy (cr); } static struct framebuffer * @@ -87,25 +43,18 @@ ximage_open (int argc, char **argv) struct ximage_device *device; Display *dpy; Screen *scr; + Window win; int screen; XSetWindowAttributes attr; - int major, minor, has_pixmap; int x, y; - XGCValues gcv; dpy = XOpenDisplay (NULL); if (dpy == NULL) return NULL; - if (! XShmQueryExtension (dpy)) { - XCloseDisplay (dpy); - return NULL; - } - device = (struct ximage_device *) malloc (sizeof (struct ximage_device)); device->base.name = "ximage"; device->base.get_framebuffer = get_fb; - device->display = dpy; screen = DefaultScreen (dpy); scr = XScreenOfDisplay (dpy, screen); @@ -149,52 +98,27 @@ ximage_open (int argc, char **argv) } attr.override_redirect = True; - device->drawable = XCreateWindow (dpy, DefaultRootWindow (dpy), - x, y, - device->base.width, device->base.height, 0, - DefaultDepth (dpy, screen), - InputOutput, - DefaultVisual (dpy, screen), - CWOverrideRedirect, &attr); - XMapWindow (dpy, device->drawable); - - device->stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, device->base.width); - - device->shm.shmid = shmget(IPC_PRIVATE, device->stride * device->base.height, IPC_CREAT | 0777); - device->shm.shmaddr = (char *) shmat (device->shm.shmid, NULL, 0); - device->shm.readOnly = False; - - if (!XShmAttach (dpy, &device->shm)) - abort (); - - device->base.scanout = cairo_image_surface_create_for_data ((uint8_t *) device->shm.shmaddr, - CAIRO_FORMAT_RGB24, - device->base.width, - device->base.height, - device->stride); - XShmQueryVersion (dpy, &major, &minor, &has_pixmap); - - if (has_pixmap) { - printf ("Using SHM Pixmap\n"); - device->pixmap = XShmCreatePixmap (dpy, - device->drawable, - device->shm.shmaddr, - &device->shm, - device->base.width, - device->base.height, - 24); - } else { - printf ("Using SHM PutImage\n"); - device->pixmap = 0; - } - - gcv.graphics_exposures = False; - device->gc = XCreateGC (dpy, device->drawable, GCGraphicsExposures, &gcv); + win = XCreateWindow (dpy, DefaultRootWindow (dpy), + x, y, + device->base.width, device->base.height, 0, + DefaultDepth (dpy, screen), + InputOutput, + DefaultVisual (dpy, screen), + CWOverrideRedirect, &attr); + XMapWindow (dpy, win); + + device->base.scanout = cairo_xlib_surface_create (dpy, win, + DefaultVisual (dpy, screen), + device->base.width, device->base.height); + + device->fb.surface = + cairo_surface_create_similar_image (device->base.scanout, + CAIRO_FORMAT_RGB24, + device->base.width, device->base.height); device->fb.device = &device->base; device->fb.show = show; device->fb.destroy = destroy; - device->fb.surface = device->base.scanout; return &device->base; } @@ -28,6 +28,8 @@ show (struct framebuffer *fb) { struct xlib_device *device = (struct xlib_device *) fb->device; + cairo_surface_flush (fb->surface); + XCopyArea(device->display, device->pixmap[device->q&1], device->drawable, @@ -0,0 +1,200 @@ +#include <cairo-xlib.h> + +#include "demo.h" + +#include <stdlib.h> +#include <stdio.h> + +#include <X11/extensions/XShm.h> +#include <sys/ipc.h> +#include <sys/shm.h> + +struct xshm_device { + struct device base; + struct framebuffer fb; + + Display *display; + Window drawable; + + int stride; + Pixmap pixmap; + GC gc; + XShmSegmentInfo shm; +}; + +static void +destroy (struct framebuffer *abstract_framebuffer) +{ +} + +static cairo_bool_t +_native_byte_order_lsb (void) +{ + int x = 1; + + return *((char *) &x) == 1; +} + +static void +show (struct framebuffer *fb) +{ + struct xshm_device *device = (struct xshm_device *) fb->device; + + if (device->pixmap) { + XCopyArea (device->display, device->pixmap, device->drawable, device->gc, + 0, 0, + device->base.width, device->base.height, + 0, 0); + } else { + XImage xshm; + int native_byte_order = _native_byte_order_lsb () ? LSBFirst : MSBFirst; + + xshm.width = device->base.width; + xshm.height = device->base.height; + xshm.format = ZPixmap; + xshm.byte_order = native_byte_order; + xshm.bitmap_unit = 32; /* always for libpixman */ + xshm.bitmap_bit_order = native_byte_order; + xshm.bitmap_pad = 32; /* always for libpixman */ + xshm.depth = 24; + xshm.red_mask = 0xff; + xshm.green_mask = 0xff00; + xshm.blue_mask = 0xff000; + xshm.xoffset = 0; + xshm.bits_per_pixel = 32; + xshm.data = device->shm.shmaddr; + xshm.obdata = (char *) &device->shm; + xshm.bytes_per_line = device->stride; + + XShmPutImage (device->display, device->drawable, device->gc, &xshm, + 0, 0, 0, 0, device->base.width, device->base.height, + False); + } + + XSync (device->display, True); +} + +static struct framebuffer * +get_fb (struct device *abstract_device) +{ + struct xshm_device *device = (struct xshm_device *) abstract_device; + return &device->fb; +} + +struct device * +xshm_open (int argc, char **argv) +{ + struct xshm_device *device; + Display *dpy; + Screen *scr; + int screen; + XSetWindowAttributes attr; + int major, minor, has_pixmap; + int x, y; + XGCValues gcv; + + dpy = XOpenDisplay (NULL); + if (dpy == NULL) + return NULL; + + if (! XShmQueryExtension (dpy)) { + XCloseDisplay (dpy); + return NULL; + } + + device = (struct xshm_device *) malloc (sizeof (struct xshm_device)); + device->base.name = "xshm"; + device->base.get_framebuffer = get_fb; + device->display = dpy; + + screen = DefaultScreen (dpy); + scr = XScreenOfDisplay (dpy, screen); + device->base.width = WidthOfScreen (scr); + device->base.height = HeightOfScreen (scr); + device_get_size (argc, argv, &device->base.width, &device->base.height); + x = y = 0; + switch (device_get_split(argc, argv)) { + case SPLIT_NONE: + break; + case SPLIT_LEFT: + device->base.width /= 2; + break; + case SPLIT_RIGHT: + x = device->base.width /= 2; + break; + case SPLIT_TOP: + device->base.height /= 2; + break; + case SPLIT_BOTTOM: + y = device->base.height /= 2; + break; + + case SPLIT_BOTTOM_LEFT: + device->base.width /= 2; + y = device->base.height /= 2; + break; + case SPLIT_BOTTOM_RIGHT: + x = device->base.width /= 2; + y = device->base.height /= 2; + break; + + case SPLIT_TOP_LEFT: + device->base.width /= 2; + device->base.height /= 2; + break; + case SPLIT_TOP_RIGHT: + x = device->base.width /= 2; + device->base.height /= 2; + break; + } + + attr.override_redirect = True; + device->drawable = XCreateWindow (dpy, DefaultRootWindow (dpy), + x, y, + device->base.width, device->base.height, 0, + DefaultDepth (dpy, screen), + InputOutput, + DefaultVisual (dpy, screen), + CWOverrideRedirect, &attr); + XMapWindow (dpy, device->drawable); + + device->stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, device->base.width); + + device->shm.shmid = shmget(IPC_PRIVATE, device->stride * device->base.height, IPC_CREAT | 0777); + device->shm.shmaddr = (char *) shmat (device->shm.shmid, NULL, 0); + device->shm.readOnly = False; + + if (!XShmAttach (dpy, &device->shm)) + abort (); + + device->base.scanout = cairo_image_surface_create_for_data ((uint8_t *) device->shm.shmaddr, + CAIRO_FORMAT_RGB24, + device->base.width, + device->base.height, + device->stride); + XShmQueryVersion (dpy, &major, &minor, &has_pixmap); + + if (has_pixmap) { + printf ("Using SHM Pixmap\n"); + device->pixmap = XShmCreatePixmap (dpy, + device->drawable, + device->shm.shmaddr, + &device->shm, + device->base.width, + device->base.height, + 24); + } else { + printf ("Using SHM PutImage\n"); + device->pixmap = 0; + } + + gcv.graphics_exposures = False; + device->gc = XCreateGC (dpy, device->drawable, GCGraphicsExposures, &gcv); + + device->fb.device = &device->base; + device->fb.show = show; + device->fb.destroy = destroy; + device->fb.surface = device->base.scanout; + + return &device->base; +} |