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 | |
| 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".
| -rw-r--r-- | CMakeLists.txt | 24 | ||||
| -rw-r--r-- | CMakeScripts/Modules/FindXCB.cmake | 57 | ||||
| -rw-r--r-- | README | 6 | ||||
| -rw-r--r-- | config.h.cmake | 5 | ||||
| -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 |
11 files changed, 348 insertions, 5 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index acae6ac..1b7ad76 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,7 @@ option(ENABLE_SKIA "Build in skia tests" ON) option(ENABLE_CAIRO "Build in cairo tests" ON) option(ENABLE_GLX "Build against GLX for OpenGL" OFF) option(ENABLE_EGL "Build against EGL for OpenGL" ON) +option(ENABLE_XCB "Build against XCB for X11" ON) option(ENABLE_CAIROGLES "Use the cairogles fork API additions" OFF) # ---------------------------------------------------------------------- @@ -120,6 +121,28 @@ if (ENABLE_EGL) endif (EGL_LIBRARIES) endif (ENABLE_EGL) +set(USE_XCB 0) +if (ENABLE_XCB) + set(XCB_LIBRARIES "") + + find_package(XCB) + if (XCB_FOUND) + message("Using XCB libraries for X11") + list(APPEND CASKBENCH_INCS_SYS ${XCB_INCLUDE_DIRS}) + list(APPEND XCB_LIBRARIES ${XCB_LIBRARIES}) + check_include_files(xcb/xcb.h HAVE_XCB_H) + set(USE_XCB 1) + else (XCB_FOUND) + message("find_package did not find XCB") + endif (XCB_FOUND) + + if (XCB_LIBRARIES) + list(REMOVE_DUPLICATES XCB_LIBRARIES) + list(APPEND CASKBENCH_LIBS ${XCB_LIBRARIES}) + list(APPEND CASKBENCH_LIBS xcb) + endif (XCB_LIBRARIES) +endif (ENABLE_XCB) + # ---------------------------------------------------------------------- # Build # ---------------------------------------------------------------------- @@ -178,6 +201,7 @@ message("SKIA: ${ENABLE_SKIA} -> ${USE_SKIA}") message("CAIRO: ${ENABLE_CAIRO} -> ${USE_CAIRO}") message("GLX: ${ENABLE_GLX} -> ${USE_GLX}") message("EGL: ${ENABLE_EGL} -> ${USE_EGL}") +message("XCB: ${ENABLE_XCB} -> ${USE_XCB}") message("OPENGLES2: ${OPENGLES2_FOUND}") message("OPENGLES3: ${OPENGLES3_FOUND}") message("CAIROGLES: ${ENABLE_CAIROGLES}") diff --git a/CMakeScripts/Modules/FindXCB.cmake b/CMakeScripts/Modules/FindXCB.cmake new file mode 100644 index 0000000..2590ac6 --- /dev/null +++ b/CMakeScripts/Modules/FindXCB.cmake @@ -0,0 +1,57 @@ +#.rst: +# FindXCB +# ------- +# +# Find XCB libraries +# +# Tries to find xcb libraries on unix systems. +# +# - Be sure to set the COMPONENTS to the components you want to link to +# - The XCB_LIBRARIES variable is set ONLY to your COMPONENTS list +# - To use only a specific component check the XCB_LIBRARIES_${COMPONENT} variable +# +# The following values are defined +# +# :: +# +# XCB_FOUND - True if xcb is available +# XCB_INCLUDE_DIRS - Include directories for xcb +# XCB_LIBRARIES - List of libraries for xcb +# XCB_DEFINITIONS - List of definitions for xcb +# +#============================================================================= +# Copyright (c) 2015 Jari Vetoniemi +# +# Distributed under the OSI-approved BSD License (the "License"); +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= + +include(FeatureSummary) +set_package_properties(XCB PROPERTIES + URL "http://xcb.freedesktop.org/" + DESCRIPTION "X protocol C-language Binding") + +if (NOT XCB_FIND_COMPONENTS) + set(XCB_FIND_COMPONENTS xcb) +endif (NOT XCB_FIND_COMPONENTS) + +find_package(PkgConfig) +pkg_check_modules(PC_XCB QUIET xcb ${XCB_FIND_COMPONENTS}) + +find_library(XCB_LIBRARIES xcb HINTS ${PC_XCB_LIBRARY_DIRS}) +find_path(XCB_INCLUDE_DIRS xcb/xcb.h PATH_SUFFIXES xcb HINTS ${PC_XCB_INCLUDE_DIRS}) + +foreach(COMPONENT ${XCB_FIND_COMPONENTS}) + find_library(XCB_LIBRARIES_${COMPONENT} ${COMPONENT} HINTS ${PC_XCB_LIBRARY_DIRS}) + list(APPEND XCB_LIBRARIES ${XCB_LIBRARIES_${COMPONENT}}) + mark_as_advanced(XCB_LIBRARIES_${COMPONENT}) +endforeach(COMPONENT ${XCB_FIND_COMPONENTS}) + +set(XCB_DEFINITIONS ${PC_XCB_CFLAGS_OTHER}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(XCB DEFAULT_MSG XCB_LIBRARIES XCB_INCLUDE_DIRS) +mark_as_advanced(XCB_INCLUDE_DIRS XCB_LIBRARIES XCB_DEFINITIONS) @@ -17,11 +17,11 @@ optimization work to high level benchmarking of devices. == Building == -Prerequisites include popt and gles3. To install these on Ubuntu 13.04: +Prerequisites include popt, gles, and xcb. To install these on Ubuntu: - $ sudo apt-get install libpopt-dev libgles2-mesa-dev + $ sudo apt-get install libpopt-dev libgles2-mesa-dev libxcb1-dev -You will also need Skia and a GL-enabled version of libcairo installed. +You may also need Skia and a GL-enabled version of libcairo installed. These aren't packaged for Ubuntu currently, so you'll need to build from source. diff --git a/config.h.cmake b/config.h.cmake index 796b39b..685a400 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -8,8 +8,9 @@ #cmakedefine USE_SKIA 1 #cmakedefine USE_CAIRO 1 #cmakedefine USE_EGL 1 -#cmakedefine USE_GLX 0 -#cmakedefine USE_CAIROGLES 0 +#cmakedefine USE_GLX 1 +#cmakedefine USE_XCB 1 +#cmakedefine USE_CAIROGLES 1 #define PACKAGE "${PROJECT_NAME}" #define PACKAGE_NAME "${PROJECT_NAME}" 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 : |