Merge lp:~linaro-graphics-wg/glmark2/canvas-fbo into lp:glmark2/2011.11

Proposed by Alexandros Frantzis
Status: Merged
Merged at revision: 202
Proposed branch: lp:~linaro-graphics-wg/glmark2/canvas-fbo
Merge into: lp:glmark2/2011.11
Diff against target: 724 lines (+393/-35)
14 files modified
doc/glmark2.1.in (+5/-3)
src/canvas-x11-egl.cpp (+15/-12)
src/canvas-x11-egl.h (+1/-0)
src/canvas-x11-glx.cpp (+13/-0)
src/canvas-x11-glx.h (+1/-0)
src/canvas-x11.cpp (+210/-7)
src/canvas-x11.h (+35/-1)
src/canvas.h (+17/-1)
src/gl-headers.cpp (+20/-0)
src/gl-headers.h (+25/-1)
src/main.cpp (+2/-0)
src/options.cpp (+35/-6)
src/options.h (+10/-1)
src/scene-desktop.cpp (+4/-3)
To merge this branch: bzr merge lp:~linaro-graphics-wg/glmark2/canvas-fbo
Reviewer Review Type Date Requested Status
Jesse Barker Approve
Review via email: mp+98416@code.launchpad.net

Description of the change

Add support for rendering to an off-screen surface.

To post a comment you must log in.
Revision history for this message
Jesse Barker (jesse-barker) wrote :

