diff options
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 : |