diff mbox

[Branch,~glmark2-dev/glmark2/trunk] Rev 251: Merge of lp:~glmark2-dev/glmark2/egl-state.

Message ID 20121116182812.9115.83783.launchpad@ackee.canonical.com
State Accepted
Headers show

Commit Message

Jesse Barker Nov. 16, 2012, 6:28 p.m. UTC
Merge authors:
  Jesse Barker (jesse-barker)
Related merge proposals:
  https://code.launchpad.net/~glmark2-dev/glmark2/egl-state/+merge/134155
  proposed by: Jesse Barker (jesse-barker)
  review: Approve - Alexandros Frantzis (afrantzis)
  review: Resubmit - Jesse Barker (jesse-barker)
------------------------------------------------------------
revno: 251 [merge]
committer: Jesse Barker <jesse.barker@linaro.org>
branch nick: trunk
timestamp: Fri 2012-11-16 10:26:15 -0800
message:
  Merge of lp:~glmark2-dev/glmark2/egl-state.
  
  Adds EGLState object, which consolidates all EGL interactions.
added:
  src/egl-state.cpp
  src/egl-state.h
modified:
  src/canvas-x11-egl.cpp
  src/canvas-x11-egl.h
  src/canvas-x11-glx.h
  src/canvas-x11.cpp
  src/canvas-x11.h
  src/wscript_build


--
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
diff mbox

Patch

=== modified file 'src/canvas-x11-egl.cpp'
--- src/canvas-x11-egl.cpp	2012-05-11 13:53:08 +0000
+++ src/canvas-x11-egl.cpp	2012-11-13 16:56:32 +0000
@@ -31,6 +31,14 @@ 
  * Protected methods *
  *********************/
 
