diff options
author | Chad Versace <chad.versace@linux.intel.com> | 2012-04-06 13:23:13 -0700 |
---|---|---|
committer | Chad Versace <chad.versace@linux.intel.com> | 2012-05-23 21:57:10 -0700 |
commit | f63a777a4c025a0c074f42cbdf328cc5db30ef48 (patch) | |
tree | cd190116e962c838be89720b1edd90bc71bc4069 /src | |
parent | ed415cd9746674be5daceadd1a6fb00dfa3244e9 (diff) |
glut_waffle: Add libglut_waffle [v3]
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.
v3: Fix typo that set WAFFLE_ACCUM_BUFFER to false.
CC: Eric Anholt <eric@anholt.net>
Reviewed-by: Pauli Nieminen <pauli.nieminen@intel.com> [v1]
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com> [v1]
Reviewed-by: Anuj Phogat <anuj.phogat@gmail.com> [v1]
Signed-off-by: Chad Versace <chad.versace@linux.intel.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/glut_waffle/CMakeLists.no_api.txt | 6 | ||||
-rw-r--r-- | src/glut_waffle/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/glut_waffle/README.txt | 5 | ||||
-rw-r--r-- | src/glut_waffle/TODO.txt | 2 | ||||
-rw-r--r-- | src/glut_waffle/glut_waffle.c | 421 | ||||
-rw-r--r-- | src/glut_waffle/glut_waffle.h | 87 |
7 files changed, 526 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2a01ca056..cc3143a5f 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 000000000..b49965a9d --- /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 000000000..144a306f4 --- /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 000000000..a8fe20e37 --- /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 000000000..866382575 --- /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 000000000..60db674c5 --- /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, true); + } + + 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 000000000..0ac5ead25 --- /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@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); |