summaryrefslogtreecommitdiff
path: root/boilerplate
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-06-01 23:03:36 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2011-06-02 08:57:13 +0100
commitbf1b08d066ebcffa71f5e728dc333f4494ff4ba3 (patch)
tree1544b7292a17eeb87e31354048f2f489ae79b442 /boilerplate
parent52f79bfcf34c504c7baa7d996983a7283f02f51e (diff)
perf
Diffstat (limited to 'boilerplate')
-rw-r--r--boilerplate/cairo-boilerplate-glx.c4
-rw-r--r--boilerplate/cairo-boilerplate-xcb.c67
-rw-r--r--boilerplate/cairo-boilerplate-xlib.c58
-rw-r--r--boilerplate/cairo-boilerplate.c72
-rw-r--r--boilerplate/cairo-boilerplate.h11
5 files changed, 206 insertions, 6 deletions
diff --git a/boilerplate/cairo-boilerplate-glx.c b/boilerplate/cairo-boilerplate-glx.c
index f41907025..690844ead 100644
--- a/boilerplate/cairo-boilerplate-glx.c
+++ b/boilerplate/cairo-boilerplate-glx.c
@@ -373,6 +373,7 @@ static const cairo_boilerplate_target_t targets[] = {
CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
"cairo_gl_surface_create",
_cairo_boilerplate_gl_create_surface,
+ cairo_surface_create_similar,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
@@ -386,6 +387,7 @@ static const cairo_boilerplate_target_t targets[] = {
CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR, 1,
"cairo_gl_surface_create",
_cairo_boilerplate_gl_create_surface,
+ cairo_surface_create_similar,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
@@ -399,6 +401,7 @@ static const cairo_boilerplate_target_t targets[] = {
CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
"cairo_gl_surface_create_for_window",
_cairo_boilerplate_gl_create_window,
+ cairo_surface_create_similar,
NULL,
_cairo_boilerplate_gl_finish_window,
_cairo_boilerplate_get_image_surface,
@@ -413,6 +416,7 @@ static const cairo_boilerplate_target_t targets[] = {
CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
"cairo_gl_surface_create_for_window",
_cairo_boilerplate_gl_create_window_db,
+ cairo_surface_create_similar,
NULL,
_cairo_boilerplate_gl_finish_window,
_cairo_boilerplate_get_image_surface,
diff --git a/boilerplate/cairo-boilerplate-xcb.c b/boilerplate/cairo-boilerplate-xcb.c
index 418e138fb..7cccbdac5 100644
--- a/boilerplate/cairo-boilerplate-xcb.c
+++ b/boilerplate/cairo-boilerplate-xcb.c
@@ -170,6 +170,66 @@ find_depth (xcb_connection_t *connection,
return NULL;
}
+static const cairo_user_data_key_t key;
+
+struct similar {
+ xcb_connection_t *connection;
+ xcb_drawable_t pixmap;
+};
+
+static void _destroy_similar (void *closure)
+{
+ struct similar *similar = closure;
+
+ xcb_free_pixmap (similar->connection, similar->pixmap);
+ free (similar);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_xcb_create_similar (cairo_surface_t *other,
+ cairo_content_t content,
+ int width, int height)
+{
+ xcb_screen_t *root;
+ cairo_surface_t *surface;
+ struct similar *similar;
+ xcb_render_pictforminfo_t *render_format;
+ int depth;
+ void *formats;
+
+ similar = malloc (sizeof (*similar));
+
+ switch (content) {
+ default:
+ case CAIRO_CONTENT_COLOR_ALPHA: depth = 32; break;
+ case CAIRO_CONTENT_COLOR: depth = 24; break;
+ case CAIRO_CONTENT_ALPHA: depth = 8; break;
+ }
+
+ similar->connection =
+ cairo_xcb_device_get_connection (cairo_surface_get_device(other));
+ similar->pixmap = xcb_generate_id (similar->connection);
+
+ root = xcb_setup_roots_iterator(xcb_get_setup(similar->connection)).data;
+ xcb_create_pixmap (similar->connection, depth,
+ similar->pixmap, root->root,
+ width, height);
+
+ render_format = find_depth (similar->connection, depth, &formats);
+ if (render_format == NULL)
+ return NULL;
+
+ surface = cairo_xcb_surface_create_with_xrender_format (similar->connection,
+ root,
+ similar->pixmap,
+ render_format,
+ width, height);
+ cairo_surface_set_user_data (surface, &key, similar, _destroy_similar);
+ free(formats);
+
+ return surface;
+}
+
static cairo_surface_t *
_cairo_boilerplate_xcb_create_surface (const char *name,
cairo_content_t content,
@@ -681,6 +741,7 @@ static const cairo_boilerplate_target_t targets[] = {
CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR_ALPHA, 1,
"cairo_xcb_surface_create_with_xrender_format",
_cairo_boilerplate_xcb_create_surface,
+ _cairo_boilerplate_xcb_create_similar,
NULL,
_cairo_boilerplate_xcb_finish_surface,
_cairo_boilerplate_get_image_surface,
@@ -695,6 +756,7 @@ static const cairo_boilerplate_target_t targets[] = {
CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR, 1,
"cairo_xcb_surface_create_with_xrender_format",
_cairo_boilerplate_xcb_create_surface,
+ _cairo_boilerplate_xcb_create_similar,
NULL,
_cairo_boilerplate_xcb_finish_surface,
_cairo_boilerplate_get_image_surface,
@@ -709,6 +771,7 @@ static const cairo_boilerplate_target_t targets[] = {
CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR, 1,
"cairo_xcb_surface_create_with_xrender_format",
_cairo_boilerplate_xcb_create_window,
+ _cairo_boilerplate_xcb_create_similar,
NULL,
_cairo_boilerplate_xcb_finish_surface,
_cairo_boilerplate_get_image_surface,
@@ -723,6 +786,7 @@ static const cairo_boilerplate_target_t targets[] = {
CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR, 1,
"cairo_xcb_surface_create_with_xrender_format",
_cairo_boilerplate_xcb_create_window_db,
+ _cairo_boilerplate_xcb_create_similar,
NULL,
_cairo_boilerplate_xcb_finish_surface,
_cairo_boilerplate_get_image_surface,
@@ -737,6 +801,7 @@ static const cairo_boilerplate_target_t targets[] = {
CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR_ALPHA, 1,
"cairo_xcb_surface_create_with_xrender_format",
_cairo_boilerplate_xcb_create_render_0_0,
+ cairo_surface_create_similar,
NULL,
_cairo_boilerplate_xcb_finish_surface,
_cairo_boilerplate_get_image_surface,
@@ -751,6 +816,7 @@ static const cairo_boilerplate_target_t targets[] = {
CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR, 1,
"cairo_xcb_surface_create_with_xrender_format",
_cairo_boilerplate_xcb_create_render_0_0,
+ cairo_surface_create_similar,
NULL,
_cairo_boilerplate_xcb_finish_surface,
_cairo_boilerplate_get_image_surface,
@@ -765,6 +831,7 @@ static const cairo_boilerplate_target_t targets[] = {
CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR, 1,
"cairo_xcb_surface_create_with_xrender_format",
_cairo_boilerplate_xcb_create_fallback,
+ cairo_surface_create_similar,
NULL,
_cairo_boilerplate_xcb_finish_surface,
_cairo_boilerplate_get_image_surface,
diff --git a/boilerplate/cairo-boilerplate-xlib.c b/boilerplate/cairo-boilerplate-xlib.c
index f82b78b8d..797fe9724 100644
--- a/boilerplate/cairo-boilerplate-xlib.c
+++ b/boilerplate/cairo-boilerplate-xlib.c
@@ -35,6 +35,8 @@
#include <X11/Xutil.h> /* for XDestroyImage */
+static const cairo_user_data_key_t key;
+
typedef struct _xlib_target_closure {
Display *dpy;
Drawable drawable;
@@ -215,6 +217,58 @@ _cairo_boilerplate_xlib_perf_create_surface (Display *dpy,
width, height);
}
+struct similar {
+ Display *dpy;
+ Pixmap pixmap;
+};
+
+static void _destroy_similar (void *closure)
+{
+ struct similar *similar = closure;
+
+ XFreePixmap (similar->dpy, similar->pixmap);
+ free (similar);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_xlib_create_similar (cairo_surface_t *other,
+ cairo_content_t content,
+ int width,
+ int height)
+{
+ XRenderPictFormat *xrender_format;
+ uint32_t format;
+ struct similar *similar;
+ cairo_surface_t *surface;
+
+ similar = malloc (sizeof (*similar));
+ similar->dpy = cairo_xlib_surface_get_display (other);
+
+ switch (content) {
+ default:
+ case CAIRO_CONTENT_COLOR_ALPHA: format = PictStandardARGB32; break;
+ case CAIRO_CONTENT_COLOR: format = PictStandardRGB24; break;
+ case CAIRO_CONTENT_ALPHA: format = PictStandardA8; break;
+ }
+
+ xrender_format = XRenderFindStandardFormat (similar->dpy, format);
+ similar->pixmap = XCreatePixmap (similar->dpy,
+ DefaultRootWindow (similar->dpy),
+ width, height,
+ xrender_format->depth);
+
+ surface =
+ cairo_xlib_surface_create_with_xrender_format (similar->dpy,
+ similar->pixmap,
+ DefaultScreenOfDisplay (similar->dpy),
+ xrender_format,
+ width, height);
+
+ cairo_surface_set_user_data (surface, &key, similar, _destroy_similar);
+
+ return surface;
+}
+
static cairo_surface_t *
_cairo_boilerplate_xlib_create_surface (const char *name,
cairo_content_t content,
@@ -511,6 +565,7 @@ static const cairo_boilerplate_target_t targets[] = {
CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR_ALPHA, 1,
"cairo_xlib_surface_create_with_xrender_format",
_cairo_boilerplate_xlib_create_surface,
+ _cairo_boilerplate_xlib_create_similar,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
@@ -524,6 +579,7 @@ static const cairo_boilerplate_target_t targets[] = {
CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1,
"cairo_xlib_surface_create_with_xrender_format",
_cairo_boilerplate_xlib_create_surface,
+ _cairo_boilerplate_xlib_create_similar,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
@@ -537,6 +593,7 @@ static const cairo_boilerplate_target_t targets[] = {
CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1,
"cairo_xlib_surface_create",
_cairo_boilerplate_xlib_window_create_surface,
+ cairo_surface_create_similar,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
@@ -554,6 +611,7 @@ static const cairo_boilerplate_target_t targets[] = {
CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1,
"cairo_xlib_surface_create",
_cairo_boilerplate_xlib_fallback_create_surface,
+ cairo_surface_create_similar,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
diff --git a/boilerplate/cairo-boilerplate.c b/boilerplate/cairo-boilerplate.c
index a77fa578a..b89e6d817 100644
--- a/boilerplate/cairo-boilerplate.c
+++ b/boilerplate/cairo-boilerplate.c
@@ -151,6 +151,35 @@ _cairo_boilerplate_image_create_surface (const char *name,
return cairo_image_surface_create (format, ceil (width), ceil (height));
}
+static const cairo_user_data_key_t key;
+
+static cairo_surface_t *
+_cairo_boilerplate_image_create_similar (cairo_surface_t *other,
+ cairo_content_t content,
+ int width, int height)
+{
+ cairo_format_t format;
+ cairo_surface_t *surface;
+ int stride;
+ void *ptr;
+
+ switch (content) {
+ case CAIRO_CONTENT_ALPHA: format = CAIRO_FORMAT_A8; break;
+ case CAIRO_CONTENT_COLOR: format = CAIRO_FORMAT_RGB24; break;
+ default:
+ case CAIRO_CONTENT_COLOR_ALPHA: format = CAIRO_FORMAT_ARGB32; break;
+ }
+
+ stride = cairo_format_stride_for_width(format, width);
+ ptr = malloc (stride* height);
+
+ surface = cairo_image_surface_create_for_data (ptr, format,
+ width, height, stride);
+ cairo_surface_set_user_data (surface, &key, ptr, free);
+
+ return surface;
+}
+
static cairo_surface_t *
_cairo_boilerplate_image16_create_surface (const char *name,
cairo_content_t content,
@@ -160,7 +189,7 @@ _cairo_boilerplate_image16_create_surface (const char *name,
double max_height,
cairo_boilerplate_mode_t mode,
int id,
- void **closure)
+ void **closure)
{
*closure = NULL;
@@ -168,6 +197,33 @@ _cairo_boilerplate_image16_create_surface (const char *name,
return cairo_image_surface_create (CAIRO_FORMAT_RGB16_565, ceil (width), ceil (height));
}
+static cairo_surface_t *
+_cairo_boilerplate_image16_create_similar (cairo_surface_t *other,
+ cairo_content_t content,
+ int width, int height)
+{
+ cairo_format_t format;
+ cairo_surface_t *surface;
+ int stride;
+ void *ptr;
+
+ switch (content) {
+ case CAIRO_CONTENT_ALPHA: format = CAIRO_FORMAT_A8; break;
+ case CAIRO_CONTENT_COLOR: format = CAIRO_FORMAT_RGB16_565; break;
+ default:
+ case CAIRO_CONTENT_COLOR_ALPHA: format = CAIRO_FORMAT_ARGB32; break;
+ }
+
+ stride = cairo_format_stride_for_width(format, width);
+ ptr = malloc (stride* height);
+
+ surface = cairo_image_surface_create_for_data (ptr, format,
+ width, height, stride);
+ cairo_surface_set_user_data (surface, &key, ptr, free);
+
+ return surface;
+}
+
static char *
_cairo_boilerplate_image_describe (void *closure)
{
@@ -334,7 +390,9 @@ static const cairo_boilerplate_target_t builtin_targets[] = {
{
"image", "image", NULL, NULL,
CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR_ALPHA, 0,
- NULL, _cairo_boilerplate_image_create_surface,
+ NULL,
+ _cairo_boilerplate_image_create_surface,
+ _cairo_boilerplate_image_create_similar,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
@@ -345,7 +403,9 @@ static const cairo_boilerplate_target_t builtin_targets[] = {
{
"image", "image", NULL, NULL,
CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR, 0,
- NULL, _cairo_boilerplate_image_create_surface,
+ NULL,
+ _cairo_boilerplate_image_create_surface,
+ _cairo_boilerplate_image_create_similar,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
@@ -356,7 +416,9 @@ static const cairo_boilerplate_target_t builtin_targets[] = {
{
"image16", "image", NULL, NULL,
CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR, 0,
- NULL, _cairo_boilerplate_image16_create_surface,
+ NULL,
+ _cairo_boilerplate_image16_create_surface,
+ _cairo_boilerplate_image16_create_similar,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
@@ -370,6 +432,7 @@ static const cairo_boilerplate_target_t builtin_targets[] = {
CAIRO_SURFACE_TYPE_RECORDING, CAIRO_CONTENT_COLOR_ALPHA, 0,
"cairo_recording_surface_create",
_cairo_boilerplate_recording_create_surface,
+ cairo_surface_create_similar,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
@@ -382,6 +445,7 @@ static const cairo_boilerplate_target_t builtin_targets[] = {
CAIRO_SURFACE_TYPE_RECORDING, CAIRO_CONTENT_COLOR, 0,
"cairo_recording_surface_create",
_cairo_boilerplate_recording_create_surface,
+ cairo_surface_create_similar,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
diff --git a/boilerplate/cairo-boilerplate.h b/boilerplate/cairo-boilerplate.h
index c0a045222..d145a1e1c 100644
--- a/boilerplate/cairo-boilerplate.h
+++ b/boilerplate/cairo-boilerplate.h
@@ -126,6 +126,12 @@ typedef cairo_surface_t *
int id,
void **closure);
+typedef cairo_surface_t *
+(*cairo_boilerplate_create_similar_t) (cairo_surface_t *other,
+ cairo_content_t content,
+ int width,
+ int height);
+
typedef void
(*cairo_boilerplate_force_fallbacks_t) (cairo_surface_t *surface,
double x_pixels_per_inch,
@@ -163,11 +169,12 @@ typedef struct _cairo_boilerplate_target {
unsigned int error_tolerance;
const char *probe; /* runtime dl check */
cairo_boilerplate_create_surface_t create_surface;
- cairo_boilerplate_force_fallbacks_t force_fallbacks;
+ cairo_boilerplate_create_similar_t create_similar;
+ cairo_boilerplate_force_fallbacks_t force_fallbacks;
cairo_boilerplate_finish_surface_t finish_surface;
cairo_boilerplate_get_image_surface_t get_image_surface;
cairo_boilerplate_write_to_png_t write_to_png;
- cairo_boilerplate_cleanup_t cleanup;
+ cairo_boilerplate_cleanup_t cleanup;
cairo_boilerplate_wait_t synchronize;
cairo_boilerplate_describe_t describe;
cairo_bool_t is_measurable;