[Piglit] [PATCH 11/14] glut_waffle: Add libglut_waffle
Chad Versace
chad.versace at linux.intel.com
Mon May 21 23:15:19 PDT 2012
This patch adds libglut_waffle to the build. No tests use it yet.
glut_waffle is an implementation of the subset of GLUT used by Piglit.
glut_waffle is transitionary only and not intended to be a permanent
addition to Piglit. Its purpose is to make Piglit's transition from GLUT
to Waffle go smoothly. Once the transition is complete, piglit-framework.c
will be updated to use Waffle directly, and libglut_waffle will be
removed.
Signed-off-by: Chad Versace <chad.versace at linux.intel.com>
---
src/CMakeLists.txt | 4 +
src/glut_waffle/CMakeLists.no_api.txt | 6 +
src/glut_waffle/CMakeLists.txt | 1 +
src/glut_waffle/README.txt | 5 +
src/glut_waffle/TODO.txt | 2 +
src/glut_waffle/glut_waffle.c | 436 +++++++++++++++++++++++++++++++++
src/glut_waffle/glut_waffle.h | 87 +++++++
tests/util/piglit-framework-fbo.c | 15 +-
8 files changed, 546 insertions(+), 10 deletions(-)
create mode 100644 src/glut_waffle/CMakeLists.no_api.txt
create mode 100644 src/glut_waffle/CMakeLists.txt
create mode 100644 src/glut_waffle/README.txt
create mode 100644 src/glut_waffle/TODO.txt
create mode 100644 src/glut_waffle/glut_waffle.c
create mode 100644 src/glut_waffle/glut_waffle.h
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 2a01ca0..cc3143a 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,3 +1,7 @@
+if(USE_WAFFLE)
+ add_subdirectory(glut_waffle)
+endif(USE_WAFFLE)
+
if(OPENGL_egl_LIBRARY)
add_subdirectory(glut_egl)
endif(OPENGL_egl_LIBRARY)
diff --git a/src/glut_waffle/CMakeLists.no_api.txt b/src/glut_waffle/CMakeLists.no_api.txt
new file mode 100644
index 0000000..b49965a
--- /dev/null
+++ b/src/glut_waffle/CMakeLists.no_api.txt
@@ -0,0 +1,6 @@
+include_directories(${WAFFLE_INCLUDE_DIR})
+link_libraries(${WAFFLE_waffle_LIBRARY})
+
+add_library(glut_waffle SHARED
+ glut_waffle.c
+ )
diff --git a/src/glut_waffle/CMakeLists.txt b/src/glut_waffle/CMakeLists.txt
new file mode 100644
index 0000000..144a306
--- /dev/null
+++ b/src/glut_waffle/CMakeLists.txt
@@ -0,0 +1 @@
+piglit_include_target_api()
diff --git a/src/glut_waffle/README.txt b/src/glut_waffle/README.txt
new file mode 100644
index 0000000..a8fe20e
--- /dev/null
+++ b/src/glut_waffle/README.txt
@@ -0,0 +1,5 @@
+glut_waffle is transitionary only and not intended to be a permanent
+addition to Piglit. Its purpose is to make Piglit's transition from GLUT
+to Waffle go smoothly. Once the transition is complete, piglit-framework.c
+will be updated to use Waffle directly, and libglut_waffle will be
+removed.
diff --git a/src/glut_waffle/TODO.txt b/src/glut_waffle/TODO.txt
new file mode 100644
index 0000000..8663825
--- /dev/null
+++ b/src/glut_waffle/TODO.txt
@@ -0,0 +1,2 @@
+* Support basic input.
+* Support multiple windows.
diff --git a/src/glut_waffle/glut_waffle.c b/src/glut_waffle/glut_waffle.c
new file mode 100644
index 0000000..033f064
--- /dev/null
+++ b/src/glut_waffle/glut_waffle.c
@@ -0,0 +1,436 @@
+/*
+ * Copyright 2012 Intel Corporation
+ * Copyright 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "glut_waffle.h"
+
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include <EGL/egl.h>
+#include <waffle/waffle.h>
+
+extern int piglit_automatic;
+
+struct glut_waffle_window;
+
+struct glut_waffle_state {
+ /** \brief One of `WAFFLE_PLATFORM_*`. */
+ int waffle_platform;
+
+ /** \brief One of `WAFFLE_CONTEXT_OPENGL*`.
+ *
+ * The default value is `WAFFLE_CONTEXT_OPENGL`. To change the value,
+ * call glutInitAPIMask().
+ */
+ int waffle_context_api;
+
+ /** \brief A bitmask of enum glut_display_mode`. */
+ int display_mode;
+
+ int window_width;
+ int window_height;
+
+ int verbose;
+ int init_time;
+
+ GLUT_EGLidleCB idle_cb;
+
+ struct waffle_display *display;
+ struct waffle_context *context;
+ struct glut_window *window;
+
+ int redisplay;
+ int window_id_pool;
+};
+
+static struct glut_waffle_state _glut_waffle_state = {
+ .display_mode = GLUT_RGB,
+ .window_width = 300,
+ .window_height = 300,
+ .verbose = 0,
+ .window_id_pool = 0,
+};
+
+static struct glut_waffle_state *const _glut = &_glut_waffle_state;
+
+struct glut_window {
+ struct waffle_window *waffle;
+
+ int id;
+
+ GLUT_EGLreshapeCB reshape_cb;
+ GLUT_EGLdisplayCB display_cb;
+ GLUT_EGLkeyboardCB keyboard_cb;
+ GLUT_EGLspecialCB special_cb;
+};
+
+static void
+glutFatal(char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+
+ fflush(stdout);
+ fprintf(stderr, "glut_waffle: ");
+ vfprintf(stderr, format, args);
+ va_end(args);
+ putc('\n', stderr);
+
+ exit(1);
+}
+
+/** Return current time (in milliseconds). */
+static int
+glutNow(void)
+{
+ struct timeval tv;
+#ifdef __VMS
+ (void) gettimeofday(&tv, NULL );
+#else
+ struct timezone tz;
+ (void) gettimeofday(&tv, &tz);
+#endif
+ return tv.tv_sec * 1000 + tv.tv_usec / 1000;
+}
+
+void
+glutInitAPIMask(int mask)
+{
+ switch (mask) {
+ case GLUT_OPENGL_BIT:
+ _glut->waffle_context_api = WAFFLE_CONTEXT_OPENGL;
+ break;
+ case GLUT_OPENGL_ES1_BIT:
+ _glut->waffle_context_api = WAFFLE_CONTEXT_OPENGL_ES1;
+ break;
+ case GLUT_OPENGL_ES2_BIT:
+ _glut->waffle_context_api = WAFFLE_CONTEXT_OPENGL_ES2;
+ break;
+ default:
+ glutFatal("api_mask has bad value %#x", mask);
+ break;
+ }
+}
+
+void
+glutInit(int *argcp, char **argv)
+{
+ const char *piglit_platform;
+ const char *display_name = NULL;
+ bool ok = true;
+ int i;
+
+ int32_t waffle_init_attrib_list[] = {
+ WAFFLE_PLATFORM, 0x31415925,
+ 0,
+ };
+
+ for (i = 1; i < *argcp; i++) {
+ if (strcmp(argv[i], "-display") == 0)
+ display_name = argv[++i];
+ else if (strcmp(argv[i], "-info") == 0) {
+ printf("waffle_glut: ignoring -info\n");
+ }
+ }
+
+ _glut->waffle_context_api = WAFFLE_CONTEXT_OPENGL;
+
+ piglit_platform = getenv("PIGLIT_PLATFORM");
+ if (piglit_platform == NULL) {
+ _glut->waffle_platform = WAFFLE_PLATFORM_GLX;
+ } else if (!strcmp(piglit_platform, "glx")) {
+ _glut->waffle_platform = WAFFLE_PLATFORM_GLX;
+ } else if (!strcmp(piglit_platform, "x11_egl")) {
+ _glut->waffle_platform = WAFFLE_PLATFORM_X11_EGL;
+ } else if (!strcmp(piglit_platform, "wayland")) {
+ _glut->waffle_platform = WAFFLE_PLATFORM_WAYLAND;
+ } else {
+ glutFatal("environment var PIGLIT_PLATFORM has bad "
+ "value \"%s\"", piglit_platform);
+ }
+
+ waffle_init_attrib_list[1] = _glut->waffle_platform;
+ ok = waffle_init(waffle_init_attrib_list);
+ if (!ok)
+ glutFatal("waffle_init() failed");
+
+ _glut->display = waffle_display_connect(display_name);
+ if (!_glut->display)
+ glutFatal("waffle_display_connect() failed");
+
+ _glut->init_time = glutNow();
+}
+
+void
+glutInitDisplayMode(unsigned int mode)
+{
+ _glut->display_mode = mode;
+}
+
+void
+glutInitWindowPosition(int x, int y)
+{
+ // empty
+}
+
+void
+glutInitWindowSize(int width, int height)
+{
+ _glut->window_width = width;
+ _glut->window_height = height;
+}
+
+static struct waffle_config*
+glutChooseConfig(void)
+{
+ struct waffle_config *config = NULL;
+ int32_t attrib_list[64];
+ int i = 0;
+
+ #define ADD_ATTR(name, value) \
+ do { \
+ attrib_list[i++] = name; \
+ attrib_list[i++] = value; \
+ } while (0)
+
+ ADD_ATTR(WAFFLE_CONTEXT_API, _glut->waffle_context_api);
+
+ if (_glut->display_mode & (GLUT_RGB | GLUT_RGBA)) {
+ ADD_ATTR(WAFFLE_RED_SIZE, 1);
+ ADD_ATTR(WAFFLE_GREEN_SIZE, 1);
+ ADD_ATTR(WAFFLE_BLUE_SIZE, 1);
+ } else {
+ ADD_ATTR(WAFFLE_RED_SIZE, WAFFLE_DONT_CARE);
+ ADD_ATTR(WAFFLE_GREEN_SIZE, WAFFLE_DONT_CARE);
+ ADD_ATTR(WAFFLE_BLUE_SIZE, WAFFLE_DONT_CARE);
+ }
+
+ if (_glut->display_mode & (GLUT_ALPHA | GLUT_RGBA)) {
+ ADD_ATTR(WAFFLE_ALPHA_SIZE, 1);
+ } else {
+ ADD_ATTR(WAFFLE_ALPHA_SIZE, WAFFLE_DONT_CARE);
+ }
+
+ if (_glut->display_mode & GLUT_DEPTH) {
+ ADD_ATTR(WAFFLE_DEPTH_SIZE, 1);
+ } else {
+ ADD_ATTR(WAFFLE_DEPTH_SIZE, WAFFLE_DONT_CARE);
+ }
+
+ if (_glut->display_mode & GLUT_STENCIL) {
+ ADD_ATTR(WAFFLE_STENCIL_SIZE, 1);
+ } else {
+ ADD_ATTR(WAFFLE_STENCIL_SIZE, WAFFLE_DONT_CARE);
+ }
+
+ if (_glut->display_mode & GLUT_DOUBLE) {
+ ADD_ATTR(WAFFLE_DOUBLE_BUFFERED, true);
+ } else {
+ ADD_ATTR(WAFFLE_DOUBLE_BUFFERED, false);
+ }
+
+ if (_glut->display_mode & GLUT_ACCUM) {
+ ADD_ATTR(WAFFLE_ACCUM_BUFFER, true);
+ } else {
+ ADD_ATTR(WAFFLE_ACCUM_BUFFER, false);
+ }
+
+ attrib_list[i++] = WAFFLE_NONE;
+
+
+ config = waffle_config_choose(_glut->display, attrib_list);
+ if (!config)
+ glutFatal("waffle_config_choose() failed");
+ return config;
+}
+
+int
+glutGet(int state)
+{
+ int val;
+
+ switch (state) {
+ case GLUT_ELAPSED_TIME:
+ val = glutNow() - _glut->init_time;
+ break;
+ default:
+ val = -1;
+ break;
+ }
+
+ return val;
+}
+
+void
+glutIdleFunc(GLUT_EGLidleCB func)
+{
+ _glut->idle_cb = func;
+}
+
+void
+glutPostRedisplay(void)
+{
+ _glut->redisplay = 1;
+}
+
+static void
+_glutDefaultKeyboard(unsigned char key, int x, int y)
+{
+ if (key == 27)
+ exit(0);
+}
+
+int
+glutCreateWindow(const char *title)
+{
+ bool ok = true;
+ struct waffle_config *config = NULL;
+
+ if (_glut->window)
+ glutFatal("cannot create window; one already exists");
+
+ config = glutChooseConfig();
+
+ _glut->context = waffle_context_create(config, NULL);
+ if (!_glut->context)
+ glutFatal("waffle_context_create() failed");
+
+ _glut->window = calloc(1, sizeof(*_glut->window));
+ if (!_glut->window)
+ glutFatal("out of memory");
+
+ _glut->window->waffle = waffle_window_create(config,
+ _glut->window_width,
+ _glut->window_height);
+ if (!_glut->window->waffle)
+ glutFatal("waffle_window_create() failed");
+
+ ok = waffle_make_current(_glut->display, _glut->window->waffle,
+ _glut->context);
+ if (!ok)
+ glutFatal("waffle_make_current() failed");
+
+ _glut->window->id = ++_glut->window_id_pool;
+ _glut->window->keyboard_cb = _glutDefaultKeyboard;
+
+ return _glut->window->id;
+}
+
+void
+glutDestroyWindow(int win)
+{
+ bool ok = true;
+
+ if (!_glut->window || _glut->window->id != win)
+ glutFatal("bad window id");
+
+ ok = waffle_window_destroy(_glut->window->waffle);
+ if (!ok)
+ glutFatal("waffle_window_destroy() failed");
+
+ free(_glut->window);
+ _glut->window = NULL;
+}
+
+void
+glutShowWindow(int win)
+{
+ bool ok = true;
+
+ if (!_glut->window || _glut->window->id != win)
+ glutFatal("bad window id");
+
+ ok = waffle_window_show(_glut->window->waffle);
+ if (!ok)
+ glutFatal("waffle_window_show() failed");
+}
+
+void
+glutDisplayFunc(GLUT_EGLdisplayCB func)
+{
+ _glut->window->display_cb = func;
+}
+
+void
+glutReshapeFunc(GLUT_EGLreshapeCB func)
+{
+ _glut->window->reshape_cb = func;
+}
+
+void
+glutKeyboardFunc(GLUT_EGLkeyboardCB func)
+{
+ _glut->window->keyboard_cb = func;
+}
+
+void
+glutSpecialFunc(GLUT_EGLspecialCB func)
+{
+ _glut->window->special_cb = func;
+}
+
+void
+glutMainLoop(void)
+{
+ bool ok = true;
+
+ if (!_glut->window)
+ glutFatal("no window is created");
+
+ ok = waffle_window_show(_glut->window->waffle);
+ if (!ok)
+ glutFatal("waffle_window_show() failed");
+
+ if (_glut->window->reshape_cb)
+ _glut->window->reshape_cb(_glut->window_width,
+ _glut->window_height);
+
+ if (_glut->window->display_cb)
+ _glut->window->display_cb();
+
+ if (_glut->window)
+ waffle_window_swap_buffers(_glut->window->waffle);
+
+ // FIXME: Tests run without -auto require basic input.
+
+ // Workaround for input:
+ // Since glut_waffle doesn't handle input yet, it sleeps in order to
+ // give the user a chance to see the test output. If the user wishes
+ // the test to sleep for a shorter or longer time, he can use Ctrl-C
+ // or Ctrl-Z.
+ sleep(20);
+}
+
+void
+glutSwapBuffers(void)
+{
+ bool ok = waffle_window_swap_buffers(_glut->window->waffle);
+ if (!ok)
+ glutFatal("waffle_window_swap_buffers() failed");
+}
diff --git a/src/glut_waffle/glut_waffle.h b/src/glut_waffle/glut_waffle.h
new file mode 100644
index 0000000..0ac5ead
--- /dev/null
+++ b/src/glut_waffle/glut_waffle.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv at lunarg.com>
+ */
+
+#pragma once
+
+enum glut_display_mode {
+ GLUT_RGB = 0,
+ GLUT_RGBA = 0,
+ GLUT_INDEX = 1,
+ GLUT_SINGLE = 0,
+ GLUT_DOUBLE = 2,
+ GLUT_ACCUM = 4,
+ GLUT_ALPHA = 8,
+ GLUT_DEPTH = 16,
+ GLUT_STENCIL = 32,
+};
+
+/* used by glutInitAPIMask */
+enum glut_api {
+ GLUT_OPENGL_BIT = 0x1,
+ GLUT_OPENGL_ES1_BIT = 0x2,
+ GLUT_OPENGL_ES2_BIT = 0x4,
+};
+
+/* used by glutGet */
+enum {
+ GLUT_ELAPSED_TIME,
+ GLUT_WINDOW_RED_SIZE,
+ GLUT_WINDOW_GREEN_SIZE,
+ GLUT_WINDOW_BLUE_SIZE,
+ GLUT_WINDOW_ALPHA_SIZE,
+};
+
+typedef void (*GLUT_EGLidleCB)(void);
+typedef void (*GLUT_EGLreshapeCB)(int, int);
+typedef void (*GLUT_EGLdisplayCB)(void);
+typedef void (*GLUT_EGLkeyboardCB)(unsigned char, int, int);
+typedef void (*GLUT_EGLspecialCB)(int, int, int);
+
+void glutInitAPIMask(int mask);
+void glutInitDisplayMode(unsigned int mode);
+void glutInitWindowPosition(int x, int y);
+void glutInitWindowSize(int width, int height);
+void glutInit(int *argcp, char **argv);
+
+int glutGet(int state);
+
+void glutIdleFunc(GLUT_EGLidleCB func);
+void glutPostRedisplay(void);
+
+void glutMainLoop(void);
+
+/**
+ * Create the window, but do not show it.
+ */
+int glutCreateWindow(const char *title);
+
+void glutDestroyWindow(int win);
+void glutShowWindow(int win);
+
+void glutDisplayFunc(GLUT_EGLdisplayCB func);
+void glutReshapeFunc(GLUT_EGLreshapeCB func);
+void glutKeyboardFunc(GLUT_EGLkeyboardCB func);
+void glutSpecialFunc(GLUT_EGLspecialCB func);
+void glutSwapBuffers(void);
diff --git a/tests/util/piglit-framework-fbo.c b/tests/util/piglit-framework-fbo.c
index 9dfceec..7c68b88 100644
--- a/tests/util/piglit-framework-fbo.c
+++ b/tests/util/piglit-framework-fbo.c
@@ -103,18 +103,13 @@ piglit_framework_fbo_glx_destroy(void)
static void
fatal_waffle_error(const char *func_name)
{
- int32_t error_code;
- const char *error_name;
- const char *message;
- size_t message_length;
-
- waffle_error_get_info(&error_code, &message, &message_length);
- error_name = waffle_error_to_string(error_code);
+ const struct waffle_error_info *info = waffle_error_get_info();
fflush(stdout);
- fprintf(stderr, "%s failed with error: %s", func_name, error_name);
- if (message_length > 0)
- fprintf(stderr, ": %s", message);
+ fprintf(stderr, "%s failed with error: %s", func_name,
+ waffle_error_to_string(info->code));
+ if (info->message_length)
+ fprintf(stderr, ": %s", info->message);
fprintf(stderr, "\n");
piglit_report_result(PIGLIT_FAIL);
--
1.7.10.1
More information about the Piglit
mailing list