blob: 0a9b64c4c7b7533db6f4aaf06bdf5a1a7bb48236 [file] [log] [blame]
From 94fc503c2764bc6cb2dcbf4c455705abd214091b Mon Sep 17 00:00:00 2001
From: Frank Henigman <fjhenigman@google.com>
Date: Wed, 1 Apr 2015 23:55:27 -0400
Subject: [PATCH 6/6] Add waffle backend.
Only WAFFLE_PLATFORM_NULL supported so far, though it shouldn't be hard
to make it work with any waffle platform.
---
src/gl-headers-waffle.h | 128 ++++++++++++++++++++++
src/gl-headers.h | 4 +
src/gl-state-waffle.cpp | 259 ++++++++++++++++++++++++++++++++++++++++++++
src/gl-state-waffle.h | 62 +++++++++++
src/main.cpp | 8 ++
src/native-state-waffle.cpp | 155 ++++++++++++++++++++++++++
src/native-state-waffle.h | 47 ++++++++
src/wscript_build | 12 +-
wscript | 2 +
9 files changed, 675 insertions(+), 2 deletions(-)
create mode 100644 src/gl-headers-waffle.h
create mode 100644 src/gl-state-waffle.cpp
create mode 100644 src/gl-state-waffle.h
create mode 100644 src/native-state-waffle.cpp
create mode 100644 src/native-state-waffle.h
diff --git a/src/gl-headers-waffle.h b/src/gl-headers-waffle.h
new file mode 100644
index 0000000..3efc67a
--- /dev/null
+++ b/src/gl-headers-waffle.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#ifndef GL_HEADERS_WAFFLE_H_
+#define GL_HEADERS_WAFFLE_H_
+
+#include <KHR/khrplatform.h>
+
+namespace hide_gles2 {
+// Can't use the function declarations in this header because we need to
+// declare them as pointers to be looked up with waffle, so hide them in
+// this namespace.
+// This way we still get all the #defines in the header.
+#include <GLES2/gl2.h>
+};
+
+// Unfortunately now these types are hidden and need to be exposed.
+using hide_gles2::GLbyte;
+using hide_gles2::GLclampf;
+using hide_gles2::GLfixed;
+using hide_gles2::GLshort;
+using hide_gles2::GLushort;
+using hide_gles2::GLvoid;
+using hide_gles2::GLsync;
+using hide_gles2::GLint64;
+using hide_gles2::GLuint64;
+using hide_gles2::GLenum;
+using hide_gles2::GLuint;
+using hide_gles2::GLchar;
+using hide_gles2::GLfloat;
+using hide_gles2::GLsizeiptr;
+using hide_gles2::GLintptr;
+using hide_gles2::GLbitfield;
+using hide_gles2::GLint;
+using hide_gles2::GLboolean;
+using hide_gles2::GLsizei;
+using hide_gles2::GLubyte;
+
+namespace waffle_hide {
+#define GLES2_FUNCTION_LIST(f) \
+f(void , glActiveTexture , (GLenum texture)) \
+f(void , glAttachShader , (GLuint program, GLuint shader)) \
+f(void , glBindBuffer , (GLenum target, GLuint buffer)) \
+f(void , glBindFramebuffer , (GLenum target, GLuint framebuffer)) \
+f(void , glBindRenderbuffer , (GLenum target, GLuint renderbuffer)) \
+f(void , glBindTexture , (GLenum target, GLuint texture)) \
+f(void , glBlendFunc , (GLenum sfactor, GLenum dfactor)) \
+f(void , glBlendFuncSeparate , (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha)) \
+f(void , glBufferData , (GLenum target, GLsizeiptr size, const void *data, GLenum usage)) \
+f(void , glBufferSubData , (GLenum target, GLintptr offset, GLsizeiptr size, const void *data)) \
+f(GLenum , glCheckFramebufferStatus , (GLenum target)) \
+f(void , glClearColor , (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)) \
+f(void , glClearDepthf , (GLfloat d)) \
+f(void , glClear , (GLbitfield mask)) \
+f(void , glColorMask , (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)) \
+f(void , glCompileShader , (GLuint shader)) \
+f(GLuint , glCreateProgram , (void)) \
+f(GLuint , glCreateShader , (GLenum type)) \
+f(void , glCullFace , (GLenum mode)) \
+f(void , glDeleteBuffers , (GLsizei n, const GLuint *buffers)) \
+f(void , glDeleteFramebuffers , (GLsizei n, const GLuint *framebuffers)) \
+f(void , glDeleteProgram , (GLuint program)) \
+f(void , glDeleteRenderbuffers , (GLsizei n, const GLuint *renderbuffers)) \
+f(void , glDeleteShader , (GLuint shader)) \
+f(void , glDeleteTextures , (GLsizei n, const GLuint *textures)) \
+f(void , glDepthFunc , (GLenum func)) \
+f(void , glDepthMask , (GLboolean flag)) \
+f(void , glDisable , (GLenum cap)) \
+f(void , glDisableVertexAttribArray, (GLuint index)) \
+f(void , glDrawArrays , (GLenum mode, GLint first, GLsizei count)) \
+f(void , glDrawElements , (GLenum mode, GLsizei count, GLenum type, const void *indices)) \
+f(void , glEnable , (GLenum cap)) \
+f(void , glEnableVertexAttribArray , (GLuint index)) \
+f(void , glFinish , (void)) \
+f(void , glFramebufferRenderbuffer , (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)) \
+f(void , glFramebufferTexture2D , (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)) \
+f(void , glGenBuffers , (GLsizei n, GLuint *buffers)) \
+f(void , glGenerateMipmap , (GLenum target)) \
+f(void , glGenFramebuffers , (GLsizei n, GLuint *framebuffers)) \
+f(void , glGenRenderbuffers , (GLsizei n, GLuint *renderbuffers)) \
+f(void , glGenTextures , (GLsizei n, GLuint *textures)) \
+f(GLint , glGetAttribLocation , (GLuint program, const GLchar *name)) \
+f(void , glGetBooleanv , (GLenum pname, GLboolean *data)) \
+f(GLenum , glGetError , (void)) \
+f(void , glGetIntegerv , (GLenum pname, GLint *data)) \
+f(void , glGetProgramInfoLog , (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog)) \
+f(void , glGetProgramiv , (GLuint program, GLenum pname, GLint *params)) \
+f(void , glGetShaderInfoLog , (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog)) \
+f(void , glGetShaderiv , (GLuint shader, GLenum pname, GLint *params)) \
+f(const GLubyte *, glGetString , (GLenum name)) \
+f(GLint , glGetUniformLocation , (GLuint program, const GLchar *name)) \
+f(GLboolean , glIsEnabled , (GLenum cap)) \
+f(void , glLinkProgram , (GLuint program)) \
+f(void , glReadPixels , (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels)) \
+f(void , glRenderbufferStorage , (GLenum target, GLenum internalformat, GLsizei width, GLsizei height)) \
+f(void , glShaderSource , (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length)) \
+f(void , glTexImage2D , (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels)) \
+f(void , glTexParameteri , (GLenum target, GLenum pname, GLint param)) \
+f(void , glUniform1f , (GLint location, GLfloat v0)) \
+f(void , glUniform1i , (GLint location, GLint v0)) \
+f(void , glUniform2fv , (GLint location, GLsizei count, const GLfloat *value)) \
+f(void , glUniform3fv , (GLint location, GLsizei count, const GLfloat *value)) \
+f(void , glUniform4fv , (GLint location, GLsizei count, const GLfloat *value)) \
+f(void , glUniformMatrix3fv , (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) \
+f(void , glUniformMatrix4fv , (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) \
+f(void , glUseProgram , (GLuint program)) \
+f(void , glVertexAttribPointer , (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer)) \
+f(void , glViewport , (GLint x, GLint y, GLsizei width, GLsizei height)) \
+
+
+#define DECLARE(type, func, args) extern type (*func) args;
+GLES2_FUNCTION_LIST(DECLARE)
+#undef DECLARE
+}; // end namespace waffle_hide
+using namespace waffle_hide;
+
+#endif // GL_HEADERS_WAFFLE_H_
diff --git a/src/gl-headers.h b/src/gl-headers.h
index 1d0527a..25b569b 100644
--- a/src/gl-headers.h
+++ b/src/gl-headers.h
@@ -31,7 +31,11 @@
#define GL_RGB565 0x8D62
#endif
#elif GLMARK2_USE_GLESv2
+#ifdef GLMARK2_USE_WAFFLE
+#include <gl-headers-waffle.h>
+#else
#include <GLES2/gl2.h>
+#endif
#include <GLES2/gl2ext.h>
#ifndef GL_WRITE_ONLY
#define GL_WRITE_ONLY GL_WRITE_ONLY_OES
diff --git a/src/gl-state-waffle.cpp b/src/gl-state-waffle.cpp
new file mode 100644
index 0000000..1b2cf40
--- /dev/null
+++ b/src/gl-state-waffle.cpp
@@ -0,0 +1,259 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#include "gl-state-waffle.h"
+#include "log.h"
+#include "options.h"
+#include "gl-headers.h"
+#include "limits.h"
+#include "gl-headers.h"
+#include <iomanip>
+#include <sstream>
+#include <waffle_null.h>
+
+using std::vector;
+using std::string;
+
+/*****************************
+ * GLStateWaffle public methods *
+ ****************************/
+
+bool
+GLStateWaffle::init_display(void* native_display, GLVisualConfig& visual_config)
+{
+ native_display_ = native_display;
+ requested_visual_config_ = visual_config;
+
+ return gotValidDisplay();
+}
+
+bool
+GLStateWaffle::init_surface(void* native_window)
+{
+ native_window_ = native_window;
+
+ return gotValidSurface();
+}
+
+void
+GLStateWaffle::init_gl_extensions()
+{
+#if GLMARK2_USE_GLESv2
+ if (GLExtensions::support("GL_OES_mapbuffer")) {
+ GLExtensions::MapBuffer =
+ reinterpret_cast<PFNGLMAPBUFFEROESPROC>(eglGetProcAddress("glMapBufferOES"));
+ GLExtensions::UnmapBuffer =
+ reinterpret_cast<PFNGLUNMAPBUFFEROESPROC>(eglGetProcAddress("glUnmapBufferOES"));
+ }
+#elif GLMARK2_USE_GL
+ GLExtensions::MapBuffer = glMapBuffer;
+ GLExtensions::UnmapBuffer = glUnmapBuffer;
+#endif
+}
+
+static void
+LogWaffleError(const char* msg)
+{
+ const struct waffle_error_info* info = waffle_error_get_info();
+ Log::error("%s - %s - %s\n", msg, info->message,
+ waffle_error_to_string(info->code));
+}
+
+bool
+GLStateWaffle::valid()
+{
+ if (!gotValidDisplay())
+ return false;
+
+ if (!gotValidConfig())
+ return false;
+
+ if (!gotValidSurface())
+ return false;
+
+ if (!gotValidContext())
+ return false;
+
+ if (!waffle_make_current(waffle_display_, waffle_surface_, waffle_context_)) {
+ LogWaffleError("waffle_make_current failed");
+ return false;
+ }
+
+ init_gl_extensions();
+
+ return true;
+}
+
+bool
+GLStateWaffle::reset()
+{
+ if (!gotValidDisplay()) {
+ return false;
+ }
+
+ if (!waffle_context_) {
+ return true;
+ }
+
+ if (!waffle_context_destroy(waffle_context_)) {
+ LogWaffleError("waffle_context_destroy failed");
+ }
+
+ waffle_context_ = 0;
+
+ return true;
+}
+
+void
+GLStateWaffle::swap()
+{
+ waffle_window_swap_buffers(waffle_surface_);
+}
+
+bool
+GLStateWaffle::gotNativeConfig(intptr_t& vid)
+{
+ if (!gotValidConfig())
+ return false;
+
+ vid = (intptr_t) waffle_config_;
+ return true;
+}
+
+void
+GLStateWaffle::getVisualConfig(GLVisualConfig& vc)
+{
+ if (!gotValidConfig())
+ return;
+
+ get_glvisualconfig(waffle_config_, vc);
+}
+
+/******************************
+ * GLStateWaffle private methods *
+ *****************************/
+
+bool
+GLStateWaffle::gotValidDisplay()
+{
+ if (waffle_display_)
+ return true;
+
+ waffle_display_ = (waffle_display*)native_display_;
+ if (!waffle_display_) {
+ Log::error("no native display - this shouldn't happen");
+ return false;
+ }
+
+ return true;
+}
+
+void
+GLStateWaffle::get_glvisualconfig(waffle_config* waffle_config, GLVisualConfig& visual_config)
+{
+ waffle_native_config *n = waffle_config_get_native(waffle_config);
+ /*
+ * NOTE: This works for WAFFLE_PLATFORM_NULL only.
+ * Other platforms will need something different.
+ */
+ EGLDisplay dpy = n->null->display.egl_display;
+ EGLConfig config = n->null->egl_config;
+
+ free(n);
+ eglGetConfigAttrib(dpy, config, EGL_BUFFER_SIZE, &visual_config.buffer);
+ eglGetConfigAttrib(dpy, config, EGL_RED_SIZE, &visual_config.red);
+ eglGetConfigAttrib(dpy, config, EGL_GREEN_SIZE, &visual_config.green);
+ eglGetConfigAttrib(dpy, config, EGL_BLUE_SIZE, &visual_config.blue);
+ eglGetConfigAttrib(dpy, config, EGL_ALPHA_SIZE, &visual_config.alpha);
+ eglGetConfigAttrib(dpy, config, EGL_DEPTH_SIZE, &visual_config.depth);
+ eglGetConfigAttrib(dpy, config, EGL_STENCIL_SIZE, &visual_config.stencil);
+}
+
+bool
+GLStateWaffle::gotValidConfig()
+{
+ if (waffle_config_)
+ return true;
+
+ if (!gotValidDisplay())
+ return false;
+
+ const int32_t config_attribs[] = {
+ WAFFLE_RED_SIZE, requested_visual_config_.red,
+ WAFFLE_GREEN_SIZE, requested_visual_config_.green,
+ WAFFLE_BLUE_SIZE, requested_visual_config_.blue,
+ WAFFLE_ALPHA_SIZE, requested_visual_config_.alpha,
+ WAFFLE_DEPTH_SIZE, requested_visual_config_.depth,
+ WAFFLE_STENCIL_SIZE, requested_visual_config_.stencil,
+#if GLMARK2_USE_GLESv2
+ WAFFLE_CONTEXT_API, WAFFLE_CONTEXT_OPENGL_ES2,
+#elif GLMARK2_USE_GL
+ WAFFLE_CONTEXT_API, WAFFLE_CONTEXT_OPENGL,
+#endif
+ WAFFLE_NONE
+ };
+
+ waffle_config_ = waffle_config_choose(waffle_display_, config_attribs);
+ if (!waffle_config_) {
+ LogWaffleError("waffle_config_choose failed");
+ return false;
+ }
+
+ return true;
+}
+
+bool
+GLStateWaffle::gotValidSurface()
+{
+ if (waffle_surface_)
+ return true;
+
+ if (!gotValidDisplay())
+ return false;
+
+ if (!gotValidConfig())
+ return false;
+
+ waffle_surface_ = (waffle_window*) native_window_;
+ if (!waffle_surface_) {
+ Log::error("no native window - this shouldn't happen");
+ return false;
+ }
+
+ return true;
+}
+
+bool
+GLStateWaffle::gotValidContext()
+{
+ if (waffle_context_)
+ return true;
+
+ if (!gotValidDisplay())
+ return false;
+
+ if (!gotValidConfig())
+ return false;
+
+ waffle_context_ = waffle_context_create(waffle_config_, NULL);
+ if (!waffle_context_) {
+ LogWaffleError("waffle_context_create failed");
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/gl-state-waffle.h b/src/gl-state-waffle.h
new file mode 100644
index 0000000..e66c079
--- /dev/null
+++ b/src/gl-state-waffle.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#ifndef GLMARK2_GL_STATE_WAFFLE_H_
+#define GLMARK2_GL_STATE_WAFFLE_H_
+
+#include <vector>
+#include <EGL/egl.h>
+#include <waffle.h>
+#include "gl-state.h"
+#include "gl-visual-config.h"
+
+class GLStateWaffle : public GLState
+{
+ void* native_display_;
+ void* native_window_;
+ waffle_display* waffle_display_;
+ waffle_config* waffle_config_;
+ waffle_context* waffle_context_;
+ waffle_window* waffle_surface_;
+ GLVisualConfig requested_visual_config_;
+ bool gotValidDisplay();
+ bool gotValidConfig();
+ bool gotValidSurface();
+ bool gotValidContext();
+ void get_glvisualconfig(waffle_config* config, GLVisualConfig& visual_config);
+ EGLConfig select_best_config(std::vector<EGLConfig>& configs);
+public:
+ GLStateWaffle() :
+ native_display_(0),
+ native_window_(0),
+ waffle_display_(0),
+ waffle_config_(0),
+ waffle_context_(0),
+ waffle_surface_(0) {}
+
+ bool init_display(void* native_display, GLVisualConfig& config_pref);
+ bool init_surface(void* native_window);
+ void init_gl_extensions();
+ bool valid();
+ bool reset();
+ void swap();
+ // Performs a config search, returning a native visual ID on success
+ bool gotNativeConfig(intptr_t& vid);
+ void getVisualConfig(GLVisualConfig& vc);
+};
+
+#endif // GLMARK2_GL_STATE_WAFFLE_H_
diff --git a/src/main.cpp b/src/main.cpp
index b84b827..d62bade 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -42,12 +42,16 @@
#include "native-state-mir.h"
#elif GLMARK2_USE_WAYLAND
#include "native-state-wayland.h"
+#elif GLMARK2_USE_WAFFLE
+#include "native-state-waffle.h"
#endif
#if GLMARK2_USE_EGL
#include "gl-state-egl.h"
#elif GLMARK2_USE_GLX
#include "gl-state-glx.h"
+#elif GLMARK2_USE_WAFFLE
+#include "gl-state-waffle.h"
#endif
using std::vector;
@@ -168,12 +172,16 @@ main(int argc, char *argv[])
NativeStateMir native_state;
#elif GLMARK2_USE_WAYLAND
NativeStateWayland native_state;
+#elif GLMARK2_USE_WAFFLE
+ NativeStateWaffle native_state;
#endif
#if GLMARK2_USE_EGL
GLStateEGL gl_state;
#elif GLMARK2_USE_GLX
GLStateGLX gl_state;
+#elif GLMARK2_USE_WAFFLE
+ GLStateWaffle gl_state;
#endif
CanvasGeneric canvas(native_state, gl_state, Options::size.first, Options::size.second);
diff --git a/src/native-state-waffle.cpp b/src/native-state-waffle.cpp
new file mode 100644
index 0000000..90e6c9e
--- /dev/null
+++ b/src/native-state-waffle.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#include "gl-headers-waffle.h"
+#include "native-state-waffle.h"
+#include "log.h"
+
+#include <waffle_null.h>
+
+namespace waffle_hide {
+#define DEFINE(type, func, args) type (*func) args;
+GLES2_FUNCTION_LIST(DEFINE)
+#undef DEFINE
+};
+
+/******************
+ * Public methods *
+ ******************/
+
+NativeStateWaffle::~NativeStateWaffle()
+{
+ if (wdpy_)
+ {
+ if (wwin_)
+ waffle_window_destroy(wwin_);
+
+ waffle_display_disconnect(wdpy_);
+ waffle_teardown();
+ }
+}
+
+bool
+NativeStateWaffle::init_display()
+{
+ if (!wdpy_) {
+ const int32_t attrib[] = {
+ WAFFLE_PLATFORM, WAFFLE_PLATFORM_NULL,
+ 0
+ };
+ if (!waffle_init(attrib))
+ return false;
+ wdpy_ = waffle_display_connect(NULL);
+ }
+
+#define LOOKUP(type, func, args) \
+ func = (type (*) args) waffle_dl_sym(WAFFLE_DL_OPENGL_ES2, #func); \
+ if (!func) \
+ return false;
+GLES2_FUNCTION_LIST(LOOKUP)
+#undef LOOKUP
+
+ return (wdpy_ != 0);
+}
+
+void*
+NativeStateWaffle::display()
+{
+ return (void*)wdpy_;
+}
+
+bool
+NativeStateWaffle::create_window(WindowProperties const& properties)
+{
+ if (!wdpy_) {
+ Log::error("Error: waffle display has not been initialized!\n");
+ return false;
+ }
+
+ /* Recreate an existing window only if it has actually been resized */
+ if (wwin_) {
+ if (properties_.fullscreen != properties.fullscreen ||
+ (properties.fullscreen == false &&
+ (properties_.width != properties.width ||
+ properties_.height != properties.height)))
+ {
+ waffle_window_destroy(wwin_);
+ wwin_ = 0;
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+ /* Set desired attributes */
+ properties_.fullscreen = properties.fullscreen;
+ properties_.visual_id = properties.visual_id;
+
+ intptr_t attrib[] = {
+ /*
+ * NOTE: This works for WAFFLE_PLATFORM_NULL only.
+ * Other platforms could call egl/glx-SwapInterval.
+ */
+ WAFFLE_WINDOW_NULL_VSYNC_WAIT, false,
+
+ WAFFLE_WINDOW_WIDTH, properties.width,
+ WAFFLE_WINDOW_HEIGHT, properties.height,
+ 0
+ };
+ if (properties_.fullscreen) {
+ attrib[2] = WAFFLE_WINDOW_FULLSCREEN;
+ attrib[3] = true;
+ attrib[4] = 0;
+ }
+
+ wwin_ = waffle_window_create2((waffle_config*) properties_.visual_id,
+ attrib);
+
+ if (!wwin_) {
+ Log::error("Error: waffle_window_create() failed!\n");
+ return false;
+ }
+
+ union waffle_native_window *nw = waffle_window_get_native(wwin_);
+ /*
+ * NOTE: This works for WAFFLE_PLATFORM_NULL only.
+ * Other platforms will need something different.
+ */
+ properties_.width = nw->null->width;
+ properties_.height = nw->null->height;
+
+ return true;
+}
+
+void*
+NativeStateWaffle::window(WindowProperties& properties)
+{
+ properties = properties_;
+ return (void*)wwin_;
+}
+
+void
+NativeStateWaffle::visible(bool visible)
+{
+ if (visible)
+ waffle_window_show(wwin_);
+}
+
+bool
+NativeStateWaffle::should_quit()
+{
+ return false;
+}
diff --git a/src/native-state-waffle.h b/src/native-state-waffle.h
new file mode 100644
index 0000000..1ea2f1b
--- /dev/null
+++ b/src/native-state-waffle.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#ifndef GLMARK2_NATIVE_STATE_WAFFLE_H_
+#define GLMARK2_NATIVE_STATE_WAFFLE_H_
+
+#include "native-state.h"
+#define WAFFLE_API_VERSION 0x0106
+#include <waffle.h>
+
+class NativeStateWaffle : public NativeState
+{
+public:
+ NativeStateWaffle() : wdpy_(0), wwin_(0), properties_() {}
+ ~NativeStateWaffle();
+
+ 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:
+ /** The waffle display associated with this canvas. */
+ waffle_display* wdpy_;
+ /** The waffle window associated with this canvas. */
+ waffle_window* wwin_;
+ WindowProperties properties_;
+};
+
+#endif /* GLMARK2_NATIVE_STATE_WAFFLE_H_ */
diff --git a/src/wscript_build b/src/wscript_build
index c0173c3..4082ade 100644
--- a/src/wscript_build
+++ b/src/wscript_build
@@ -15,6 +15,7 @@ flavor_sources = {
'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'],
+ 'waffle' : ['canvas-generic.cpp', 'native-state-waffle.cpp', 'gl-state-waffle.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']
}
@@ -25,6 +26,7 @@ flavor_uselibs = {
'drm-glesv2' : ['drm', 'gbm', 'egl', 'glesv2', 'matrix-gl'],
'mir-gl' : ['mirclient', 'egl', 'gl', 'matrix-gl'],
'mir-glesv2' : ['mirclient', 'egl', 'glesv2', 'matrix-gl'],
+ 'waffle' : ['waffle-1', 'egl', 'matrix-glesv2'],
'wayland-gl' : ['wayland-client', 'wayland-egl', 'egl', 'gl', 'matrix-gl'],
'wayland-glesv2' : ['wayland-client', 'wayland-egl', 'egl', 'glesv2', 'matrix-gl']
}
@@ -35,6 +37,7 @@ flavor_defines = {
'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'],
+ 'waffle' : ['GLMARK2_USE_WAFFLE', 'GLMARK2_USE_GLESv2'],
'wayland-gl' : ['GLMARK2_USE_WAYLAND', 'GLMARK2_USE_GL', 'GLMARK2_USE_EGL'],
'wayland-glesv2' : ['GLMARK2_USE_WAYLAND', 'GLMARK2_USE_GLESv2', 'GLMARK2_USE_EGL']
}
@@ -58,6 +61,11 @@ for name in bld.env.keys():
)
all_uselibs |= set(flavor_uselibs[flavor])
+
+matrix_defines = ['USE_EXCEPTIONS']
+if 'waffle' in flavor:
+ matrix_defines += ['GLMARK2_USE_WAFFLE']
+
if 'matrix-gl' in all_uselibs:
bld(
features = ['cxx', 'cxxstlib'],
@@ -66,7 +74,7 @@ if 'matrix-gl' in all_uselibs:
lib = ['m'],
includes = ['.'],
export_includes = 'libmatrix',
- defines = ['GLMARK2_USE_GL', 'USE_EXCEPTIONS']
+ defines = matrix_defines + ['GLMARK2_USE_GL']
)
if 'matrix-glesv2' in all_uselibs:
@@ -77,5 +85,5 @@ if 'matrix-glesv2' in all_uselibs:
lib = ['m'],
includes = ['.'],
export_includes = 'libmatrix',
- defines = ['GLMARK2_USE_GLESv2', 'USE_EXCEPTIONS']
+ defines = matrix_defines + ['GLMARK2_USE_GLESv2']
)
diff --git a/wscript b/wscript
index 7b0d1c2..e254118 100644
--- a/wscript
+++ b/wscript
@@ -18,6 +18,7 @@ FLAVORS = {
'drm-glesv2' : 'glmark2-es2-drm',
'mir-gl' : 'glmark2-mir',
'mir-glesv2' : 'glmark2-es2-mir',
+ 'waffle' : 'glmark2-waffle',
'wayland-gl' : 'glmark2-wayland',
'wayland-glesv2' : 'glmark2-es2-wayland'
}
@@ -117,6 +118,7 @@ def configure(ctx):
('libdrm','drm', list_contains(Options.options.flavors, 'drm')),
('gbm','gbm', list_contains(Options.options.flavors, 'drm')),
('mirclient','mirclient', list_contains(Options.options.flavors, 'mir')),
+ ('waffle-1', 'waffle-1', list_contains(Options.options.flavors, 'waffle')),
('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:
--
2.2.0.rc0.207.ga3a616c