Looks good. I think this will really give us some additional flexibility moving forward.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'doc/glmark2.1.in'
2--- doc/glmark2.1.in 2012-02-16 11:45:12 +0000
3+++ doc/glmark2.1.in 2012-03-20 14:03:47 +0000
4@@ -21,9 +21,11 @@
5 Run a quick output validation test instead of
6 running the benchmarks
7 .TP
8-\fB\-\-no\-swap\-buffers\fR
9-Don't update the screen by swapping the front and
10-back buffer, use glFinish() instead
11+\fB\-\-frame-end\fR
12+How to end a frame [default,none,swap,finish,readpixels]
13+.TP
14+\fB\-\-off-screen\fR
15+Render to an off-screen surface
16 .TP
17 \fB\-\-reuse\-context\fR
18 Use a single context for all scenes
19
20=== modified file 'src/canvas-x11-egl.cpp'
21--- src/canvas-x11-egl.cpp 2012-01-04 16:51:20 +0000
22+++ src/canvas-x11-egl.cpp 2012-03-20 14:03:47 +0000
23@@ -86,6 +86,20 @@
24 return true;
25 }
26
27+void
28+CanvasX11EGL::get_glvisualinfo(GLVisualInfo &gl_visinfo)
29+{
30+ if (!ensure_egl_config())
31+ return;
32+
33+ eglGetConfigAttrib(egl_display_, egl_config_, EGL_BUFFER_SIZE, &gl_visinfo.buffer_size);
34+ eglGetConfigAttrib(egl_display_, egl_config_, EGL_RED_SIZE, &gl_visinfo.red_size);
35+ eglGetConfigAttrib(egl_display_, egl_config_, EGL_GREEN_SIZE, &gl_visinfo.green_size);
36+ eglGetConfigAttrib(egl_display_, egl_config_, EGL_BLUE_SIZE, &gl_visinfo.blue_size);
37+ eglGetConfigAttrib(egl_display_, egl_config_, EGL_ALPHA_SIZE, &gl_visinfo.alpha_size);
38+ eglGetConfigAttrib(egl_display_, egl_config_, EGL_DEPTH_SIZE, &gl_visinfo.depth_size);
39+}
40+
41 /*******************
42 * Private methods *
43 *******************/
44@@ -256,18 +270,7 @@
45 CanvasX11EGL::init_gl_extensions()
46 {
47 #if USE_GLESv2
48- /*
49- * Parse the extensions we care about from the extension string.
50- * Don't even bother to get function pointers until we know the
51- * extension is present.
52- */
53- std::string extString;
54- const char* exts = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
55- if (exts) {
56- extString = exts;
57- }
58-
59- if (extString.find("GL_OES_mapbuffer") != std::string::npos) {
60+ if (GLExtensions::support("GL_OES_mapbuffer")) {
61 GLExtensions::MapBuffer =
62 reinterpret_cast<PFNGLMAPBUFFEROESPROC>(eglGetProcAddress("glMapBufferOES"));
63 GLExtensions::UnmapBuffer =
64
65=== modified file 'src/canvas-x11-egl.h'
66--- src/canvas-x11-egl.h 2012-01-04 00:37:12 +0000
67+++ src/canvas-x11-egl.h 2012-03-20 14:03:47 +0000
68@@ -43,6 +43,7 @@
69 bool make_current();
70 bool reset_context();
71 void swap_buffers() { eglSwapBuffers(egl_display_, egl_surface_); }
72+ void get_glvisualinfo(GLVisualInfo &gl_visinfo);
73
74 private:
75 bool ensure_egl_display();
76
77=== modified file 'src/canvas-x11-glx.cpp'
78--- src/canvas-x11-glx.cpp 2012-01-04 00:37:12 +0000
79+++ src/canvas-x11-glx.cpp 2012-03-20 14:03:47 +0000
80@@ -68,6 +68,19 @@
81 return true;
82 }
83
84+void
85+CanvasX11GLX::get_glvisualinfo(GLVisualInfo &gl_visinfo)
86+{
87+ if (!ensure_glx_fbconfig())
88+ return;
89+
90+ glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_BUFFER_SIZE, &gl_visinfo.buffer_size);
91+ glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_RED_SIZE, &gl_visinfo.red_size);
92+ glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_GREEN_SIZE, &gl_visinfo.green_size);
93+ glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_BLUE_SIZE, &gl_visinfo.blue_size);
94+ glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_ALPHA_SIZE, &gl_visinfo.alpha_size);
95+ glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_DEPTH_SIZE, &gl_visinfo.depth_size);
96+}
97
98 /*******************
99 * Private methods *
100
101=== modified file 'src/canvas-x11-glx.h'
102--- src/canvas-x11-glx.h 2012-01-04 00:37:12 +0000
103+++ src/canvas-x11-glx.h 2012-03-20 14:03:47 +0000
104@@ -43,6 +43,7 @@
105 bool make_current();
106 bool reset_context();
107 void swap_buffers() { glXSwapBuffers(xdpy_, xwin_); }
108+ void get_glvisualinfo(GLVisualInfo &gl_visinfo);
109
110 private:
111 bool check_glx_version();
112
113=== modified file 'src/canvas-x11.cpp'
114--- src/canvas-x11.cpp 2012-01-04 00:37:12 +0000
115+++ src/canvas-x11.cpp 2012-03-20 14:03:47 +0000
116@@ -35,10 +35,12 @@
117 bool
118 CanvasX11::reset()
119 {
120+ release_fbo();
121+
122 if (!reset_context())
123 return false;
124
125- if (!make_current())
126+ if (!do_make_current())
127 return false;
128
129 if (!supports_gl2()) {
130@@ -78,7 +80,7 @@
131 void
132 CanvasX11::visible(bool visible)
133 {
134- if (visible)
135+ if (visible && !offscreen_)
136 XMapWindow(xdpy_, xwin_);
137 }
138
139@@ -97,16 +99,35 @@
140 void
141 CanvasX11::update()
142 {
143- if (Options::swap_buffers)
144- swap_buffers();
145- else
146- glFinish();
147+ Options::FrameEnd m = Options::frame_end;
148+
149+ if (m == Options::FrameEndDefault) {
150+ if (offscreen_)
151+ m = Options::FrameEndFinish;
152+ else
153+ m = Options::FrameEndSwap;
154+ }
155+
156+ switch(m) {
157+ case Options::FrameEndSwap:
158+ swap_buffers();
159+ break;
160+ case Options::FrameEndFinish:
161+ glFinish();
162+ break;
163+ case Options::FrameEndReadPixels:
164+ read_pixel(width_ / 2, height_ / 2);
165+ break;
166+ case Options::FrameEndNone:
167+ default:
168+ break;
169+ }
170 }
171
172 void
173 CanvasX11::print_info()
174 {
175- make_current();
176+ do_make_current();
177
178 std::stringstream ss;
179
180@@ -173,6 +194,12 @@
181 glViewport(0, 0, width_, height_);
182 }
183
184+unsigned int
185+CanvasX11::fbo()
186+{
187+ return fbo_;
188+}
189+
190 bool
191 CanvasX11::supports_gl2()
192 {
193@@ -285,7 +312,183 @@
194 if (!ensure_x_window())
195 Log::error("Error: Couldn't create X Window!\n");
196
197+ if (color_renderbuffer_) {
198+ glBindRenderbuffer(GL_RENDERBUFFER, color_renderbuffer_);
199+ glRenderbufferStorage(GL_RENDERBUFFER, gl_color_format_,
200+ width_, height_);
201+ }
202+
203+ if (depth_renderbuffer_) {
204+ glBindRenderbuffer(GL_RENDERBUFFER, depth_renderbuffer_);
205+ glRenderbufferStorage(GL_RENDERBUFFER, gl_depth_format_,
206+ width_, height_);
207+ }
208+
209 projection_ = LibMatrix::Mat4::perspective(60.0, width_ / static_cast<float>(height_),
210 1.0, 1024.0);
211 }
212
213+bool
214+CanvasX11::do_make_current()
215+{
216+ if (!make_current())
217+ return false;
218+
219+ if (offscreen_) {
220+ if (!ensure_fbo())
221+ return false;
222+
223+ glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
224+ }
225+
226+ return true;
227+}
228+
229+bool
230+CanvasX11::ensure_gl_formats()
231+{
232+ if (gl_color_format_ && gl_depth_format_)
233+ return true;
234+
235+ GLVisualInfo gl_visinfo;
236+ get_glvisualinfo(gl_visinfo);
237+
238+ gl_color_format_ = 0;
239+ gl_depth_format_ = 0;
240+
241+ bool supports_rgba8(false);
242+ bool supports_rgb8(false);
243+ bool supports_depth24(false);
244+ bool supports_depth32(false);
245+
246+#if USE_GLESv2
247+ if (GLExtensions::support("GL_ARM_rgba8"))
248+ supports_rgba8 = true;
249+
250+ if (GLExtensions::support("GL_OES_rgb8_rgba8")) {
251+ supports_rgba8 = true;
252+ supports_rgb8 = true;
253+ }
254+
255+ if (GLExtensions::support("GL_OES_depth24"))
256+ supports_depth24 = true;
257+
258+ if (GLExtensions::support("GL_OES_depth32"))
259+ supports_depth32 = true;
260+#elif USE_GL
261+ supports_rgba8 = true;
262+ supports_rgb8 = true;
263+ supports_depth24 = true;
264+ supports_depth32 = true;
265+#endif
266+
267+ if (gl_visinfo.buffer_size == 32) {
268+ if (supports_rgba8)
269+ gl_color_format_ = GL_RGBA8;
270+ else
271+ gl_color_format_ = GL_RGBA4;
272+ }
273+ else if (gl_visinfo.buffer_size == 24) {
274+ if (supports_rgb8)
275+ gl_color_format_ = GL_RGB8;
276+ else
277+ gl_color_format_ = GL_RGB565;
278+ }
279+ else if (gl_visinfo.buffer_size == 16) {
280+ if (gl_visinfo.red_size == 4 && gl_visinfo.green_size == 4 &&
281+ gl_visinfo.blue_size == 4 && gl_visinfo.alpha_size == 4)
282+ {
283+ gl_color_format_ = GL_RGBA4;
284+ }
285+ else if (gl_visinfo.red_size == 5 && gl_visinfo.green_size == 5 &&
286+ gl_visinfo.blue_size == 5 && gl_visinfo.alpha_size == 1)
287+ {
288+ gl_color_format_ = GL_RGB5_A1;
289+ }
290+ else if (gl_visinfo.red_size == 5 && gl_visinfo.green_size == 6 &&
291+ gl_visinfo.blue_size == 5 && gl_visinfo.alpha_size == 0)
292+ {
293+ gl_color_format_ = GL_RGB565;
294+ }
295+ }
296+
297+ if (gl_visinfo.depth_size == 32 && supports_depth32)
298+ gl_depth_format_ = GL_DEPTH_COMPONENT32;
299+ else if (gl_visinfo.depth_size >= 24 && supports_depth24)
300+ gl_depth_format_ = GL_DEPTH_COMPONENT24;
301+ else if (gl_visinfo.depth_size == 16)
302+ gl_depth_format_ = GL_DEPTH_COMPONENT16;
303+
304+ Log::debug("Selected Renderbuffer ColorFormat: %s DepthFormat: %s\n",
305+ get_gl_format_str(gl_color_format_),
306+ get_gl_format_str(gl_depth_format_));
307+
308+ return (gl_color_format_ && gl_depth_format_);
309+}
310+
311+bool
312+CanvasX11::ensure_fbo()
313+{
314+ if (!fbo_) {
315+ if (!ensure_gl_formats())
316+ return false;
317+
318+ /* Create a texture for the color attachment */
319+ glGenRenderbuffers(1, &color_renderbuffer_);
320+ glBindRenderbuffer(GL_RENDERBUFFER, color_renderbuffer_);
321+ glRenderbufferStorage(GL_RENDERBUFFER, gl_color_format_,
322+ width_, height_);
323+
324+ /* Create a renderbuffer for the depth attachment */
325+ glGenRenderbuffers(1, &depth_renderbuffer_);
326+ glBindRenderbuffer(GL_RENDERBUFFER, depth_renderbuffer_);
327+ glRenderbufferStorage(GL_RENDERBUFFER, gl_depth_format_,
328+ width_, height_);
329+
330+ /* Create a FBO and set it up */
331+ glGenFramebuffers(1, &fbo_);
332+ glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
333+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
334+ GL_RENDERBUFFER, color_renderbuffer_);
335+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
336+ GL_RENDERBUFFER, depth_renderbuffer_);
337+ }
338+
339+ return true;
340+}
341+
342+void
343+CanvasX11::release_fbo()
344+{
345+ glDeleteFramebuffers(1, &fbo_);
346+ glDeleteRenderbuffers(1, &color_renderbuffer_);
347+ glDeleteRenderbuffers(1, &depth_renderbuffer_);
348+ fbo_ = 0;
349+ color_renderbuffer_ = 0;
350+ depth_renderbuffer_ = 0;
351+
352+ gl_color_format_ = 0;
353+ gl_depth_format_ = 0;
354+}
355+
356+const char *
357+CanvasX11::get_gl_format_str(GLenum f)
358+{
359+ const char *str;
360+
361+ switch(f) {
362+ case GL_RGBA8: str = "GL_RGBA8"; break;
363+ case GL_RGB8: str = "GL_RGB8"; break;
364+ case GL_RGBA4: str = "GL_RGBA4"; break;
365+ case GL_RGB5_A1: str = "GL_RGB5_A1"; break;
366+ case GL_RGB565: str = "GL_RGB565"; break;
367+ case GL_DEPTH_COMPONENT16: str = "GL_DEPTH_COMPONENT16"; break;
368+ case GL_DEPTH_COMPONENT24: str = "GL_DEPTH_COMPONENT24"; break;
369+ case GL_DEPTH_COMPONENT32: str = "GL_DEPTH_COMPONENT32"; break;
370+ case GL_NONE: str = "GL_NONE"; break;
371+ default: str = "Unknown"; break;
372+ }
373+
374+ return str;
375+}
376+
377
378=== modified file 'src/canvas-x11.h'
379--- src/canvas-x11.h 2012-01-04 00:37:12 +0000
380+++ src/canvas-x11.h 2012-03-20 14:03:47 +0000
381@@ -44,10 +44,25 @@
382 virtual void write_to_file(std::string &filename);
383 virtual bool should_quit();
384 virtual void resize(int width, int height);
385+ virtual unsigned int fbo();
386
387 protected:
388 CanvasX11(int width, int height) :
389- Canvas(width, height), xwin_(0), xdpy_(0) {}
390+ Canvas(width, height), xwin_(0), xdpy_(0),
391+ gl_color_format_(0), gl_depth_format_(0),
392+ color_renderbuffer_(0), depth_renderbuffer_(0), fbo_(0) {}
393+
394+ /**
395+ * Information about a GL visual.
396+ */
397+ struct GLVisualInfo {
398+ int buffer_size;
399+ int red_size;
400+ int green_size;
401+ int blue_size;
402+ int alpha_size;
403+ int depth_size;
404+ };
405
406 /**
407 * Gets the XVisualInfo to use for creating the X window with.
408@@ -88,6 +103,13 @@
409 virtual void swap_buffers() = 0;
410
411 /**
412+ * Gets information about the GL visual used for this canvas.
413+ *
414+ * This method should be implemented in derived classes.
415+ */
416+ virtual void get_glvisualinfo(GLVisualInfo &gl_visinfo) = 0;
417+
418+ /**
419 * Whether the current implementation supports GL(ES) 2.0.
420 *
421 * @return true if it supports GL(ES) 2.0, false otherwise
422@@ -103,6 +125,18 @@
423 private:
424 void resize_no_viewport(int width, int height);
425 bool ensure_x_window();
426+ bool do_make_current();
427+ bool ensure_gl_formats();
428+ bool ensure_fbo();
429+ void release_fbo();
430+
431+ const char *get_gl_format_str(GLenum f);
432+
433+ GLenum gl_color_format_;
434+ GLenum gl_depth_format_;
435+ GLuint color_renderbuffer_;
436+ GLuint depth_renderbuffer_;
437+ GLuint fbo_;
438 };
439
440 #endif
441
442=== modified file 'src/canvas.h'
443--- src/canvas.h 2012-01-04 00:37:12 +0000
444+++ src/canvas.h 2012-03-20 14:03:47 +0000
445@@ -191,6 +191,13 @@
446 virtual void resize(int width, int height) { static_cast<void>(width); static_cast<void>(height); }
447
448 /**
449+ * Gets the FBO associated with the canvas.
450+ *
451+ * @return the FBO
452+ */
453+ virtual unsigned int fbo() { return 0; }
454+
455+ /**
456 * Gets a dummy canvas object.
457 *
458 * @return the dummy canvas
459@@ -224,12 +231,21 @@
460 */
461 const LibMatrix::mat4 &projection() { return projection_; }
462
463+ /**
464+ * Sets whether the canvas should be backed by an off-screen surface.
465+ *
466+ * This takes effect after the next init()/reset().
467+ */
468+ void offscreen(bool offscreen) { offscreen_ = offscreen; }
469+
470 protected:
471- Canvas(int width, int height) : width_(width), height_(height) {}
472+ Canvas(int width, int height) :
473+ width_(width), height_(height), offscreen_(false) {}
474
475 int width_;
476 int height_;
477 LibMatrix::mat4 projection_;
478+ bool offscreen_;
479 };
480
481 #endif
482
483=== modified file 'src/gl-headers.cpp'
484--- src/gl-headers.cpp 2011-10-10 11:00:36 +0000
485+++ src/gl-headers.cpp 2012-03-20 14:03:47 +0000
486@@ -24,3 +24,23 @@
487 void* (*GLExtensions::MapBuffer) (GLenum target, GLenum access) = 0;
488 GLboolean (*GLExtensions::UnmapBuffer) (GLenum target) = 0;
489
490+bool
491+GLExtensions::support(const std::string &ext)
492+{
493+ std::string ext_string;
494+ const char* exts = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
495+ if (exts) {
496+ ext_string = exts;
497+ }
498+
499+ const size_t ext_size = ext.size();
500+ size_t pos = 0;
501+
502+ while ((pos = ext_string.find(ext, pos)) != std::string::npos) {
503+ char c = ext_string[pos + ext_size];
504+ if (c == ' ' || c == '\0')
505+ break;
506+ }
507+
508+ return pos != std::string::npos;
509+}
510
511=== modified file 'src/gl-headers.h'
512--- src/gl-headers.h 2011-10-26 11:12:19 +0000
513+++ src/gl-headers.h 2012-03-20 14:03:47 +0000
514@@ -27,19 +27,43 @@
515 #if USE_GL
516 #include <GL/gl.h>
517 #include <GL/glext.h>
518+#ifndef GL_RGB565
519+#define GL_RGB565 0x8D62
520+#endif
521 #elif USE_GLESv2
522 #include <GLES2/gl2.h>
523 #include <GLES2/gl2ext.h>
524 #ifndef GL_WRITE_ONLY
525 #define GL_WRITE_ONLY GL_WRITE_ONLY_OES
526 #endif
527-#endif
528+#ifndef GL_DEPTH_COMPONENT24
529+#define GL_DEPTH_COMPONENT24 GL_DEPTH_COMPONENT24_OES
530+#endif
531+#ifndef GL_DEPTH_COMPONENT32
532+#define GL_DEPTH_COMPONENT32 GL_DEPTH_COMPONENT32_OES
533+#endif
534+#ifndef GL_RGBA8
535+#define GL_RGBA8 GL_RGBA8_OES
536+#endif
537+#ifndef GL_RGB8
538+#define GL_RGB8 GL_RGB8_OES
539+#endif
540+#endif
541+
542+#include <string>
543
544 /**
545 * Struct that holds pointers to functions that belong to extensions
546 * in either GL2.0 or GLES2.0.
547 */
548 struct GLExtensions {
549+ /**
550+ * Whether the current context has support for a GL extension.
551+ *
552+ * @return true if the extension is supported
553+ */
554+ static bool support(const std::string &ext);
555+
556 static void* (*MapBuffer) (GLenum target, GLenum access);
557 static GLboolean (*UnmapBuffer) (GLenum target);
558 };
559
560=== modified file 'src/main.cpp'
561--- src/main.cpp 2012-03-09 09:40:49 +0000
562+++ src/main.cpp 2012-03-20 14:03:47 +0000
563@@ -165,6 +165,8 @@
564 CanvasX11EGL canvas(Options::size.first, Options::size.second);
565 #endif
566
567+ canvas.offscreen(Options::offscreen);
568+
569 vector<Scene*> scenes;
570
571 // Register the scenes, so they can be looked up by name
572
573=== modified file 'src/options.cpp'
574--- src/options.cpp 2012-02-16 09:03:42 +0000
575+++ src/options.cpp 2012-03-20 14:03:47 +0000
576@@ -33,7 +33,7 @@
577 std::vector<std::string> Options::benchmarks;
578 std::vector<std::string> Options::benchmark_files;
579 bool Options::validate = false;
580-bool Options::swap_buffers = true;
581+Options::FrameEnd Options::frame_end = Options::FrameEndDefault;
582 std::pair<int,int> Options::size(800, 600);
583 bool Options::list_scenes = false;
584 bool Options::show_all_options = false;
585@@ -42,13 +42,15 @@
586 bool Options::reuse_context = false;
587 bool Options::run_forever = false;
588 bool Options::annotate = false;
589+bool Options::offscreen = false;
590
591 static struct option long_options[] = {
592 {"annotate", 0, 0, 0},
593 {"benchmark", 1, 0, 0},
594 {"benchmark-file", 1, 0, 0},
595 {"validate", 0, 0, 0},
596- {"no-swap-buffers", 0, 0, 0},
597+ {"frame-end", 1, 0, 0},
598+ {"off-screen", 0, 0, 0},
599 {"reuse-context", 0, 0, 0},
600 {"run-forever", 0, 0, 0},
601 {"size", 1, 0, 0},
602@@ -83,6 +85,31 @@
603 size.second = size.first;
604 }
605
606+/**
607+ * Parses a frame-end method string
608+ *
609+ * @param str the string to parse
610+ *
611+ * @return the parsed frame end method
612+ */
613+static Options::FrameEnd
614+frame_end_from_str(const std::string &str)
615+{
616+ Options::FrameEnd m = Options::FrameEndDefault;
617+
618+ if (str == "swap")
619+ m = Options::FrameEndSwap;
620+ else if (str == "finish")
621+ m = Options::FrameEndFinish;
622+ else if (str == "readpixels")
623+ m = Options::FrameEndReadPixels;
624+ else if (str == "none")
625+ m = Options::FrameEndNone;
626+
627+ return m;
628+}
629+
630+
631 void
632 Options::print_help()
633 {
634@@ -96,8 +123,8 @@
635 " (the option can be used multiple times)\n"
636 " --validate Run a quick output validation test instead of \n"
637 " running the benchmarks\n"
638- " --no-swap-buffers Don't update the canvas by swapping the front and\n"
639- " back buffer, use glFinish() instead\n"
640+ " --frame-end METHOD How to end a frame [default,none,swap,finish,readpixels]\n"
641+ " --off-screen Render to an off-screen surface\n"
642 " --reuse-context Use a single context for all scenes\n"
643 " (by default, each scene gets its own context)\n"
644 " -s, --size WxH Size of the output window (default: 800x600)\n"
645@@ -139,8 +166,10 @@
646 Options::benchmark_files.push_back(optarg);
647 else if (!strcmp(optname, "validate"))
648 Options::validate = true;
649- else if (!strcmp(optname, "no-swap-buffers"))
650- Options::swap_buffers = false;
651+ else if (!strcmp(optname, "frame-end"))
652+ Options::frame_end = frame_end_from_str(optarg);
653+ else if (!strcmp(optname, "off-screen"))
654+ Options::offscreen = true;
655 else if (!strcmp(optname, "reuse-context"))
656 Options::reuse_context = true;
657 else if (c == 's' || !strcmp(optname, "size"))
658
659=== modified file 'src/options.h'
660--- src/options.h 2012-02-16 09:03:42 +0000
661+++ src/options.h 2012-03-20 14:03:47 +0000
662@@ -28,13 +28,21 @@
663 #include <vector>
664
665 struct Options {
666+ enum FrameEnd {
667+ FrameEndDefault,
668+ FrameEndNone,
669+ FrameEndSwap,
670+ FrameEndFinish,
671+ FrameEndReadPixels
672+ };
673+
674 static bool parse_args(int argc, char **argv);
675 static void print_help();
676
677 static std::vector<std::string> benchmarks;
678 static std::vector<std::string> benchmark_files;
679 static bool validate;
680- static bool swap_buffers;
681+ static FrameEnd frame_end;
682 static std::pair<int,int> size;
683 static bool list_scenes;
684 static bool show_all_options;
685@@ -43,6 +51,7 @@
686 static bool reuse_context;
687 static bool run_forever;
688 static bool annotate;
689+ static bool offscreen;
690 };
691
692 #endif /* OPTIONS_H_ */
693
694=== modified file 'src/scene-desktop.cpp'
695--- src/scene-desktop.cpp 2012-02-13 09:43:54 +0000
696+++ src/scene-desktop.cpp 2012-03-20 14:03:47 +0000
697@@ -356,6 +356,7 @@
698 class RenderScreen : public RenderObject
699 {
700 public:
701+ RenderScreen(Canvas &canvas) { fbo_ = canvas.fbo(); }
702 virtual void init() {}
703 virtual void release() {}
704 };
705@@ -736,8 +737,8 @@
706 RenderClearImage desktop;
707 std::vector<RenderObject *> windows;
708
709- SceneDesktopPrivate() :
710- desktop(GLMARK_DATA_PATH"/textures/effect-2d.png") {}
711+ SceneDesktopPrivate(Canvas &canvas) :
712+ screen(canvas), desktop(GLMARK_DATA_PATH"/textures/effect-2d.png") {}
713
714 ~SceneDesktopPrivate() { Util::dispose_pointer_vector(windows); }
715
716@@ -747,7 +748,7 @@
717 SceneDesktop::SceneDesktop(Canvas &canvas) :
718 Scene(canvas, "desktop")
719 {
720- priv_ = new SceneDesktopPrivate();
721+ priv_ = new SceneDesktopPrivate(canvas);
722 options_["effect"] = Scene::Option("effect", "blur",
723 "the effect to use [blur]");
724 options_["windows"] = Scene::Option("windows", "4",

Subscribers

People subscribed via source and target branches