diff options
| author | Bryce Harrington <bryce@osg.samsung.com> | 2017-12-01 20:11:12 -0800 |
|---|---|---|
| committer | Bryce Harrington <bryce@osg.samsung.com> | 2017-12-01 20:19:53 -0800 |
| commit | 45f67bf2ab96f15ef2d99848ef150128b3d44465 (patch) | |
| tree | 4c122afb9043665a0a9c901efd93827a643b2b28 /src | |
| parent | e3c990e8ab999a26d24c28222738040546db5ab5 (diff) | |
This adds an XCB backend and hooks it up for cairo (not skia... yet).
This is for doing performance comparisons of the GL backend against
"standard Cairo".
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 12 | ||||
| -rw-r--r-- | src/cairo-xcb.cpp | 82 | ||||
| -rw-r--r-- | src/caskbench.cpp | 3 | ||||
| -rw-r--r-- | src/caskbench_context.cpp | 8 | ||||
| -rw-r--r-- | src/caskbench_context.h | 5 | ||||
| -rw-r--r-- | src/xcb.cpp | 117 | ||||
| -rw-r--r-- | src/xcb.h | 34 |
7 files changed, 261 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 62d0482..a140ccc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,6 +20,12 @@ if (USE_EGL) ) endif (USE_EGL) +if (USE_XCB) + list(APPEND caskbench_SOURCES + xcb.cpp + ) +endif (USE_XCB) + if (USE_SKIA) file(GLOB skia_files skia-util.cpp @@ -34,6 +40,9 @@ if (USE_SKIA) if (USE_EGL) list(APPEND caskbench_SOURCES skia-egl.cpp) endif (USE_EGL) + if (USE_XCB) + list(APPEND caskbench_SOURCES skia-xcb.cpp) + endif (USE_XCB) endif (USE_SKIA) if (USE_CAIRO) @@ -50,6 +59,9 @@ if (USE_CAIRO) if (USE_EGL) list(APPEND caskbench_SOURCES cairo-egl.cpp) endif (USE_EGL) + if (USE_XCB) + list(APPEND caskbench_SOURCES cairo-xcb.cpp) + endif (USE_XCB) endif (USE_CAIRO) add_executable(generate_tests IMPORTED) diff --git a/src/cairo-xcb.cpp b/src/cairo-xcb.cpp new file mode 100644 index 0000000..7a67a54 --- /dev/null +++ b/src/cairo-xcb.cpp @@ -0,0 +1,82 @@ +/* + * Copyright 2017 © Samsung Research America, Silicon Valley + * + * Use of this source code is governed by the 3-Clause BSD license + * specified in the COPYING file included with this source code. + */ +#include <config.h> + +#include <err.h> +#include <stdlib.h> +#include <assert.h> + +#include <cairo.h> +#include <cairo-xcb.h> + +#include "xcb.h" +#include "device_config.h" + +static xcb_state_t *state; +static cairo_surface_t *cairo_surface; + +cairo_surface_t * +create_cairo_surface_xcb (const device_config_t& config) +{ + // TODO: This needs initted to 0 + state = (xcb_state_t*) malloc (sizeof (xcb_state_t)); + if (!state) { + warnx ("Out of memory\n"); + return NULL; + } + + if (!createXCBContextAndWindow(state, config.width, config.height)) { + cleanup_state_xcb(state); + errx (-1, "Could not create XCB context and window\n"); + } + + assert(state->xcb_window >= 0); + assert(state->xcb_connection); + assert(state->xcb_visual_type); + + // TODO: Do XCB-specific setup and surface creation + cairo_surface = cairo_xcb_surface_create( + state->xcb_connection, // XCB connection + state->xcb_window, // XCB drawable window + state->xcb_visual_type, // Visual to use for drawing to window + config.width, // Window width + config.height); // Window height + + // TODO: Set background, clear colors, etc. + + return cairo_surface; +} + +void +destroy_cairo_xcb(void) +{ + cleanup_state_xcb((void*)state); + + cairo_surface_finish(cairo_surface); + + // TODO: Do I need to destroy the surface here, or higher up? If here, then do I need to track + // cairo_surface in state? Uncommented, this causes a ref count fault, so it appears to + // already have been destroyed (maybe by _finish?) + //cairo_surface_destroy(cairo_surface); +} + +void +update_cairo_xcb(void) +{ + // TODO +} + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/caskbench.cpp b/src/caskbench.cpp index 6fe9823..2b12b32 100644 --- a/src/caskbench.cpp +++ b/src/caskbench.cpp @@ -113,6 +113,9 @@ print_surfaces_available() #if USE_EGL printf("egl\n"); #endif +#if USE_XCB + printf("xcb\n"); +#endif } static void diff --git a/src/caskbench_context.cpp b/src/caskbench_context.cpp index 50f9e1d..375d4e1 100644 --- a/src/caskbench_context.cpp +++ b/src/caskbench_context.cpp @@ -70,6 +70,14 @@ context_setup_cairo(caskbench_context_t *context, const device_config_t& config) #else errx(1, "egl unsupported in this build\n"); #endif + } else if (!strncmp(config.surface_type, "xcb", 3)) { +#if USE_XCB + context->setup_cairo = create_cairo_surface_xcb; + context->destroy_cairo = destroy_cairo_xcb; + context->update_cairo = update_cairo_xcb; +#else + errx(1, "xcb unsupported in this build\n"); +#endif } assert (context->setup_cairo); assert (context->destroy_cairo); diff --git a/src/caskbench_context.h b/src/caskbench_context.h index 691afc8..1351d8d 100644 --- a/src/caskbench_context.h +++ b/src/caskbench_context.h @@ -68,6 +68,11 @@ void destroy_skia_egl(); void update_skia_egl(); #endif +#if USE_XCB +cairo_surface_t * create_cairo_surface_xcb (const device_config_t& config); +void destroy_cairo_xcb(); +void update_cairo_xcb(); +#endif // Context initialization and management void context_init(caskbench_context_t *context, int size); diff --git a/src/xcb.cpp b/src/xcb.cpp new file mode 100644 index 0000000..4de34da --- /dev/null +++ b/src/xcb.cpp @@ -0,0 +1,117 @@ +/* + * Copyright 2017 © Samsung Research America, Silicon Valley + * + * Use of this source code is governed by the 3-Clause BSD license + * specified in the COPYING file included with this source code. + */ +#include <config.h> + +#include <err.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "xcb.h" +#include "device_config.h" + +bool +createXCBContextAndWindow(xcb_state_t *state, int width, int height) +{ + xcb_screen_t *screen; + uint32_t mask[2]; + const xcb_setup_t *setup; + xcb_visualtype_t *visual; + xcb_generic_event_t *event; + xcb_screen_iterator_t screen_iter; + xcb_depth_iterator_t depth_iter; + + // Set up XCB + state->xcb_connection = xcb_connect(NULL, &state->xcb_screen_number); + if (state->xcb_connection == NULL) { + warnx("Could not create XCB context\n"); + return false; + } else if (xcb_connection_has_error(state->xcb_connection)) { + warnx("Could not connect to X11 server\n"); + return false; + } + + // Set up screen + setup = xcb_get_setup(state->xcb_connection); + if (setup == NULL) { + warnx("Could not create XCB setup\n"); + return false; + } + screen_iter = xcb_setup_roots_iterator(setup); + for (; screen_iter.rem; --state->xcb_screen_number, xcb_screen_next(&screen_iter)) { + if (state->xcb_screen_number == 0) { + state->xcb_screen = screen_iter.data; + break; + } + } + if (state->xcb_screen == NULL) { + warnx("Could not create XCB screen\n"); + return false; + } + + // Create window + state->xcb_window = xcb_generate_id(state->xcb_connection); + mask[0] = 1; + mask[1] = XCB_EVENT_MASK_EXPOSURE; + xcb_create_window(state->xcb_connection, // XCB connection to X11 + XCB_COPY_FROM_PARENT, // Window's depth + state->xcb_window, // Window ID + state->xcb_screen->root, // Parent window + 20, 20, // X, Y position + width, // Window width + height, // Window height + 0, // Border width in pixels + XCB_WINDOW_CLASS_INPUT_OUTPUT, // Behavior class for window + state->xcb_screen->root_visual, // New window's visual id + XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK, // Mask type + mask); // Mask values list + xcb_map_window(state->xcb_connection, state->xcb_window); + xcb_flush(state->xcb_connection); + + // Get the visual + depth_iter = xcb_screen_allowed_depths_iterator(state->xcb_screen); + for (; depth_iter.rem; xcb_depth_next(&depth_iter)) { + xcb_visualtype_iterator_t visual_iter; + + visual_iter = xcb_depth_visuals_iterator(depth_iter.data); + for (; visual_iter.rem; xcb_visualtype_next(&visual_iter)) { + if (state->xcb_screen->root_visual == visual_iter.data->visual_id) { + state->xcb_visual_type = visual_iter.data; + return true; + } + } + } + + warnx("XCB internal error, could not find visual\n"); + xcb_disconnect(state->xcb_connection); + return false; +} + +void +destroyXCBContextAndWindow (xcb_state_t *state) +{ + xcb_disconnect(state->xcb_connection); +} + +void +cleanup_state_xcb (void *data) +{ + xcb_state_t *state = (xcb_state_t*)data; + destroyXCBContextAndWindow(state); + free(state); +} + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/xcb.h b/src/xcb.h new file mode 100644 index 0000000..0b807f4 --- /dev/null +++ b/src/xcb.h @@ -0,0 +1,34 @@ +/* + * Copyright 2017 © Samsung Research America, Silicon Valley + * + * Use of this source code is governed by the 3-Clause BSD license + * specified in the COPYING file included with this source code. + */ +#ifndef XCB_H_ // -*- mode: c++ -*- +#define XCB_H_ + +#include <xcb/xcb.h> + +typedef struct { + int xcb_screen_number; + xcb_screen_t *xcb_screen; + xcb_window_t xcb_window; + xcb_visualtype_t *xcb_visual_type; + xcb_connection_t *xcb_connection; +} xcb_state_t; + +bool createXCBContextAndWindow(xcb_state_t *state, int width, int height); +void destroyXCBContextAndWindow(xcb_state_t *state); +void cleanup_state_xcb(void *state); + +#endif // XCB_H_ +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : |