=== modified file 'doc/glmark2.1.in'
@@ -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'
@@ -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'
@@ -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'
@@ -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'
@@ -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'
@@ -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'
@@ -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'
@@ -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'
@@ -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'
@@ -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'
@@ -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'
@@ -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);