[Piglit] [PATCH] glut_waffle: Add libglut_waffle [v2]

Chad Versace chad.versace at linux.intel.com
Wed May 23 13:09:06 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.

v2: Remove else blocks in glutChooseConfig that just set default values,
    per Anholt.

Reviewed-by: Pauli Nieminen <pauli.nieminen at intel.com> [v1]
Reviewed-by: Jordan Justen <jordan.l.justen at intel.com> [v1]
Reviewed-by: Anuj Phogat <anuj.phogat at gmail.com> [v1]
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         |  421 +++++++++++++++++++++++++++++++++
 src/glut_waffle/glut_waffle.h         |   87 +++++++
 7 files changed, 526 insertions(+)
 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..efe0a3d
--- /dev/null
+++ b/src/glut_waffle/glut_waffle.c
@@ -0,0 +1,421 @@
+/*
+ * 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);
+	}
+
+	if (_glut->display_mode & (GLUT_ALPHA | GLUT_RGBA)) {
+		ADD_ATTR(WAFFLE_ALPHA_SIZE, 1);
+	}
+
+	if (_glut->display_mode & GLUT_DEPTH) {
+		ADD_ATTR(WAFFLE_DEPTH_SIZE, 1);
+	}
+
+	if (_glut->display_mode & GLUT_STENCIL) {
+		ADD_ATTR(WAFFLE_STENCIL_SIZE, 1);
+	}
+
+	if (!(_glut->display_mode & GLUT_DOUBLE)) {
+		ADD_ATTR(WAFFLE_DOUBLE_BUFFERED, false);
+	}
+
+	if (!(_glut->display_mode & GLUT_ACCUM)) {
+		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);
-- 
1.7.10.1



More information about the Piglit mailing list