Merge lp:~linaro-graphics-wg/glmark2/desktop into lp:glmark2/2011.11
- desktop
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 130 |
Proposed branch: | lp:~linaro-graphics-wg/glmark2/desktop |
Merge into: | lp:glmark2/2011.11 |
Diff against target: |
958 lines (+848/-8) 9 files modified
data/shaders/desktop-blur.frag (+17/-0) data/shaders/desktop.frag (+14/-0) data/shaders/desktop.vert (+11/-0) src/android.cpp (+2/-0) src/canvas-android.cpp (+2/-2) src/canvas-x11.cpp (+6/-6) src/main.cpp (+2/-0) src/scene-desktop.cpp (+775/-0) src/scene.h (+19/-0) |
To merge this branch: | bzr merge lp:~linaro-graphics-wg/glmark2/desktop |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jesse Barker | Pending | ||
Review via email: mp+75039@code.launchpad.net |
Commit message
Description of the change
New "desktop" benchmarking scene and one effect (blur).
Jesse Barker (jesse-barker) wrote : | # |
- 139. By Alexandros Frantzis
-
SceneDesktop: Set texture and fbo variables to 0 after deleting their resources.
- 140. By Alexandros Frantzis
-
SceneDesktop: Code cleanup.
Alexandros Frantzis (afrantzis) wrote : | # |
> > +protected:
> > + void draw_quad_
> *texcoord,
> > + Program &program)
>
> Why not make this take "const vector<vec2>& position" and "const
> vector<vec2>& texcoord"? Works just fine with the GL interfaces....
The reasons I am not keen on this are:
1. Currently (ie not C++11) there is no simple way to initialize a static const std::vector.
2. Due to the way the vector is going to be used in the function (&vector[0]), all safety benefits of using std::vector are essentially lost.
3. We don't really need a variable-size container in this case.
Preview Diff
1 | === added file 'data/shaders/desktop-blur.frag' |
2 | --- data/shaders/desktop-blur.frag 1970-01-01 00:00:00 +0000 |
3 | +++ data/shaders/desktop-blur.frag 2011-09-13 09:41:05 +0000 |
4 | @@ -0,0 +1,17 @@ |
5 | +#ifdef GL_ES |
6 | +precision mediump float; |
7 | +#endif |
8 | + |
9 | +uniform sampler2D Texture0; |
10 | + |
11 | +varying vec2 TextureCoord; |
12 | + |
13 | +void main(void) |
14 | +{ |
15 | + vec4 result; |
16 | + |
17 | + $CONVOLUTION$ |
18 | + |
19 | + gl_FragColor = result; |
20 | +} |
21 | + |
22 | |
23 | === added file 'data/shaders/desktop.frag' |
24 | --- data/shaders/desktop.frag 1970-01-01 00:00:00 +0000 |
25 | +++ data/shaders/desktop.frag 2011-09-13 09:41:05 +0000 |
26 | @@ -0,0 +1,14 @@ |
27 | +#ifdef GL_ES |
28 | +precision mediump float; |
29 | +#endif |
30 | + |
31 | +uniform sampler2D MaterialTexture0; |
32 | + |
33 | +varying vec2 TextureCoord; |
34 | + |
35 | +void main(void) |
36 | +{ |
37 | + vec4 texel = texture2D(MaterialTexture0, TextureCoord); |
38 | + gl_FragColor = texel; |
39 | +} |
40 | + |
41 | |
42 | === added file 'data/shaders/desktop.vert' |
43 | --- data/shaders/desktop.vert 1970-01-01 00:00:00 +0000 |
44 | +++ data/shaders/desktop.vert 2011-09-13 09:41:05 +0000 |
45 | @@ -0,0 +1,11 @@ |
46 | +attribute vec2 position; |
47 | +attribute vec2 texcoord; |
48 | + |
49 | +varying vec2 TextureCoord; |
50 | + |
51 | +void main(void) |
52 | +{ |
53 | + gl_Position = vec4(position, 0.0, 1.0); |
54 | + |
55 | + TextureCoord = texcoord; |
56 | +} |
57 | |
58 | === added file 'data/textures/desktop-window.png' |
59 | Binary files data/textures/desktop-window.png 1970-01-01 00:00:00 +0000 and data/textures/desktop-window.png 2011-09-13 09:41:05 +0000 differ |
60 | === modified file 'src/android.cpp' |
61 | --- src/android.cpp 2011-08-18 15:03:40 +0000 |
62 | +++ src/android.cpp 2011-09-13 09:41:05 +0000 |
63 | @@ -44,6 +44,7 @@ |
64 | "effect2d:kernel=0,1,0;1,-4,1;0,1,0;", |
65 | "effect2d:kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;", |
66 | "pulsar:quads=5:texture=false:light=false", |
67 | + "desktop:windows=4:effect=blur:blur-radius=5:passes=1:separable=true", |
68 | "conditionals:vertex-steps=0:fragment-steps=0", |
69 | "conditionals:vertex-steps=0:fragment-steps=5", |
70 | "conditionals:vertex-steps=5:fragment-steps=0", |
71 | @@ -85,6 +86,7 @@ |
72 | Benchmark::register_scene(*new SceneBump(*g_canvas)); |
73 | Benchmark::register_scene(*new SceneEffect2D(*g_canvas)); |
74 | Benchmark::register_scene(*new ScenePulsar(*g_canvas)); |
75 | + Benchmark::register_scene(*new SceneDesktop(canvas)); |
76 | |
77 | add_default_benchmarks(g_benchmarks); |
78 | |
79 | |
80 | === modified file 'src/canvas-android.cpp' |
81 | --- src/canvas-android.cpp 2011-08-10 18:00:03 +0000 |
82 | +++ src/canvas-android.cpp 2011-09-13 09:41:05 +0000 |
83 | @@ -35,8 +35,6 @@ |
84 | if (!eglSwapInterval(eglGetCurrentDisplay(), 0)) |
85 | Log::info("** Failed to set swap interval. Results may be bounded above by refresh rate.\n"); |
86 | |
87 | - glClearColor(0.0f, 0.0f, 0.0f, 0.5f); |
88 | - glClearDepthf(1.0f); |
89 | glEnable(GL_DEPTH_TEST); |
90 | glDepthFunc(GL_LEQUAL); |
91 | glEnable(GL_CULL_FACE); |
92 | @@ -56,6 +54,8 @@ |
93 | void |
94 | CanvasAndroid::clear() |
95 | { |
96 | + glClearColor(0.0f, 0.0f, 0.0f, 0.5f); |
97 | + glClearDepthf(1.0f); |
98 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
99 | } |
100 | |
101 | |
102 | === modified file 'src/canvas-x11.cpp' |
103 | --- src/canvas-x11.cpp 2011-08-09 10:51:03 +0000 |
104 | +++ src/canvas-x11.cpp 2011-09-13 09:41:05 +0000 |
105 | @@ -84,12 +84,6 @@ |
106 | if (!make_current()) |
107 | return false; |
108 | |
109 | - glClearColor(0.0f, 0.0f, 0.0f, 0.5f); |
110 | -#if USE_GL |
111 | - glClearDepth(1.0f); |
112 | -#elif USE_GLESv2 |
113 | - glClearDepthf(1.0f); |
114 | -#endif |
115 | glEnable(GL_DEPTH_TEST); |
116 | glDepthFunc(GL_LEQUAL); |
117 | glEnable(GL_CULL_FACE); |
118 | @@ -110,6 +104,12 @@ |
119 | void |
120 | CanvasX11::clear() |
121 | { |
122 | + glClearColor(0.0f, 0.0f, 0.0f, 0.5f); |
123 | +#if USE_GL |
124 | + glClearDepth(1.0f); |
125 | +#elif USE_GLESv2 |
126 | + glClearDepthf(1.0f); |
127 | +#endif |
128 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
129 | } |
130 | |
131 | |
132 | === modified file 'src/main.cpp' |
133 | --- src/main.cpp 2011-09-07 09:40:57 +0000 |
134 | +++ src/main.cpp 2011-09-13 09:41:05 +0000 |
135 | @@ -54,6 +54,7 @@ |
136 | "effect2d:kernel=0,1,0;1,-4,1;0,1,0;", |
137 | "effect2d:kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;", |
138 | "pulsar:quads=5:texture=false:light=false", |
139 | + "desktop:windows=4:effect=blur:blur-radius=5:passes=1:separable=true", |
140 | "conditionals:vertex-steps=0:fragment-steps=0", |
141 | "conditionals:vertex-steps=0:fragment-steps=5", |
142 | "conditionals:vertex-steps=5:fragment-steps=0", |
143 | @@ -96,6 +97,7 @@ |
144 | scenes.push_back(new SceneBump(canvas)); |
145 | scenes.push_back(new SceneEffect2D(canvas)); |
146 | scenes.push_back(new ScenePulsar(canvas)); |
147 | + scenes.push_back(new SceneDesktop(canvas)); |
148 | |
149 | for (vector<Scene*>::const_iterator iter = scenes.begin(); |
150 | iter != scenes.end(); |
151 | |
152 | === added file 'src/scene-desktop.cpp' |
153 | --- src/scene-desktop.cpp 1970-01-01 00:00:00 +0000 |
154 | +++ src/scene-desktop.cpp 2011-09-13 09:41:05 +0000 |
155 | @@ -0,0 +1,775 @@ |
156 | +/* |
157 | + * Copyright © 2010-2011 Linaro Limited |
158 | + * |
159 | + * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark. |
160 | + * |
161 | + * glmark2 is free software: you can redistribute it and/or modify it under the |
162 | + * terms of the GNU General Public License as published by the Free Software |
163 | + * Foundation, either version 3 of the License, or (at your option) any later |
164 | + * version. |
165 | + * |
166 | + * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY |
167 | + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
168 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
169 | + * details. |
170 | + * |
171 | + * You should have received a copy of the GNU General Public License along with |
172 | + * glmark2. If not, see <http://www.gnu.org/licenses/>. |
173 | + * |
174 | + * Authors: |
175 | + * Alexandros Frantzis (glmark2) |
176 | + */ |
177 | +#include <cmath> |
178 | + |
179 | +#include "scene.h" |
180 | +#include "mat.h" |
181 | +#include "stack.h" |
182 | +#include "vec.h" |
183 | +#include "log.h" |
184 | +#include "program.h" |
185 | +#include "shader-source.h" |
186 | +#include "util.h" |
187 | + |
188 | +enum BlurDirection { |
189 | + BlurDirectionHorizontal, |
190 | + BlurDirectionVertical, |
191 | + BlurDirectionBoth |
192 | +}; |
193 | + |
194 | +static void |
195 | +create_blur_shaders(ShaderSource& vtx_source, ShaderSource& frg_source, |
196 | + unsigned int radius, float sigma, BlurDirection direction) |
197 | +{ |
198 | + vtx_source.append_file(GLMARK_DATA_PATH"/shaders/desktop.vert"); |
199 | + frg_source.append_file(GLMARK_DATA_PATH"/shaders/desktop-blur.frag"); |
200 | + |
201 | + /* Don't let the gaussian curve become too narrow */ |
202 | + if (sigma < 1.0) |
203 | + sigma = 1.0; |
204 | + |
205 | + unsigned int side = 2 * radius + 1; |
206 | + |
207 | + for (size_t i = 0; i < radius + 1; i++) { |
208 | + float s2 = 2.0 * sigma * sigma; |
209 | + float k = 1.0 / std::sqrt(M_PI * s2) * std::exp( - ((float)i * i) / s2); |
210 | + std::stringstream ss_tmp; |
211 | + ss_tmp << "Kernel" << i; |
212 | + frg_source.add_const(ss_tmp.str(), k); |
213 | + } |
214 | + |
215 | + std::stringstream ss; |
216 | + ss << "result = " << std::endl; |
217 | + |
218 | + if (direction == BlurDirectionHorizontal) { |
219 | + for (size_t i = 0; i < side; i++) { |
220 | + int offset = (int)(i - radius); |
221 | + ss << "texture2D(Texture0, TextureCoord + vec2(" << |
222 | + offset << ".0 * TextureStepX, 0.0)) * Kernel" << |
223 | + std::abs(offset) << " +" << std::endl; |
224 | + } |
225 | + ss << "0.0 ;" << std::endl; |
226 | + } |
227 | + else if (direction == BlurDirectionVertical) { |
228 | + for (size_t i = 0; i < side; i++) { |
229 | + int offset = (int)(i - radius); |
230 | + ss << "texture2D(Texture0, TextureCoord + vec2(0.0, " << |
231 | + offset << ".0 * TextureStepY)) * Kernel" << |
232 | + std::abs(offset) << " +" << std::endl; |
233 | + } |
234 | + ss << "0.0 ;" << std::endl; |
235 | + } |
236 | + else if (direction == BlurDirectionBoth) { |
237 | + for (size_t i = 0; i < side; i++) { |
238 | + int ioffset = (int)(i - radius); |
239 | + for (size_t j = 0; j < side; j++) { |
240 | + int joffset = (int)(j - radius); |
241 | + ss << "texture2D(Texture0, TextureCoord + vec2(" << |
242 | + ioffset << ".0 * TextureStepX, " << |
243 | + joffset << ".0 * TextureStepY))" << |
244 | + " * Kernel" << std::abs(ioffset) << |
245 | + " * Kernel" << std::abs(joffset) << " +" << std::endl; |
246 | + } |
247 | + } |
248 | + ss << " 0.0;" << std::endl; |
249 | + } |
250 | + |
251 | + frg_source.replace("$CONVOLUTION$", ss.str()); |
252 | +} |
253 | + |
254 | +/** |
255 | + * A RenderObject represents a source and target of rendering |
256 | + * operations. |
257 | + */ |
258 | +class RenderObject |
259 | +{ |
260 | +public: |
261 | + RenderObject() : texture_(0), fbo_(0) { } |
262 | + |
263 | + virtual ~RenderObject() { release(); } |
264 | + |
265 | + virtual void init() |
266 | + { |
267 | + /* Create a texture to draw to */ |
268 | + glGenTextures(1, &texture_); |
269 | + glBindTexture(GL_TEXTURE_2D, texture_); |
270 | + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
271 | + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
272 | + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
273 | + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
274 | + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size_.x(), size_.y(), 0, |
275 | + GL_RGBA, GL_UNSIGNED_BYTE, 0); |
276 | + |
277 | + /* Create a FBO */ |
278 | + glGenFramebuffers(1, &fbo_); |
279 | + glBindFramebuffer(GL_FRAMEBUFFER, fbo_); |
280 | + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
281 | + GL_TEXTURE_2D, texture_, 0); |
282 | + |
283 | + glBindFramebuffer(GL_FRAMEBUFFER, 0); |
284 | + |
285 | + /* Load the shader program when this class if first used */ |
286 | + if (RenderObject::use_count == 0) { |
287 | + ShaderSource vtx_source(GLMARK_DATA_PATH"/shaders/desktop.vert"); |
288 | + ShaderSource frg_source(GLMARK_DATA_PATH"/shaders/desktop.frag"); |
289 | + Scene::load_shaders_from_strings(main_program, vtx_source.str(), |
290 | + frg_source.str()); |
291 | + } |
292 | + |
293 | + RenderObject::use_count++; |
294 | + } |
295 | + |
296 | + virtual void release() |
297 | + { |
298 | + /* Release resources */ |
299 | + glDeleteTextures(1, &texture_); |
300 | + glDeleteFramebuffers(1, &fbo_); |
301 | + texture_ = 0; |
302 | + fbo_ = 0; |
303 | + |
304 | + /* |
305 | + * Release the shader program when object of this class |
306 | + * are no longer in use. |
307 | + */ |
308 | + RenderObject::use_count--; |
309 | + if (RenderObject::use_count == 0) |
310 | + RenderObject::main_program.release(); |
311 | + } |
312 | + |
313 | + void make_current() |
314 | + { |
315 | + glBindFramebuffer(GL_FRAMEBUFFER, fbo_); |
316 | + glViewport(0, 0, size_.x(), size_.y()); |
317 | + } |
318 | + |
319 | + void position(const LibMatrix::vec2& pos) { pos_ = pos; } |
320 | + const LibMatrix::vec2& position() { return pos_; } |
321 | + |
322 | + |
323 | + virtual void size(const LibMatrix::vec2& size) |
324 | + { |
325 | + /* Recreate the backing texture with correct size */ |
326 | + if (size_.x() != size.x() || size_.y() != size.y()) { |
327 | + size_ = size; |
328 | + glBindTexture(GL_TEXTURE_2D, texture_); |
329 | + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size_.x(), size_.y(), 0, |
330 | + GL_RGBA, GL_UNSIGNED_BYTE, 0); |
331 | + clear(); |
332 | + } |
333 | + } |
334 | + |
335 | + const LibMatrix::vec2& size() { return size_; } |
336 | + |
337 | + const LibMatrix::vec2& speed() { return speed_; } |
338 | + void speed(const LibMatrix::vec2& speed) { speed_ = speed; } |
339 | + |
340 | + GLuint texture() { return texture_; } |
341 | + |
342 | + virtual void clear() |
343 | + { |
344 | + make_current(); |
345 | + glClear(GL_COLOR_BUFFER_BIT); |
346 | + } |
347 | + |
348 | + virtual void render_to(RenderObject& target, Program& program = main_program) |
349 | + { |
350 | + LibMatrix::vec2 final_pos(pos_ + size_); |
351 | + LibMatrix::vec2 ll(target.normalize_position(pos_)); |
352 | + LibMatrix::vec2 ur(target.normalize_position(final_pos)); |
353 | + |
354 | + GLfloat position[2 * 4] = { |
355 | + ll.x(), ll.y(), |
356 | + ur.x(), ll.y(), |
357 | + ll.x(), ur.y(), |
358 | + ur.x(), ur.y(), |
359 | + }; |
360 | + |
361 | + static const GLfloat texcoord[2 * 4] = { |
362 | + 0.0, 0.0, |
363 | + 1.0, 0.0, |
364 | + 0.0, 1.0, |
365 | + 1.0, 1.0, |
366 | + }; |
367 | + |
368 | + target.make_current(); |
369 | + |
370 | + glActiveTexture(GL_TEXTURE0); |
371 | + glBindTexture(GL_TEXTURE_2D, texture_); |
372 | + draw_quad_with_program(position, texcoord, program); |
373 | + } |
374 | + |
375 | + virtual void render_from(RenderObject& target, Program& program = main_program) |
376 | + { |
377 | + LibMatrix::vec2 final_pos(pos_ + size_); |
378 | + LibMatrix::vec2 ll_tex(target.normalize_texcoord(pos_)); |
379 | + LibMatrix::vec2 ur_tex(target.normalize_texcoord(final_pos)); |
380 | + |
381 | + static const GLfloat position_blur[2 * 4] = { |
382 | + -1.0, -1.0, |
383 | + 1.0, -1.0, |
384 | + -1.0, 1.0, |
385 | + 1.0, 1.0, |
386 | + }; |
387 | + GLfloat texcoord_blur[2 * 4] = { |
388 | + ll_tex.x(), ll_tex.y(), |
389 | + ur_tex.x(), ll_tex.y(), |
390 | + ll_tex.x(), ur_tex.y(), |
391 | + ur_tex.x(), ur_tex.y(), |
392 | + }; |
393 | + |
394 | + make_current(); |
395 | + glBindTexture(GL_TEXTURE_2D, target.texture()); |
396 | + draw_quad_with_program(position_blur, texcoord_blur, program); |
397 | + } |
398 | + |
399 | + /** |
400 | + * Normalizes a position from [0, size] to [-1.0, 1.0] |
401 | + */ |
402 | + LibMatrix::vec2 normalize_position(LibMatrix::vec2& pos) |
403 | + { |
404 | + return LibMatrix::vec2(2.0 * pos.x() / size_.x() - 1.0, |
405 | + 2.0 * pos.y() / size_.y() - 1.0); |
406 | + } |
407 | + |
408 | + /** |
409 | + * Normalizes a position from [0, size] to [0.0, 1.0] |
410 | + */ |
411 | + LibMatrix::vec2 normalize_texcoord(LibMatrix::vec2& pos) |
412 | + { |
413 | + return LibMatrix::vec2(pos.x() / size_.x(), |
414 | + pos.y() / size_.y()); |
415 | + } |
416 | + |
417 | + |
418 | +protected: |
419 | + void draw_quad_with_program(const GLfloat *position, const GLfloat *texcoord, |
420 | + Program &program) |
421 | + { |
422 | + int pos_index = program["position"].location(); |
423 | + int tex_index = program["texcoord"].location(); |
424 | + |
425 | + program.start(); |
426 | + |
427 | + glEnableVertexAttribArray(pos_index); |
428 | + glEnableVertexAttribArray(tex_index); |
429 | + glVertexAttribPointer(pos_index, 2, |
430 | + GL_FLOAT, GL_FALSE, 0, position); |
431 | + glVertexAttribPointer(tex_index, 2, |
432 | + GL_FLOAT, GL_FALSE, 0, texcoord); |
433 | + |
434 | + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
435 | + |
436 | + glDisableVertexAttribArray(tex_index); |
437 | + glDisableVertexAttribArray(pos_index); |
438 | + |
439 | + program.stop(); |
440 | + } |
441 | + |
442 | + static Program main_program; |
443 | + |
444 | + LibMatrix::vec2 pos_; |
445 | + LibMatrix::vec2 size_; |
446 | + LibMatrix::vec2 speed_; |
447 | + GLuint texture_; |
448 | + GLuint fbo_; |
449 | + |
450 | +private: |
451 | + static int use_count; |
452 | + |
453 | +}; |
454 | + |
455 | +int RenderObject::use_count = 0; |
456 | +Program RenderObject::main_program; |
457 | + |
458 | +/** |
459 | + * A RenderObject representing the screen. |
460 | + * |
461 | + * Rendering to this objects renders to the screen framebuffer. |
462 | + */ |
463 | +class RenderScreen : public RenderObject |
464 | +{ |
465 | +public: |
466 | + virtual void init() {} |
467 | +}; |
468 | + |
469 | +/** |
470 | + * A RenderObject with a background image. |
471 | + * |
472 | + * The image is drawn to the RenderObject automatically when the |
473 | + * object is cleared, resized etc |
474 | + */ |
475 | +class RenderClearImage : public RenderObject |
476 | +{ |
477 | +public: |
478 | + RenderClearImage(const std::string& texture) : |
479 | + RenderObject(), background_texture_name(texture), |
480 | + background_texture_(0) {} |
481 | + |
482 | + virtual void init() |
483 | + { |
484 | + RenderObject::init(); |
485 | + |
486 | + /* Load the image into a texture */ |
487 | + Texture::load(background_texture_name, |
488 | + &background_texture_, GL_LINEAR, GL_LINEAR, 0); |
489 | + |
490 | + } |
491 | + |
492 | + virtual void release() |
493 | + { |
494 | + glDeleteTextures(1, &background_texture_); |
495 | + background_texture_ = 0; |
496 | + |
497 | + RenderObject::release(); |
498 | + } |
499 | + |
500 | + virtual void clear() |
501 | + { |
502 | + static const GLfloat position[2 * 4] = { |
503 | + -1.0, -1.0, |
504 | + 1.0, -1.0, |
505 | + -1.0, 1.0, |
506 | + 1.0, 1.0, |
507 | + }; |
508 | + static const GLfloat texcoord[2 * 4] = { |
509 | + 0.0, 0.0, |
510 | + 1.0, 0.0, |
511 | + 0.0, 1.0, |
512 | + 1.0, 1.0, |
513 | + }; |
514 | + |
515 | + make_current(); |
516 | + glClear(GL_COLOR_BUFFER_BIT); |
517 | + |
518 | + glActiveTexture(GL_TEXTURE0); |
519 | + glBindTexture(GL_TEXTURE_2D, background_texture_); |
520 | + |
521 | + glEnable(GL_BLEND); |
522 | + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
523 | + draw_quad_with_program(position, texcoord, main_program); |
524 | + glDisable(GL_BLEND); |
525 | + } |
526 | + |
527 | +private: |
528 | + std::string background_texture_name; |
529 | + GLuint background_texture_; |
530 | +}; |
531 | + |
532 | +/** |
533 | + * A RenderObject that blurs the target it is drawn to. |
534 | + */ |
535 | +class RenderWindowBlur : public RenderObject |
536 | +{ |
537 | +public: |
538 | + RenderWindowBlur(unsigned int passes, unsigned int radius, bool separable, |
539 | + bool draw_contents = true) : |
540 | + RenderObject(), passes_(passes), radius_(radius), separable_(separable), |
541 | + draw_contents_(draw_contents) {} |
542 | + |
543 | + virtual void init() |
544 | + { |
545 | + RenderObject::init(); |
546 | + |
547 | + /* Only have one instance of the window contents data */ |
548 | + if (draw_contents_ && RenderWindowBlur::use_count == 0) |
549 | + window_contents_.init(); |
550 | + |
551 | + RenderWindowBlur::use_count++; |
552 | + } |
553 | + |
554 | + virtual void release() |
555 | + { |
556 | + RenderWindowBlur::use_count--; |
557 | + |
558 | + /* Only have one instance of the window contents data */ |
559 | + if (draw_contents_ && RenderWindowBlur::use_count == 0) |
560 | + window_contents_.release(); |
561 | + |
562 | + RenderObject::release(); |
563 | + } |
564 | + |
565 | + virtual void size(const LibMatrix::vec2& size) |
566 | + { |
567 | + RenderObject::size(size); |
568 | + if (draw_contents_) |
569 | + window_contents_.size(size); |
570 | + } |
571 | + |
572 | + virtual void render_to(RenderObject& target, Program& program) |
573 | + { |
574 | + (void)program; |
575 | + |
576 | + if (separable_) { |
577 | + Program& blur_program_h1 = blur_program_h(target.size().x()); |
578 | + Program& blur_program_v1 = blur_program_v(target.size().y()); |
579 | + |
580 | + for (unsigned int i = 0; i < passes_; i++) { |
581 | + render_from(target, blur_program_h1); |
582 | + RenderObject::render_to(target, blur_program_v1); |
583 | + } |
584 | + } |
585 | + else { |
586 | + Program& blur_program1 = blur_program(target.size().x(), target.size().y()); |
587 | + |
588 | + for (unsigned int i = 0; i < passes_; i++) { |
589 | + if (i % 2 == 0) |
590 | + render_from(target, blur_program1); |
591 | + else |
592 | + RenderObject::render_to(target, blur_program1); |
593 | + } |
594 | + |
595 | + if (passes_ % 2 == 1) |
596 | + RenderObject::render_to(target); |
597 | + } |
598 | + |
599 | + /* |
600 | + * Blend the window contents with the target texture. |
601 | + */ |
602 | + if (draw_contents_) { |
603 | + glEnable(GL_BLEND); |
604 | + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
605 | + window_contents_.position(position()); |
606 | + window_contents_.render_to(target); |
607 | + glDisable(GL_BLEND); |
608 | + } |
609 | + } |
610 | + |
611 | +private: |
612 | + Program& blur_program(unsigned int w, unsigned int h) |
613 | + { |
614 | + /* |
615 | + * If the size of the window has changed we must recreate |
616 | + * the shader to contain the correct texture step values. |
617 | + */ |
618 | + if (blur_program_dim_.x() != w || blur_program_dim_.y() != h || |
619 | + !blur_program_.ready()) |
620 | + { |
621 | + blur_program_dim_.x(w); |
622 | + blur_program_dim_.y(h); |
623 | + |
624 | + blur_program_.release(); |
625 | + |
626 | + ShaderSource vtx_source; |
627 | + ShaderSource frg_source; |
628 | + create_blur_shaders(vtx_source, frg_source, radius_, |
629 | + radius_ / 3.0, BlurDirectionBoth); |
630 | + frg_source.add_const("TextureStepX", 1.0 / w); |
631 | + frg_source.add_const("TextureStepY", 1.0 / h); |
632 | + Scene::load_shaders_from_strings(blur_program_, vtx_source.str(), |
633 | + frg_source.str()); |
634 | + } |
635 | + |
636 | + return blur_program_; |
637 | + } |
638 | + |
639 | + Program& blur_program_h(unsigned int w) |
640 | + { |
641 | + /* |
642 | + * If the size of the window has changed we must recreate |
643 | + * the shader to contain the correct texture step values. |
644 | + */ |
645 | + if (blur_program_dim_.x() != w || |
646 | + !blur_program_h_.ready()) |
647 | + { |
648 | + blur_program_dim_.x(w); |
649 | + |
650 | + blur_program_h_.release(); |
651 | + |
652 | + ShaderSource vtx_source; |
653 | + ShaderSource frg_source; |
654 | + create_blur_shaders(vtx_source, frg_source, radius_, |
655 | + radius_ / 3.0, BlurDirectionHorizontal); |
656 | + frg_source.add_const("TextureStepX", 1.0 / w); |
657 | + Scene::load_shaders_from_strings(blur_program_h_, vtx_source.str(), |
658 | + frg_source.str()); |
659 | + } |
660 | + |
661 | + return blur_program_h_; |
662 | + } |
663 | + |
664 | + Program& blur_program_v(unsigned int h) |
665 | + { |
666 | + /* |
667 | + * If the size of the window has changed we must recreate |
668 | + * the shader to contain the correct texture step values. |
669 | + */ |
670 | + if (blur_program_dim_.y() != h || |
671 | + !blur_program_v_.ready()) |
672 | + { |
673 | + blur_program_dim_.y(h); |
674 | + |
675 | + blur_program_v_.release(); |
676 | + |
677 | + ShaderSource vtx_source; |
678 | + ShaderSource frg_source; |
679 | + create_blur_shaders(vtx_source, frg_source, radius_, |
680 | + radius_ / 3.0, BlurDirectionVertical); |
681 | + frg_source.add_const("TextureStepY", 1.0 / h); |
682 | + Scene::load_shaders_from_strings(blur_program_v_, vtx_source.str(), |
683 | + frg_source.str()); |
684 | + } |
685 | + |
686 | + return blur_program_v_; |
687 | + } |
688 | + |
689 | + LibMatrix::uvec2 blur_program_dim_; |
690 | + Program blur_program_; |
691 | + Program blur_program_h_; |
692 | + Program blur_program_v_; |
693 | + unsigned int passes_; |
694 | + unsigned int radius_; |
695 | + bool separable_; |
696 | + bool draw_contents_; |
697 | + |
698 | + static int use_count; |
699 | + static RenderClearImage window_contents_; |
700 | + |
701 | +}; |
702 | + |
703 | +int RenderWindowBlur::use_count = 0; |
704 | +RenderClearImage RenderWindowBlur::window_contents_(GLMARK_DATA_PATH"/textures/desktop-window.png"); |
705 | + |
706 | +/******************************* |
707 | + * SceneDesktop implementation * |
708 | + *******************************/ |
709 | + |
710 | +/** |
711 | + * Private structure used to avoid contaminating scene.h with all of the |
712 | + * SceneDesktop internal classes. |
713 | + */ |
714 | +struct SceneDesktopPrivate |
715 | +{ |
716 | + RenderScreen screen; |
717 | + RenderClearImage desktop; |
718 | + std::vector<RenderObject *> windows; |
719 | + |
720 | + SceneDesktopPrivate() : |
721 | + desktop(GLMARK_DATA_PATH"/textures/effect-2d.png") {} |
722 | + |
723 | + ~SceneDesktopPrivate() { Util::dispose_pointer_vector(windows); } |
724 | + |
725 | +}; |
726 | + |
727 | + |
728 | +SceneDesktop::SceneDesktop(Canvas &canvas) : |
729 | + Scene(canvas, "desktop") |
730 | +{ |
731 | + priv_ = new SceneDesktopPrivate(); |
732 | + mOptions["effect"] = Scene::Option("effect", "blur", |
733 | + "the effect to use [blur]"); |
734 | + mOptions["windows"] = Scene::Option("windows", "4", |
735 | + "the number of windows"); |
736 | + mOptions["window-size"] = Scene::Option("window-size", "0.35", |
737 | + "the window size as a percentage of the minimum screen dimension [0.0 - 0.5]"); |
738 | + mOptions["passes"] = Scene::Option("passes", "1", |
739 | + "the number of effect passes (effect dependent)"); |
740 | + mOptions["blur-radius"] = Scene::Option("blur-radius", "5", |
741 | + "the blur effect radius (in pixels)"); |
742 | + mOptions["separable"] = Scene::Option("separable", "true", |
743 | + "use separable convolution for the blur effect"); |
744 | +} |
745 | + |
746 | +SceneDesktop::~SceneDesktop() |
747 | +{ |
748 | + delete priv_; |
749 | +} |
750 | + |
751 | +int |
752 | +SceneDesktop::load() |
753 | +{ |
754 | + priv_->screen.init(); |
755 | + priv_->desktop.init(); |
756 | + return 1; |
757 | +} |
758 | + |
759 | +void |
760 | +SceneDesktop::unload() |
761 | +{ |
762 | + priv_->desktop.release(); |
763 | + priv_->screen.release(); |
764 | +} |
765 | + |
766 | +void |
767 | +SceneDesktop::setup() |
768 | +{ |
769 | + Scene::setup(); |
770 | + |
771 | + std::stringstream ss; |
772 | + unsigned int windows(0); |
773 | + unsigned int passes(0); |
774 | + unsigned int blur_radius(0); |
775 | + float window_size_factor(0.0); |
776 | + bool separable(mOptions["separable"].value == "true"); |
777 | + |
778 | + ss << mOptions["windows"].value; |
779 | + ss >> windows; |
780 | + ss.clear(); |
781 | + ss << mOptions["window-size"].value; |
782 | + ss >> window_size_factor; |
783 | + ss.clear(); |
784 | + ss << mOptions["passes"].value; |
785 | + ss >> passes; |
786 | + ss.clear(); |
787 | + ss << mOptions["blur-radius"].value; |
788 | + ss >> blur_radius; |
789 | + |
790 | + /* Ensure we get a transparent clear color for all following operations */ |
791 | + glClearColor(0.0, 0.0, 0.0, 0.0); |
792 | + glDisable(GL_DEPTH_TEST); |
793 | + glDepthMask(GL_FALSE); |
794 | + |
795 | + /* Set up the screen and desktop RenderObjects */ |
796 | + priv_->screen.size(LibMatrix::vec2(mCanvas.width(), mCanvas.height())); |
797 | + priv_->desktop.size(LibMatrix::vec2(mCanvas.width(), mCanvas.height())); |
798 | + |
799 | + /* Create the windows */ |
800 | + float angular_step(2.0 * M_PI / windows); |
801 | + unsigned int min_dimension = std::min(mCanvas.width(), mCanvas.height()); |
802 | + float window_size(min_dimension * window_size_factor); |
803 | + static const LibMatrix::vec2 corner_offset(window_size / 2.0, |
804 | + window_size / 2.0); |
805 | + |
806 | + for (unsigned int i = 0; i < windows; i++) { |
807 | + LibMatrix::vec2 center(mCanvas.width() * (0.5 + 0.25 * cos(i * angular_step)), |
808 | + mCanvas.height() * (0.5 + 0.25 * sin(i * angular_step))); |
809 | + RenderObject* win(new RenderWindowBlur(passes, blur_radius, separable)); |
810 | + (void)angular_step; |
811 | + |
812 | + win->init(); |
813 | + win->position(center - corner_offset); |
814 | + win->size(LibMatrix::vec2(window_size, window_size)); |
815 | + /* |
816 | + * Set the speed in increments of about 30 degrees (but not exactly, |
817 | + * so we don't get windows moving just on the X axis or Y axis). |
818 | + */ |
819 | + win->speed(LibMatrix::vec2(cos(0.1 + i * M_PI / 6.0) * mCanvas.width() / 3, |
820 | + sin(0.1 + i * M_PI / 6.0) * mCanvas.height() / 3)); |
821 | + /* |
822 | + * Perform a dummy rendering to ensure internal shaders are initialized |
823 | + * now, in order not to affect the benchmarking. |
824 | + */ |
825 | + win->render_to(priv_->desktop); |
826 | + priv_->windows.push_back(win); |
827 | + } |
828 | + |
829 | + /* |
830 | + * Ensure the screen is the current rendering target (it might have changed |
831 | + * to a FBO in the previous steps). |
832 | + */ |
833 | + priv_->screen.make_current(); |
834 | + |
835 | + mCurrentFrame = 0; |
836 | + mRunning = true; |
837 | + mStartTime = Scene::get_timestamp_us() / 1000000.0; |
838 | + mLastUpdateTime = mStartTime; |
839 | +} |
840 | + |
841 | +void |
842 | +SceneDesktop::teardown() |
843 | +{ |
844 | + Util::dispose_pointer_vector(priv_->windows); |
845 | + priv_->screen.make_current(); |
846 | + |
847 | + glEnable(GL_DEPTH_TEST); |
848 | + glDepthMask(GL_TRUE); |
849 | + |
850 | + Scene::teardown(); |
851 | +} |
852 | + |
853 | +void |
854 | +SceneDesktop::update() |
855 | +{ |
856 | + double current_time = Scene::get_timestamp_us() / 1000000.0; |
857 | + double dt = current_time - mLastUpdateTime; |
858 | + double elapsed_time = current_time - mStartTime; |
859 | + |
860 | + mLastUpdateTime = current_time; |
861 | + |
862 | + std::vector<RenderObject *>& windows(priv_->windows); |
863 | + |
864 | + /* |
865 | + * Move the windows around the screen, bouncing them back when |
866 | + * they reach the edge. |
867 | + */ |
868 | + for (std::vector<RenderObject *>::const_iterator iter = windows.begin(); |
869 | + iter != windows.end(); |
870 | + iter++) |
871 | + { |
872 | + bool should_update = true; |
873 | + RenderObject *win = *iter; |
874 | + LibMatrix::vec2 new_pos( |
875 | + win->position().x() + win->speed().x() * dt, |
876 | + win->position().y() + win->speed().y() * dt); |
877 | + |
878 | + if (new_pos.x() < 0.0 || |
879 | + new_pos.x() + win->size().x() > ((float)mCanvas.width())) |
880 | + { |
881 | + win->speed(LibMatrix::vec2(-win->speed().x(), win->speed().y())); |
882 | + should_update = false; |
883 | + } |
884 | + |
885 | + if (new_pos.y() < 0.0 || |
886 | + new_pos.y() + win->size().y() > ((float)mCanvas.height())) |
887 | + { |
888 | + win->speed(LibMatrix::vec2(win->speed().x(), -win->speed().y())); |
889 | + should_update = false; |
890 | + } |
891 | + |
892 | + if (should_update) |
893 | + win->position(new_pos); |
894 | + } |
895 | + |
896 | + if (elapsed_time >= mDuration) { |
897 | + mAverageFPS = mCurrentFrame / elapsed_time; |
898 | + mRunning = false; |
899 | + } |
900 | + |
901 | + mCurrentFrame++; |
902 | +} |
903 | + |
904 | +void |
905 | +SceneDesktop::draw() |
906 | +{ |
907 | + std::vector<RenderObject *>& windows(priv_->windows); |
908 | + |
909 | + /* Ensure we get a transparent clear color for all following operations */ |
910 | + glClearColor(0.0, 0.0, 0.0, 0.0); |
911 | + |
912 | + priv_->desktop.clear(); |
913 | + |
914 | + for (std::vector<RenderObject *>::const_iterator iter = windows.begin(); |
915 | + iter != windows.end(); |
916 | + iter++) |
917 | + { |
918 | + RenderObject *win = *iter; |
919 | + win->render_to(priv_->desktop); |
920 | + } |
921 | + |
922 | + priv_->desktop.render_to(priv_->screen); |
923 | + |
924 | +} |
925 | + |
926 | +Scene::ValidationResult |
927 | +SceneDesktop::validate() |
928 | +{ |
929 | + return ValidationUnknown; |
930 | +} |
931 | |
932 | === modified file 'src/scene.h' |
933 | --- src/scene.h 2011-08-18 13:20:04 +0000 |
934 | +++ src/scene.h 2011-09-13 09:41:05 +0000 |
935 | @@ -331,4 +331,23 @@ |
936 | void create_and_setup_mesh(); |
937 | }; |
938 | |
939 | +struct SceneDesktopPrivate; |
940 | + |
941 | +class SceneDesktop : public Scene |
942 | +{ |
943 | +public: |
944 | + SceneDesktop(Canvas &canvas); |
945 | + int load(); |
946 | + void unload(); |
947 | + void setup(); |
948 | + void teardown(); |
949 | + void update(); |
950 | + void draw(); |
951 | + ValidationResult validate(); |
952 | + |
953 | + ~SceneDesktop(); |
954 | + |
955 | +private: |
956 | + SceneDesktopPrivate *priv_; |
957 | +}; |
958 | #endif |
Overall, looks really good. I like it. A few very small nits inline,
none of which should hold up the merge (and are all optional)...
On Mon, Sep 12, 2011 at 9:40 AM, Alexandros Frantzis <email address hidden> wrote: /code.launchpad .net/~linaro- graphics- wg/glmark2/ desktop/ +merge/ 75039 /code.launchpad .net/~linaro- graphics- wg/glmark2/ desktop/ +merge/ 75039 desktop- blur.frag' desktop- blur.frag 1970-01-01 00:00:00 +0000 desktop- blur.frag 2011-09-12 16:40:37 +0000 desktop. frag' desktop. frag 1970-01-01 00:00:00 +0000 desktop. frag 2011-09-12 16:40:37 +0000 MaterialTexture 0, TextureCoord); desktop. vert' desktop. vert 1970-01-01 00:00:00 +0000 desktop. vert 2011-09-12 16:40:37 +0000 desktop- window. png' desktop- window. png 1970-01-01 00:00:00 +0000 and data/textures/ desktop- window. png 2011-09-12 16:40:37 +0000 differ kernel= 0,1,0;1, -4,1;0, 1,0;", kernel= 1,1,1,1, 1;1,1,1, 1,1;1,1, 1,1,1;" , quads=5: texture= false:light= false", windows= 4:effect= blur:blur- radius= 5:passes= 1:separable= true", vertex- steps=0: fragment- steps=0" , vertex- steps=0: fragment- steps=5" , vertex- steps=5: fragment- steps=0" , :register_ scene(* new SceneBump( *g_canvas) ); :register_ scene(* new SceneEffect2D( *g_canvas) ); :register_ scene(* new ScenePulsar( *g_canvas) ); :register_ scene(* new SceneDesktop( canvas) ); benchmarks( g_benchmarks) ; android. cpp' android. cpp 2011-08-10 18:00:03 +0000
> Alexandros Frantzis has proposed merging lp:~linaro-graphics-wg/glmark2/desktop into lp:glmark2.
>
> Requested reviews:
> Jesse Barker (jesse-barker)
>
> For more details, see:
> https:/
>
> New "desktop" benchmarking scene and one effect (blur).
> --
> https:/
> You are requested to review the proposed merge of lp:~linaro-graphics-wg/glmark2/desktop into lp:glmark2.
>
> === added file 'data/shaders/
> --- data/shaders/
> +++ data/shaders/
> @@ -0,0 +1,17 @@
> +#ifdef GL_ES
> +precision mediump float;
> +#endif
> +
> +uniform sampler2D Texture0;
> +
> +varying vec2 TextureCoord;
> +
> +void main(void)
> +{
> + vec4 result;
> +
> + $CONVOLUTION$
> +
> + gl_FragColor = result;
> +}
> +
>
> === added file 'data/shaders/
> --- data/shaders/
> +++ data/shaders/
> @@ -0,0 +1,14 @@
> +#ifdef GL_ES
> +precision mediump float;
> +#endif
> +
> +uniform sampler2D MaterialTexture0;
> +
> +varying vec2 TextureCoord;
> +
> +void main(void)
> +{
> + vec4 texel = texture2D(
> + gl_FragColor = texel;
> +}
> +
>
> === added file 'data/shaders/
> --- data/shaders/
> +++ data/shaders/
> @@ -0,0 +1,11 @@
> +attribute vec2 position;
> +attribute vec2 texcoord;
> +
> +varying vec2 TextureCoord;
> +
> +void main(void)
> +{
> + gl_Position = vec4(position, 0.0, 1.0);
> +
> + TextureCoord = texcoord;
> +}
>
> === added file 'data/textures/
> Binary files data/textures/
> === modified file 'src/android.cpp'
> --- src/android.cpp 2011-08-18 15:03:40 +0000
> +++ src/android.cpp 2011-09-12 16:40:37 +0000
> @@ -44,6 +44,7 @@
> "effect2d:
> "effect2d:
> "pulsar:
> + "desktop:
> "conditionals:
> "conditionals:
> "conditionals:
> @@ -85,6 +86,7 @@
> Benchmark:
> Benchmark:
> Benchmark:
> + Benchmark:
>
> add_default_
>
>
> === modified file 'src/canvas-
> --- src/canvas-
> +++ src/canv...