Merge lp:~glmark2-dev/glmark2/live-fps into lp:glmark2/2011.11

Proposed by Alexandros Frantzis
Status: Merged
Merged at revision: 178
Proposed branch: lp:~glmark2-dev/glmark2/live-fps
Merge into: lp:glmark2/2011.11
Diff against target: 504 lines (+397/-0)
8 files modified
data/shaders/text-renderer.frag (+10/-0)
data/shaders/text-renderer.vert (+10/-0)
doc/glmark2.1.in (+4/-0)
src/main.cpp (+15/-0)
src/options.cpp (+6/-0)
src/options.h (+1/-0)
src/text-renderer.cpp (+291/-0)
src/text-renderer.h (+60/-0)
To merge this branch: bzr merge lp:~glmark2-dev/glmark2/live-fps
Reviewer Review Type Date Requested Status
Jesse Barker Pending
Review via email: mp+85499@code.launchpad.net

Description of the change

Add support for optionally showing a live FPS counter on screen.

To post a comment you must log in.
lp:~glmark2-dev/glmark2/live-fps updated
179. By Alexandros Frantzis

TextRenderer: Avoid setting/restoring the VBO state more than once.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'data/shaders/text-renderer.frag'
--- data/shaders/text-renderer.frag 1970-01-01 00:00:00 +0000
+++ data/shaders/text-renderer.frag 2012-01-05 09:43:24 +0000
@@ -0,0 +1,10 @@
1uniform sampler2D Texture0;
2
3varying vec2 TextureCoord;
4
5void main(void)
6{
7 vec4 texel = texture2D(Texture0, TextureCoord);
8 gl_FragColor = texel;
9}
10
011
=== added file 'data/shaders/text-renderer.vert'
--- data/shaders/text-renderer.vert 1970-01-01 00:00:00 +0000
+++ data/shaders/text-renderer.vert 2012-01-05 09:43:24 +0000
@@ -0,0 +1,10 @@
1attribute vec2 position;
2attribute vec2 texcoord;
3
4varying vec2 TextureCoord;
5
6void main(void)
7{
8 TextureCoord = texcoord;
9 gl_Position = vec4(position, 0.0, 1.0);
10}
011
=== added file 'data/textures/glyph-atlas.png'
1Binary files data/textures/glyph-atlas.png 1970-01-01 00:00:00 +0000 and data/textures/glyph-atlas.png 2012-01-05 09:43:24 +0000 differ12Binary files data/textures/glyph-atlas.png 1970-01-01 00:00:00 +0000 and data/textures/glyph-atlas.png 2012-01-05 09:43:24 +0000 differ
=== modified file 'doc/glmark2.1.in'
--- doc/glmark2.1.in 2011-12-15 13:52:04 +0000
+++ doc/glmark2.1.in 2012-01-05 09:43:24 +0000
@@ -36,6 +36,10 @@
36Show all scene option values used for benchmarks36Show all scene option values used for benchmarks
37(only explicitly set options are shown by default)37(only explicitly set options are shown by default)
38.TP38.TP
39\fB\-\-show-fps\fR
40Show live FPS count on screen (showing live FPS
41affects benchmarking results, use with care!)
42.TP
39\fB\-d\fR, \fB\-\-debug\fR43\fB\-d\fR, \fB\-\-debug\fR
40Display debug messages44Display debug messages
41.TP45.TP
4246
=== modified file 'src/main.cpp'
--- src/main.cpp 2011-11-11 11:07:15 +0000
+++ src/main.cpp 2012-01-05 09:43:24 +0000
@@ -28,6 +28,7 @@
28#include "log.h"28#include "log.h"
29#include "util.h"29#include "util.h"
30#include "default-benchmarks.h"30#include "default-benchmarks.h"
31#include "text-renderer.h"
3132
32#include <iostream>33#include <iostream>
33#include <fstream>34#include <fstream>
@@ -149,6 +150,8 @@
149void150void
150do_benchmark(Canvas &canvas, vector<Benchmark *> &benchmarks)151do_benchmark(Canvas &canvas, vector<Benchmark *> &benchmarks)
151{152{
153 static const unsigned int fps_interval = 500000;
154 TextRenderer fps_renderer(canvas);
152 unsigned score = 0;155 unsigned score = 0;
153 unsigned int benchmarks_run = 0;156 unsigned int benchmarks_run = 0;
154157
@@ -158,6 +161,7 @@
158 {161 {
159 bool keep_running = true;162 bool keep_running = true;
160 Benchmark *bench = *bench_iter;163 Benchmark *bench = *bench_iter;
164 uint64_t fps_timestamp = Util::get_timestamp_us();
161 Scene &scene = bench->setup_scene();165 Scene &scene = bench->setup_scene();
162166
163 if (!scene.name().empty()) {167 if (!scene.name().empty()) {
@@ -172,6 +176,17 @@
172 scene.draw();176 scene.draw();
173 scene.update();177 scene.update();
174178
179 if (Options::show_fps) {
180 uint64_t now = Util::get_timestamp_us();
181 if (now - fps_timestamp >= fps_interval) {
182 std::stringstream ss;
183 ss << "FPS: " << scene.average_fps();
184 fps_renderer.text(ss.str());
185 fps_timestamp = now;
186 }
187 fps_renderer.render();
188 }
189
175 canvas.update();190 canvas.update();
176 }191 }
177192
178193
=== modified file 'src/options.cpp'
--- src/options.cpp 2011-11-01 16:46:08 +0000
+++ src/options.cpp 2012-01-05 09:43:24 +0000
@@ -39,6 +39,7 @@
39bool Options::list_scenes = false;39bool Options::list_scenes = false;
40bool Options::show_all_options = false;40bool Options::show_all_options = false;
41bool Options::show_debug = false;41bool Options::show_debug = false;
42bool Options::show_fps = false;
42bool Options::show_help = false;43bool Options::show_help = false;
4344
44static struct option long_options[] = {45static struct option long_options[] = {
@@ -49,6 +50,7 @@
49 {"size", 1, 0, 0},50 {"size", 1, 0, 0},
50 {"list-scenes", 0, 0, 0},51 {"list-scenes", 0, 0, 0},
51 {"show-all-options", 0, 0, 0},52 {"show-all-options", 0, 0, 0},
53 {"show-fps", 0, 0, 0},
52 {"debug", 0, 0, 0},54 {"debug", 0, 0, 0},
53 {"help", 0, 0, 0},55 {"help", 0, 0, 0},
54 {0, 0, 0, 0}56 {0, 0, 0, 0}
@@ -98,6 +100,8 @@
98 " and their options\n"100 " and their options\n"
99 " --show-all-options Show all scene option values used for benchmarks\n"101 " --show-all-options Show all scene option values used for benchmarks\n"
100 " (only explicitly set options are shown by default)\n"102 " (only explicitly set options are shown by default)\n"
103 " --show-fps Show live FPS count on screen (showing live FPS\n"
104 " affects benchmarking results, use with care!)\n"
101 " -d, --debug Display debug messages\n"105 " -d, --debug Display debug messages\n"
102 " -h, --help Display help\n");106 " -h, --help Display help\n");
103}107}
@@ -134,6 +138,8 @@
134 Options::list_scenes = true;138 Options::list_scenes = true;
135 else if (!strcmp(optname, "show-all-options"))139 else if (!strcmp(optname, "show-all-options"))
136 Options::show_all_options = true;140 Options::show_all_options = true;
141 else if (!strcmp(optname, "show-fps"))
142 Options::show_fps = true;
137 else if (c == 'd' || !strcmp(optname, "debug"))143 else if (c == 'd' || !strcmp(optname, "debug"))
138 Options::show_debug = true;144 Options::show_debug = true;
139 else if (c == 'h' || !strcmp(optname, "help"))145 else if (c == 'h' || !strcmp(optname, "help"))
140146
=== modified file 'src/options.h'
--- src/options.h 2011-09-20 12:52:21 +0000
+++ src/options.h 2012-01-05 09:43:24 +0000
@@ -39,6 +39,7 @@
39 static bool list_scenes;39 static bool list_scenes;
40 static bool show_all_options;40 static bool show_all_options;
41 static bool show_debug;41 static bool show_debug;
42 static bool show_fps;
42 static bool show_help;43 static bool show_help;
43};44};
4445
4546
=== added file 'src/text-renderer.cpp'
--- src/text-renderer.cpp 1970-01-01 00:00:00 +0000
+++ src/text-renderer.cpp 2012-01-05 09:43:24 +0000
@@ -0,0 +1,291 @@
1/*
2 * Copyright © 2011 Linaro Limited
3 *
4 * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
5 *
6 * glmark2 is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software
8 * Foundation, either version 3 of the License, or (at your option) any later
9 * version.
10 *
11 * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 * details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * glmark2. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Authors:
20 * Alexandros Frantzis (glmark2)
21 */
22#include "text-renderer.h"
23#include "gl-headers.h"
24#include "scene.h"
25#include "shader-source.h"
26#include "vec.h"
27#include "mat.h"
28#include "texture.h"
29
30using LibMatrix::vec2;
31using LibMatrix::mat4;
32
33/* These are specific to the glyph texture atlas we are using */
34static const unsigned int texture_size(512);
35static const vec2 glyph_size_pixels(29.0, 57.0);
36static const vec2 glyph_size(glyph_size_pixels/texture_size);
37
38/******************
39 * Public methods *
40 ******************/
41
42/**
43 * TextRenderer default constructor.
44 */
45TextRenderer::TextRenderer(Canvas& canvas) :
46 canvas_(canvas), dirty_(false), position_(-1.0, -1.0),
47 texture_(0)
48{
49 size(0.03);
50
51 glGenBuffers(2, vbo_);
52 ShaderSource vtx_source(GLMARK_DATA_PATH"/shaders/text-renderer.vert");
53 ShaderSource frg_source(GLMARK_DATA_PATH"/shaders/text-renderer.frag");
54
55 if (!Scene::load_shaders_from_strings(program_, vtx_source.str(),
56 frg_source.str()))
57 {
58 return;
59 }
60
61 GLint prev_program;
62 glGetIntegerv(GL_CURRENT_PROGRAM, &prev_program);
63
64 program_.start();
65 program_["Texture0"] = 0;
66
67 glUseProgram(prev_program);
68
69 /* Load the glyph texture atlas */
70 Texture::load(GLMARK_DATA_PATH"/textures/glyph-atlas.png", &texture_,
71 GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR,0);
72}
73
74TextRenderer::~TextRenderer()
75{
76 glDeleteBuffers(2, vbo_);
77 glDeleteTextures(1, &texture_);
78}
79
80/**
81 * Sets the text string to render.
82 *
83 * @param t the text string
84 */
85void
86TextRenderer::text(const std::string& t)
87{
88 if (text_ != t) {
89 text_ = t;
90 dirty_ = true;
91 }
92}
93
94/**
95 * Sets the screen position to render at.
96 *
97 * @param t the position
98 */
99void
100TextRenderer::position(LibMatrix::vec2& p)
101{
102 if (position_ != p) {
103 position_ = p;
104 dirty_ = true;
105 }
106}
107
108/**
109 * Sets the size of each rendered glyph.
110 *
111 * The size corresponds to the width of each glyph
112 * in normalized screen coordinates.
113 *
114 * @param s the size of each glyph
115 */
116void
117TextRenderer::size(float s)
118{
119 if (size_.x() != s) {
120 /* Take into account the glyph and canvas aspect ratio */
121 double canvas_aspect =
122 static_cast<double>(canvas_.width()) / canvas_.height();
123 double glyph_aspect_rev = glyph_size.y() / glyph_size.x();
124 size_ = vec2(s, s * canvas_aspect * glyph_aspect_rev);
125 dirty_ = true;
126 }
127}
128
129/**
130 * Renders the text.
131 */
132void
133TextRenderer::render()
134{
135 /* Save state */
136 GLint prev_program = 0;
137 GLint prev_array_buffer = 0;
138 GLint prev_elem_array_buffer = 0;
139 GLint prev_blend_src_rgb = 0;
140 GLint prev_blend_dst_rgb = 0;
141 GLint prev_blend_src_alpha = 0;
142 GLint prev_blend_dst_alpha = 0;
143 GLboolean prev_blend = GL_FALSE;
144 GLboolean prev_depth_test = GL_FALSE;
145 glGetIntegerv(GL_CURRENT_PROGRAM, &prev_program);
146 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &prev_array_buffer);
147 glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &prev_elem_array_buffer);
148 glGetIntegerv(GL_BLEND_SRC_RGB, &prev_blend_src_rgb);
149 glGetIntegerv(GL_BLEND_DST_RGB, &prev_blend_dst_rgb);
150 glGetIntegerv(GL_BLEND_SRC_ALPHA, &prev_blend_src_alpha);
151 glGetIntegerv(GL_BLEND_DST_ALPHA, &prev_blend_dst_alpha);
152 glGetBooleanv(GL_BLEND, &prev_blend);
153 glGetBooleanv(GL_DEPTH_TEST, &prev_depth_test);
154
155 /* Set new state */
156 glActiveTexture(GL_TEXTURE0);
157 glBindTexture(GL_TEXTURE_2D, texture_);
158 glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]);
159 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_[1]);
160 glEnable(GL_BLEND);
161 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
162 glDisable(GL_DEPTH_TEST);
163
164 if (dirty_) {
165 create_geometry();
166 dirty_ = false;
167 }
168
169 program_.start();
170 GLint position_loc = program_["position"].location();
171 GLint texcoord_loc = program_["texcoord"].location();
172
173 /* Render */
174 glEnableVertexAttribArray(position_loc);
175 glEnableVertexAttribArray(texcoord_loc);
176 glVertexAttribPointer(position_loc, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
177 glVertexAttribPointer(texcoord_loc, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float),
178 reinterpret_cast<const GLvoid *>(2 * sizeof(float)));
179
180 glDrawElements(GL_TRIANGLES, 6 * text_.length(), GL_UNSIGNED_SHORT, 0);
181
182 glDisableVertexAttribArray(texcoord_loc);
183 glDisableVertexAttribArray(position_loc);
184
185 /* Restore state */
186 if (prev_depth_test == GL_TRUE)
187 glEnable(GL_DEPTH_TEST);
188 if (prev_blend == GL_FALSE)
189 glDisable(GL_BLEND);
190 glBlendFuncSeparate(prev_blend_src_rgb, prev_blend_dst_rgb,
191 prev_blend_src_alpha, prev_blend_dst_alpha);
192 glBindBuffer(GL_ARRAY_BUFFER, prev_array_buffer);
193 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prev_elem_array_buffer);
194 glUseProgram(prev_program);
195}
196
197/*******************
198 * Private methods *
199 *******************/
200
201/**
202 * Creates the geometry needed to render the text.
203 *
204 * This method assumes that the text VBOs are properly bound.
205 */
206void
207TextRenderer::create_geometry()
208{
209 std::vector<float> array;
210 std::vector<GLushort> elem_array;
211 vec2 pos(position_);
212
213 for (size_t i = 0; i < text_.size(); i++) {
214 vec2 texcoord = get_glyph_coords(text_[i]);
215
216 /* Emit the elements for this glyph quad */
217 /* Lower left */
218 array.push_back(pos.x());
219 array.push_back(pos.y());
220 array.push_back(texcoord.x());
221 array.push_back(texcoord.y());
222
223 /* Lower right */
224 pos.x(pos.x() + size_.x());
225 texcoord.x(texcoord.x() + glyph_size.x());
226 array.push_back(pos.x());
227 array.push_back(pos.y());
228 array.push_back(texcoord.x());
229 array.push_back(texcoord.y());
230
231 /* Upper left */
232 pos.x(pos.x() - size_.x());
233 pos.y(pos.y() + size_.y());
234 texcoord.x(texcoord.x() - glyph_size.x());
235 texcoord.y(texcoord.y() + glyph_size.y());
236 array.push_back(pos.x());
237 array.push_back(pos.y());
238 array.push_back(texcoord.x());
239 array.push_back(texcoord.y());
240
241 /* Upper right */
242 pos.x(pos.x() + size_.x());
243 texcoord.x(texcoord.x() + glyph_size.x());
244 array.push_back(pos.x());
245 array.push_back(pos.y());
246 array.push_back(texcoord.x());
247 array.push_back(texcoord.y());
248
249 /* Prepare for the next glyph */
250 pos.y(pos.y() - size_.y());
251
252 /* Emit the element indices for this glyph quad */
253 elem_array.push_back(4 * i);
254 elem_array.push_back(4 * i + 1);
255 elem_array.push_back(4 * i + 2);
256 elem_array.push_back(4 * i + 2);
257 elem_array.push_back(4 * i + 1);
258 elem_array.push_back(4 * i + 3);
259 }
260
261 /* Load the data into the corresponding VBOs */
262 glBufferData(GL_ARRAY_BUFFER, array.size() * sizeof(float),
263 &array[0], GL_DYNAMIC_DRAW);
264
265 glBufferData(GL_ELEMENT_ARRAY_BUFFER, elem_array.size() * sizeof(GLushort),
266 &elem_array[0], GL_DYNAMIC_DRAW);
267}
268
269/**
270 * Gets the texcoords of a glyph in the glyph texture atlas.
271 *
272 * @param c the character to get the glyph texcoords of
273 *
274 * @return the texcoords
275 */
276vec2
277TextRenderer::get_glyph_coords(char c)
278{
279 static const unsigned int glyphs_per_row(texture_size / glyph_size_pixels.x());
280
281 /* We only support the ASCII printable characters */
282 if (c < 32 || c >= 127)
283 c = 32;
284
285 int n = c - 32;
286 int row = n / glyphs_per_row;
287 int col = n % glyphs_per_row;
288
289 return vec2(col * glyph_size.x(), 1.0 - (row + 1) * glyph_size.y());
290}
291
0292
=== added file 'src/text-renderer.h'
--- src/text-renderer.h 1970-01-01 00:00:00 +0000
+++ src/text-renderer.h 2012-01-05 09:43:24 +0000
@@ -0,0 +1,60 @@
1/*
2 * Copyright © 2011 Linaro Limited
3 *
4 * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
5 *
6 * glmark2 is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software
8 * Foundation, either version 3 of the License, or (at your option) any later
9 * version.
10 *
11 * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 * details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * glmark2. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Authors:
20 * Alexandros Frantzis (glmark2)
21 */
22#ifndef GLMARK2_TEXT_RENDERER_H_
23#define GLMARK2_TEXT_RENDERER_H_
24
25#include <string>
26#include "gl-headers.h"
27#include "vec.h"
28#include "program.h"
29#include "canvas.h"
30
31/**
32 * Renders text using OpenGL textures.
33 */
34class TextRenderer
35{
36public:
37 TextRenderer(Canvas& canvas);
38 ~TextRenderer();
39
40 void text(const std::string& t);
41 void position(LibMatrix::vec2& p);
42 void size(float s);
43
44 void render();
45
46private:
47 void create_geometry();
48 LibMatrix::vec2 get_glyph_coords(char c);
49
50 Canvas& canvas_;
51 bool dirty_;
52 std::string text_;
53 LibMatrix::vec2 position_;
54 LibMatrix::vec2 size_;
55 Program program_;
56 GLuint vbo_[2];
57 GLuint texture_;
58};
59
60#endif

Subscribers

People subscribed via source and target branches

to all changes: