=== modified file 'src/main.cpp'
@@ -43,6 +43,8 @@
#include "native-state-drm.h"
#elif GLMARK2_USE_MIR
#include "native-state-mir.h"
+#elif GLMARK2_USE_WAYLAND
+#include "native-state-wayland.h"
#endif
#if GLMARK2_USE_EGL
@@ -196,6 +198,8 @@
NativeStateDRM native_state;
#elif GLMARK2_USE_MIR
NativeStateMir native_state;
+#elif GLMARK2_USE_WAYLAND
+ NativeStateWayland native_state;
#endif
#if GLMARK2_USE_EGL
=== added file 'src/native-state-wayland.cpp'
@@ -0,0 +1,261 @@
+/*
+ * Copyright © 2013 Rafal Mielniczuk
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Rafal Mielniczuk <rafal.mielniczuk2@gmail.com>
+ */
+
+#include "native-state-wayland.h"
+
+#include <cstring>
+#include <csignal>
+
+const struct wl_registry_listener NativeStateWayland::registry_listener_ = {
+ NativeStateWayland::registry_handle_global,
+ NativeStateWayland::registry_handle_global_remove
+};
+
+const struct wl_shell_surface_listener NativeStateWayland::shell_surface_listener_ = {
+ NativeStateWayland::shell_surface_handle_ping,
+ NativeStateWayland::shell_surface_handle_configure,
+ NativeStateWayland::shell_surface_handle_popup_done
+};
+
+const struct wl_output_listener NativeStateWayland::output_listener_ = {
+ NativeStateWayland::output_handle_geometry,
+ NativeStateWayland::output_handle_mode
+};
+
+volatile bool NativeStateWayland::should_quit_ = false;
+
+NativeStateWayland::NativeStateWayland() : display_(0), window_(0)
+{
+}
+
+NativeStateWayland::~NativeStateWayland()
+{
+ wl_shell_surface_destroy(window_->shell_surface);
+ wl_surface_destroy(window_->surface);
+ wl_egl_window_destroy(window_->native);
+ delete window_;
+
+ wl_shell_destroy(display_->shell);
+ for (OutputsVector::iterator it = display_->outputs.begin();
+ it != display_->outputs.end(); ++it) {
+
+ wl_output_destroy((*it)->output);
+ delete *it;
+ }
+ wl_compositor_destroy(display_->compositor);
+ wl_registry_destroy(display_->registry);
+ wl_display_flush(display_->display);
+ wl_display_disconnect(display_->display);
+ delete display_;
+}
+
+void
+NativeStateWayland::registry_handle_global(void *data, struct wl_registry *registry,
+ uint32_t id, const char *interface,
+ uint32_t /*version*/)
+{
+ NativeStateWayland *that = static_cast<NativeStateWayland *>(data);
+ if (strcmp(interface, "wl_compositor") == 0) {
+ that->display_->compositor =
+ static_cast<struct wl_compositor *>(
+ wl_registry_bind(registry,
+ id, &wl_compositor_interface, 1));
+ } else if (strcmp(interface, "wl_shell") == 0) {
+ that->display_->shell =
+ static_cast<struct wl_shell *>(
+ wl_registry_bind(registry,
+ id, &wl_shell_interface, 1));
+ } else if (strcmp(interface, "wl_output") == 0) {
+ struct my_output *my_output = new struct my_output;
+ memset(my_output, 0, sizeof(*my_output));
+ my_output->output =
+ static_cast<struct wl_output *>(
+ wl_registry_bind(registry,
+ id, &wl_output_interface, 1));
+ that->display_->outputs.push_back(my_output);
+
+ wl_output_add_listener(my_output->output, &output_listener_, my_output);
+ wl_display_roundtrip(that->display_->display);
+ }
+}
+
+void
+NativeStateWayland::registry_handle_global_remove(void * /*data*/,
+ struct wl_registry * /*registry*/,
+ uint32_t /*name*/)
+{
+}
+
+void
+NativeStateWayland::output_handle_geometry(void * /*data*/, struct wl_output * /*wl_output*/,
+ int32_t /*x*/, int32_t /*y*/, int32_t /*physical_width*/,
+ int32_t /*physical_height*/, int32_t /*subpixel*/,
+ const char * /*make*/, const char * /*model*/,
+ int32_t /*transform*/)
+{
+}
+
+void
+NativeStateWayland::output_handle_mode(void *data, struct wl_output * /*wl_output*/,
+ uint32_t /*flags*/, int32_t width, int32_t height,
+ int32_t refresh)
+{
+ struct my_output *my_output = static_cast<struct my_output *>(data);
+ my_output->width = width;
+ my_output->height = height;
+ my_output->refresh = refresh;
+}
+
+void
+NativeStateWayland::shell_surface_handle_ping(void * /*data*/, struct wl_shell_surface *shell_surface,
+ uint32_t serial)
+{
+ wl_shell_surface_pong(shell_surface, serial);
+}
+
+void
+NativeStateWayland::shell_surface_handle_popup_done(void * /*data*/,
+ struct wl_shell_surface * /*shell_surface*/)
+{
+}
+
+void
+NativeStateWayland::shell_surface_handle_configure(void *data, struct wl_shell_surface * /*shell_surface*/,
+ uint32_t /*edges*/, int32_t width, int32_t height)
+{
+ NativeStateWayland *that = static_cast<NativeStateWayland *>(data);
+ that->window_->properties.width = width;
+ that->window_->properties.height = height;
+ wl_egl_window_resize(that->window_->native, width, height, 0, 0);
+}
+
+bool
+NativeStateWayland::init_display()
+{
+ struct sigaction sa;
+ sa.sa_handler = &NativeStateWayland::quit_handler;
+ sa.sa_flags = 0;
+ sigemptyset(&sa.sa_mask);
+
+ sigaction(SIGINT, &sa, NULL);
+ sigaction(SIGTERM, &sa, NULL);
+
+ display_ = new struct my_display;
+
+ if (!display_) {
+ return false;
+ }
+
+ display_->display = wl_display_connect(NULL);
+
+ if (!display_->display) {
+ return false;
+ }
+
+ display_->registry = wl_display_get_registry(display_->display);
+
+ wl_registry_add_listener(display_->registry, ®istry_listener_, this);
+
+ wl_display_roundtrip(display_->display);
+
+ return true;
+}
+
+void*
+NativeStateWayland::display()
+{
+ return static_cast<void *>(display_->display);
+}
+
+bool
+NativeStateWayland::create_window(WindowProperties const& properties)
+{
+ struct my_output *output = 0;
+ if (!display_->outputs.empty()) output = display_->outputs.at(0);
+ window_ = new struct my_window;
+ window_->properties = properties;
+ window_->surface = wl_compositor_create_surface(display_->compositor);
+ if (window_->properties.fullscreen && output) {
+ window_->native = wl_egl_window_create(window_->surface,
+ output->width, output->height);
+ window_->properties.width = output->width;
+ window_->properties.height = output->height;
+ } else {
+ window_->native = wl_egl_window_create(window_->surface,
+ properties.width, properties.height);
+ }
+ window_->shell_surface = wl_shell_get_shell_surface(display_->shell,
+ window_->surface);
+
+ if (window_->shell_surface) {
+ wl_shell_surface_add_listener(window_->shell_surface,
+ &shell_surface_listener_, this);
+ }
+
+ wl_shell_surface_set_title(window_->shell_surface, "glmark2");
+
+ if (window_->properties.fullscreen) {
+ wl_shell_surface_set_fullscreen(window_->shell_surface,
+ WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER,
+ output->refresh, output->output);
+ } else {
+ wl_shell_surface_set_toplevel(window_->shell_surface);
+ }
+
+ return true;
+}
+
+void*
+NativeStateWayland::window(WindowProperties &properties)
+{
+ if (window_) {
+ properties = window_->properties;
+ return window_->native;
+ }
+
+ return 0;
+}
+
+void
+NativeStateWayland::visible(bool /*v*/)
+{
+}
+
+bool
+NativeStateWayland::should_quit()
+{
+ return should_quit_;
+}
+
+void
+NativeStateWayland::flip()
+{
+ int ret = wl_display_dispatch(display_->display);
+ should_quit_ = (ret == -1) || should_quit_;
+}
+
+void
+NativeStateWayland::quit_handler(int /*signum*/)
+{
+ should_quit_ = true;
+}
+
=== added file 'src/native-state-wayland.h'
@@ -0,0 +1,138 @@
+/*
+ * Copyright © 2013 Rafal Mielniczuk
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Rafal Mielniczuk <rafal.mielniczuk2@gmail.com>
+ */
+
+#ifndef GLMARK2_NATIVE_STATE_WAYLAND_H_
+#define GLMARK2_NATIVE_STATE_WAYLAND_H_
+
+#include <vector>
+#include <wayland-client.h>
+#include <wayland-egl.h>
+
+#include "native-state.h"
+
+class NativeStateWayland : public NativeState
+{
+public:
+ NativeStateWayland();
+ ~NativeStateWayland();
+
+ bool init_display();
+ void* display();
+ bool create_window(WindowProperties const& properties);
+ void* window(WindowProperties& properties);
+ void visible(bool v);
+ bool should_quit();
+ void flip();
+
+private:
+ static void quit_handler(int signum);
+
+ static const struct wl_registry_listener registry_listener_;
+ static const struct wl_shell_surface_listener shell_surface_listener_;
+ static const struct wl_output_listener output_listener_;
+
+ static void
+ registry_handle_global(void *data, struct wl_registry *registry,
+ uint32_t id, const char *interface,
+ uint32_t version);
+ static void
+ registry_handle_global_remove(void *data, struct wl_registry *registry,
+ uint32_t name);
+
+ static void
+ output_handle_geometry(void *data, struct wl_output *wl_output,
+ int32_t x, int32_t y, int32_t physical_width,
+ int32_t physical_height, int32_t subpixel,
+ const char *make, const char *model,
+ int32_t transform);
+
+ static void
+ output_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags,
+ int32_t width, int32_t height, int32_t refresh);
+
+ static void
+ shell_surface_handle_ping(void *data, struct wl_shell_surface *shell_surface,
+ uint32_t serial);
+ static void
+ shell_surface_handle_configure(void *data,
+ struct wl_shell_surface *shell_surface,
+ uint32_t edges,
+ int32_t width, int32_t height);
+ static void
+ shell_surface_handle_popup_done(void *data,
+ struct wl_shell_surface *shell_surface);
+
+ static void
+ keyboard_handle_keymap(void *data, struct wl_keyboard *wl_keyboard,
+ uint32_t format, int32_t fd, uint32_t size);
+
+ static void
+ keyboard_handle_enter(void *data, struct wl_keyboard *wl_keyboard,
+ uint32_t serial, struct wl_surface *surface,
+ struct wl_array *keys);
+
+ static void
+ keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard,
+ uint32_t serial, struct wl_surface *surface);
+
+ static void
+ keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard,
+ uint32_t serial, uint32_t time, uint32_t key,
+ uint32_t state);
+
+ static void
+ keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard,
+ uint32_t serial, uint32_t mods_depressed,
+ uint32_t mods_latched, uint32_t mods_locked,
+ uint32_t group);
+
+ static void
+ seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
+ uint32_t capabilities);
+
+ struct my_output {
+ wl_output *output;
+ int32_t width, height;
+ int32_t refresh;
+ };
+
+ typedef std::vector<struct my_output *> OutputsVector;
+
+ struct my_display {
+ wl_display *display;
+ wl_registry *registry;
+ wl_compositor *compositor;
+ wl_shell *shell;
+ OutputsVector outputs;
+ } *display_;
+
+ struct my_window {
+ WindowProperties properties;
+ struct wl_surface *surface;
+ struct wl_egl_window *native;
+ struct wl_shell_surface *shell_surface;
+ } *window_;
+
+ static volatile bool should_quit_;
+};
+
+#endif /* GLMARK2_NATIVE_STATE_WAYLAND_H_ */
=== modified file 'src/wscript_build'
@@ -14,7 +14,9 @@
'drm-gl' : ['canvas-generic.cpp', 'native-state-drm.cpp', 'gl-state-egl.cpp'],
'drm-glesv2' : ['canvas-generic.cpp', 'native-state-drm.cpp', 'gl-state-egl.cpp'],
'mir-gl' : ['canvas-generic.cpp', 'native-state-mir.cpp', 'gl-state-egl.cpp'],
- 'mir-glesv2' : ['canvas-generic.cpp', 'native-state-mir.cpp', 'gl-state-egl.cpp']
+ 'mir-glesv2' : ['canvas-generic.cpp', 'native-state-mir.cpp', 'gl-state-egl.cpp'],
+ 'wayland-gl' : ['canvas-generic.cpp', 'native-state-wayland.cpp', 'gl-state-egl.cpp'],
+ 'wayland-glesv2' : ['canvas-generic.cpp', 'native-state-wayland.cpp', 'gl-state-egl.cpp']
}
flavor_uselibs = {
'x11-gl' : ['x11', 'gl', 'matrix-gl'],
@@ -22,7 +24,9 @@
'drm-gl' : ['drm', 'gbm', 'egl', 'gl', 'matrix-gl'],
'drm-glesv2' : ['drm', 'gbm', 'egl', 'glesv2', 'matrix-gl'],
'mir-gl' : ['mirclient', 'egl', 'gl', 'matrix-gl'],
- 'mir-glesv2' : ['mirclient', 'egl', 'glesv2', 'matrix-gl']
+ 'mir-glesv2' : ['mirclient', 'egl', 'glesv2', 'matrix-gl'],
+ 'wayland-gl' : ['wayland-client', 'wayland-egl', 'egl', 'gl', 'matrix-gl'],
+ 'wayland-glesv2' : ['wayland-client', 'wayland-egl', 'egl', 'glesv2', 'matrix-gl']
}
flavor_defines = {
'x11-gl' : ['GLMARK2_USE_X11', 'GLMARK2_USE_GL', 'GLMARK2_USE_GLX'],
@@ -30,7 +34,9 @@
'drm-gl' : ['GLMARK2_USE_DRM', 'GLMARK2_USE_GL', 'GLMARK2_USE_EGL', '__GBM__'],
'drm-glesv2' : ['GLMARK2_USE_DRM', 'GLMARK2_USE_GLESv2', 'GLMARK2_USE_EGL', '__GBM__'],
'mir-gl' : ['GLMARK2_USE_MIR', 'GLMARK2_USE_GL', 'GLMARK2_USE_EGL'],
- 'mir-glesv2' : ['GLMARK2_USE_MIR', 'GLMARK2_USE_GLESv2', 'GLMARK2_USE_EGL']
+ 'mir-glesv2' : ['GLMARK2_USE_MIR', 'GLMARK2_USE_GLESv2', 'GLMARK2_USE_EGL'],
+ 'wayland-gl' : ['GLMARK2_USE_WAYLAND', 'GLMARK2_USE_GL', 'GLMARK2_USE_EGL'],
+ 'wayland-glesv2' : ['GLMARK2_USE_WAYLAND', 'GLMARK2_USE_GLESv2', 'GLMARK2_USE_EGL']
}
includes = ['.', 'scene-ideas', 'scene-terrain']
=== modified file 'wscript'
@@ -17,7 +17,9 @@
'drm-gl' : 'glmark2-drm',
'drm-glesv2' : 'glmark2-es2-drm',
'mir-gl' : 'glmark2-mir',
- 'mir-glesv2' : 'glmark2-es2-mir'
+ 'mir-glesv2' : 'glmark2-es2-mir',
+ 'wayland-gl' : 'glmark2-wayland',
+ 'wayland-glesv2' : 'glmark2-es2-wayland'
}
FLAVORS_STR = ", ".join(FLAVORS.keys())
@@ -104,7 +106,9 @@
('glesv2', 'glesv2', list_contains(Options.options.flavors, 'glesv2$')),
('libdrm','drm', list_contains(Options.options.flavors, 'drm')),
('gbm','gbm', list_contains(Options.options.flavors, 'drm')),
- ('mirclient','mirclient', list_contains(Options.options.flavors, 'mir'))]
+ ('mirclient','mirclient', list_contains(Options.options.flavors, 'mir')),
+ ('wayland-client','wayland-client', list_contains(Options.options.flavors, 'wayland')),
+ ('wayland-egl','wayland-egl', list_contains(Options.options.flavors, 'wayland'))]
for (pkg, uselib, mandatory) in opt_pkgs:
ctx.check_cfg(package = pkg, uselib_store = uselib,
args = '--cflags --libs', mandatory = mandatory)