Merge lp:~glcompbench-dev/glcompbench/blur into lp:glcompbench

Proposed by Jesse Barker
Status: Merged
Merged at revision: 78
Proposed branch: lp:~glcompbench-dev/glcompbench/blur
Merge into: lp:glcompbench
Diff against target: 1511 lines (+1231/-21)
20 files modified
data/desktop-blur.frag (+13/-0)
data/desktop.frag (+10/-0)
data/desktop.vert (+11/-0)
src/benchmark.cc (+3/-2)
src/benchmark.h (+1/-1)
src/composite-canvas.cc (+1/-1)
src/composite-test-default-options.cc (+3/-1)
src/composite-test-pixman.cc (+3/-1)
src/composite-test-simple-base.cc (+3/-1)
src/composite-test-simple-blur.cc (+474/-0)
src/composite-test-simple-brick.cc (+2/-2)
src/composite-test-xrender.cc (+3/-1)
src/composite-test.h (+25/-6)
src/glcompbench.cc (+2/-0)
src/render-object.cc (+282/-0)
src/render-object.h (+152/-0)
src/texture.cc (+201/-0)
src/texture.h (+37/-0)
src/wscript_build (+4/-4)
wscript (+1/-1)
To merge this branch: bzr merge lp:~glcompbench-dev/glcompbench/blur
Reviewer Review Type Date Requested Status
Alexandros Frantzis Pending
Review via email: mp+98238@code.launchpad.net

Description of the change

Adds a new test for a blur effect. This is derived from the work on glmark2 in its SceneDesktop, but with a somewhat refactored set of objects, and the window contents come from the window list (rather than being static as they are in glmark2). The canvas background image is preserved as blur is largely uninteresting against a solid background (even if the GPU is going through all of the same computations).

To post a comment you must log in.
lp:~glcompbench-dev/glcompbench/blur updated
93. By Jesse Barker

