From patchwork Thu Jul 21 12:36:33 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandros Frantzis X-Patchwork-Id: 2950 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id C844E23F4D for ; Thu, 21 Jul 2011 12:42:37 +0000 (UTC) Received: from mail-qw0-f52.google.com (mail-qw0-f52.google.com [209.85.216.52]) by fiordland.canonical.com (Postfix) with ESMTP id 7A1E4A18398 for ; Thu, 21 Jul 2011 12:42:37 +0000 (UTC) Received: by mail-qw0-f52.google.com with SMTP id 8so853237qwb.11 for ; Thu, 21 Jul 2011 05:42:37 -0700 (PDT) Received: by 10.229.68.200 with SMTP id w8mr190674qci.114.1311252157249; Thu, 21 Jul 2011 05:42:37 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.229.217.78 with SMTP id hl14cs139506qcb; Thu, 21 Jul 2011 05:42:37 -0700 (PDT) Received: by 10.227.176.65 with SMTP id bd1mr166175wbb.78.1311251796215; Thu, 21 Jul 2011 05:36:36 -0700 (PDT) Received: from adelie.canonical.com (adelie.canonical.com [91.189.90.139]) by mx.google.com with ESMTP id ev16si2368198wbb.129.2011.07.21.05.36.35; Thu, 21 Jul 2011 05:36:36 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.139 as permitted sender) client-ip=91.189.90.139; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.139 as permitted sender) smtp.mail=bounces@canonical.com Received: from loganberry.canonical.com ([91.189.90.37]) by adelie.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1QjsUU-0000D3-40 for ; Thu, 21 Jul 2011 12:36:34 +0000 Received: from loganberry.canonical.com (localhost [127.0.0.1]) by loganberry.canonical.com (Postfix) with ESMTP id 2AFA52E802E for ; Thu, 21 Jul 2011 12:36:33 +0000 (UTC) MIME-Version: 1.0 X-Launchpad-Project: glmark2 X-Launchpad-Branch: ~glmark2-dev/glmark2/trunk X-Launchpad-Message-Rationale: Subscriber X-Launchpad-Branch-Revision-Number: 43 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~glmark2-dev/glmark2/trunk] Rev 43: Add OpenGL ES 2.0 screen. Message-Id: <20110721123633.17019.36098.launchpad@loganberry.canonical.com> Date: Thu, 21 Jul 2011 12:36:33 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="13475"; Instance="initZopeless config overlay" X-Launchpad-Hash: efe1976e561b8b6193f3c8c9f83801f9655d7167 ------------------------------------------------------------ revno: 43 committer: Alexandros Frantzis timestamp: Mon 2010-07-12 16:37:04 +0300 message: Add OpenGL ES 2.0 screen. added: src/screen-sdl-glesv2.cpp src/screen-sdl-glesv2.h src/sdlgles/ src/sdlgles/SDL_gles.c src/sdlgles/SDL_gles.h src/sdlgles/attribs.inc modified: src/main.cpp src/screen-sdl-gl.cpp src/wscript_build wscript --- lp:glmark2 https://code.launchpad.net/~glmark2-dev/glmark2/trunk You are subscribed to branch lp:glmark2. To unsubscribe from this branch go to https://code.launchpad.net/~glmark2-dev/glmark2/trunk/+edit-subscription === modified file 'src/main.cpp' --- src/main.cpp 2010-07-12 12:15:52 +0000 +++ src/main.cpp 2010-07-12 13:37:04 +0000 @@ -1,7 +1,11 @@ #include "oglsdl.h" +#include "scene.h" +#if USE_GL #include "screen-sdl-gl.h" -#include "scene.h" +#elif USE_GLESv2 +#include "screen-sdl-glesv2.h" +#endif int main(int argc, char *argv[]) { @@ -10,7 +14,11 @@ unsigned current_scene = 0; // Create the screen +#if USE_GL ScreenSDLGL screen(800, 600, 24, 0); +#elif USE_GLESv2 + ScreenSDLGLESv2 screen(800, 600, 24, 0); +#endif if (!screen.mInitSuccess) { printf("Error: %s: Could not initialize screen\n", __FUNCTION__); === modified file 'src/screen-sdl-gl.cpp' --- src/screen-sdl-gl.cpp 2010-07-12 12:15:52 +0000 +++ src/screen-sdl-gl.cpp 2010-07-12 13:37:04 +0000 @@ -37,4 +37,3 @@ printf(" GL_RENDERER: %s\n", glGetString(GL_RENDERER)); printf(" GL_VERSION: %s\n", glGetString(GL_VERSION)); } - === added file 'src/screen-sdl-glesv2.cpp' --- src/screen-sdl-glesv2.cpp 1970-01-01 00:00:00 +0000 +++ src/screen-sdl-glesv2.cpp 2010-07-12 13:37:04 +0000 @@ -0,0 +1,60 @@ +#include "screen-sdl-glesv2.h" +#include "sdlgles/SDL_gles.h" + +ScreenSDLGLESv2::ScreenSDLGLESv2(int pWidth, int pHeight, int pBpp, int pFullScreen, int pFlags) + : ScreenSDL(pWidth, pHeight, pBpp, pFullScreen, pFlags | SDL_OPENGL) +{ + mInitSuccess = 0; + + if (SDL_GLES_Init(SDL_GLES_VERSION_2_0) < 0) { + fprintf(stderr, "[ Fail ] - GLES initialization failed: %s\n", SDL_GetError()); + } + + SDL_GLES_Context *context; + context = SDL_GLES_CreateContext(); + if (context == NULL) { + fprintf(stderr, "[ Fail ] - GLES create context: %s\n", SDL_GetError()); + return; + } + + if (SDL_GLES_MakeCurrent(context) != 0) { + fprintf(stderr, "[ Fail ] - GLES make context current: %s\n", SDL_GetError()); + return; + } + + glClearColor(0.0f, 0.0f, 0.0f, 0.5f); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + + glViewport(0, 0, mWidth, mHeight); + + clear(); + + mInitSuccess = 1; +} + +ScreenSDLGLESv2::~ScreenSDLGLESv2() +{ +} + + +void ScreenSDLGLESv2::clear() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +} + +void ScreenSDLGLESv2::update() +{ + SDL_GLES_SwapBuffers(); +} + +void ScreenSDLGLESv2::print_info() +{ + printf(" OpenGL Information\n"); + printf(" GL_VENDOR: %s\n", glGetString(GL_VENDOR)); + printf(" GL_RENDERER: %s\n", glGetString(GL_RENDERER)); + printf(" GL_VERSION: %s\n", glGetString(GL_VERSION)); +} + === added file 'src/screen-sdl-glesv2.h' --- src/screen-sdl-glesv2.h 1970-01-01 00:00:00 +0000 +++ src/screen-sdl-glesv2.h 2010-07-12 13:37:04 +0000 @@ -0,0 +1,17 @@ +#ifndef _SCREEN_SDL_GLESv2_H +#define _SCREEN_SDL_GLESv2_H + +#include "screen-sdl.h" + +class ScreenSDLGLESv2 : public ScreenSDL +{ +public: + ScreenSDLGLESv2(int pWidth, int pHeight, int pBpp, int pFullscreen, int pFlags = 0); + ~ScreenSDLGLESv2(); + + virtual void clear(); + virtual void update(); + virtual void print_info(); +}; + +#endif === added directory 'src/sdlgles' === added file 'src/sdlgles/SDL_gles.c' --- src/sdlgles/SDL_gles.c 1970-01-01 00:00:00 +0000 +++ src/sdlgles/SDL_gles.c 2010-07-12 13:37:04 +0000 @@ -0,0 +1,428 @@ +/* This file is part of SDL_gles - SDL addon for OpenGL|ES + * Copyright (C) 2010 Javier S. Pedro + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA or see . + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "SDL_gles.h" + +typedef struct SDL_GLES_ContextPriv +{ + SDL_GLES_Context p; + + EGLConfig egl_config; + EGLContext egl_context; +} SDL_GLES_ContextPriv; + +static const char * default_libgl[] = { + [SDL_GLES_VERSION_1_1] = "/usr/lib/libGLES_CM.so", + [SDL_GLES_VERSION_2_0] = "/usr/lib/libGLESv2.so" +}; + +/** SDL GFX display */ +static Display *display = NULL; +/** EGLDisplay for the above X11 display */ +static EGLDisplay *egl_display = EGL_NO_DISPLAY; +/** The current surface. Recreated by SDL_GLES_SetVideoMode(). */ +static EGLSurface egl_surface = EGL_NO_SURFACE; +/** A pointer to the current active context. */ +static SDL_GLES_ContextPriv *cur_context = NULL; + +/** The desired GLES version, as selected by the SDL_GLES_Init() call. */ +static SDL_GLES_Version gl_version = SDL_GLES_VERSION_NONE; +/** A handle to the dynamically loaded GL library. */ +static void* gl_handle = NULL; +/** EGL version. */ +static EGLint egl_major, egl_minor; + +/** Your average countof() macro. */ +#define countof(a) (sizeof(a)/sizeof(a[0])) + +/** List of EGLConfig attributes we care about; + * Used for filtering; modified by SDL_GLES_Get/SetAttribute(). */ +static EGLint attrib_list[] = { +#define A(number, attrib, default_value) \ + attrib, default_value, +#include "attribs.inc" +#undef A + EGL_NONE +}; +/** A enum which maps A_EGL_* attrib constants to attrib_list positions. */ +typedef enum { +#define A(number, attrib, default_value) \ + A_ ## attrib = (number * 2), +#include "attribs.inc" +#undef A +} attrib_enum; +static EGLint context_attrib_list[] = { + EGL_CONTEXT_CLIENT_VERSION, 1, + EGL_NONE +}; + +static const char * get_error_string(int error) { + switch (error) { + case EGL_SUCCESS: + return "EGL_SUCCESS"; + case EGL_NOT_INITIALIZED: + return "EGL_NOT_INITIALIZED"; + case EGL_BAD_ACCESS: + return "EGL_BAD_ACCESS"; + case EGL_BAD_ALLOC: + return "EGL_BAD_ALLOC"; + case EGL_BAD_ATTRIBUTE: + return "EGL_BAD_ATTRIBUTE"; + case EGL_BAD_CONFIG: + return "EGL_BAD_CONFIG"; + case EGL_BAD_CONTEXT: + return "EGL_BAD_CONTEXT"; + case EGL_BAD_CURRENT_SURFACE: + return "EGL_BAD_CURRENT_SURFACE"; + case EGL_BAD_DISPLAY: + return "EGL_BAD_DISPLAY"; + case EGL_BAD_MATCH: + return "EGL_BAD_MATCH"; + case EGL_BAD_NATIVE_PIXMAP: + return "EGL_BAD_NATIVE_PIXMAP"; + case EGL_BAD_NATIVE_WINDOW: + return "EGL_BAD_NATIVE_WINDOW"; + case EGL_BAD_PARAMETER: + return "EGL_BAD_PARAMETER"; + case EGL_BAD_SURFACE: + return "EGL_BAD_SURFACE"; + case EGL_CONTEXT_LOST: + return "EGL_CONTEXT_LOST"; + default: + return "EGL_UNKNOWN_ERROR"; + } +} + +static inline void set_egl_attrib(attrib_enum attrib, EGLint value) +{ + const unsigned int i = (unsigned int)attrib + 1; + assert(i < countof(attrib_list)); + attrib_list[i] = value; +} + +static inline EGLint get_egl_attrib(attrib_enum attrib) +{ + const unsigned int i = (unsigned int)attrib + 1; + assert(i < countof(attrib_list)); + return attrib_list[i]; +} + +static inline void set_egl_context_attrib(EGLenum attrib, EGLint value) +{ + /* Only one attribute supported here. */ + assert(attrib == EGL_CONTEXT_CLIENT_VERSION); + context_attrib_list[1] = value; +} + +int SDL_GLES_LoadLibrary(const char *path) +{ + /* If path is NULL, try first to use path from SDL_VIDEO_GL_DRIVER, + * otherwise use a sane default depending on selected GLES version. */ + if (!path) { + path = getenv("SDL_VIDEO_GL_DRIVER"); + if (!path) { + switch (gl_version) { + case SDL_GLES_VERSION_1_1: + case SDL_GLES_VERSION_2_0: + path = default_libgl[gl_version]; + break; + default: + SDL_SetError("No GL version specific and SDL_VIDEO_GL_DRIVER set"); + return -1; + } + } + } + + /* Dynamically load the desired GL library */ + gl_handle = dlopen(path, RTLD_LAZY|RTLD_GLOBAL); + if (!gl_handle) { + SDL_SetError("Failed to open GL library: %s (%s)", path, dlerror()); + return -2; + } + + return 0; +} + +void* SDL_GLES_GetProcAddress(const char *proc) +{ + if (!gl_handle) return NULL; + return dlsym(gl_handle, proc); +} + +int SDL_GLES_Init(SDL_GLES_Version version) +{ + SDL_SysWMinfo info; + EGLBoolean res; + + SDL_VERSION(&info.version); + if (SDL_GetWMInfo(&info) != 1) { + SDL_SetError("SDL_gles is incompatible with this SDL version"); + return -1; + } + + /* We use the SDL GFX display (we're using the GFX window too after all) */ + display = info.info.x11.gfxdisplay; + + egl_display = eglGetDisplay((EGLNativeDisplayType)display); + if (egl_display == EGL_NO_DISPLAY) { + SDL_SetError("EGL found no available displays"); + return -2; + } + + res = eglInitialize(egl_display, &egl_major, &egl_minor); + if (!res) { + SDL_SetError("EGL failed to initialize: %s", + get_error_string(eglGetError())); + return -2; + } + + /* Configure some context attributes and bind the required API now. */ + EGLenum api_to_bind = EGL_OPENGL_ES_API; + gl_version = version; + switch (gl_version) { + case SDL_GLES_VERSION_1_1: + /* OpenGL|ES 1.1 */ + api_to_bind = EGL_OPENGL_ES_API; + /* filter non ES 1.0 renderable configurations */ + set_egl_attrib(A_EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT); + /* default egl_context_client_version is OK */ + break; + case SDL_GLES_VERSION_2_0: + /* OpenGL|ES 2.0 */ + api_to_bind = EGL_OPENGL_ES_API; /* Note: no EGL_OPENGL_ES2_API */ + /* filter non ES 2.0 renderable configurations */ + set_egl_attrib(A_EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT); + /* and request GL ES 2.0 contexts */ + set_egl_context_attrib(EGL_CONTEXT_CLIENT_VERSION, 2); + break; + default: + SDL_SetError("Unsupported API version"); + return -1; + } + + res = eglBindAPI(api_to_bind); + if (!res) { + SDL_SetError("EGL failed to bind the required API"); + return -2; + } + + return 0; +} + +void SDL_GLES_Quit() +{ + /* Close the loaded GL library (if any) */ + if (gl_handle) { + dlclose(gl_handle); + gl_handle = NULL; + } + /* Unallocate most stuff we can unallocate. */ + if (egl_display != EGL_NO_DISPLAY) { + eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, + EGL_NO_CONTEXT); + + if (cur_context) { + eglDestroyContext(egl_display, cur_context->egl_context); + free(cur_context); + cur_context = 0; + } + if (egl_surface != EGL_NO_SURFACE) { + eglDestroySurface(egl_display, egl_surface); + egl_surface = EGL_NO_SURFACE; + } + + eglTerminate(egl_display); + egl_display = EGL_NO_DISPLAY; + } +} + +int SDL_GLES_SetVideoMode() +{ + SDL_SysWMinfo info; + EGLBoolean res; + + SDL_VERSION(&info.version); + if (SDL_GetWMInfo(&info) != 1) { + SDL_SetError("SDL_gles is incompatible with this SDL version"); + return -1; + } + + /* Destroy previous surface, if any. */ + if (egl_surface != EGL_NO_SURFACE) { + /* Ensure the surface is not the current one, + * thus freeing memory earlier. */ + eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, + EGL_NO_CONTEXT); + eglDestroySurface(egl_display, egl_surface); + egl_surface = EGL_NO_SURFACE; + } + + /* No current context? Quietly defer surface creation. + * Surface will be created on the call to MakeCurrent. */ + if (!cur_context) { + return 0; + } + + /* Create the new window surface. */ + egl_surface = eglCreateWindowSurface(egl_display, cur_context->egl_config, + (EGLNativeWindowType)info.info.x11.window, NULL); + if (egl_surface == EGL_NO_SURFACE) { + SDL_SetError("EGL failed to create a window surface: %s", + get_error_string(eglGetError())); + return -2; + } + + /* New surface created. Make it active. */ + assert(cur_context && cur_context->egl_context != EGL_NO_CONTEXT); + res = eglMakeCurrent(egl_display, egl_surface, egl_surface, + cur_context->egl_context); + + if (!res) { + SDL_SetError("EGL failed to change current surface: %s", + get_error_string(eglGetError())); + cur_context = NULL; + return -2; + } + + return 0; +} + +SDL_GLES_Context* SDL_GLES_CreateContext(void) +{ + SDL_GLES_ContextPriv *context = malloc(sizeof(SDL_GLES_ContextPriv)); + if (!context) { + SDL_Error(SDL_ENOMEM); + return NULL; + } + + EGLBoolean res; + EGLConfig configs[1]; + EGLint num_config; + + res = eglChooseConfig(egl_display, attrib_list, configs, 1, &num_config); + if (!res || num_config < 1) { + SDL_SetError("EGL failed to find any valid config with required attributes: %s", + get_error_string(eglGetError())); + free(context); + return NULL; + } + + context->egl_config = configs[0]; + context->egl_context = eglCreateContext(egl_display, configs[0], + EGL_NO_CONTEXT, context_attrib_list); + if (context->egl_context == EGL_NO_CONTEXT) { + SDL_SetError("EGL failed to create context: %s", + get_error_string(eglGetError())); + free(context); + return NULL; + } + + return (SDL_GLES_Context*) context; +} + +void SDL_GLES_DeleteContext(SDL_GLES_Context* c) +{ + SDL_GLES_ContextPriv *context = (SDL_GLES_ContextPriv*)c; + if (!context) return; + + if (cur_context == context) { + /* Deleting the active context */ + SDL_GLES_MakeCurrent(NULL); + } + + eglDestroyContext(egl_display, context->egl_context); + free(context); +} + +int SDL_GLES_MakeCurrent(SDL_GLES_Context* c) +{ + SDL_GLES_ContextPriv *context = (SDL_GLES_ContextPriv*)c; + int res; + + cur_context = context; + + /* SDL_GLES_SetVideoMode() will appropiately clear the current context + * (and surface), then create a new surface matching the selected context + * config and make both the surface and the context the active ones. */ + res = SDL_GLES_SetVideoMode(); + if (res != 0) return res; /* Surface (re-)creation failed. */ + + return 0; +} + +void SDL_GLES_SwapBuffers() +{ + eglSwapBuffers(egl_display, egl_surface); +} + +/** A simple map between SDL_GLES_* attributes and EGL ones. + * More abstraction layers is always good. + */ +static const attrib_enum attrib_map[] = { + [SDL_GLES_BUFFER_SIZE] = A_EGL_BUFFER_SIZE, + [SDL_GLES_RED_SIZE] = A_EGL_RED_SIZE, + [SDL_GLES_GREEN_SIZE] = A_EGL_GREEN_SIZE, + [SDL_GLES_BLUE_SIZE] = A_EGL_BLUE_SIZE, + [SDL_GLES_ALPHA_SIZE] = A_EGL_ALPHA_SIZE, + [SDL_GLES_LUMINANCE_SIZE] = A_EGL_LUMINANCE_SIZE, + [SDL_GLES_DEPTH_SIZE] = A_EGL_DEPTH_SIZE, + [SDL_GLES_STENCIL_SIZE] = A_EGL_STENCIL_SIZE, +}; + +int SDL_GLES_SetAttribute(SDL_GLES_Attr attr, int value) +{ + if (attr >= countof(attrib_map)) return -1; + attrib_enum list_attr = attrib_map[attr]; + set_egl_attrib(list_attr, value); + return 0; +} + +int SDL_GLES_GetAttribute(SDL_GLES_Attr attr, int *value) +{ + if (attr >= countof(attrib_map)) return -1; + attrib_enum list_attr = attrib_map[attr]; + if (cur_context) { + EGLenum egl_attr = attrib_list[list_attr]; + EGLint egl_value = 0; + EGLBoolean res = eglGetConfigAttrib(egl_display, + cur_context->egl_config, egl_attr, &egl_value); + if (res) { + *value = egl_value; + return 0; + } else { + printf("Failed: %s\n", get_error_string(eglGetError())); + return -1; + } + } else { + *value = get_egl_attrib(list_attr); + return 0; + } +} + === added file 'src/sdlgles/SDL_gles.h' --- src/sdlgles/SDL_gles.h 1970-01-01 00:00:00 +0000 +++ src/sdlgles/SDL_gles.h 2010-07-12 13:37:04 +0000 @@ -0,0 +1,121 @@ +/* This file is part of SDL_gles - SDL addon for OpenGL|ES + * Copyright (C) 2010 Javier S. Pedro + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA or see . + */ + +#ifndef __SDL_GLES_H +#define __SDL_GLES_H + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum SDL_GLES_Version +{ + SDL_GLES_VERSION_NONE = 0, + SDL_GLES_VERSION_1_1 = 1, + SDL_GLES_VERSION_2_0 = 2 +} SDL_GLES_Version; + +typedef enum SDL_GLES_Attr +{ + SDL_GLES_BUFFER_SIZE = 0, + SDL_GLES_RED_SIZE, + SDL_GLES_GREEN_SIZE, + SDL_GLES_BLUE_SIZE, + SDL_GLES_ALPHA_SIZE, + SDL_GLES_LUMINANCE_SIZE, + SDL_GLES_DEPTH_SIZE, + SDL_GLES_STENCIL_SIZE +} SDL_GLES_Attr; + +typedef struct SDL_GLES_Context +{ + /* Opaque pointer to an EGLContext */ +} SDL_GLES_Context; + +/** Invoke after SDL_Init. + @return 0 if SDL_gles was initialized correctly. + */ +extern DECLSPEC int SDLCALL SDL_GLES_Init(SDL_GLES_Version version); + +/** Invoke just before SDL_Quit. + */ +extern DECLSPEC void SDLCALL SDL_GLES_Quit(); + +/** Call before calling GetProcAddress. Dynamically loads a GLES library. + * @param path full path to the library to load, or leave as NULL to load + * the default GL ES library (version as specified in SDL_GLES_Init()). + * @return 0 if everything went OK. + */ +extern DECLSPEC int SDLCALL SDL_GLES_LoadLibrary(const char *path); +/** Returns the address of a symbol in the loaded GL ES library. + * @param name of the symbol to look up. + * @return address of the symbol or NULL. + */ +extern DECLSPEC void* SDLCALL SDL_GLES_GetProcAddress(const char *proc); + +/** Creates a new GL ES rendering context. This is where all your textures, + * etc. are stored. You need one for rendering; after creating it, make sure + * it is the current one calling SDL_GLES_MakeCurrent(). + * @return the created context or NULL. + */ +extern DECLSPEC SDL_GLES_Context* SDLCALL SDL_GLES_CreateContext(void); +/** Deletes an existing GL ES rendering context. This can delete the current + * context, but after that no context will be current. + * @param context context to delete + */ +extern DECLSPEC void SDLCALL SDL_GLES_DeleteContext(SDL_GLES_Context *context); + +/** Call after calling SDL_SetVideoMode() if you have an active context + * to refresh the surface parameters. + * @return 0 if everything went OK. + */ +extern DECLSPEC int SDLCALL SDL_GLES_SetVideoMode(void); +/** Makes a context the current one. All GLES calls will use it from now on. + * @param context context to use + * @return 0 if everything went OK. + */ +extern DECLSPEC int SDLCALL SDL_GLES_MakeCurrent(SDL_GLES_Context *context); + +/** Equivalent to SDL_Flip(). Call when you're finished issuing GL calls + * and want to draw the color buffer contents to the window surface. + */ +extern DECLSPEC void SDLCALL SDL_GLES_SwapBuffers(void); + +/** Sets a specific context attribute before calling SDL_CreateContext(). + * @param attr + * @param value + * @return 0 if the attribute exists, -1 otherwise. + */ +extern DECLSPEC int SDLCALL SDL_GLES_SetAttribute(SDL_GLES_Attr attr, int value); + +/** Gets a context attribute from the current context, or from the wanted + * attribute set if no context is current. + * @param attr + * @param value pointer where the result will be stored. + * @return 0 if the attribute exists, -1 otherwise. + */ +extern DECLSPEC int SDLCALL SDL_GLES_GetAttribute(SDL_GLES_Attr attr, int *value); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#endif === added file 'src/sdlgles/attribs.inc' --- src/sdlgles/attribs.inc 1970-01-01 00:00:00 +0000 +++ src/sdlgles/attribs.inc 2010-07-12 13:37:04 +0000 @@ -0,0 +1,22 @@ +/* List of EGL attributes we care about */ +A(0, EGL_BUFFER_SIZE, 0) +A(1, EGL_RED_SIZE, 0) +A(2, EGL_GREEN_SIZE, 0) +A(3, EGL_BLUE_SIZE, 0) +A(4, EGL_LUMINANCE_SIZE, 0) +A(5, EGL_ALPHA_SIZE, 0) +A(6, EGL_CONFIG_CAVEAT, EGL_DONT_CARE) +A(7, EGL_CONFIG_ID, EGL_DONT_CARE) +A(8, EGL_DEPTH_SIZE, 0) +A(9, EGL_LEVEL, 0) +A(10, EGL_NATIVE_RENDERABLE, EGL_DONT_CARE) +A(11, EGL_NATIVE_VISUAL_TYPE, EGL_DONT_CARE) +A(12, EGL_RENDERABLE_TYPE, 0) +A(13, EGL_SAMPLE_BUFFERS, 0) +A(14, EGL_SAMPLES, 0) +A(15, EGL_STENCIL_SIZE, 0) +A(16, EGL_SURFACE_TYPE, EGL_WINDOW_BIT) +A(17, EGL_TRANSPARENT_TYPE, EGL_NONE) +A(18, EGL_TRANSPARENT_RED_VALUE, EGL_DONT_CARE) +A(19, EGL_TRANSPARENT_GREEN_VALUE,EGL_DONT_CARE) +A(20, EGL_TRANSPARENT_BLUE_VALUE, EGL_DONT_CARE) === modified file 'src/wscript_build' --- src/wscript_build 2010-07-12 10:06:29 +0000 +++ src/wscript_build 2010-07-12 13:37:04 +0000 @@ -1,7 +1,32 @@ -lib = bld( +all_sources = bld.path.ant_glob('*.cpp').split(); +common_sources = [f for f in all_sources if f.find('screen-') == -1] +gl_sources = ['screen-sdl.cpp', 'screen-sdl-gl.cpp'] +glesv2_sources = ['screen-sdl.cpp', 'screen-sdl-glesv2.cpp'] + +if bld.env.USE_GL: + bld( features = ['cxx', 'cprogram'], - source = bld.path.ant_glob('*.cpp'), + source = common_sources + gl_sources, target = 'glmark2', uselib = ['sdl', 'gl'], lib = ['m'], + defines = ['USE_GL'] + ) + +if bld.env.USE_GLESv2: + bld( + features = ['cc', 'cstaticlib'], + source = bld.path.ant_glob('sdlgles/*.c'), + target = 'sdlgles', + uselib = ['sdl', 'glesv2', 'egl'], + lib = ['m'], + ) + bld( + features = ['cxx', 'cprogram'], + source = common_sources + glesv2_sources, + target = 'glmark2-es2', + uselib = ['sdl', 'glesv2'], + uselib_local = ['sdlgles'], + lib = ['m'], + defines = ['USE_GLESv2'] ) === modified file 'wscript' --- wscript 2010-07-12 10:06:29 +0000 +++ wscript 2010-07-12 13:37:04 +0000 @@ -13,17 +13,27 @@ # Produce '.tar.gz' with ./waf dist Scripting.g_gz = 'gz' +def conf_message(conf, first, second): + conf.check_message_1(first) + conf.check_message_2(second, color='PINK') + def set_options(opt): + opt.tool_options('compiler_cc') opt.tool_options('compiler_cxx') + opt.add_option('--gl', action='store_true', dest = 'gl', default = False, help='build using OpenGL 2.0') + opt.add_option('--glesv2', action='store_true', dest = 'glesv2', default = False, help='build using OpenGL ES 2.0') opt.add_option('--no-debug', action='store_false', dest = 'debug', default = True, help='disable compiler debug information') opt.add_option('--no-opt', action='store_false', dest = 'opt', default = True, help='disable compiler optimizations') opt.add_option('--data-path', action='store', dest = 'data_path', help='the path to install the data to') def configure(conf): + if not Options.options.gl and not Options.options.glesv2: + conf.fatal("You must configure using at least one of --gl, --glesv2") + + conf.check_tool('compiler_cc') conf.check_tool('compiler_cxx') - conf.check_tool('misc') - + # Check required headers req_headers = ['stdlib.h', 'string.h', 'unistd.h', 'fcntl.h'] for header in req_headers: @@ -40,11 +50,18 @@ conf.check_cxx(function_name = func, header_name = header, uselib = uselib, mandatory = True) # Check required packages - req_pkgs = [('sdl', 'sdl'), ('gl', 'gl')] + req_pkgs = [('sdl', 'sdl')] for (pkg, uselib) in req_pkgs: conf.check_cfg(package = pkg, uselib_store = uselib, args = '--cflags --libs', mandatory = True) + # Check optional packages + opt_pkgs = [('gl', 'gl', Options.options.gl), ('egl', 'egl', Options.options.glesv2), + ('glesv2', 'glesv2', Options.options.glesv2)] + for (pkg, uselib, mandatory) in opt_pkgs: + conf.check_cfg(package = pkg, uselib_store = uselib, args = '--cflags --libs', + mandatory = mandatory) + conf.env.append_unique('CXXFLAGS', '-Wall -Wextra -pedantic'.split(' ')) # Prepend -O# and -g flags so that they can be overriden by the CFLAGS environment variable @@ -59,8 +76,13 @@ conf.env.append_unique('GLMARK_DATA_PATH', Options.options.data_path) conf.env.append_unique('CXXDEFINES', 'GLMARK_DATA_PATH="%s"' % Options.options.data_path) - print("Data path: %s" % Options.options.data_path) - print("Prefix : %s" % conf.env.PREFIX) + conf.env.USE_GL = Options.options.gl + conf.env.USE_GLESv2 = Options.options.glesv2 + + conf_message(conf, "Prefix", conf.env.PREFIX) + conf_message(conf, "Data path", Options.options.data_path) + conf_message(conf, "Building GL2 version", "Yes" if conf.env.USE_GL else "No") + conf_message(conf, "Building GLESv2 version", "Yes" if conf.env.USE_GLESv2 else "No") def build(bld): bld.recurse('src')