+bool
+CanvasX11EGL::init_gl_winsys()
+{
+    egl_.init_display(reinterpret_cast<EGLNativeDisplayType>(xdpy_),
+                      visual_config_);
+    return true;
+}
+
 XVisualInfo *
 CanvasX11EGL::get_xvisualinfo()
 {
@@ -39,14 +47,9 @@ 
     int num_visuals;
     EGLint vid;
 
-    if (!ensure_egl_config())
-        return 0;
-
-    if (!eglGetConfigAttrib(egl_display_, egl_config_,
-                            EGL_NATIVE_VISUAL_ID, &vid))
+    if (!egl_.gotNativeConfig(vid))
     {
-        Log::error("eglGetConfigAttrib() failed with error: %d\n",
-                   eglGetError());
+        Log::error("Failed to get a native-renderable EGLConfig\n");
         return 0;
     }
 
@@ -65,35 +68,27 @@ 
 bool
 CanvasX11EGL::make_current()
 {
-    if (!ensure_egl_surface())
-        return false;
-
-    if (!ensure_egl_context())
-        return false;
-
-    if (egl_context_ == eglGetCurrentContext())
-        return true;
-
-    if (!eglMakeCurrent(egl_display_, egl_surface_, egl_surface_, egl_context_)) {
-        Log::error("Error: eglMakeCurrent failed with error %d\n", eglGetError());
+    egl_.init_surface(reinterpret_cast<EGLNativeWindowType>(xwin_));
+    if (!egl_.valid()) {
+        Log::error("CanvasX11EGL: Invalid EGL state\n");
         return false;
     }
 
-    if (!eglSwapInterval(egl_display_, 0))
-        Log::info("** Failed to set swap interval. Results may be bounded above by refresh rate.\n");
-
     init_gl_extensions();
 
     return true;
 }
 
 void
+CanvasX11EGL::swap_buffers()
+{
+    egl_.swap();
+}
+
+void
 CanvasX11EGL::get_glvisualconfig(GLVisualConfig &visual_config)
 {
-    if (!ensure_egl_config())
-        return;
-
-    get_glvisualconfig_egl(egl_config_, visual_config);
+    egl_.getVisualConfig(visual_config);
 }
 
 /*******************
@@ -101,184 +96,9 @@ 
  *******************/
 
 bool
-CanvasX11EGL::ensure_egl_display()
-{
-    if (egl_display_)
-        return true;
-
-    egl_display_ = eglGetDisplay((EGLNativeDisplayType) xdpy_);
-    if (!egl_display_) {
-        Log::error("eglGetDisplay() failed with error: %d\n",
-                   eglGetError());
-        return false;
-    }
-    if (!eglInitialize(egl_display_, NULL, NULL)) {
-        Log::error("eglInitialize() failed with error: %d\n",
-                   eglGetError());
-        return false;
-        egl_display_ = 0;
-    }
-
-    return true;
-}
-
-bool
-CanvasX11EGL::ensure_egl_config()
-{
-    const EGLint attribs[] = {
-        EGL_RED_SIZE, visual_config_.red,
-        EGL_GREEN_SIZE, visual_config_.green,
-        EGL_BLUE_SIZE, visual_config_.blue,
-        EGL_ALPHA_SIZE, visual_config_.alpha,
-        EGL_DEPTH_SIZE, visual_config_.depth,
-        EGL_BUFFER_SIZE, visual_config_.buffer,
-#ifdef USE_GLESv2
-        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-#elif USE_GL
-        EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
-#endif
-        EGL_NONE
-    };
-    EGLint num_configs;
-    EGLint vid;
-
-    if (egl_config_)
-        return true;
-
-    if (!ensure_egl_display())
-        return false;
-
-    /* Find out how many configs match the attributes */
-    if (!eglChooseConfig(egl_display_, attribs, 0, 0, &num_configs)) {
-        Log::error("eglChooseConfig() (explore) failed with error: %d\n",
-                   eglGetError());
-        return false;
-    }
-
-    if (num_configs == 0) {
-        Log::error("eglChooseConfig() didn't return any configs\n");
-        return false;
-    }
-
-    /* Get all the matching configs */
-    std::vector<EGLConfig> configs(num_configs);
-
-    if (!eglChooseConfig(egl_display_, attribs, &(configs[0]),
-                         num_configs, &num_configs))
-    {
-        Log::error("eglChooseConfig() failed with error: %d\n",
-                     eglGetError());
-        return false;
-    }
-
-    /* Select the best matching config */
-    egl_config_ = select_best_config(configs);
-
-    if (!eglGetConfigAttrib(egl_display_, egl_config_,
-                            EGL_NATIVE_VISUAL_ID, &vid))
-    {
-        Log::error("eglGetConfigAttrib() failed with error: %d\n",
-                   eglGetError());
-        return false;
-    }
-
-    if (Options::show_debug) {
-        int buf, red, green, blue, alpha, depth, id, native_id;
-        eglGetConfigAttrib(egl_display_, egl_config_, EGL_CONFIG_ID, &id);
-        eglGetConfigAttrib(egl_display_, egl_config_, EGL_NATIVE_VISUAL_ID, &native_id);
-        eglGetConfigAttrib(egl_display_, egl_config_, EGL_BUFFER_SIZE, &buf);
-        eglGetConfigAttrib(egl_display_, egl_config_, EGL_RED_SIZE, &red);
-        eglGetConfigAttrib(egl_display_, egl_config_, EGL_GREEN_SIZE, &green);
-        eglGetConfigAttrib(egl_display_, egl_config_, EGL_BLUE_SIZE, &blue);
-        eglGetConfigAttrib(egl_display_, egl_config_, EGL_ALPHA_SIZE, &alpha);
-        eglGetConfigAttrib(egl_display_, egl_config_, EGL_DEPTH_SIZE, &depth);
-        Log::debug("EGL chosen config ID: 0x%x Native Visual ID: 0x%x\n"
-                   "  Buffer: %d bits\n"
-                   "     Red: %d bits\n"
-                   "   Green: %d bits\n"
-                   "    Blue: %d bits\n"
-                   "   Alpha: %d bits\n"
-                   "   Depth: %d bits\n",
-                   id, native_id,
-                   buf, red, green, blue, alpha, depth);
-    }
-
-    return true;
-}
-
-bool
 CanvasX11EGL::reset_context()
 {
-    if (!ensure_egl_display())
-        return false;
-
-    if (!egl_context_)
-        return true;
-
-    if (eglDestroyContext(egl_display_, egl_context_) == EGL_FALSE) {
-        Log::debug("eglDestroyContext() failed with error: 0x%x\n",
-                   eglGetError());
-    }
-
-    egl_context_ = 0;
-    return true;
-}
-
-bool
-CanvasX11EGL::ensure_egl_context()
-{
-    if (egl_context_)
-        return true;
-
-    if (!ensure_egl_display())
-        return false;
-
-    if (!ensure_egl_config())
-        return false;
-
-    static const EGLint ctx_attribs[] = {
-#ifdef USE_GLESv2
-        EGL_CONTEXT_CLIENT_VERSION, 2,
-#endif
-        EGL_NONE
-    };
-
-    egl_context_ = eglCreateContext(egl_display_, egl_config_,
-                                    EGL_NO_CONTEXT, ctx_attribs);
-    if (!egl_context_) {
-        Log::error("eglCreateContext() failed with error: 0x%x\n",
-                     eglGetError());
-        return false;
-    }
-
-    return true;
-}
-
-bool
-CanvasX11EGL::ensure_egl_surface()
-{
-    if (egl_surface_)
-        return true;
-
-    if (!ensure_egl_display())
-        return false;
-
-#ifdef USE_GLESv2
-    eglBindAPI(EGL_OPENGL_ES_API);
-#elif USE_GL
-    eglBindAPI(EGL_OPENGL_API);
-#endif
-
-    egl_surface_ = eglCreateWindowSurface(egl_display_, egl_config_,
-                                          (EGLNativeWindowType) xwin_,
-                                          NULL);
-    if (!egl_surface_) {
-        Log::error("eglCreateWindowSurface failed with error: %d\n",
-                     eglGetError());
-        return false;
-    }
-
-    return true;
+    return egl_.reset();
 }
 
 void
@@ -296,45 +116,3 @@ 
     GLExtensions::UnmapBuffer = glUnmapBuffer;
 #endif
 }
-
-void
-CanvasX11EGL::get_glvisualconfig_egl(EGLConfig config, GLVisualConfig &visual_config)
-{
-    eglGetConfigAttrib(egl_display_, config, EGL_BUFFER_SIZE, &visual_config.buffer);
-    eglGetConfigAttrib(egl_display_, config, EGL_RED_SIZE, &visual_config.red);
-    eglGetConfigAttrib(egl_display_, config, EGL_GREEN_SIZE, &visual_config.green);
-    eglGetConfigAttrib(egl_display_, config, EGL_BLUE_SIZE, &visual_config.blue);
-    eglGetConfigAttrib(egl_display_, config, EGL_ALPHA_SIZE, &visual_config.alpha);
-    eglGetConfigAttrib(egl_display_, config, EGL_DEPTH_SIZE, &visual_config.depth);
-}
-
-EGLConfig
-CanvasX11EGL::select_best_config(std::vector<EGLConfig> configs)
-{
-    int best_score(INT_MIN);
-    EGLConfig best_config(0);
-
-    /*
-     * Go through all the configs and choose the one with the best score,
-     * i.e., the one better matching the requested config.
-     */
-    for (std::vector<EGLConfig>::const_iterator iter = configs.begin();
-         iter != configs.end();
-         iter++)
-    {
-        const EGLConfig config(*iter);
-        GLVisualConfig vc;
-        int score;
-
-        get_glvisualconfig_egl(config, vc);
-
-        score = vc.match_score(visual_config_);
-
-        if (score > best_score) {
-            best_score = score;
-            best_config = config;
-        }
-    }
-
-    return best_config;
-}

=== modified file 'src/canvas-x11-egl.h'
--- src/canvas-x11-egl.h	2012-05-11 13:53:08 +0000
+++ src/canvas-x11-egl.h	2012-11-13 16:56:32 +0000
@@ -18,14 +18,13 @@ 
  *
  * Authors:
  *  Alexandros Frantzis (glmark2)
+ *  Jesse Barker
  */
 #ifndef GLMARK2_CANVAS_X11_EGL_H_
 #define GLMARK2_CANVAS_X11_EGL_H_
 
 #include "canvas-x11.h"
-
-#include <EGL/egl.h>
-#include <vector>
+#include "egl-state.h"
 
 /**
  * Canvas for rendering to an X11 window using EGL.
@@ -34,32 +33,20 @@ 
 {
 public:
     CanvasX11EGL(int width, int height) :
-        CanvasX11(width, height), egl_display_(EGL_NO_DISPLAY),
-        egl_surface_(EGL_NO_SURFACE), egl_config_(0),
-        egl_context_(EGL_NO_CONTEXT) {}
+        CanvasX11(width, height) {}
     ~CanvasX11EGL() {}
 
 protected:
     XVisualInfo *get_xvisualinfo();
     bool make_current();
     bool reset_context();
-    void swap_buffers() { eglSwapBuffers(egl_display_, egl_surface_); }
+    void swap_buffers();
     void get_glvisualconfig(GLVisualConfig &visual_config);
+    bool init_gl_winsys();
 
 private:
-    bool ensure_egl_display();
-    bool ensure_egl_config();
-    bool ensure_egl_context();
-    bool ensure_egl_surface();
     void init_gl_extensions();
-    void get_glvisualconfig_egl(EGLConfig config, GLVisualConfig &visual_config);
-    EGLConfig select_best_config(std::vector<EGLConfig> configs);
-
-    EGLDisplay egl_display_;
-    EGLSurface egl_surface_;
-    EGLConfig egl_config_;
-    EGLContext egl_context_;
+    EGLState egl_;
 };
 
 #endif
-

=== modified file 'src/canvas-x11-glx.h'
--- src/canvas-x11-glx.h	2012-05-11 13:53:08 +0000
+++ src/canvas-x11-glx.h	2012-11-13 16:56:32 +0000
@@ -45,6 +45,7 @@ 
     bool reset_context();
     void swap_buffers() { glXSwapBuffers(xdpy_, xwin_); }
     void get_glvisualconfig(GLVisualConfig &visual_config);
+    bool init_gl_winsys() { return true; }
 
 private:
     bool check_glx_version();

=== modified file 'src/canvas-x11.cpp'
--- src/canvas-x11.cpp	2012-07-03 17:34:53 +0000
+++ src/canvas-x11.cpp	2012-11-13 16:56:32 +0000
@@ -70,6 +70,9 @@ 
     if (!xdpy_)
         return false;
 
+    if (!init_gl_winsys())
+        return false;
+
     resize_no_viewport(width_, height_);
 
     if (!xwin_)

=== modified file 'src/canvas-x11.h'
--- src/canvas-x11.h	2012-06-15 09:03:04 +0000
+++ src/canvas-x11.h	2012-11-13 16:56:32 +0000
@@ -64,6 +64,15 @@ 
     virtual XVisualInfo *get_xvisualinfo() = 0;
 
     /**
+     * Initializes window system interfaces for GL rendering.
+     *
+     * This method should be implemented in derived classes.
+     *
+     * @return whether the operation succeeded
+     */
+    virtual bool init_gl_winsys() = 0;
+
+    /**
      * Makes the canvas the current target for GL rendering.
      *
      * This method should be implemented in derived classes.

=== added file 'src/egl-state.cpp'
--- src/egl-state.cpp	1970-01-01 00:00:00 +0000
+++ src/egl-state.cpp	2012-11-15 23:06:53 +0000
@@ -0,0 +1,527 @@ 
+//
+// Copyright Š 2012 Linaro Limited
+//
+// This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+//
+// glmark2 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 3 of the License, or (at your option) any later
+// version.
+//
+// glmark2 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
+// glmark2.  If not, see <http://www.gnu.org/licenses/>.
+//
+// Authors:
+//  Jesse Barker
+//
+#include "egl-state.h"
+#include "log.h"
+#include "options.h"
+#include "limits.h"
+#include <iomanip>
+#include <sstream>
+
+using std::vector;
+using std::string;
+
+EglConfig::EglConfig(EGLDisplay dpy, EGLConfig config) :
+    handle_(config),
+    bufferSize_(0),
+    redSize_(0),
+    greenSize_(0),
+    blueSize_(0),
+    luminanceSize_(0),
+    alphaSize_(0),
+    alphaMaskSize_(0),
+    bufferType_(EGL_RGB_BUFFER),
+    caveat_(0),
+    configID_(0),
+    depthSize_(0),
+    nativeID_(0),
+    nativeType_(0),
+    nativeRenderable_(false),
+    sampleBuffers_(0),
+    samples_(0),
+    stencilSize_(0),
+    surfaceType_(0),
+    xparentType_(0),
+    xparentRedValue_(0),
+    xparentGreenValue_(0),
+    xparentBlueValue_(0)
+{
+    vector<string> badAttribVec;
+    if (!eglGetConfigAttrib(dpy, handle_, EGL_CONFIG_ID, &configID_))
+    {
+        badAttribVec.push_back("EGL_CONFIG_ID");
+    }
+    if (!eglGetConfigAttrib(dpy, handle_, EGL_CONFIG_CAVEAT, &caveat_))
+    {
+        badAttribVec.push_back("EGL_CONFIG_CAVEAT");
+    }
+    if (!eglGetConfigAttrib(dpy, handle_, EGL_COLOR_BUFFER_TYPE, &bufferType_))
+    {
+        badAttribVec.push_back("EGL_COLOR_BUFFER_TYPE");
+    }
+    if (!eglGetConfigAttrib(dpy, handle_, EGL_BUFFER_SIZE, &bufferSize_))
+    {
+        badAttribVec.push_back("EGL_BUFFER_SIZE");
+    }
+
+    if (bufferType_ == EGL_RGB_BUFFER)
+    {
+        if (!eglGetConfigAttrib(dpy, handle_, EGL_RED_SIZE, &redSize_))
+        {
+            badAttribVec.push_back("EGL_RED_SIZE");
+        }
+        if (!eglGetConfigAttrib(dpy, handle_, EGL_GREEN_SIZE, &greenSize_))
+        {
+            badAttribVec.push_back("EGL_GREEN_SIZE");
+        }
+        if (!eglGetConfigAttrib(dpy, handle_, EGL_BLUE_SIZE, &blueSize_))
+        {
+            badAttribVec.push_back("EGL_BLUE_SIZE");
+        }
+    }
+    else
+    {
+        if (!eglGetConfigAttrib(dpy, handle_, EGL_LUMINANCE_SIZE, &luminanceSize_))
+        {
+            badAttribVec.push_back("EGL_LUMINANCE_SIZE");
+        }
+    }
+    if (!eglGetConfigAttrib(dpy, handle_, EGL_ALPHA_SIZE, &alphaSize_))
+    {
+        badAttribVec.push_back("EGL_ALPHA_SIZE");
+    }
+    if (!eglGetConfigAttrib(dpy, handle_, EGL_DEPTH_SIZE, &depthSize_))
+    {
+        badAttribVec.push_back("EGL_DEPTH_SIZE");
+    }
+    if (!eglGetConfigAttrib(dpy, handle_, EGL_STENCIL_SIZE, &stencilSize_))
+    {
+        badAttribVec.push_back("EGL_STENCIL_SIZE");
+    }
+    EGLint doNative(EGL_FALSE);
+    if (!eglGetConfigAttrib(dpy, handle_, EGL_NATIVE_RENDERABLE, &doNative))
+    {
+        badAttribVec.push_back("EGL_NATIVE_RENDERABLE");
+    }
+    if (doNative == EGL_TRUE)
+    {
+        nativeRenderable_ = true;
+    }
+    if (!eglGetConfigAttrib(dpy, handle_, EGL_NATIVE_VISUAL_TYPE, &nativeType_))
+    {
+        badAttribVec.push_back("EGL_NATIVE_VISUAL_TYPE");
+    }
+    if (!eglGetConfigAttrib(dpy, handle_, EGL_NATIVE_VISUAL_ID, &nativeID_))
+    {
+        badAttribVec.push_back("EGL_NATIVE_VISUAL_ID");
+    }
+    if (!eglGetConfigAttrib(dpy, handle_, EGL_SURFACE_TYPE, &surfaceType_))
+    {
+        badAttribVec.push_back("EGL_SURFACE_TYPE");
+    }
+    if (!eglGetConfigAttrib(dpy, handle_, EGL_SAMPLE_BUFFERS, &sampleBuffers_))
+    {
+        badAttribVec.push_back("EGL_SAMPLE_BUFFERS");
+    }
+    if (sampleBuffers_)
+    {
+        if (!eglGetConfigAttrib(dpy, handle_, EGL_SAMPLES, &samples_))
+        {
+            badAttribVec.push_back("EGL_SAMPLES");
+        }        
+    }    
+    if (!eglGetConfigAttrib(dpy, handle_, EGL_TRANSPARENT_TYPE, &xparentType_))
+    {
+        badAttribVec.push_back("EGL_TRANSPARENT_TYPE");
+    }
+    //if (xparentType_ != EGL_NONE)
+    {
+        if (!eglGetConfigAttrib(dpy, handle_, EGL_TRANSPARENT_RED_VALUE, &xparentRedValue_))
+        {
+            badAttribVec.push_back("EGL_TRANSPARENT_RED_VALUE");
+        }
+        if (!eglGetConfigAttrib(dpy, handle_, EGL_TRANSPARENT_GREEN_VALUE, &xparentGreenValue_))
+        {
+            badAttribVec.push_back("EGL_TRANSPARENT_GREEN_VALUE");
+        }
+        if (!eglGetConfigAttrib(dpy, handle_, EGL_TRANSPARENT_BLUE_VALUE, &xparentBlueValue_))
+        {
+            badAttribVec.push_back("EGL_TRANSPARENT_BLUE_VALUE");
+        }
+    }
+
+    if (!badAttribVec.empty())
+    {
+        Log::error("Failed to get the following config attributes for config 0x%x:\n",
+                    config);
+        for (vector<string>::const_iterator attribIt = badAttribVec.begin();
+             attribIt != badAttribVec.end();
+             attribIt++)
+        {
+            Log::error("%s\n", attribIt->c_str());
+        }
+    }
+}
+
+void
+EglConfig::print_header()
+{
+    Log::debug("\n");
+    Log::debug("    cfg buf  rgb  colorbuffer dp st config native support surface sample\n");
+    Log::debug("     id  sz  lum  r  g  b  a  th cl caveat render  visid    type  buf ns\n");
+    Log::debug("------------------------------------------------------------------------\n");
+}
+
+void
+EglConfig::print() const
+{
+    std::ostringstream s;
+    s.setf(std::ios::showbase);
+    s.fill(' ');
+    s << std::setw(7) << std::hex << configID_;
+    s << std::setw(4) << std::dec << bufferSize_;
+    if (bufferType_ == EGL_RGB_BUFFER)
+    {
+        s << std::setw(5) << "rgb";
+        s << std::setw(3) << redSize_;
+        s << std::setw(3) << greenSize_;
+        s << std::setw(3) << blueSize_;
+    }
+    else
+    {
+        s << std::setw(5) << "lum";
+        s << std::setw(3) << luminanceSize_;
+        s << std::setw(3) << 0;
+        s << std::setw(3) << 0;
+    }
+    s << std::setw(3) << alphaSize_;
+    s << std::setw(4) << depthSize_;
+    s << std::setw(3) << stencilSize_;
+    string caveat("None");
+    switch (caveat_)
+    {
+        case EGL_SLOW_CONFIG:
+            caveat = string("Slow");
+            break;
+        case EGL_NON_CONFORMANT_CONFIG:
+            caveat = string("Ncon");
+            break;
+        case EGL_NONE:
+            // Initialized to none.
+            break;
+    }
+    s << std::setw(7) << caveat;
+    string doNative(nativeRenderable_ ? "true" : "false");
+    s << std::setw(7) << doNative;
+    s << std::setw(8) << std::hex << nativeID_;
+    s << std::setw(8) << std::hex << surfaceType_;
+    s << std::setw(4) << std::dec << sampleBuffers_;
+    s << std::setw(3) << std::dec << samples_;
+    Log::debug("%s\n", s.str().c_str());
+}
+
+
+bool
+EGLState::init_display(EGLNativeDisplayType native_display, GLVisualConfig& visual_config)
+{
+    native_display_ = native_display;
+    visual_config_ = visual_config;
+
+    return gotValidDisplay();
+}
+
+bool
+EGLState::init_surface(EGLNativeWindowType native_window)
+{
+    native_window_ = reinterpret_cast<EGLNativeWindowType>(native_window);
+
+    return gotValidSurface();
+}
+
+void
+EGLState::swap()
+{
+    eglSwapBuffers(egl_display_, egl_surface_);
+}
+
+bool
+EGLState::gotValidDisplay()
+{
+    if (egl_display_)
+        return true;
+
+    egl_display_ = eglGetDisplay(native_display_);
+    if (!egl_display_) {
+        Log::error("eglGetDisplay() failed with error: 0x%x\n", eglGetError());
+        return false;
+    }
+    int egl_major(-1);
+    int egl_minor(-1);
+    if (!eglInitialize(egl_display_, &egl_major, &egl_minor)) {
+        Log::error("eglInitialize() failed with error: 0x%x\n", eglGetError());
+        egl_display_ = 0;
+        return false;
+    }
+
+#if USE_GLESv2
+    EGLenum apiType(EGL_OPENGL_ES_API);
+#elif USE_GL
+    EGLenum apiType(EGL_OPENGL_API);
+#endif
+    if (!eglBindAPI(apiType)) {
+        Log::error("Failed to bind api EGL_OPENGL_ES_API\n");
+        return false;
+    }
+
+    return true;
+}
+
+void
+EGLState::get_glvisualconfig(EGLConfig config, GLVisualConfig& visual_config)
+{
+    eglGetConfigAttrib(egl_display_, config, EGL_BUFFER_SIZE, &visual_config.buffer);
+    eglGetConfigAttrib(egl_display_, config, EGL_RED_SIZE, &visual_config.red);
+    eglGetConfigAttrib(egl_display_, config, EGL_GREEN_SIZE, &visual_config.green);
+    eglGetConfigAttrib(egl_display_, config, EGL_BLUE_SIZE, &visual_config.blue);
+    eglGetConfigAttrib(egl_display_, config, EGL_ALPHA_SIZE, &visual_config.alpha);
+    eglGetConfigAttrib(egl_display_, config, EGL_DEPTH_SIZE, &visual_config.depth);
+}
+
+EGLConfig
+EGLState::select_best_config(std::vector<EGLConfig>& configs)
+{
+    int best_score(INT_MIN);
+    EGLConfig best_config(0);
+
+    /*
+     * Go through all the configs and choose the one with the best score,
+     * i.e., the one better matching the requested config.
+     */
+    for (std::vector<EGLConfig>::const_iterator iter = configs.begin();
+         iter != configs.end();
+         iter++)
+    {
+        const EGLConfig config(*iter);
+        GLVisualConfig vc;
+        int score;
+
+        get_glvisualconfig(config, vc);
+
+        score = vc.match_score(visual_config_);
+
+        if (score > best_score) {
+            best_score = score;
+            best_config = config;
+        }
+    }
+
+    return best_config;
+}
+
+bool
+EGLState::gotValidConfig()
+{
+    if (egl_config_)
+        return true;
+
+    if (!gotValidDisplay())
+        return false;
+
+    const EGLint config_attribs[] = {
+        EGL_RED_SIZE, visual_config_.red,
+        EGL_GREEN_SIZE, visual_config_.green,
+        EGL_BLUE_SIZE, visual_config_.blue,
+        EGL_ALPHA_SIZE, visual_config_.alpha,
+        EGL_DEPTH_SIZE, visual_config_.depth,
+#if USE_GLESv2
+        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+#elif USE_GL
+        EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
+#endif
+        EGL_NONE
+    };
+
+    // Find out how many configs match the attributes.
+    EGLint num_configs(0);
+    if (!eglChooseConfig(egl_display_, config_attribs, 0, 0, &num_configs)) {
+        Log::error("eglChooseConfig() (count query) failed with error: %d\n",
+                   eglGetError());
+        return false;
+    }
+
+    if (num_configs == 0) {
+        Log::error("eglChooseConfig() didn't return any configs\n");
+        return false;
+    }
+
+    // Get all the matching configs
+    vector<EGLConfig> configs(num_configs);
+    if (!eglChooseConfig(egl_display_, config_attribs, &configs.front(),
+                         num_configs, &num_configs))
+    {
+        Log::error("eglChooseConfig() failed with error: %d\n",
+                     eglGetError());
+        return false;
+    }
+
+    // Select the best matching config
+    egl_config_ = select_best_config(configs);
+
+    vector<EglConfig> configVec;
+    for (vector<EGLConfig>::const_iterator configIt = configs.begin();
+         configIt != configs.end();
+         configIt++)
+    {
+        EglConfig cfg(egl_display_, *configIt);
+        configVec.push_back(cfg);
+        if (*configIt == egl_config_) {
+            best_config_ = cfg;
+        }
+    } 
+
+    // Print out the config information, and let the user know the decision
+    // about the "best" one with respect to the options.
+    unsigned int lineNumber(0);
+    Log::debug("Got %u suitable EGLConfigs:\n", num_configs);
+    for (vector<EglConfig>::const_iterator configIt = configVec.begin();
+         configIt != configVec.end();
+         configIt++, lineNumber++)
+    {
+        if (!(lineNumber % 32))
+        {
+            configIt->print_header();
+        }
+        configIt->print();
+    }
+    Log::debug("\n");
+    Log::debug("Best EGLConfig ID: 0x%x\n", best_config_.configID());
+
+    return true;
+}
+
+bool
+EGLState::gotValidSurface()
+{
+    if (egl_surface_)
+        return true;
+
+    if (!gotValidDisplay())
+        return false;
+
+    if (!gotValidConfig())
+        return false;
+
+    egl_surface_ = eglCreateWindowSurface(egl_display_, egl_config_, native_window_, 0);
+    if (!egl_surface_) {
+        Log::error("eglCreateWindowSurface failed with error: 0x%x\n", eglGetError());
+        return false;
+    }
+
+    return true;
+}
+
+bool
+EGLState::gotValidContext()
+{
+    if (egl_context_)
+        return true;
+
+    if (!gotValidDisplay())
+        return false;
+
+    if (!gotValidConfig())
+        return false;
+
+    static const EGLint context_attribs[] = {
+#ifdef USE_GLESv2
+        EGL_CONTEXT_CLIENT_VERSION, 2,
+#endif
+        EGL_NONE
+    };
+
+    egl_context_ = eglCreateContext(egl_display_, egl_config_,
+                                    EGL_NO_CONTEXT, context_attribs);
+    if (!egl_context_) {
+        Log::error("eglCreateContext() failed with error: 0x%x\n",
+                   eglGetError());
+        return false;
+    }
+
+    return true;
+}
+
+bool
+EGLState::valid()
+{
+    if (!gotValidDisplay())
+        return false;
+
+    if (!gotValidConfig())
+        return false;
+
+    if (!gotValidSurface())
+        return false;
+
+    if (!gotValidContext())
+        return false;
+
+    if (egl_context_ == eglGetCurrentContext())
+        return true;
+
+    if (!eglMakeCurrent(egl_display_, egl_surface_, egl_surface_, egl_context_)) {
+        Log::error("eglMakeCurrent failed with error: 0x%x\n", eglGetError());
+        return false;
+    }
+
+    if (!eglSwapInterval(egl_display_, 0)) {
+        Log::info("** Failed to set swap interval. Results may be bounded above by refresh rate.\n");
+    }
+
+    return true;
+}
+
+bool
+EGLState::gotNativeConfig(int& vid)
+{
+    if (!gotValidConfig())
+        return false;
+
+    EGLint native_id;
+    if (!eglGetConfigAttrib(egl_display_, egl_config_, EGL_NATIVE_VISUAL_ID,
+        &native_id))
+    {
+        Log::debug("Failed to get native visual id for EGLConfig 0x%x\n", egl_config_);
+        return false;
+    }
+
+    vid = native_id;
+    return true;
+}
+
+bool
+EGLState::reset()
+{
+    if (!gotValidDisplay()) {
+        return false;
+    }
+
+    if (!egl_context_) {
+        return true;
+    }
+
+    if (EGL_FALSE == eglDestroyContext(egl_display_, egl_context_)) {
+        Log::debug("eglDestroyContext failed with error: 0x%x\n", eglGetError());
+    }
+
+    egl_context_ = 0;
+
+    return true;
+}

=== added file 'src/egl-state.h'
--- src/egl-state.h	1970-01-01 00:00:00 +0000
+++ src/egl-state.h	2012-11-13 16:53:41 +0000
@@ -0,0 +1,130 @@ 
+//
+// Copyright Š 2012 Linaro Limited
+//
+// This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+//
+// glmark2 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 3 of the License, or (at your option) any later
+// version.
+//
+// glmark2 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
+// glmark2.  If not, see <http://www.gnu.org/licenses/>.
+//
+// Authors:
+//  Jesse Barker
+//
+#ifndef EGL_STATE_H_
+#define EGL_STATE_H_
+
+#include <vector>
+#include <EGL/egl.h>
+#include "gl-visual-config.h"
+
+class EglConfig
+{
+    EGLConfig handle_;
+    // Color buffer attributes.
+    EGLint bufferSize_;
+    EGLint redSize_;
+    EGLint greenSize_;
+    EGLint blueSize_;
+    EGLint luminanceSize_;
+    EGLint alphaSize_;
+    EGLint alphaMaskSize_;
+    EGLint bufferType_;
+    // Base config attributes
+    EGLint caveat_;
+    EGLint configID_;
+    // Depth buffer
+    EGLint depthSize_;
+    // Native window system attributes.
+    EGLint nativeID_;
+    EGLint nativeType_;
+    bool nativeRenderable_;
+    // Multisample support
+    EGLint sampleBuffers_;
+    EGLint samples_;
+    // Stencil buffer
+    EGLint stencilSize_;
+    EGLint surfaceType_;
+    // Transparency
+    EGLint xparentType_; // Should be RGB or NONE
+    EGLint xparentRedValue_;
+    EGLint xparentGreenValue_;
+    EGLint xparentBlueValue_;
+
+public:
+    EglConfig() :
+        handle_(0),
+        bufferSize_(0),
+        redSize_(0),
+        greenSize_(0),
+        blueSize_(0),
+        luminanceSize_(0),
+        alphaSize_(0),
+        alphaMaskSize_(0),
+        bufferType_(EGL_RGB_BUFFER),
+        caveat_(0),
+        configID_(0),
+        depthSize_(0),
+        nativeID_(0),
+        nativeType_(0),
+        nativeRenderable_(false),
+        sampleBuffers_(0),
+        samples_(0),
+        stencilSize_(0),
+        surfaceType_(0),
+        xparentType_(0),
+        xparentRedValue_(0),
+        xparentGreenValue_(0),
+        xparentBlueValue_(0) {}
+    EglConfig(EGLDisplay dpy, EGLConfig config);
+    ~EglConfig() {}
+    void print() const;
+    static void print_header();
+    bool isWindowConfig() const { return surfaceType_ & EGL_WINDOW_BIT; }
+    EGLint configID() const { return configID_; }
+};
+
+class EGLState
+{
+    EGLNativeDisplayType native_display_;
+    EGLNativeWindowType native_window_;
+    EGLDisplay egl_display_;
+    EGLConfig egl_config_;
+    EGLContext egl_context_;
+    EGLSurface egl_surface_;
+    GLVisualConfig visual_config_;
+    EglConfig best_config_;
+    bool gotValidDisplay();
+    bool gotValidConfig();
+    bool gotValidSurface();
+    bool gotValidContext();
+    void get_glvisualconfig(EGLConfig config, GLVisualConfig& visual_config);
+    EGLConfig select_best_config(std::vector<EGLConfig>& configs);
+public:
+    EGLState() :
+        native_display_(0),
+        native_window_(0),
+        egl_display_(0),
+        egl_config_(0),
+        egl_context_(0),
+        egl_surface_(0) {}
+    ~EGLState() {}
+    bool valid();
+    bool init_display(EGLNativeDisplayType native_display, GLVisualConfig& config_pref);
+    bool init_surface(EGLNativeWindowType native_window);
+    bool reset();
+    void swap();
+    // Performs a config search, returning a native visual ID on success
+    bool gotNativeConfig(int& vid);
+    void getVisualConfig(GLVisualConfig& vc) { vc = visual_config_; }
+};
+
+#endif // EGL_STATE_H_

=== modified file 'src/wscript_build'
--- src/wscript_build	2012-06-29 12:27:16 +0000
+++ src/wscript_build	2012-11-13 16:53:41 +0000
@@ -1,8 +1,9 @@ 
 all_sources = bld.path.ant_glob('*.cpp scene-ideas/*.cc scene-terrain/*.cpp')
 common_sources = [f for f in all_sources if f.name.find('canvas-') == -1 and
-                                            f.name.find('android') == -1 ]
+                                            f.name.find('android') == -1 and
+                                            f.name.find('egl-') == -1]
 gl_sources = ['canvas-x11.cpp', 'canvas-x11-glx.cpp']
-glesv2_sources = ['canvas-x11.cpp', 'canvas-x11-egl.cpp']
+glesv2_sources = ['canvas-x11.cpp', 'canvas-x11-egl.cpp', 'egl-state.cpp']
 libmatrix_sources = [f for f in bld.path.ant_glob('libmatrix/*.cc')
                      if not f.name.endswith('test.cc')]
 includes = ['.', 'scene-ideas', 'scene-terrain']