Change the condition of a RenderObject missing from the map from error to debug.
The current state of the test is targeted at the scripted mode where we have a
fixed window list, but if windows are added during the test run, they currently
will not have a RenderObject. That's a follow on feature.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'data/background.png'
0Binary files data/background.png 1970-01-01 00:00:00 +0000 and data/background.png 2012-03-20 16:31:20 +0000 differ0Binary files data/background.png 1970-01-01 00:00:00 +0000 and data/background.png 2012-03-20 16:31:20 +0000 differ
=== added file 'data/desktop-blur.frag'
--- data/desktop-blur.frag 1970-01-01 00:00:00 +0000
+++ data/desktop-blur.frag 2012-03-20 16:31:20 +0000
@@ -0,0 +1,13 @@
1uniform sampler2D Texture0;
2
3varying vec2 TextureCoord;
4
5void main(void)
6{
7 vec4 result;
8
9 $CONVOLUTION$
10
11 gl_FragColor = result;
12}
13
014
=== added file 'data/desktop.frag'
--- data/desktop.frag 1970-01-01 00:00:00 +0000
+++ data/desktop.frag 2012-03-20 16:31:20 +0000
@@ -0,0 +1,10 @@
1uniform sampler2D MaterialTexture0;
2
3varying vec2 TextureCoord;
4
5void main(void)
6{
7 vec4 texel = texture2D(MaterialTexture0, TextureCoord);
8 gl_FragColor = vec4(texel.xyz, 0.5);
9}
10
011
=== added file 'data/desktop.vert'
--- data/desktop.vert 1970-01-01 00:00:00 +0000
+++ data/desktop.vert 2012-03-20 16:31:20 +0000
@@ -0,0 +1,11 @@
1attribute vec2 position;
2attribute vec2 texcoord;
3
4varying vec2 TextureCoord;
5
6void main(void)
7{
8 gl_Position = vec4(position, 0.0, 1.0);
9
10 TextureCoord = texcoord;
11}
012
=== added file 'data/window.png'
1Binary files data/window.png 1970-01-01 00:00:00 +0000 and data/window.png 2012-03-20 16:31:20 +0000 differ13Binary files data/window.png 1970-01-01 00:00:00 +0000 and data/window.png 2012-03-20 16:31:20 +0000 differ
=== modified file 'src/benchmark.cc'
--- src/benchmark.cc 2011-06-22 11:35:50 +0000
+++ src/benchmark.cc 2012-03-20 16:31:20 +0000
@@ -28,6 +28,7 @@
28using std::string;28using std::string;
29using std::vector;29using std::vector;
30using std::map;30using std::map;
31using std::list;
3132
32std::map<string, CompositeTest *> Benchmark::test_map_;33std::map<string, CompositeTest *> Benchmark::test_map_;
3334
@@ -113,12 +114,12 @@
113}114}
114115
115CompositeTest &116CompositeTest &
116Benchmark::setup_test()117Benchmark::setup_test(list<CompositeWindow*> &window_list)
117{118{
118 test_.reset_options();119 test_.reset_options();
119 load_options();120 load_options();
120121
121 test_.prepare_for_run();122 test_.prepare_for_run(window_list);
122123
123 return test_;124 return test_;
124}125}
125126
=== modified file 'src/benchmark.h'
--- src/benchmark.h 2011-07-15 10:20:09 +0000
+++ src/benchmark.h 2012-03-20 16:31:20 +0000
@@ -40,7 +40,7 @@
40 // test[:opt1=val1:opt2=val2...]40 // test[:opt1=val1:opt2=val2...]
41 Benchmark(const std::string &s);41 Benchmark(const std::string &s);
4242
43 CompositeTest &setup_test();43 CompositeTest &setup_test(std::list<CompositeWindow*> &window_list);
44 void teardown_test();44 void teardown_test();
4545
46 CompositeTest &get_test() { return test_; }46 CompositeTest &get_test() { return test_; }
4747
=== modified file 'src/composite-canvas.cc'
--- src/composite-canvas.cc 2011-09-21 13:57:01 +0000
+++ src/composite-canvas.cc 2012-03-20 16:31:20 +0000
@@ -633,7 +633,7 @@
633 benchIt++)633 benchIt++)
634 {634 {
635 Benchmark *benchmark = *benchIt;635 Benchmark *benchmark = *benchIt;
636 current_test_ = &benchmark->setup_test();636 current_test_ = &benchmark->setup_test(this->window_list_);
637637
638 if (!current_test_->name().empty()) {638 if (!current_test_->name().empty()) {
639 load_current_test_options();639 load_current_test_options();
640640
=== modified file 'src/composite-test-default-options.cc'
--- src/composite-test-default-options.cc 2011-06-23 13:52:16 +0000
+++ src/composite-test-default-options.cc 2012-03-20 16:31:20 +0000
@@ -29,8 +29,10 @@
29 * Prepares the test for a test run.29 * Prepares the test for a test run.
30 */30 */
31void31void
32CompositeTestDefaultOptions::prepare_for_run()32CompositeTestDefaultOptions::prepare_for_run(std::list<CompositeWindow*> &window_list)
33{33{
34 CompositeTest::prepare_for_run(window_list);
35
34 const std::map<std::string, CompositeTest *> &tests = Benchmark::tests();36 const std::map<std::string, CompositeTest *> &tests = Benchmark::tests();
3537
36 for (std::list<std::pair<std::string, std::string> >::const_iterator iter = default_options_.begin();38 for (std::list<std::pair<std::string, std::string> >::const_iterator iter = default_options_.begin();
3739
=== modified file 'src/composite-test-pixman.cc'
--- src/composite-test-pixman.cc 2011-07-19 13:54:14 +0000
+++ src/composite-test-pixman.cc 2012-03-20 16:31:20 +0000
@@ -49,8 +49,10 @@
49}49}
5050
51void51void
52CompositeTestPixman::prepare_for_run()52CompositeTestPixman::prepare_for_run(std::list<CompositeWindow*> &window_list)
53{53{
54 CompositeTest::prepare_for_run(window_list);
55
54 if (options_["filter"].value == "bilinear")56 if (options_["filter"].value == "bilinear")
55 pixman_filter_ = PIXMAN_FILTER_BILINEAR;57 pixman_filter_ = PIXMAN_FILTER_BILINEAR;
56 else58 else
5759
=== modified file 'src/composite-test-simple-base.cc'
--- src/composite-test-simple-base.cc 2011-12-05 19:01:24 +0000
+++ src/composite-test-simple-base.cc 2012-03-20 16:31:20 +0000
@@ -138,8 +138,10 @@
138 * Prepares the test for a test run.138 * Prepares the test for a test run.
139 */139 */
140void140void
141CompositeTestSimpleBase::prepare_for_run()141CompositeTestSimpleBase::prepare_for_run(std::list<CompositeWindow*> &window_list)
142{142{
143 CompositeTest::prepare_for_run(window_list);
144
143 vboData_.useBufferObject(options_["use-vbo"].value == "true");145 vboData_.useBufferObject(options_["use-vbo"].value == "true");
144146
145 program_.start();147 program_.start();
146148
=== added file 'src/composite-test-simple-blur.cc'
--- src/composite-test-simple-blur.cc 1970-01-01 00:00:00 +0000
+++ src/composite-test-simple-blur.cc 2012-03-20 16:31:20 +0000
@@ -0,0 +1,474 @@
1/*
2 * Copyright © 2011 Linaro Limited
3 *
4 * This file is part of glcompbench.
5 *
6 * glcompbench is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * glcompbench is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with glcompbench. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Authors:
20 * Alexandros Frantzis <alexandros.frantzis@linaro.org>
21 * Jesse Barker <jesse.barker@linaro.org>
22 */
23
24#include <sstream>
25#include <cmath>
26#include "gl-headers.h"
27#include "composite-test.h"
28#include "options.h"
29#include "log.h"
30#include "util.h"
31#include "render-object.h"
32#include "texture.h"
33#include "composite-window-ximage.h"
34
35using std::string;
36using std::map;
37using std::list;
38using LibMatrix::vec2;
39
40//
41// A RenderObject that blurs the target it is drawn to.
42//
43class RenderWindowBlur : public RenderObject
44{
45public:
46 RenderWindowBlur(unsigned int passes, unsigned int radius, bool separable) :
47 RenderObject(),
48 passes_(passes),
49 radius_(radius),
50 separable_(separable),
51 window_contents_() {}
52
53 virtual void init(Program& program)
54 {
55 RenderObject::init(program);
56 window_contents_.init(program);
57 }
58
59 virtual void set_background(unsigned int background_texture)
60 {
61 window_contents_.set_background(background_texture);
62 }
63
64 void refresh_window(unsigned int background_texture)
65 {
66 glClearColor(0.0, 0.0, 0.0, 0.0);
67 window_contents_.set_background(background_texture);
68 window_contents_.clear();
69 }
70
71 virtual void release()
72 {
73 window_contents_.release();
74 RenderObject::release();
75 }
76
77 virtual void resize(const vec2& size)
78 {
79 RenderObject::resize(size);
80 window_contents_.resize(size);
81 }
82
83 virtual void render_to(RenderObject& target)
84 {
85 if (separable_) {
86 Program& blur_program_h1 = blur_program_h(target.size().x());
87 Program& blur_program_v1 = blur_program_v(target.size().y());
88
89 for (unsigned int i = 0; i < passes_; i++) {
90 render_from(target, blur_program_h1);
91 RenderObject::render_to(target, blur_program_v1);
92 }
93 }
94 else {
95 Program& blur_program1 = blur_program(target.size().x(), target.size().y());
96
97 for (unsigned int i = 0; i < passes_; i++) {
98 if (i % 2 == 0)
99 render_from(target, blur_program1);
100 else
101 RenderObject::render_to(target, blur_program1);
102 }
103
104 if (passes_ % 2 == 1)
105 RenderObject::render_to(target);
106 }
107
108 // Blend the window contents with the target texture.
109 glEnable(GL_BLEND);
110 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
111 window_contents_.position(position());
112 window_contents_.render_to(target);
113 glDisable(GL_BLEND);
114 }
115
116private:
117 enum BlurDirection {
118 BlurDirectionHorizontal,
119 BlurDirectionVertical,
120 BlurDirectionBoth
121 };
122
123 void render_from(RenderObject& target, Program& program)
124 {
125 vec2 final_pos(pos_ + size_);
126 vec2 ll_tex(target.normalize_texcoord(pos_));
127 vec2 ur_tex(target.normalize_texcoord(final_pos));
128
129 static const GLfloat position_blur[2 * 4] = {
130 -1.0, -1.0,
131 1.0, -1.0,
132 -1.0, 1.0,
133 1.0, 1.0,
134 };
135 GLfloat texcoord_blur[2 * 4] = {
136 ll_tex.x(), ll_tex.y(),
137 ur_tex.x(), ll_tex.y(),
138 ll_tex.x(), ur_tex.y(),
139 ur_tex.x(), ur_tex.y(),
140 };
141
142 make_current();
143 glBindTexture(GL_TEXTURE_2D, target.texture());
144 draw_quad_with_program(position_blur, texcoord_blur, program);
145 }
146
147 Program& blur_program(unsigned int w, unsigned int h)
148 {
149 /*
150 * If the size of the window has changed we must recreate
151 * the shader to contain the correct texture step values.
152 */
153 if (blur_program_dim_.x() != w || blur_program_dim_.y() != h ||
154 !blur_program_.ready())
155 {
156 blur_program_dim_.x(w);
157 blur_program_dim_.y(h);
158
159 blur_program_.release();
160
161 ShaderSource vtx_source;
162 ShaderSource frg_source;
163 create_blur_shaders(vtx_source, frg_source, radius_,
164 radius_ / 3.0, BlurDirectionBoth);
165 frg_source.add_const("TextureStepX", 1.0 / w);
166 frg_source.add_const("TextureStepY", 1.0 / h);
167 load_shaders_from_strings(blur_program_, vtx_source.str(),
168 frg_source.str());
169 }
170
171 return blur_program_;
172 }
173
174 Program& blur_program_h(unsigned int w)
175 {
176 /*
177 * If the size of the window has changed we must recreate
178 * the shader to contain the correct texture step values.
179 */
180 if (blur_program_dim_.x() != w ||
181 !blur_program_h_.ready())
182 {
183 blur_program_dim_.x(w);
184
185 blur_program_h_.release();
186
187 ShaderSource vtx_source;
188 ShaderSource frg_source;
189 create_blur_shaders(vtx_source, frg_source, radius_,
190 radius_ / 3.0, BlurDirectionHorizontal);
191 frg_source.add_const("TextureStepX", 1.0 / w);
192 load_shaders_from_strings(blur_program_h_, vtx_source.str(),
193 frg_source.str());
194 }
195
196 return blur_program_h_;
197 }
198
199 Program& blur_program_v(unsigned int h)
200 {
201 /*
202 * If the size of the window has changed we must recreate
203 * the shader to contain the correct texture step values.
204 */
205 if (blur_program_dim_.y() != h ||
206 !blur_program_v_.ready())
207 {
208 blur_program_dim_.y(h);
209
210 blur_program_v_.release();
211
212 ShaderSource vtx_source;
213 ShaderSource frg_source;
214 create_blur_shaders(vtx_source, frg_source, radius_,
215 radius_ / 3.0, BlurDirectionVertical);
216 frg_source.add_const("TextureStepY", 1.0 / h);
217 load_shaders_from_strings(blur_program_v_, vtx_source.str(),
218 frg_source.str());
219 }
220
221 return blur_program_v_;
222 }
223
224 static void
225 create_blur_shaders(ShaderSource& vtx_source, ShaderSource& frg_source,
226 unsigned int radius, float sigma, BlurDirection direction);
227 LibMatrix::uvec2 blur_program_dim_;
228 Program blur_program_;
229 Program blur_program_h_;
230 Program blur_program_v_;
231 unsigned int passes_;
232 unsigned int radius_;
233 bool separable_;
234 RenderClearImage window_contents_;
235};
236
237void
238RenderWindowBlur::create_blur_shaders(ShaderSource& vtx_source,
239 ShaderSource& frg_source, unsigned int radius, float sigma,
240 BlurDirection direction)
241{
242 vtx_source.append_file(GLCOMPBENCH_DATA_PATH"/desktop.vert");
243 frg_source.append_file(GLCOMPBENCH_DATA_PATH"/desktop-blur.frag");
244
245 /* Don't let the gaussian curve become too narrow */
246 if (sigma < 1.0)
247 sigma = 1.0;
248
249 unsigned int side = 2 * radius + 1;
250
251 for (unsigned int i = 0; i < radius + 1; i++) {
252 float s2 = 2.0 * sigma * sigma;
253 float k = 1.0 / std::sqrt(M_PI * s2) * std::exp( - (static_cast<float>(i) * i) / s2);
254 std::stringstream ss_tmp;
255 ss_tmp << "Kernel" << i;
256 frg_source.add_const(ss_tmp.str(), k);
257 }
258
259 std::stringstream ss;
260 ss << "result = " << std::endl;
261
262 if (direction == BlurDirectionHorizontal) {
263 for (unsigned int i = 0; i < side; i++) {
264 int offset = static_cast<int>(i - radius);
265 ss << "texture2D(Texture0, TextureCoord + vec2(" <<
266 offset << ".0 * TextureStepX, 0.0)) * Kernel" <<
267 std::abs(offset) << " +" << std::endl;
268 }
269 ss << "0.0 ;" << std::endl;
270 }
271 else if (direction == BlurDirectionVertical) {
272 for (unsigned int i = 0; i < side; i++) {
273 int offset = static_cast<int>(i - radius);
274 ss << "texture2D(Texture0, TextureCoord + vec2(0.0, " <<
275 offset << ".0 * TextureStepY)) * Kernel" <<
276 std::abs(offset) << " +" << std::endl;
277 }
278 ss << "0.0 ;" << std::endl;
279 }
280 else if (direction == BlurDirectionBoth) {
281 for (unsigned int i = 0; i < side; i++) {
282 int ioffset = static_cast<int>(i - radius);
283 for (unsigned int j = 0; j < side; j++) {
284 int joffset = static_cast<int>(j - radius);
285 ss << "texture2D(Texture0, TextureCoord + vec2(" <<
286 ioffset << ".0 * TextureStepX, " <<
287 joffset << ".0 * TextureStepY))" <<
288 " * Kernel" << std::abs(ioffset) <<
289 " * Kernel" << std::abs(joffset) << " +" << std::endl;
290 }
291 }
292 ss << " 0.0;" << std::endl;
293 }
294
295 frg_source.replace("$CONVOLUTION$", ss.str());
296}
297
298//
299// Private structure used to avoid contaminating composite-test.h with all of
300// the CompositeTestSimpleBlur internal classes.
301//
302struct BlurPrivate
303{
304 RenderScreen screen;
305 RenderClearImage desktop;
306 map<unsigned int, RenderWindowBlur*> windowMap;
307 int screen_width;
308 int screen_height;
309 double lastUpdateTime;
310 float window_scale_factor;
311
312 BlurPrivate() :
313 desktop(GLCOMPBENCH_DATA_PATH"/background.png"),
314 screen_width(0),
315 screen_height(0),
316 lastUpdateTime(0),
317 window_scale_factor(0.4) {}
318
319 ~BlurPrivate() {}
320};
321
322CompositeTestSimpleBlur::CompositeTestSimpleBlur() :
323 CompositeTestSimpleBase("blur",
324 GLCOMPBENCH_DATA_PATH"/desktop.vert",
325 GLCOMPBENCH_DATA_PATH"/desktop.frag")
326{
327 options_["use-vbo"] = CompositeTest::Option("use-vbo", "false",
328 "Whether to use VBOs for rendering [true,false]");
329 options_["window-size"] = CompositeTest::Option("window-size", "0.5",
330 "a scaling factor for the window size (relative to screen screen size) [0.0 - 0.5]");
331 options_["passes"] = CompositeTest::Option("passes", "1",
332 "the number of effect passes (effect dependent)");
333 options_["blur-radius"] = CompositeTest::Option("blur-radius", "5",
334 "the blur effect radius (in pixels)");
335 options_["separable"] = CompositeTest::Option("separable", "true",
336 "use separable convolution for the blur effect");
337 priv_ = new BlurPrivate();
338}
339
340CompositeTestSimpleBlur::~CompositeTestSimpleBlur()
341{
342 for (map<unsigned int, RenderWindowBlur*>::iterator winIt = priv_->windowMap.begin();
343 winIt != priv_->windowMap.end();
344 winIt++)
345 {
346 RenderWindowBlur* ro = winIt->second;
347 delete ro;
348 }
349 delete priv_;
350}
351
352//
353// Width/height values used to compute buffer sizes are likely to generate
354// errors in the GL implementation if they are not at least 1, so make sure we
355// have sane values.
356//
357static void
358clamp_size(vec2& size)
359{
360 if (size.x() < 1.0)
361 {
362 size.x(1.0);
363 }
364 if (size.y() < 1.0)
365 {
366 size.y(1.0);
367 }
368}
369
370void
371CompositeTestSimpleBlur::prepare_for_run(list<CompositeWindow*>& window_list)
372{
373 // See how our options tell us to behave...
374 priv_->window_scale_factor = Util::fromString<float>(options_["window-size"].value);
375 unsigned int passes(Util::fromString<unsigned int>(options_["passes"].value));
376 unsigned int radius(Util::fromString<unsigned int>(options_["blur-radius"].value));
377 bool separable(options_["separable"].value == "true");
378
379 // Ensure we get a transparent clear color for all following operations
380 glClearColor(0.0, 0.0, 0.0, 0.0);
381 glDisable(GL_DEPTH_TEST);
382 glDepthMask(GL_FALSE);
383
384 priv_->screen.init(program_);
385 priv_->desktop.init(program_);
386
387 unsigned int visible_windows(num_visible_windows(window_list));
388 float angular_step(2 * M_PI / visible_windows);
389 vec2 screen_size = priv_->screen.size();
390 unsigned int i(0);
391 for(list<CompositeWindow*>::iterator iter = window_list.begin();
392 iter != window_list.end();
393 ++iter)
394 {
395 CompositeWindow* win = *iter;
396 if (!win->get_texture().is_valid())
397 {
398 continue;
399 }
400 vec2 window_size(win->width(), win->height());
401 window_size *= priv_->window_scale_factor;
402 clamp_size(window_size);
403 vec2 corner_offset(window_size / 2.0);
404 RenderWindowBlur* ro = new RenderWindowBlur(passes, radius, separable);
405 ro->init(program_);
406 ro->set_background(win->get_texture().i);
407 vec2 center(screen_size.x() * (0.5 + 0.25 * cos(i * angular_step)),
408 screen_size.y() * (0.5 + 0.25 * sin(i * angular_step)));
409 ro->position(center - corner_offset);
410 ro->resize(window_size);
411 priv_->windowMap.insert(make_pair(win->get_xwindow(), ro));
412 i++;
413 }
414 //
415 // Ensure the screen is the current rendering target (it might have changed
416 // to a FBO in the previous steps).
417 //
418 priv_->screen.make_current();
419}
420
421void
422CompositeTestSimpleBlur::reshape(int width, int height)
423{
424 CompositeTestSimpleBase::reshape(width, height);
425 vec2 screen_size(width, height);
426 priv_->screen.resize(screen_size);
427 priv_->desktop.resize(screen_size);
428}
429
430void
431CompositeTestSimpleBlur::draw(list<CompositeWindow *> &window_list)
432{
433 unsigned int visible_windows(num_visible_windows(window_list));
434 float angular_step(2 * M_PI / visible_windows);
435 vec2 screen_size = priv_->screen.size();
436 unsigned int i(0);
437
438 // Ensure we get a transparent clear color for all following operations.
439 glClearColor(0.0, 0.0, 0.0, 0.0);
440 priv_->desktop.clear();
441
442 for(list<CompositeWindow*>::iterator cwIt = window_list.begin();
443 cwIt != window_list.end();
444 ++cwIt)
445 {
446 CompositeWindow* cw = *cwIt;
447 if (!cw->get_texture().is_valid())
448 {
449 continue;
450 }
451 unsigned int winHandle(cw->get_xwindow());
452 map<unsigned int, RenderWindowBlur*>::iterator roIt = priv_->windowMap.find(winHandle);
453 if (roIt == priv_->windowMap.end())
454 {
455 Log::debug("Failed to find window 0x%x in window map\n", winHandle);
456 continue;
457 }
458 RenderWindowBlur* ro = roIt->second;
459 ro->refresh_window(cw->get_texture().i);
460 vec2 window_size(cw->width(), cw->height());
461 window_size *= priv_->window_scale_factor;
462 clamp_size(window_size);
463 vec2 corner_offset(window_size / 2.0);
464 vec2 center(screen_size.x() * (0.5 + 0.25 * cos(i * angular_step)),
465 screen_size.y() * (0.5 + 0.25 * sin(i * angular_step)));
466 ro->position(center - corner_offset);
467 ro->resize(window_size);
468 ro->render_to(priv_->desktop);
469 i++;
470 }
471
472 // Present the results to the screen.
473 priv_->desktop.render_to(priv_->screen);
474}
0475
=== modified file 'src/composite-test-simple-brick.cc'
--- src/composite-test-simple-brick.cc 2011-09-05 15:23:11 +0000
+++ src/composite-test-simple-brick.cc 2012-03-20 16:31:20 +0000
@@ -37,9 +37,9 @@
37const vec2 CompositeTestSimpleBrick::brickPct_(0.90, 0.85);37const vec2 CompositeTestSimpleBrick::brickPct_(0.90, 0.85);
3838
39void39void
40CompositeTestSimpleBrick::prepare_for_run()40CompositeTestSimpleBrick::prepare_for_run(std::list<CompositeWindow*> &window_list)
41{41{
42 CompositeTestSimpleBase::prepare_for_run();42 CompositeTestSimpleBase::prepare_for_run(window_list);
4343
44 lightPos_ = LibMatrix::vec4(0.0, 1.0, 1.0, 0.0);44 lightPos_ = LibMatrix::vec4(0.0, 1.0, 1.0, 0.0);
4545
4646
=== modified file 'src/composite-test-xrender.cc'
--- src/composite-test-xrender.cc 2011-08-03 17:14:34 +0000
+++ src/composite-test-xrender.cc 2012-03-20 16:31:20 +0000
@@ -52,8 +52,10 @@
52}52}
5353
54void54void
55CompositeTestXRender::prepare_for_run()55CompositeTestXRender::prepare_for_run(std::list<CompositeWindow*> &window_list)
56{56{
57 CompositeTest::prepare_for_run(window_list);
58
57 if (options_["filter"].value == "bilinear")59 if (options_["filter"].value == "bilinear")
58 xrender_filter_ = FilterBilinear;60 xrender_filter_ = FilterBilinear;
59 else61 else
6062
=== modified file 'src/composite-test.h'
--- src/composite-test.h 2011-12-05 18:14:07 +0000
+++ src/composite-test.h 2012-03-20 16:31:20 +0000
@@ -45,7 +45,11 @@
4545
46 virtual void init() {}46 virtual void init() {}
47 virtual void deinit() {}47 virtual void deinit() {}
48 virtual void prepare_for_run() {}48 virtual void prepare_for_run(std::list<CompositeWindow*> &window_list)
49 {
50 if (window_list.empty())
51 return;
52 }
49 virtual void draw(std::list<CompositeWindow*> &window_list)53 virtual void draw(std::list<CompositeWindow*> &window_list)
50 {54 {
51 (void)window_list;55 (void)window_list;
@@ -105,7 +109,7 @@
105public:109public:
106 CompositeTestDefaultOptions() : CompositeTest("", "") {}110 CompositeTestDefaultOptions() : CompositeTest("", "") {}
107111
108 virtual void prepare_for_run();112 virtual void prepare_for_run(std::list<CompositeWindow*> &window_list);
109 virtual bool set_option(const std::string &opt, const std::string &val);113 virtual bool set_option(const std::string &opt, const std::string &val);
110114
111protected:115protected:
@@ -121,7 +125,7 @@
121125
122 virtual void init();126 virtual void init();
123 virtual void deinit();127 virtual void deinit();
124 virtual void prepare_for_run();128 virtual void prepare_for_run(std::list<CompositeWindow*> &window_list);
125 virtual void cleanup();129 virtual void cleanup();
126 virtual void reshape(int width, int height);130 virtual void reshape(int width, int height);
127131
@@ -168,7 +172,7 @@
168 {}172 {}
169173
170 virtual void draw(std::list<CompositeWindow*> &window_list);174 virtual void draw(std::list<CompositeWindow*> &window_list);
171 virtual void prepare_for_run();175 virtual void prepare_for_run(std::list<CompositeWindow*> &window_list);
172private:176private:
173 LibMatrix::vec4 lightPos_;177 LibMatrix::vec4 lightPos_;
174 static const LibMatrix::vec3 mortarColor_;178 static const LibMatrix::vec3 mortarColor_;
@@ -187,7 +191,7 @@
187191
188 virtual void init();192 virtual void init();
189 virtual void deinit();193 virtual void deinit();
190 virtual void prepare_for_run();194 virtual void prepare_for_run(std::list<CompositeWindow*> &window_list);
191 virtual void draw(std::list<CompositeWindow*> &window_list);195 virtual void draw(std::list<CompositeWindow*> &window_list);
192196
193private:197private:
@@ -202,7 +206,7 @@
202206
203 virtual void init();207 virtual void init();
204 virtual void deinit();208 virtual void deinit();
205 virtual void prepare_for_run();209 virtual void prepare_for_run(std::list<CompositeWindow*> &window_list);
206 virtual void draw(std::list<CompositeWindow*> &window_list);210 virtual void draw(std::list<CompositeWindow*> &window_list);
207211
208private:212private:
@@ -225,4 +229,19 @@
225 virtual bool init_shaders(ShaderSource& vtx, ShaderSource& frg);229 virtual bool init_shaders(ShaderSource& vtx, ShaderSource& frg);
226};230};
227231
232struct BlurPrivate;
233
234class CompositeTestSimpleBlur : public CompositeTestSimpleBase
235{
236 static const std::string fade_bias_name_;
237 BlurPrivate* priv_;
238public:
239 CompositeTestSimpleBlur();
240 ~CompositeTestSimpleBlur();
241
242 virtual void draw(std::list<CompositeWindow*> &window_list);
243 virtual void reshape(int width, int height);
244 virtual void prepare_for_run(std::list<CompositeWindow*> &window_list);
245};
246
228#endif // COMPOSITE_TEST_H_247#endif // COMPOSITE_TEST_H_
229248
=== modified file 'src/glcompbench.cc'
--- src/glcompbench.cc 2012-02-17 11:51:23 +0000
+++ src/glcompbench.cc 2012-03-20 16:31:20 +0000
@@ -45,6 +45,7 @@
45static const char *default_benchmarks[] = {45static const char *default_benchmarks[] = {
46 "default",46 "default",
47 "fade",47 "fade",
48 "blur",
48 "brick",49 "brick",
49 "pixman",50 "pixman",
50 "xrender",51 "xrender",
@@ -195,6 +196,7 @@
195196
196 Benchmark::register_test(*new CompositeTestDefaultOptions());197 Benchmark::register_test(*new CompositeTestDefaultOptions());
197 Benchmark::register_test(*new CompositeTestSimpleDefault());198 Benchmark::register_test(*new CompositeTestSimpleDefault());
199 Benchmark::register_test(*new CompositeTestSimpleBlur());
198 Benchmark::register_test(*new CompositeTestSimpleFade());200 Benchmark::register_test(*new CompositeTestSimpleFade());
199 Benchmark::register_test(*new CompositeTestSimpleBrick());201 Benchmark::register_test(*new CompositeTestSimpleBrick());
200 Benchmark::register_test(*new CompositeTestPixman());202 Benchmark::register_test(*new CompositeTestPixman());
201203
=== added file 'src/render-object.cc'
--- src/render-object.cc 1970-01-01 00:00:00 +0000
+++ src/render-object.cc 2012-03-20 16:31:20 +0000
@@ -0,0 +1,282 @@
1/*
2 * Copyright © 2012 Linaro Limited
3 *
4 * This file is part of glcompbench.
5 *
6 * glcompbench is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * glcompbench is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with glcompbench. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Authors:
20 * Alexandros Frantzis <alexandros.frantzis@linaro.org>
21 * Jesse Barker <jesse.barker@linaro.org>
22 */
23
24#include "log.h"
25#include "render-object.h"
26#include "shader-source.h"
27#include "gl-headers.h"
28#include "texture.h"
29
30using LibMatrix::vec2;
31using std::string;
32
33bool
34RenderObject::load_shaders_from_strings(Program &program,
35 const string &vtx_shader, const string &frg_shader)
36{
37 program.init();
38
39 Log::debug("Loading vertex shader:\n%s", vtx_shader.c_str());
40
41 program.addShader(GL_VERTEX_SHADER, vtx_shader);
42 if (!program.valid()) {
43 Log::error("Failed to add vertex shader:\n %s\n", "RenderObject: ",
44 program.errorMessage().c_str());
45 program.release();
46 return false;
47 }
48
49 Log::debug("Loading fragment shader:\n%s", frg_shader.c_str());
50
51 program.addShader(GL_FRAGMENT_SHADER, frg_shader);
52 if (!program.valid()) {
53 Log::error("Failed to add fragment shader:\n %s\n",
54 program.errorMessage().c_str());
55 program.release();
56 return false;
57 }
58
59 program.build();
60 if (!program.ready()) {
61 Log::error("Failed to link program: %s\n",
62 program.errorMessage().c_str());
63 program.release();
64 return false;
65 }
66
67 return true;
68}
69
70void
71RenderObject::init(Program& default_program)
72{
73 default_program_ = &default_program;
74
75 // Create a texture to use as a render target
76 glGenTextures(1, &texture_);
77 glBindTexture(GL_TEXTURE_2D, texture_);
78 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
79 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
80 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
81 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
82 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size_.x(), size_.y(), 0,
83 GL_RGBA, GL_UNSIGNED_BYTE, 0);
84
85 // Create a FBO
86 glGenFramebuffers(1, &fbo_);
87 glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
88 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
89 GL_TEXTURE_2D, texture_, 0);
90
91 glBindFramebuffer(GL_FRAMEBUFFER, 0);
92
93 texture_contents_invalid_ = true;
94}
95
96void
97RenderObject::release()
98{
99 // Release resources
100 if (texture_ != 0)
101 {
102 glDeleteTextures(1, &texture_);
103 texture_ = 0;
104 }
105 if (fbo_ != 0)
106 {
107 glDeleteFramebuffers(1, &fbo_);
108 fbo_ = 0;
109 }
110}
111
112void
113RenderObject::make_current()
114{
115 glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
116 glViewport(0, 0, size_.x(), size_.y());
117}
118
119void
120RenderObject::resize(const vec2& size)
121{
122 /// Recreate the backing texture with correct size
123 if (size_ != size) {
124 size_ = size;
125 glBindTexture(GL_TEXTURE_2D, texture_);
126 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size_.x(), size_.y(), 0,
127 GL_RGBA, GL_UNSIGNED_BYTE, 0);
128 texture_contents_invalid_ = true;
129 }
130
131 if (texture_contents_invalid_) {
132 clear();
133 texture_contents_invalid_ = false;
134 }
135}
136
137void
138RenderObject::clear()
139{
140 make_current();
141 glClear(GL_COLOR_BUFFER_BIT);
142}
143
144void
145RenderObject::render_to(RenderObject& target)
146{
147 render_to(target, *default_program_);
148}
149
150void
151RenderObject::render_to(RenderObject& target, Program& program)
152{
153 vec2 anchor(pos_);
154 vec2 ll(pos_ - anchor);
155 vec2 ur(pos_ + size_ - anchor);
156
157 /* Calculate new position according to rotation value */
158 GLfloat position[2 * 4] = {
159 rotate_x(ll.x(), ll.y()) + anchor.x(), rotate_y(ll.x(), ll.y()) + anchor.y(),
160 rotate_x(ur.x(), ll.y()) + anchor.x(), rotate_y(ur.x(), ll.y()) + anchor.y(),
161 rotate_x(ll.x(), ur.y()) + anchor.x(), rotate_y(ll.x(), ur.y()) + anchor.y(),
162 rotate_x(ur.x(), ur.y()) + anchor.x(), rotate_y(ur.x(), ur.y()) + anchor.y(),
163 };
164
165 /* Normalize position and write back to array */
166 for (unsigned int i = 0; i < 4; i++) {
167 unsigned int idx1(2 * i);
168 unsigned int idx2(2 * i + 1);
169 const vec2& v2(target.normalize_position(vec2(position[idx1], position[idx2])));
170 position[idx1] = v2.x();
171 position[idx2] = v2.y();
172 }
173
174 static const GLfloat texcoord[2 * 4] = {
175 0.0, 0.0,
176 1.0, 0.0,
177 0.0, 1.0,
178 1.0, 1.0,
179 };
180
181 target.make_current();
182
183 glActiveTexture(GL_TEXTURE0);
184 glBindTexture(GL_TEXTURE_2D, texture_);
185 draw_quad_with_program(position, texcoord, program);
186}
187
188void
189RenderObject::draw_quad_with_program(const float *position,
190 const float *texcoord, Program &program)
191{
192 int pos_index = program["position"].location();
193 int tex_index = program["texcoord"].location();
194
195 program.start();
196
197 glEnableVertexAttribArray(pos_index);
198 glEnableVertexAttribArray(tex_index);
199 glVertexAttribPointer(pos_index, 2,
200 GL_FLOAT, GL_FALSE, 0, position);
201 glVertexAttribPointer(tex_index, 2,
202 GL_FLOAT, GL_FALSE, 0, texcoord);
203
204 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
205
206 glDisableVertexAttribArray(tex_index);
207 glDisableVertexAttribArray(pos_index);
208
209 program.stop();
210}
211
212RenderClearImage::RenderClearImage(const string& image_file) :
213 RenderObject(), background_texture_name_(image_file),
214 background_texture_(0), background_is_image_(false),
215 texcoord_(texcoord_window_)
216{
217 if (!background_texture_name_.empty())
218 {
219 background_is_image_ = true;
220 texcoord_ = texcoord_image_;
221 }
222}
223
224RenderClearImage::RenderClearImage() :
225 RenderObject(),
226 background_texture_(0), background_is_image_(false),
227 texcoord_(texcoord_window_)
228{
229}
230
231void
232RenderClearImage::init(Program& program)
233{
234 RenderObject::init(program);
235 if (background_is_image_)
236 {
237 // Load the image into a texture.
238 Texture::load(background_texture_name_,
239 &background_texture_, GL_LINEAR, GL_LINEAR, 0);
240 }
241}
242
243void
244RenderClearImage::set_background(unsigned int background_texture)
245{
246 background_texture_ = background_texture;
247}
248
249void
250RenderClearImage::clear()
251{
252 make_current();
253 glClear(GL_COLOR_BUFFER_BIT);
254
255 glActiveTexture(GL_TEXTURE0);
256 glBindTexture(GL_TEXTURE_2D, background_texture_);
257
258 glEnable(GL_BLEND);
259 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
260 draw_quad_with_program(position_, texcoord_, *default_program_);
261 glDisable(GL_BLEND);
262}
263
264const float RenderClearImage::position_[8] = {
265 -1.0, -1.0,
266 1.0, -1.0,
267 -1.0, 1.0,
268 1.0, 1.0,
269};
270const float RenderClearImage::texcoord_image_[8] = {
271 0.0, 0.0,
272 1.0, 0.0,
273 0.0, 1.0,
274 1.0, 1.0,
275};
276const float RenderClearImage::texcoord_window_[8] = {
277 0.0, 1.0,
278 1.0, 1.0,
279 0.0, 0.0,
280 1.0, 0.0,
281};
282
0283
=== added file 'src/render-object.h'
--- src/render-object.h 1970-01-01 00:00:00 +0000
+++ src/render-object.h 2012-03-20 16:31:20 +0000
@@ -0,0 +1,152 @@
1/*
2 * Copyright © 2012 Linaro Limited
3 *
4 * This file is part of glcompbench.
5 *
6 * glcompbench is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * glcompbench is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with glcompbench. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Authors:
20 * Alexandros Frantzis <alexandros.frantzis@linaro.org>
21 * Jesse Barker <jesse.barker@linaro.org>
22 */
23#ifndef RENDER_OBJECT_H_
24#define RENDER_OBJECT_H_
25
26#include "vec.h"
27#include "program.h"
28
29//
30// A RenderObject represents a source and target of rendering
31// operations.
32//
33class RenderObject
34{
35public:
36 RenderObject() :
37 texture_(0), fbo_(0), rotation_rad_(0),
38 texture_contents_invalid_(true) {}
39
40 // Public interfaces with default implementations
41 virtual void init(Program& default_program);
42 virtual void release();
43 virtual void resize(const LibMatrix::vec2& size);
44 virtual void clear();
45 virtual void render_to(RenderObject& target);
46 virtual void render_to(RenderObject& target, Program& program);
47
48 // Public methods
49 void make_current();
50
51 // Get/set methods
52 void position(const LibMatrix::vec2& pos) { pos_ = pos; }
53 const LibMatrix::vec2& position() { return pos_; }
54 const LibMatrix::vec2& size() { return size_; }
55 unsigned int texture() { return texture_; }
56
57 // Normalizes a position from [0, size] to [-1.0, 1.0]
58 LibMatrix::vec2 normalize_position(const LibMatrix::vec2& pos)
59 {
60 return pos * 2.0 / size_ - 1.0;
61 }
62
63 // Normalizes a position from [0, size] to [0.0, 1.0]
64 LibMatrix::vec2 normalize_texcoord(const LibMatrix::vec2& pos)
65 {
66 return pos / size_;
67 }
68
69 void rotation(float degrees)
70 {
71 rotation_rad_ = (M_PI * degrees / 180.0);
72 }
73
74protected:
75 static bool load_shaders_from_strings(Program& program,
76 const std::string& vtx_shader, const std::string& frg_shader);
77 static void draw_quad_with_program(const float *position, const float *texcoord,
78 Program &program);
79
80 LibMatrix::vec2 pos_;
81 LibMatrix::vec2 size_;
82 unsigned int texture_;
83 unsigned int fbo_;
84 Program* default_program_;
85
86private:
87 float rotate_x(float x, float y)
88 {
89 return x * cos(rotation_rad_) - y * sin(rotation_rad_);
90 }
91
92 float rotate_y(float x, float y)
93 {
94 return x * sin(rotation_rad_) + y * cos(rotation_rad_);
95 }
96
97 float rotation_rad_;
98 bool texture_contents_invalid_;
99};
100
101//
102// A RenderObject representing the screen.
103//
104// Rendering to this objects renders to the screen framebuffer.
105//
106class RenderScreen : public RenderObject
107{
108public:
109 // Our own implementation of the init and release interfaces.
110 virtual void init(Program& program) { default_program_ = &program; }
111 virtual void release() {}
112};
113
114//
115// A RenderObject with a background image.
116//
117// The image is drawn to the RenderObject automatically when the
118// object is cleared, resized etc. The background texture for this object
119// can either be an image loaded from a named file (in which case the texture
120// name is created during the load), or it can be set from an existing texture
121// object.
122//
123class RenderClearImage : public RenderObject
124{
125public:
126 RenderClearImage();
127 RenderClearImage(const std::string& image_file);
128
129 // Our own implementation of the init interface.
130 virtual void init(Program& program);
131
132 // Sets the background texture name.
133 void set_background(unsigned int background_texture);
134
135 // "Clears" the object to the contents of the background texture.
136 void clear();
137
138private:
139 std::string background_texture_name_;
140 unsigned int background_texture_;
141 bool background_is_image_;
142 // Vertex position is always the same for any rendering with this object,
143 // however, texture coordinates vary depending upon whether the texture
144 // came from a static image loaded from a file (for example) or a window
145 // system pixmap (inverted sense of y direction).
146 const float* texcoord_;
147 static const float position_[8];
148 static const float texcoord_image_[8];
149 static const float texcoord_window_[8];
150};
151
152#endif // RENDER_OBJECT_H_
0153
=== added file 'src/texture.cc'
--- src/texture.cc 1970-01-01 00:00:00 +0000
+++ src/texture.cc 2012-03-20 16:31:20 +0000
@@ -0,0 +1,201 @@
1/*
2 * Copyright © 2008 Ben Smith
3 * Copyright © 2010-2011 Linaro Limited
4 *
5 * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
6 *
7 * glmark2 is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later
10 * version.
11 *
12 * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15 * details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * glmark2. If not, see <http://www.gnu.org/licenses/>.
19 *
20 * Authors:
21 * Ben Smith (original glmark benchmark)
22 * Alexandros Frantzis (glmark2)
23 */
24#include "texture.h"
25#include "log.h"
26#include "util.h"
27
28#include <cstdarg>
29#include <png.h>
30#include <memory>
31
32class PNGState
33{
34public:
35 PNGState() :
36 png_(0),
37 info_(0),
38 rows_(0) {}
39 ~PNGState()
40 {
41 if (png_)
42 {
43 png_destroy_read_struct(&png_, &info_, 0);
44 }
45 }
46 bool gotData(const std::string& filename)
47 {
48 static const int png_transforms = PNG_TRANSFORM_STRIP_16 |
49 PNG_TRANSFORM_GRAY_TO_RGB |
50 PNG_TRANSFORM_PACKING |
51 PNG_TRANSFORM_EXPAND;
52
53 Log::debug("Reading PNG file %s\n", filename.c_str());
54
55 const std::auto_ptr<std::istream> is_ptr(Util::get_resource(filename));
56 if (!(*is_ptr)) {
57 Log::error("Cannot open file %s!\n", filename.c_str());
58 return false;
59 }
60
61 /* Set up all the libpng structs we need */
62 png_ = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
63 if (!png_) {
64 Log::error("Couldn't create libpng read struct\n");
65 return false;
66 }
67
68 info_ = png_create_info_struct(png_);
69 if (!info_) {
70 Log::error("Couldn't create libpng info struct\n");
71 return false;
72 }
73
74 /* Set up libpng error handling */
75 if (setjmp(png_jmpbuf(png_))) {
76 Log::error("libpng error while reading file %s\n", filename.c_str());
77 return false;
78 }
79
80 /* Read the image information and data */
81 png_set_read_fn(png_, reinterpret_cast<voidp>(is_ptr.get()), png_read_fn);
82
83 png_read_png(png_, info_, png_transforms, 0);
84
85 rows_ = png_get_rows(png_, info_);
86
87 return true;
88 }
89 unsigned int width() const { return png_get_image_width(png_, info_); }
90 unsigned int height() const { return png_get_image_height(png_, info_); }
91 unsigned int pixelBytes() const
92 {
93 if (png_get_color_type(png_, info_) == PNG_COLOR_TYPE_RGB)
94 {
95 return 3;
96 }
97 return 4;
98 }
99 const unsigned char* row(unsigned int idx) const { return rows_[idx]; }
100private:
101 static void png_read_fn(png_structp png_ptr, png_bytep data, png_size_t length)
102 {
103 std::istream *is = reinterpret_cast<std::istream*>(png_get_io_ptr(png_ptr));
104 is->read(reinterpret_cast<char *>(data), length);
105 }
106 png_structp png_;
107 png_infop info_;
108 png_bytepp rows_;
109};
110
111class ImageData {
112 void resize(unsigned int w, unsigned int h, unsigned int b)
113 {
114 width = w;
115 height = h;
116 bpp = b;
117 delete [] pixels;
118 pixels = new unsigned char[bpp * width * height];
119 }
120
121public:
122 ImageData() : pixels(0), width(0), height(0), bpp(0) {}
123 ~ImageData() { delete [] pixels; }
124 bool load_png(const std::string &filename);
125
126 unsigned char *pixels;
127 unsigned int width;
128 unsigned int height;
129 unsigned int bpp;
130};
131
132bool
133ImageData::load_png(const std::string &filename)
134{
135 PNGState png;
136 bool ret = png.gotData(filename);
137 if (!ret)
138 {
139 return ret;
140 }
141
142 resize(png.width(), png.height(), png.pixelBytes());
143
144 Log::debug(" Height: %d Width: %d Bpp: %d\n", width, height, bpp);
145
146 /*
147 * Copy the image data to a contiguous memory area suitable for texture
148 * upload.
149 */
150 for (unsigned int i = 0; i < height; i++) {
151 memcpy(&pixels[bpp * width * i],
152 png.row(height - i - 1),
153 width * bpp);
154 }
155
156 return ret;
157}
158
159static void
160setup_texture(GLuint *tex, ImageData &image, GLint min_filter, GLint mag_filter)
161{
162 GLenum format = image.bpp == 3 ? GL_RGB : GL_RGBA;
163
164 glGenTextures(1, tex);
165 glBindTexture(GL_TEXTURE_2D, *tex);
166 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
167 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
168 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
169 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
170 glTexImage2D(GL_TEXTURE_2D, 0, format, image.width, image.height, 0,
171 format, GL_UNSIGNED_BYTE, image.pixels);
172
173 if ((min_filter != GL_NEAREST && min_filter != GL_LINEAR) ||
174 (mag_filter != GL_NEAREST && mag_filter != GL_LINEAR))
175 {
176 glGenerateMipmap(GL_TEXTURE_2D);
177 }
178}
179
180bool
181Texture::load(const std::string &filename, GLuint *pTexture, ...)
182{
183 ImageData image;
184
185 if (!image.load_png(filename))
186 return false;
187
188 va_list ap;
189 va_start(ap, pTexture);
190 GLint arg;
191
192 while ((arg = va_arg(ap, GLint)) != 0) {
193 GLint arg2 = va_arg(ap, GLint);
194 setup_texture(pTexture, image, arg, arg2);
195 pTexture++;
196 }
197
198 va_end(ap);
199
200 return true;
201}
0202
=== added file 'src/texture.h'
--- src/texture.h 1970-01-01 00:00:00 +0000
+++ src/texture.h 2012-03-20 16:31:20 +0000
@@ -0,0 +1,37 @@
1/*
2 * Copyright © 2008 Ben Smith
3 * Copyright © 2010-2011 Linaro Limited
4 *
5 * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
6 *
7 * glmark2 is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later
10 * version.
11 *
12 * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15 * details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * glmark2. If not, see <http://www.gnu.org/licenses/>.
19 *
20 * Authors:
21 * Ben Smith (original glmark benchmark)
22 * Alexandros Frantzis (glmark2)
23 */
24#ifndef GLMARK2_TEXTURE_H_
25#define GLMARK2_TEXTURE_H_
26
27#include "gl-headers.h"
28
29#include <string>
30
31class Texture
32{
33public:
34 static bool load(const std::string &filename, GLuint *pTexture, ...);
35};
36
37#endif
038
=== modified file 'src/wscript_build'
--- src/wscript_build 2011-12-12 13:18:23 +0000
+++ src/wscript_build 2012-03-20 16:31:20 +0000
@@ -49,7 +49,7 @@
49 source = common_sources + egl_sources,49 source = common_sources + egl_sources,
50 target = 'glcompbench-egl-gl',50 target = 'glcompbench-egl-gl',
51 uselib = ['egl', 'gl'] + common_libs,51 uselib = ['egl', 'gl'] + common_libs,
52 use = ['matrix'],52 use = ['matrix', 'libpng12'],
53 lib = ['m'],53 lib = ['m'],
54 defines = ['USE_EGL', 'USE_GL']54 defines = ['USE_EGL', 'USE_GL']
55 )55 )
@@ -60,7 +60,7 @@
60 source = common_sources + egl_sources,60 source = common_sources + egl_sources,
61 target = 'glcompbench-egl-es2',61 target = 'glcompbench-egl-es2',
62 uselib = ['egl', 'glesv2'] + common_libs,62 uselib = ['egl', 'glesv2'] + common_libs,
63 use = ['matrix-es2'],63 use = ['matrix-es2', 'libpng12'],
64 lib = ['m'],64 lib = ['m'],
65 defines = ['USE_EGL', 'USE_GLES2']65 defines = ['USE_EGL', 'USE_GLES2']
66 )66 )
@@ -71,7 +71,7 @@
71 source = common_sources + glx_sources,71 source = common_sources + glx_sources,
72 target = 'glcompbench-glx',72 target = 'glcompbench-glx',
73 uselib = ['gl'] + common_libs,73 uselib = ['gl'] + common_libs,
74 use = ['matrix'],74 use = ['matrix', 'libpng12'],
75 lib = ['m'],75 lib = ['m'],
76 defines = ['USE_GLX', 'USE_GL']76 defines = ['USE_GLX', 'USE_GL']
77 )77 )
@@ -82,7 +82,7 @@
82 source = common_sources + egl_sources + glx_sources,82 source = common_sources + egl_sources + glx_sources,
83 target = 'glcompbench',83 target = 'glcompbench',
84 uselib = ['glproxy'] + common_libs,84 uselib = ['glproxy'] + common_libs,
85 use = ['matrix-glproxy'],85 use = ['matrix-glproxy', 'libpng12'],
86 lib = ['m'],86 lib = ['m'],
87 defines = ['USE_EGL', 'USE_GLES2', 'USE_GLX', 'USE_GL', 'USE_GLPROXY']87 defines = ['USE_EGL', 'USE_GLES2', 'USE_GLX', 'USE_GL', 'USE_GLPROXY']
88 )88 )
8989
=== modified file 'wscript'
--- wscript 2012-02-16 12:19:54 +0000
+++ wscript 2012-03-20 16:31:20 +0000
@@ -64,7 +64,7 @@
64 # Check required packages64 # Check required packages
65 req_pkgs = [('x11', 'x11'), ('xdamage', 'xdamage'),65 req_pkgs = [('x11', 'x11'), ('xdamage', 'xdamage'),
66 ('xcomposite', 'xcomposite'), ('pixman-1', 'pixman'),66 ('xcomposite', 'xcomposite'), ('pixman-1', 'pixman'),
67 ('xext', 'xext'), ('xrender', 'xrender')]67 ('xext', 'xext'), ('xrender', 'xrender'), ('libpng12', 'libpng12')]
68 for (pkg, uselib) in req_pkgs:68 for (pkg, uselib) in req_pkgs:
69 ctx.check_cfg(package = pkg, uselib_store = uselib, args = '--cflags --libs',69 ctx.check_cfg(package = pkg, uselib_store = uselib, args = '--cflags --libs',
70 mandatory = True)70 mandatory = True)

Subscribers

People subscribed via source and target branches

to all changes: