Merge lp:~linaro-graphics-wg/glmark2/configurable-visual into lp:glmark2/2011.11
- configurable-visual
- Merge into trunk
Proposed by
Alexandros Frantzis
Status: | Merged |
---|---|
Merged at revision: | 208 |
Proposed branch: | lp:~linaro-graphics-wg/glmark2/configurable-visual |
Merge into: | lp:glmark2/2011.11 |
Diff against target: |
736 lines (+360/-59) 13 files modified
doc/glmark2.1.in (+5/-0) src/canvas-x11-egl.cpp (+72/-15) src/canvas-x11-egl.h (+4/-1) src/canvas-x11-glx.cpp (+54/-14) src/canvas-x11-glx.h (+4/-1) src/canvas-x11.cpp (+14/-14) src/canvas-x11.h (+1/-13) src/canvas.h (+10/-0) src/gl-visual-config.cpp (+120/-0) src/gl-visual-config.h (+64/-0) src/main.cpp (+2/-0) src/options.cpp (+8/-1) src/options.h (+2/-0) |
To merge this branch: | bzr merge lp:~linaro-graphics-wg/glmark2/configurable-visual |
Related bugs: | |
Related blueprints: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jesse Barker | Approve | ||
Review via email: mp+105642@code.launchpad.net |
Commit message
Description of the change
X11: Allow user configuration of visual used for rendering.
To post a comment you must log in.
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-03-22 10:37:35 +0000 |
3 | +++ doc/glmark2.1.in 2012-05-14 11:52:31 +0000 |
4 | @@ -27,6 +27,11 @@ |
5 | \fB\-\-off-screen\fR |
6 | Render to an off-screen surface |
7 | .TP |
8 | +\fB--visual-config\fR |
9 | +The visual configuration to use for the rendering target: |
10 | +\'red=R:green=G:blue=B:alpha=A:buffer=BUF'. The parameters may be defined |
11 | +in any order, and any omitted parameters assume a default value of '1' |
12 | +.TP |
13 | \fB\-\-reuse\-context\fR |
14 | Use a single context for all scenes |
15 | (by default, each scene gets its own context) |
16 | |
17 | === modified file 'src/canvas-x11-egl.cpp' |
18 | --- src/canvas-x11-egl.cpp 2012-03-20 11:16:03 +0000 |
19 | +++ src/canvas-x11-egl.cpp 2012-05-14 11:52:31 +0000 |
20 | @@ -25,6 +25,7 @@ |
21 | |
22 | #include <fstream> |
23 | #include <sstream> |
24 | +#include <climits> |
25 | |
26 | /********************* |
27 | * Protected methods * |
28 | @@ -87,17 +88,12 @@ |
29 | } |
30 | |
31 | void |
32 | -CanvasX11EGL::get_glvisualinfo(GLVisualInfo &gl_visinfo) |
33 | +CanvasX11EGL::get_glvisualconfig(GLVisualConfig &visual_config) |
34 | { |
35 | if (!ensure_egl_config()) |
36 | return; |
37 | |
38 | - eglGetConfigAttrib(egl_display_, egl_config_, EGL_BUFFER_SIZE, &gl_visinfo.buffer_size); |
39 | - eglGetConfigAttrib(egl_display_, egl_config_, EGL_RED_SIZE, &gl_visinfo.red_size); |
40 | - eglGetConfigAttrib(egl_display_, egl_config_, EGL_GREEN_SIZE, &gl_visinfo.green_size); |
41 | - eglGetConfigAttrib(egl_display_, egl_config_, EGL_BLUE_SIZE, &gl_visinfo.blue_size); |
42 | - eglGetConfigAttrib(egl_display_, egl_config_, EGL_ALPHA_SIZE, &gl_visinfo.alpha_size); |
43 | - eglGetConfigAttrib(egl_display_, egl_config_, EGL_DEPTH_SIZE, &gl_visinfo.depth_size); |
44 | + get_glvisualconfig_egl(egl_config_, visual_config); |
45 | } |
46 | |
47 | /******************* |
48 | @@ -129,12 +125,13 @@ |
49 | bool |
50 | CanvasX11EGL::ensure_egl_config() |
51 | { |
52 | - static const EGLint attribs[] = { |
53 | - EGL_RED_SIZE, 1, |
54 | - EGL_GREEN_SIZE, 1, |
55 | - EGL_BLUE_SIZE, 1, |
56 | - EGL_ALPHA_SIZE, 1, |
57 | - EGL_DEPTH_SIZE, 1, |
58 | + const EGLint attribs[] = { |
59 | + EGL_RED_SIZE, visual_config_.red, |
60 | + EGL_GREEN_SIZE, visual_config_.green, |
61 | + EGL_BLUE_SIZE, visual_config_.blue, |
62 | + EGL_ALPHA_SIZE, visual_config_.alpha, |
63 | + EGL_DEPTH_SIZE, visual_config_.depth, |
64 | + EGL_BUFFER_SIZE, visual_config_.buffer, |
65 | #ifdef USE_GLESv2 |
66 | EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
67 | #elif USE_GL |
68 | @@ -151,14 +148,32 @@ |
69 | if (!ensure_egl_display()) |
70 | return false; |
71 | |
72 | - if (!eglChooseConfig(egl_display_, attribs, &egl_config_, |
73 | - 1, &num_configs)) |
74 | + /* Find out how many configs match the attributes */ |
75 | + if (!eglChooseConfig(egl_display_, attribs, 0, 0, &num_configs)) { |
76 | + Log::error("eglChooseConfig() (explore) failed with error: %d\n", |
77 | + eglGetError()); |
78 | + return false; |
79 | + } |
80 | + |
81 | + if (num_configs == 0) { |
82 | + Log::error("eglChooseConfig() didn't return any configs\n"); |
83 | + return false; |
84 | + } |
85 | + |
86 | + /* Get all the matching configs */ |
87 | + std::vector<EGLConfig> configs(num_configs); |
88 | + |
89 | + if (!eglChooseConfig(egl_display_, attribs, &(configs[0]), |
90 | + num_configs, &num_configs)) |
91 | { |
92 | Log::error("eglChooseConfig() failed with error: %d\n", |
93 | eglGetError()); |
94 | return false; |
95 | } |
96 | |
97 | + /* Select the best matching config */ |
98 | + egl_config_ = select_best_config(configs); |
99 | + |
100 | if (!eglGetConfigAttrib(egl_display_, egl_config_, |
101 | EGL_NATIVE_VISUAL_ID, &vid)) |
102 | { |
103 | @@ -281,3 +296,45 @@ |
104 | GLExtensions::UnmapBuffer = glUnmapBuffer; |
105 | #endif |
106 | } |
107 | + |
108 | +void |
109 | +CanvasX11EGL::get_glvisualconfig_egl(EGLConfig config, GLVisualConfig &visual_config) |
110 | +{ |
111 | + eglGetConfigAttrib(egl_display_, config, EGL_BUFFER_SIZE, &visual_config.buffer); |
112 | + eglGetConfigAttrib(egl_display_, config, EGL_RED_SIZE, &visual_config.red); |
113 | + eglGetConfigAttrib(egl_display_, config, EGL_GREEN_SIZE, &visual_config.green); |
114 | + eglGetConfigAttrib(egl_display_, config, EGL_BLUE_SIZE, &visual_config.blue); |
115 | + eglGetConfigAttrib(egl_display_, config, EGL_ALPHA_SIZE, &visual_config.alpha); |
116 | + eglGetConfigAttrib(egl_display_, config, EGL_DEPTH_SIZE, &visual_config.depth); |
117 | +} |
118 | + |
119 | +EGLConfig |
120 | +CanvasX11EGL::select_best_config(std::vector<EGLConfig> configs) |
121 | +{ |
122 | + int best_score(INT_MIN); |
123 | + EGLConfig best_config(0); |
124 | + |
125 | + /* |
126 | + * Go through all the configs and choose the one with the best score, |
127 | + * i.e., the one better matching the requested config. |
128 | + */ |
129 | + for (std::vector<EGLConfig>::const_iterator iter = configs.begin(); |
130 | + iter != configs.end(); |
131 | + iter++) |
132 | + { |
133 | + const EGLConfig config(*iter); |
134 | + GLVisualConfig vc; |
135 | + int score; |
136 | + |
137 | + get_glvisualconfig_egl(config, vc); |
138 | + |
139 | + score = vc.match_score(visual_config_); |
140 | + |
141 | + if (score > best_score) { |
142 | + best_score = score; |
143 | + best_config = config; |
144 | + } |
145 | + } |
146 | + |
147 | + return best_config; |
148 | +} |
149 | |
150 | === modified file 'src/canvas-x11-egl.h' |
151 | --- src/canvas-x11-egl.h 2012-03-19 16:55:27 +0000 |
152 | +++ src/canvas-x11-egl.h 2012-05-14 11:52:31 +0000 |
153 | @@ -25,6 +25,7 @@ |
154 | #include "canvas-x11.h" |
155 | |
156 | #include <EGL/egl.h> |
157 | +#include <vector> |
158 | |
159 | /** |
160 | * Canvas for rendering to an X11 window using EGL. |
161 | @@ -43,7 +44,7 @@ |
162 | bool make_current(); |
163 | bool reset_context(); |
164 | void swap_buffers() { eglSwapBuffers(egl_display_, egl_surface_); } |
165 | - void get_glvisualinfo(GLVisualInfo &gl_visinfo); |
166 | + void get_glvisualconfig(GLVisualConfig &visual_config); |
167 | |
168 | private: |
169 | bool ensure_egl_display(); |
170 | @@ -51,6 +52,8 @@ |
171 | bool ensure_egl_context(); |
172 | bool ensure_egl_surface(); |
173 | void init_gl_extensions(); |
174 | + void get_glvisualconfig_egl(EGLConfig config, GLVisualConfig &visual_config); |
175 | + EGLConfig select_best_config(std::vector<EGLConfig> configs); |
176 | |
177 | EGLDisplay egl_display_; |
178 | EGLSurface egl_surface_; |
179 | |
180 | === modified file 'src/canvas-x11-glx.cpp' |
181 | --- src/canvas-x11-glx.cpp 2012-03-19 16:55:27 +0000 |
182 | +++ src/canvas-x11-glx.cpp 2012-05-14 11:52:31 +0000 |
183 | @@ -24,6 +24,7 @@ |
184 | #include "options.h" |
185 | |
186 | #include <string> |
187 | +#include <climits> |
188 | |
189 | static PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT_; |
190 | static PFNGLXSWAPINTERVALMESAPROC glXSwapIntervalMESA_; |
191 | @@ -69,17 +70,12 @@ |
192 | } |
193 | |
194 | void |
195 | -CanvasX11GLX::get_glvisualinfo(GLVisualInfo &gl_visinfo) |
196 | +CanvasX11GLX::get_glvisualconfig(GLVisualConfig &visual_config) |
197 | { |
198 | if (!ensure_glx_fbconfig()) |
199 | return; |
200 | |
201 | - glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_BUFFER_SIZE, &gl_visinfo.buffer_size); |
202 | - glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_RED_SIZE, &gl_visinfo.red_size); |
203 | - glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_GREEN_SIZE, &gl_visinfo.green_size); |
204 | - glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_BLUE_SIZE, &gl_visinfo.blue_size); |
205 | - glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_ALPHA_SIZE, &gl_visinfo.alpha_size); |
206 | - glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_DEPTH_SIZE, &gl_visinfo.depth_size); |
207 | + get_glvisualconfig_glx(glx_fbconfig_, visual_config); |
208 | } |
209 | |
210 | /******************* |
211 | @@ -151,11 +147,12 @@ |
212 | GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, |
213 | GLX_RENDER_TYPE, GLX_RGBA_BIT, |
214 | GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, |
215 | - GLX_RED_SIZE, 1, |
216 | - GLX_GREEN_SIZE, 1, |
217 | - GLX_BLUE_SIZE, 1, |
218 | - GLX_ALPHA_SIZE, 1, |
219 | - GLX_DEPTH_SIZE, 1, |
220 | + GLX_RED_SIZE, visual_config_.red, |
221 | + GLX_GREEN_SIZE, visual_config_.green, |
222 | + GLX_BLUE_SIZE, visual_config_.blue, |
223 | + GLX_ALPHA_SIZE, visual_config_.alpha, |
224 | + GLX_DEPTH_SIZE, visual_config_.depth, |
225 | + GLX_BUFFER_SIZE, visual_config_.buffer, |
226 | GLX_DOUBLEBUFFER, True, |
227 | None |
228 | }; |
229 | @@ -174,10 +171,12 @@ |
230 | return false; |
231 | } |
232 | |
233 | + std::vector<GLXFBConfig> configs(fbc, fbc + num_configs); |
234 | + |
235 | Log::debug("Found %d matching FB configs.\n", num_configs); |
236 | |
237 | - /* Get the first matching config */ |
238 | - glx_fbconfig_ = fbc[0]; |
239 | + /* Select the best matching config */ |
240 | + glx_fbconfig_ = select_best_config(configs); |
241 | |
242 | XFree(fbc); |
243 | |
244 | @@ -243,3 +242,44 @@ |
245 | return true; |
246 | } |
247 | |
248 | +void |
249 | +CanvasX11GLX::get_glvisualconfig_glx(const GLXFBConfig config, GLVisualConfig &visual_config) |
250 | +{ |
251 | + glXGetFBConfigAttrib(xdpy_, config, GLX_BUFFER_SIZE, &visual_config.buffer); |
252 | + glXGetFBConfigAttrib(xdpy_, config, GLX_RED_SIZE, &visual_config.red); |
253 | + glXGetFBConfigAttrib(xdpy_, config, GLX_GREEN_SIZE, &visual_config.green); |
254 | + glXGetFBConfigAttrib(xdpy_, config, GLX_BLUE_SIZE, &visual_config.blue); |
255 | + glXGetFBConfigAttrib(xdpy_, config, GLX_ALPHA_SIZE, &visual_config.alpha); |
256 | + glXGetFBConfigAttrib(xdpy_, config, GLX_DEPTH_SIZE, &visual_config.depth); |
257 | +} |
258 | + |
259 | +GLXFBConfig |
260 | +CanvasX11GLX::select_best_config(std::vector<GLXFBConfig> configs) |
261 | +{ |
262 | + int best_score(INT_MIN); |
263 | + GLXFBConfig best_config(0); |
264 | + |
265 | + /* |
266 | + * Go through all the configs and choose the one with the best score, |
267 | + * i.e., the one better matching the requested config. |
268 | + */ |
269 | + for (std::vector<GLXFBConfig>::const_iterator iter = configs.begin(); |
270 | + iter != configs.end(); |
271 | + iter++) |
272 | + { |
273 | + const GLXFBConfig config(*iter); |
274 | + GLVisualConfig vc; |
275 | + int score; |
276 | + |
277 | + get_glvisualconfig_glx(config, vc); |
278 | + |
279 | + score = vc.match_score(visual_config_); |
280 | + |
281 | + if (score > best_score) { |
282 | + best_score = score; |
283 | + best_config = config; |
284 | + } |
285 | + } |
286 | + |
287 | + return best_config; |
288 | +} |
289 | |
290 | === modified file 'src/canvas-x11-glx.h' |
291 | --- src/canvas-x11-glx.h 2012-03-19 16:55:27 +0000 |
292 | +++ src/canvas-x11-glx.h 2012-05-14 11:52:31 +0000 |
293 | @@ -27,6 +27,7 @@ |
294 | #define GLX_GLXEXT_PROTOTYPES |
295 | #include <GL/glx.h> |
296 | #include <GL/glxext.h> |
297 | +#include <vector> |
298 | |
299 | /** |
300 | * Canvas for rendering to an X11 window using GLX. |
301 | @@ -43,7 +44,7 @@ |
302 | bool make_current(); |
303 | bool reset_context(); |
304 | void swap_buffers() { glXSwapBuffers(xdpy_, xwin_); } |
305 | - void get_glvisualinfo(GLVisualInfo &gl_visinfo); |
306 | + void get_glvisualconfig(GLVisualConfig &visual_config); |
307 | |
308 | private: |
309 | bool check_glx_version(); |
310 | @@ -51,6 +52,8 @@ |
311 | bool ensure_glx_fbconfig(); |
312 | bool ensure_glx_context(); |
313 | void init_gl_extensions(); |
314 | + void get_glvisualconfig_glx(GLXFBConfig config, GLVisualConfig &visual_config); |
315 | + GLXFBConfig select_best_config(std::vector<GLXFBConfig> configs); |
316 | |
317 | GLXFBConfig glx_fbconfig_; |
318 | GLXContext glx_context_; |
319 | |
320 | === modified file 'src/canvas-x11.cpp' |
321 | --- src/canvas-x11.cpp 2012-05-07 12:45:34 +0000 |
322 | +++ src/canvas-x11.cpp 2012-05-14 11:52:31 +0000 |
323 | @@ -350,8 +350,8 @@ |
324 | if (gl_color_format_ && gl_depth_format_) |
325 | return true; |
326 | |
327 | - GLVisualInfo gl_visinfo; |
328 | - get_glvisualinfo(gl_visinfo); |
329 | + GLVisualConfig vc; |
330 | + get_glvisualconfig(vc); |
331 | |
332 | gl_color_format_ = 0; |
333 | gl_depth_format_ = 0; |
334 | @@ -382,41 +382,41 @@ |
335 | supports_depth32 = true; |
336 | #endif |
337 | |
338 | - if (gl_visinfo.buffer_size == 32) { |
339 | + if (vc.buffer == 32) { |
340 | if (supports_rgba8) |
341 | gl_color_format_ = GL_RGBA8; |
342 | else |
343 | gl_color_format_ = GL_RGBA4; |
344 | } |
345 | - else if (gl_visinfo.buffer_size == 24) { |
346 | + else if (vc.buffer == 24) { |
347 | if (supports_rgb8) |
348 | gl_color_format_ = GL_RGB8; |
349 | else |
350 | gl_color_format_ = GL_RGB565; |
351 | } |
352 | - else if (gl_visinfo.buffer_size == 16) { |
353 | - if (gl_visinfo.red_size == 4 && gl_visinfo.green_size == 4 && |
354 | - gl_visinfo.blue_size == 4 && gl_visinfo.alpha_size == 4) |
355 | + else if (vc.buffer == 16) { |
356 | + if (vc.red == 4 && vc.green == 4 && |
357 | + vc.blue == 4 && vc.alpha == 4) |
358 | { |
359 | gl_color_format_ = GL_RGBA4; |
360 | } |
361 | - else if (gl_visinfo.red_size == 5 && gl_visinfo.green_size == 5 && |
362 | - gl_visinfo.blue_size == 5 && gl_visinfo.alpha_size == 1) |
363 | + else if (vc.red == 5 && vc.green == 5 && |
364 | + vc.blue == 5 && vc.alpha == 1) |
365 | { |
366 | gl_color_format_ = GL_RGB5_A1; |
367 | } |
368 | - else if (gl_visinfo.red_size == 5 && gl_visinfo.green_size == 6 && |
369 | - gl_visinfo.blue_size == 5 && gl_visinfo.alpha_size == 0) |
370 | + else if (vc.red == 5 && vc.green == 6 && |
371 | + vc.blue == 5 && vc.alpha == 0) |
372 | { |
373 | gl_color_format_ = GL_RGB565; |
374 | } |
375 | } |
376 | |
377 | - if (gl_visinfo.depth_size == 32 && supports_depth32) |
378 | + if (vc.depth == 32 && supports_depth32) |
379 | gl_depth_format_ = GL_DEPTH_COMPONENT32; |
380 | - else if (gl_visinfo.depth_size >= 24 && supports_depth24) |
381 | + else if (vc.depth >= 24 && supports_depth24) |
382 | gl_depth_format_ = GL_DEPTH_COMPONENT24; |
383 | - else if (gl_visinfo.depth_size == 16) |
384 | + else if (vc.depth == 16) |
385 | gl_depth_format_ = GL_DEPTH_COMPONENT16; |
386 | |
387 | Log::debug("Selected Renderbuffer ColorFormat: %s DepthFormat: %s\n", |
388 | |
389 | === modified file 'src/canvas-x11.h' |
390 | --- src/canvas-x11.h 2012-03-20 11:29:09 +0000 |
391 | +++ src/canvas-x11.h 2012-05-14 11:52:31 +0000 |
392 | @@ -53,18 +53,6 @@ |
393 | color_renderbuffer_(0), depth_renderbuffer_(0), fbo_(0) {} |
394 | |
395 | /** |
396 | - * Information about a GL visual. |
397 | - */ |
398 | - struct GLVisualInfo { |
399 | - int buffer_size; |
400 | - int red_size; |
401 | - int green_size; |
402 | - int blue_size; |
403 | - int alpha_size; |
404 | - int depth_size; |
405 | - }; |
406 | - |
407 | - /** |
408 | * Gets the XVisualInfo to use for creating the X window with. |
409 | * |
410 | * The caller should XFree() the returned XVisualInfo when done. |
411 | @@ -107,7 +95,7 @@ |
412 | * |
413 | * This method should be implemented in derived classes. |
414 | */ |
415 | - virtual void get_glvisualinfo(GLVisualInfo &gl_visinfo) = 0; |
416 | + virtual void get_glvisualconfig(GLVisualConfig &visual_config) = 0; |
417 | |
418 | /** |
419 | * Whether the current implementation supports GL(ES) 2.0. |
420 | |
421 | === modified file 'src/canvas.h' |
422 | --- src/canvas.h 2012-03-15 12:17:22 +0000 |
423 | +++ src/canvas.h 2012-05-14 11:52:31 +0000 |
424 | @@ -27,6 +27,7 @@ |
425 | |
426 | #include "gl-headers.h" |
427 | #include "mat.h" |
428 | +#include "gl-visual-config.h" |
429 | |
430 | #include <sys/types.h> |
431 | #include <string> |
432 | @@ -86,6 +87,7 @@ |
433 | uint8_t a; |
434 | }; |
435 | |
436 | + |
437 | /** |
438 | * Initializes the canvas and makes it the target of GL operations. |
439 | * |
440 | @@ -238,6 +240,13 @@ |
441 | */ |
442 | void offscreen(bool offscreen) { offscreen_ = offscreen; } |
443 | |
444 | + /** |
445 | + * Sets the preferred visual configuration. |
446 | + * |
447 | + * This takes effect after the next init()/reset(). |
448 | + */ |
449 | + void visual_config(GLVisualConfig &config) { visual_config_ = config; } |
450 | + |
451 | protected: |
452 | Canvas(int width, int height) : |
453 | width_(width), height_(height), offscreen_(false) {} |
454 | @@ -246,6 +255,7 @@ |
455 | int height_; |
456 | LibMatrix::mat4 projection_; |
457 | bool offscreen_; |
458 | + GLVisualConfig visual_config_; |
459 | }; |
460 | |
461 | #endif |
462 | |
463 | === added file 'src/gl-visual-config.cpp' |
464 | --- src/gl-visual-config.cpp 1970-01-01 00:00:00 +0000 |
465 | +++ src/gl-visual-config.cpp 2012-05-14 11:52:31 +0000 |
466 | @@ -0,0 +1,120 @@ |
467 | +/* |
468 | + * Copyright © 2012 Linaro Limited |
469 | + * |
470 | + * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark. |
471 | + * |
472 | + * glmark2 is free software: you can redistribute it and/or modify it under the |
473 | + * terms of the GNU General Public License as published by the Free Software |
474 | + * Foundation, either version 3 of the License, or (at your option) any later |
475 | + * version. |
476 | + * |
477 | + * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY |
478 | + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
479 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
480 | + * details. |
481 | + * |
482 | + * You should have received a copy of the GNU General Public License along with |
483 | + * glmark2. If not, see <http://www.gnu.org/licenses/>. |
484 | + * |
485 | + * Authors: |
486 | + * Alexandros Frantzis <alexandros.frantzis@linaro.org> |
487 | + */ |
488 | +#include "gl-visual-config.h" |
489 | +#include "util.h" |
490 | +#include "log.h" |
491 | + |
492 | +#include <vector> |
493 | + |
494 | +GLVisualConfig::GLVisualConfig(const std::string &s) : |
495 | + red(1), green(1), blue(1), alpha(1), depth(1), buffer(1) |
496 | +{ |
497 | + std::vector<std::string> elems; |
498 | + |
499 | + Util::split(s, ':', elems); |
500 | + |
501 | + for (std::vector<std::string>::const_iterator iter = elems.begin(); |
502 | + iter != elems.end(); |
503 | + iter++) |
504 | + { |
505 | + std::vector<std::string> opt; |
506 | + |
507 | + Util::split(*iter, '=', opt); |
508 | + if (opt.size() == 2) { |
509 | + if (opt[0] == "r" || opt[0] == "red") |
510 | + red = Util::fromString<int>(opt[1]); |
511 | + else if (opt[0] == "g" || opt[0] == "green") |
512 | + green = Util::fromString<int>(opt[1]); |
513 | + else if (opt[0] == "b" || opt[0] == "blue") |
514 | + blue = Util::fromString<int>(opt[1]); |
515 | + else if (opt[0] == "a" || opt[0] == "alpha") |
516 | + alpha = Util::fromString<int>(opt[1]); |
517 | + else if (opt[0] == "d" || opt[0] == "depth") |
518 | + depth = Util::fromString<int>(opt[1]); |
519 | + else if (opt[0] == "buf" || opt[0] == "buffer") |
520 | + buffer = Util::fromString<int>(opt[1]); |
521 | + } |
522 | + else |
523 | + Log::info("Warning: ignoring invalid option string '%s' " |
524 | + "in GLVisualConfig description\n", |
525 | + iter->c_str()); |
526 | + } |
527 | +} |
528 | + |
529 | +int |
530 | +GLVisualConfig::match_score(const GLVisualConfig &target) const |
531 | +{ |
532 | + int score(0); |
533 | + |
534 | + /* |
535 | + * R,G,B,A integer values are at most 8 bits wide (for current widespread |
536 | + * hardware), so we need to scale them by 4 to get them in the [0,32] range. |
537 | + */ |
538 | + score += score_component(red, target.red, 4); |
539 | + score += score_component(green, target.green, 4); |
540 | + score += score_component(blue, target.blue, 4); |
541 | + score += score_component(alpha, target.alpha, 4); |
542 | + score += score_component(depth, target.depth, 1); |
543 | + score += score_component(buffer, target.buffer, 1); |
544 | + |
545 | + return score; |
546 | +} |
547 | + |
548 | +int |
549 | +GLVisualConfig::score_component(int component, int target, int scale) const |
550 | +{ |
551 | + /* |
552 | + * The maximum (positive) score that can be returned is based |
553 | + * on the maximum bit width of the components. We assume this to |
554 | + * be 32 bits, which is a reasonable assumption for current platforms. |
555 | + */ |
556 | + static const int MAXIMUM_COMPONENT_SCORE = 32; |
557 | + static const int UNACCEPTABLE_COMPONENT_PENALTY = -1000; |
558 | + int score(0); |
559 | + |
560 | + if ((component > 0 && target == 0) || |
561 | + (component == 0 && target > 0)) |
562 | + { |
563 | + /* |
564 | + * Penalize components that are not present but have been requested, |
565 | + * and components that have been excluded but are present. |
566 | + */ |
567 | + score = UNACCEPTABLE_COMPONENT_PENALTY; |
568 | + } |
569 | + else if (component == target) |
570 | + { |
571 | + /* Reward exact matches with the maximum per component score */ |
572 | + score = MAXIMUM_COMPONENT_SCORE; |
573 | + } |
574 | + else |
575 | + { |
576 | + /* |
577 | + * Reward deeper than requested component values, penalize shallower |
578 | + * than requested component values. Because the ranges of component |
579 | + * values vary we use a scaling factor to even them out, so that the |
580 | + * score for all components ranges from [0,MAXIMUM_COMPONENT_SCORE). |
581 | + */ |
582 | + score = scale * (component - target); |
583 | + } |
584 | + |
585 | + return score; |
586 | +} |
587 | |
588 | === added file 'src/gl-visual-config.h' |
589 | --- src/gl-visual-config.h 1970-01-01 00:00:00 +0000 |
590 | +++ src/gl-visual-config.h 2012-05-14 11:52:31 +0000 |
591 | @@ -0,0 +1,64 @@ |
592 | +/* |
593 | + * Copyright © 2012 Linaro Limited |
594 | + * |
595 | + * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark. |
596 | + * |
597 | + * glmark2 is free software: you can redistribute it and/or modify it under the |
598 | + * terms of the GNU General Public License as published by the Free Software |
599 | + * Foundation, either version 3 of the License, or (at your option) any later |
600 | + * version. |
601 | + * |
602 | + * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY |
603 | + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
604 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
605 | + * details. |
606 | + * |
607 | + * You should have received a copy of the GNU General Public License along with |
608 | + * glmark2. If not, see <http://www.gnu.org/licenses/>. |
609 | + * |
610 | + * Authors: |
611 | + * Alexandros Frantzis <alexandros.frantzis@linaro.org> |
612 | + */ |
613 | +#ifndef GLMARK2_GL_VISUAL_CONFIG_H_ |
614 | +#define GLMARK2_GL_VISUAL_CONFIG_H_ |
615 | + |
616 | +#include <string> |
617 | + |
618 | +/** |
619 | + * Configuration parameters for a GL visual |
620 | + */ |
621 | +class GLVisualConfig |
622 | +{ |
623 | +public: |
624 | + GLVisualConfig(): |
625 | + red(1), green(1), blue(1), alpha(1), depth(1), buffer(1) {} |
626 | + GLVisualConfig(int r, int g, int b, int a, int d, int buf): |
627 | + red(r), green(g), blue(b), alpha(a), depth(d), buffer(buf) {} |
628 | + GLVisualConfig(const std::string &s); |
629 | + |
630 | + /** |
631 | + * How well a GLVisualConfig matches another target config. |
632 | + * |
633 | + * The returned score has no meaning on its own. Its only purpose is |
634 | + * to allow comparison of how well different configs match a target |
635 | + * config, with a higher scores denoting a better match. |
636 | + * |
637 | + * Also note that this operation is not commutative: |
638 | + * a.match_score(b) != b.match_score(a) |
639 | + * |
640 | + * @return the match score |
641 | + */ |
642 | + int match_score(const GLVisualConfig &target) const; |
643 | + |
644 | + int red; |
645 | + int green; |
646 | + int blue; |
647 | + int alpha; |
648 | + int depth; |
649 | + int buffer; |
650 | + |
651 | +private: |
652 | + int score_component(int component, int target, int scale) const; |
653 | +}; |
654 | + |
655 | +#endif |
656 | |
657 | === modified file 'src/main.cpp' |
658 | --- src/main.cpp 2012-04-27 18:00:45 +0000 |
659 | +++ src/main.cpp 2012-05-14 11:52:31 +0000 |
660 | @@ -168,6 +168,8 @@ |
661 | |
662 | canvas.offscreen(Options::offscreen); |
663 | |
664 | + canvas.visual_config(Options::visual_config); |
665 | + |
666 | vector<Scene*> scenes; |
667 | |
668 | // Register the scenes, so they can be looked up by name |
669 | |
670 | === modified file 'src/options.cpp' |
671 | --- src/options.cpp 2012-03-20 12:55:49 +0000 |
672 | +++ src/options.cpp 2012-05-14 11:52:31 +0000 |
673 | @@ -43,6 +43,7 @@ |
674 | bool Options::run_forever = false; |
675 | bool Options::annotate = false; |
676 | bool Options::offscreen = false; |
677 | +GLVisualConfig Options::visual_config; |
678 | |
679 | static struct option long_options[] = { |
680 | {"annotate", 0, 0, 0}, |
681 | @@ -51,6 +52,7 @@ |
682 | {"validate", 0, 0, 0}, |
683 | {"frame-end", 1, 0, 0}, |
684 | {"off-screen", 0, 0, 0}, |
685 | + {"visual-config", 1, 0, 0}, |
686 | {"reuse-context", 0, 0, 0}, |
687 | {"run-forever", 0, 0, 0}, |
688 | {"size", 1, 0, 0}, |
689 | @@ -109,7 +111,6 @@ |
690 | return m; |
691 | } |
692 | |
693 | - |
694 | void |
695 | Options::print_help() |
696 | { |
697 | @@ -125,6 +126,10 @@ |
698 | " running the benchmarks\n" |
699 | " --frame-end METHOD How to end a frame [default,none,swap,finish,readpixels]\n" |
700 | " --off-screen Render to an off-screen surface\n" |
701 | + " --visual-config C The visual configuration to use for the rendering\n" |
702 | + " target: 'red=R:green=G:blue=B:alpha=A:buffer=BUF'.\n" |
703 | + " The parameters may be defined in any order, and any\n" |
704 | + " omitted parameters assume a default value of '1'\n" |
705 | " --reuse-context Use a single context for all scenes\n" |
706 | " (by default, each scene gets its own context)\n" |
707 | " -s, --size WxH Size of the output window (default: 800x600)\n" |
708 | @@ -170,6 +175,8 @@ |
709 | Options::frame_end = frame_end_from_str(optarg); |
710 | else if (!strcmp(optname, "off-screen")) |
711 | Options::offscreen = true; |
712 | + else if (!strcmp(optname, "visual-config")) |
713 | + Options::visual_config = GLVisualConfig(optarg); |
714 | else if (!strcmp(optname, "reuse-context")) |
715 | Options::reuse_context = true; |
716 | else if (c == 's' || !strcmp(optname, "size")) |
717 | |
718 | === modified file 'src/options.h' |
719 | --- src/options.h 2012-03-20 12:55:49 +0000 |
720 | +++ src/options.h 2012-05-14 11:52:31 +0000 |
721 | @@ -26,6 +26,7 @@ |
722 | |
723 | #include <string> |
724 | #include <vector> |
725 | +#include "gl-visual-config.h" |
726 | |
727 | struct Options { |
728 | enum FrameEnd { |
729 | @@ -52,6 +53,7 @@ |
730 | static bool run_forever; |
731 | static bool annotate; |
732 | static bool offscreen; |
733 | + static GLVisualConfig visual_config; |
734 | }; |
735 | |
736 | #endif /* OPTIONS_H_ */ |
Looks good. We might want to adjsust the handling (later) for the situation where the user-specified config isn't available.