summaryrefslogtreecommitdiffstatsci
diff options
context:
space:
mode:
authorBryce Harrington <bryce@osg.samsung.com>2017-12-01 20:11:12 -0800
committerBryce Harrington <bryce@osg.samsung.com>2017-12-01 20:19:53 -0800
commit45f67bf2ab96f15ef2d99848ef150128b3d44465 (patch)
tree4c122afb9043665a0a9c901efd93827a643b2b28
parente3c990e8ab999a26d24c28222738040546db5ab5 (diff)
Add XCB supportHEADmaster
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.txt24
-rw-r--r--CMakeScripts/Modules/FindXCB.cmake57
-rw-r--r--README6
-rw-r--r--config.h.cmake5
-rw-r--r--src/CMakeLists.txt12
-rw-r--r--src/cairo-xcb.cpp82
-rw-r--r--src/caskbench.cpp3
-rw-r--r--src/caskbench_context.cpp8
-rw-r--r--src/caskbench_context.h5
-rw-r--r--src/xcb.cpp117
-rw-r--r--src/xcb.h34
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)
diff --git a/README b/README
index 6738268..53f78eb 100644
--- a/README
+++ b/README
@@ -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 :