=== modified file 'doc/glmark2.1.in'
--- doc/glmark2.1.in	2012-01-05 09:46:41 +0000
+++ doc/glmark2.1.in	2012-01-18 17:13:28 +0000
@@ -25,6 +25,10 @@
 Don't update the screen by swapping the front and
 back buffer, use glFinish() instead
 .TP
+\fB\-\-reuse\-context\fR
+Use a single context for all scenes
+(by default, each scene gets its own context)
+.TP
 \fB\-s\fR, \fB\-\-size WxH\fR
 Size of the output window (default: 800x600)
 .TP

=== modified file 'src/canvas-x11-egl.cpp'
--- src/canvas-x11-egl.cpp	2011-11-02 14:56:58 +0000
+++ src/canvas-x11-egl.cpp	2012-01-04 16:51:20 +0000
@@ -67,6 +67,9 @@
     if (!ensure_egl_surface())
         return false;
 
+    if (!ensure_egl_context())
+        return false;
+
     if (egl_context_ == eglGetCurrentContext())
         return true;
 
@@ -175,8 +178,35 @@
 }
 
 bool
-CanvasX11EGL::ensure_egl_surface()
-{
+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,
@@ -184,6 +214,20 @@
         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;
 
@@ -196,14 +240,6 @@
     eglBindAPI(EGL_OPENGL_API);
 #endif
 
-    egl_context_ = eglCreateContext(egl_display_, egl_config_,
-                                    EGL_NO_CONTEXT, ctx_attribs);
-    if (!egl_context_) {
-        Log::error("eglCreateContext() failed with error: %d\n",
-                     eglGetError());
-        return false;
-    }
-
     egl_surface_ = eglCreateWindowSurface(egl_display_, egl_config_,
                                           (EGLNativeWindowType) xwin_,
                                           NULL);

=== modified file 'src/canvas-x11-egl.h'
--- src/canvas-x11-egl.h	2011-11-01 16:49:42 +0000
+++ src/canvas-x11-egl.h	2012-01-04 00:37:12 +0000
@@ -41,11 +41,13 @@
 protected:
     XVisualInfo *get_xvisualinfo();
     bool make_current();
+    bool reset_context();
     void swap_buffers() { eglSwapBuffers(egl_display_, egl_surface_); }
 
 private:
     bool ensure_egl_display();
     bool ensure_egl_config();
+    bool ensure_egl_context();
     bool ensure_egl_surface();
     void init_gl_extensions();
 

=== modified file 'src/canvas-x11-glx.cpp'
--- src/canvas-x11-glx.cpp	2011-11-11 11:07:15 +0000
+++ src/canvas-x11-glx.cpp	2012-01-04 00:37:12 +0000
@@ -201,6 +201,15 @@
 }
 
 bool
+CanvasX11GLX::reset_context()
+{
+    glXDestroyContext(xdpy_, glx_context_);
+    glx_context_ = 0;
+
+    return true;
+}
+
+bool
 CanvasX11GLX::ensure_glx_context()
 {
     if (glx_context_)

=== modified file 'src/canvas-x11-glx.h'
--- src/canvas-x11-glx.h	2011-11-01 16:49:42 +0000
+++ src/canvas-x11-glx.h	2012-01-04 00:37:12 +0000
@@ -41,6 +41,7 @@
 protected:
     XVisualInfo *get_xvisualinfo();
     bool make_current();
+    bool reset_context();
     void swap_buffers() { glXSwapBuffers(xdpy_, xwin_); }
 
 private:

=== modified file 'src/canvas-x11.cpp'
--- src/canvas-x11.cpp	2011-11-24 15:52:33 +0000
+++ src/canvas-x11.cpp	2012-01-04 00:37:12 +0000
@@ -32,17 +32,10 @@
 /******************
  * Public methods *
  ******************/
-
 bool
-CanvasX11::init()
+CanvasX11::reset()
 {
-    xdpy_ = XOpenDisplay(NULL);
-    if (!xdpy_)
-        return false;
-
-    resize_no_viewport(width_, height_);
-
-    if (!xwin_)
+    if (!reset_context())
         return false;
 
     if (!make_current())
@@ -67,6 +60,21 @@
     return true;
 }
 
+bool
+CanvasX11::init()
+{
+    xdpy_ = XOpenDisplay(NULL);
+    if (!xdpy_)
+        return false;
+
+    resize_no_viewport(width_, height_);
+
+    if (!xwin_)
+        return false;
+
+    return reset();
+}
+
 void
 CanvasX11::visible(bool visible)
 {

=== modified file 'src/canvas-x11.h'
--- src/canvas-x11.h	2011-11-24 15:52:33 +0000
+++ src/canvas-x11.h	2012-01-04 00:37:12 +0000
@@ -35,6 +35,7 @@
     ~CanvasX11() {}
 
     virtual bool init();
+    virtual bool reset();
     virtual void visible(bool visible);
     virtual void clear();
     virtual void update();
@@ -69,6 +70,15 @@
     virtual bool make_current() = 0;
 
     /**
+     * Resets the underlying GL context for rendering.
+     *
+     * This method should be implemented in derived classes.
+     *
+     * @return whether the operation succeeded
+     */
+    virtual bool reset_context() = 0;
+
+    /**
      * Swaps the GL buffers (assuming double buffering is used).
      *
      * This method should be implemented in derived classes.

=== modified file 'src/canvas.h'
--- src/canvas.h	2011-11-10 10:33:26 +0000
+++ src/canvas.h	2012-01-04 00:37:12 +0000
@@ -96,6 +96,16 @@
     virtual bool init() { return false; }
 
     /**
+     * Resets the canvas, destroying and recreating resources to give each new
+     * test scenario a fresh context for rendering.
+     *
+     * This method should be implemented in derived classes.
+     *
+     * @return whether reset succeeded
+     */
+    virtual bool reset() { return false; }
+
+    /**
      * Changes the visibility of the canvas.
      *
      * The canvas is initially not visible.

=== modified file 'src/main.cpp'
--- src/main.cpp	2012-01-17 15:44:04 +0000
+++ src/main.cpp	2012-01-18 17:13:28 +0000
@@ -174,6 +174,9 @@
          bench_iter != benchmarks.end();
          bench_iter++)
     {
+        if (!Options::reuse_context)
+            canvas.reset();
+
         bool keep_running = true;
         Benchmark *bench = *bench_iter;
         uint64_t fps_timestamp = Util::get_timestamp_us();
@@ -232,6 +235,9 @@
          bench_iter != benchmarks.end();
          bench_iter++)
     {
+        if (!Options::reuse_context)
+            canvas.reset();
+
         Benchmark *bench = *bench_iter;
         Scene &scene = bench->setup_scene();
 

=== modified file 'src/options.cpp'
--- src/options.cpp	2011-12-13 14:27:23 +0000
+++ src/options.cpp	2012-01-18 17:13:28 +0000
@@ -41,12 +41,14 @@
 bool Options::show_debug = false;
 bool Options::show_fps = false;
 bool Options::show_help = false;
+bool Options::reuse_context = false;
 
 static struct option long_options[] = {
     {"benchmark", 1, 0, 0},
     {"benchmark-file", 1, 0, 0},
     {"validate", 0, 0, 0},
     {"no-swap-buffers", 0, 0, 0},
+    {"reuse-context", 0, 0, 0},
     {"size", 1, 0, 0},
     {"list-scenes", 0, 0, 0},
     {"show-all-options", 0, 0, 0},
@@ -95,6 +97,8 @@
            "                         running the benchmarks\n"
            "      --no-swap-buffers  Don't update the canvas by swapping the front and\n"
            "                         back buffer, use glFinish() instead\n"
+           "      --reuse-context    Use a single context for all scenes\n"
+           "                         (by default, each scene gets its own context)\n"
            "  -s, --size WxH         Size of the output window (default: 800x600)\n"
            "  -l, --list-scenes      Display information about the available scenes\n"
            "                         and their options\n"
@@ -132,6 +136,8 @@
             Options::validate = true;
         else if (!strcmp(optname, "no-swap-buffers"))
             Options::swap_buffers = false;
+        else if (!strcmp(optname, "reuse-context"))
+            Options::reuse_context = true;
         else if (c == 's' || !strcmp(optname, "size"))
             parse_size(optarg, Options::size);
         else if (c == 'l' || !strcmp(optname, "list-scenes"))

=== modified file 'src/options.h'
--- src/options.h	2011-12-13 14:27:23 +0000
+++ src/options.h	2012-01-18 17:13:28 +0000
@@ -41,6 +41,7 @@
     static bool show_debug;
     static bool show_fps;
     static bool show_help;
+    static bool reuse_context;
 };
 
 #endif /* OPTIONS_H_ */

=== modified file 'src/scene-desktop.cpp'
--- src/scene-desktop.cpp	2011-12-08 11:09:09 +0000
+++ src/scene-desktop.cpp	2012-01-18 16:40:14 +0000
@@ -106,9 +106,9 @@
 class RenderObject
 {
 public:
-    RenderObject() : texture_(0), fbo_(0), rotation_rad_(0) { }
-
-    virtual ~RenderObject() { release(); }
+    RenderObject() :
+        texture_(0), fbo_(0), rotation_rad_(0),
+        texture_contents_invalid_(true) { }
 
     virtual void init()
     {
@@ -138,6 +138,7 @@
                                              frg_source.str());
         }
 
+        texture_contents_invalid_ = true;
         RenderObject::use_count++;
     }
 
@@ -182,7 +183,12 @@
             glBindTexture(GL_TEXTURE_2D, texture_);
             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size_.x(), size_.y(), 0,
                          GL_RGBA, GL_UNSIGNED_BYTE, 0);
+            texture_contents_invalid_ = true;
+        }
+
+        if (texture_contents_invalid_) {
             clear();
+            texture_contents_invalid_ = false;
         }
     }
 
@@ -332,6 +338,7 @@
     }
 
     float rotation_rad_;
+    bool texture_contents_invalid_;
     static int use_count;
 
 };
@@ -348,6 +355,7 @@
 {
 public:
     virtual void init() {}
+    virtual void release() {}
 };
 
 /**
@@ -625,7 +633,6 @@
             shadow_v_.release();
             shadow_corner_.release();
             if (draw_contents_)
-            if (draw_contents_)
                 window_contents_.release();
         }
 
@@ -849,7 +856,15 @@
 void
 SceneDesktop::teardown()
 {
-    Util::dispose_pointer_vector(priv_->windows);
+    for (std::vector<RenderObject*>::iterator winIt = priv_->windows.begin();
+         winIt != priv_->windows.end();
+         winIt++)
+    {
+        RenderObject* curObj = *winIt;
+        curObj->release();
+        delete curObj;
+    }
+    priv_->windows.clear();
     priv_->screen.make_current();
 
     glEnable(GL_DEPTH_TEST);

