=== modified file 'src/android.cpp'
@@ -30,9 +30,26 @@
#include "log.h"
#include "util.h"
#include "default-benchmarks.h"
+#include "main-loop.h"
static Canvas *g_canvas;
static std::vector<Benchmark *> g_benchmarks;
+static MainLoop *g_loop;
+
+class MainLoopAndroid : public MainLoop
+{
+public:
+ MainLoopAndroid(Canvas &canvas, const std::vector<Benchmark *> &benchmarks) :
+ MainLoop(canvas, benchmarks) {}
+
+ virtual void after_scene_setup() {}
+
+ virtual void before_scene_teardown()
+ {
+ Log::info("%s FPS: %u", scene_->info_string().c_str(),
+ scene_->average_fps());
+ }
+};
static void
add_default_benchmarks(std::vector<Benchmark *> &benchmarks)
@@ -53,6 +70,7 @@
{
static_cast<void>(clazz);
+ Options::reuse_context = true;
Log::init("glmark2", false);
Util::android_set_asset_manager(AAssetManager_fromJava(env, asset_manager));
@@ -76,6 +94,7 @@
Benchmark::register_scene(*new SceneBuffer(*g_canvas));
add_default_benchmarks(g_benchmarks);
+ g_loop = new MainLoopAndroid(*g_canvas, g_benchmarks);
}
void
@@ -96,6 +115,7 @@
{
static_cast<void>(env);
+ delete g_loop;
delete g_canvas;
}
@@ -103,50 +123,10 @@
Java_org_linaro_glmark2_Glmark2Renderer_nativeRender(JNIEnv* env)
{
static_cast<void>(env);
- static std::vector<Benchmark *>::iterator bench_iter = g_benchmarks.begin();
- static Scene *scene = 0;
- static unsigned int score = 0;
- static unsigned int benchmarks_run = 0;
-
- if (!scene) {
- /* Find the next normal scene */
- while (bench_iter != g_benchmarks.end()) {
- scene = &(*bench_iter)->setup_scene();
- if (!scene->name().empty())
- break;
- bench_iter++;
- }
-
- if (bench_iter == g_benchmarks.end()) {
- if (benchmarks_run)
- score /= benchmarks_run;
- Log::info("glmark2 Score: %u\n", score);
- /* Reset the rendering state, in case we get called again */
- bench_iter = g_benchmarks.begin();
- score = 0;
- benchmarks_run = 0;
- return false;
- }
- }
-
- if (scene->is_running()) {
- g_canvas->clear();
-
- scene->draw();
- scene->update();
- }
-
- /*
- * Need to recheck whether screen is running, because scene->update()
- * may have changed the state.
- */
- if (!scene->is_running()) {
- Log::info("%s FPS: %u", scene->info_string().c_str(), scene->average_fps());
- score += scene->average_fps();
- (*bench_iter)->teardown_scene();
- scene = 0;
- bench_iter++;
- benchmarks_run++;
+
+ if (!g_loop->step()) {
+ Log::info("glmark2 Score: %u\n", g_loop->score());
+ return false;
}
return true;
=== added file 'src/main-loop.cpp'
@@ -0,0 +1,236 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include "options.h"
+#include "main-loop.h"
+#include "util.h"
+#include "log.h"
+
+#include <string>
+#include <sstream>
+
+/************
+ * MainLoop *
+ ************/
+
+MainLoop::MainLoop(Canvas &canvas, const std::vector<Benchmark *> &benchmarks) :
+ canvas_(canvas), benchmarks_(benchmarks)
+{
+ reset();
+}
+
+void
+MainLoop::reset()
+{
+ scene_ = 0;
+ score_ = 0;
+ benchmarks_run_ = 0;
+ bench_iter_ = benchmarks_.begin();
+}
+
+unsigned int
+MainLoop::score()
+{
+ if (benchmarks_run_)
+ return score_ / benchmarks_run_;
+ else
+ return score_;
+}
+
+bool
+MainLoop::step()
+{
+ /* Find the next normal scene */
+ if (!scene_) {
+ /* Find a normal scene */
+ while (bench_iter_ != benchmarks_.end()) {
+ scene_ = &(*bench_iter_)->scene();
+
+ /*
+ * Scenes with empty names are option-setting scenes.
+ * Just set them up and continue with the search.
+ */
+ if (scene_->name().empty())
+ (*bench_iter_)->setup_scene();
+ else
+ break;
+
+ bench_iter_++;
+ }
+
+ /* If we have found a valid scene, set it up */
+ if (bench_iter_ != benchmarks_.end()) {
+ if (!Options::reuse_context)
+ canvas_.reset();
+ before_scene_setup();
+ scene_ = &(*bench_iter_)->setup_scene();
+ after_scene_setup();
+ }
+ else {
+ /* ... otherwise we are done */
+ return false;
+ }
+ }
+
+ bool should_quit = canvas_.should_quit();
+
+ if (scene_ ->running() && !should_quit)
+ draw();
+
+ /*
+ * Need to recheck whether the scene is still running, because code
+ * in draw() may have changed the state.
+ */
+ if (!scene_->running() || should_quit) {
+ score_ += scene_->average_fps();
+ before_scene_teardown();
+ (*bench_iter_)->teardown_scene();
+ scene_ = 0;
+ bench_iter_++;
+ benchmarks_run_++;
+ }
+
+ return !should_quit;
+}
+
+void
+MainLoop::draw()
+{
+ canvas_.clear();
+
+ scene_->draw();
+ scene_->update();
+
+ canvas_.update();
+}
+
+void
+MainLoop::after_scene_setup()
+{
+ Log::info("%s", scene_->info_string().c_str());
+ Log::flush();
+}
+
+void
+MainLoop::before_scene_teardown()
+{
+ static const std::string format(Log::continuation_prefix + " FPS: %u\n");
+ Log::info(format.c_str(), scene_->average_fps());
+}
+
+/**********************
+ * MainLoopDecoration *
+ **********************/
+
+MainLoopDecoration::MainLoopDecoration(Canvas &canvas, const std::vector<Benchmark *> &benchmarks) :
+ MainLoop(canvas, benchmarks), fps_renderer_(0), last_fps_(0)
+{
+
+}
+
+MainLoopDecoration::~MainLoopDecoration()
+{
+ delete fps_renderer_;
+ fps_renderer_ = 0;
+}
+
+void
+MainLoopDecoration::draw()
+{
+ static const unsigned int fps_interval = 500000;
+ uint64_t now = Util::get_timestamp_us();
+
+ canvas_.clear();
+
+ scene_->draw();
+ scene_->update();
+
+ if (now - fps_timestamp_ >= fps_interval) {
+ last_fps_ = scene_->average_fps();
+ fps_renderer_update_text(last_fps_);
+ fps_timestamp_ = now;
+ }
+ fps_renderer_->render();
+
+ canvas_.update();
+}
+
+void
+MainLoopDecoration::before_scene_setup()
+{
+ delete fps_renderer_;
+ fps_renderer_ = new TextRenderer(canvas_);
+ fps_renderer_update_text(last_fps_);
+ fps_timestamp_ = Util::get_timestamp_us();
+}
+
+void
+MainLoopDecoration::fps_renderer_update_text(unsigned int fps)
+{
+ std::stringstream ss;
+ ss << "FPS: " << fps;
+ fps_renderer_->text(ss.str());
+}
+
+/**********************
+ * MainLoopValidation *
+ **********************/
+
+MainLoopValidation::MainLoopValidation(Canvas &canvas, const std::vector<Benchmark *> &benchmarks) :
+ MainLoop(canvas, benchmarks)
+{
+}
+
+void
+MainLoopValidation::draw()
+{
+ /* Draw only the first frame of the scene and stop */
+ canvas_.clear();
+
+ scene_->draw();
+
+ canvas_.update();
+
+ scene_->running(false);
+}
+
+void
+MainLoopValidation::before_scene_teardown()
+{
+ static const std::string format(Log::continuation_prefix + " Validation: %s\n");
+ std::string result;
+
+ switch(scene_->validate()) {
+ case Scene::ValidationSuccess:
+ result = "Success";
+ break;
+ case Scene::ValidationFailure:
+ result = "Failure";
+ break;
+ case Scene::ValidationUnknown:
+ result = "Unknown";
+ break;
+ default:
+ break;
+ }
+
+ Log::info(format.c_str(), result.c_str());
+}
=== added file 'src/main-loop.h'
@@ -0,0 +1,121 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#ifndef GLMARK2_MAIN_LOOP_H_
+#define GLMARK2_MAIN_LOOP_H_
+
+#include "canvas.h"
+#include "benchmark.h"
+#include "text-renderer.h"
+#include <vector>
+
+/**
+ * Main loop for benchmarking.
+ */
+class MainLoop
+{
+public:
+ MainLoop(Canvas &canvas, const std::vector<Benchmark *> &benchmarks);
+
+ virtual ~MainLoop() {}
+
+ /**
+ * Resets the main loop.
+ *
+ * You need to call reset() if the loop has finished and
+ * you need to run it again.
+ */
+ void reset();
+
+ /**
+ * Gets the current total benchmarking score.
+ */
+ unsigned int score();
+
+ /**
+ * Perform the next main loop step.
+ *
+ * @returns whether the loop has finished
+ */
+ bool step();
+
+ /**
+ * Overridable method for drawing the canvas contents.
+ */
+ virtual void draw();
+
+ /**
+ * Overridable method for pre scene-setup customizations.
+ */
+ virtual void before_scene_setup() {}
+
+ /**
+ * Overridable method for post scene-setup customizations.
+ */
+ virtual void after_scene_setup();
+
+ /**
+ * Overridable method for pre scene-teardown customizations.
+ */
+ virtual void before_scene_teardown();
+
+protected:
+ Canvas &canvas_;
+ Scene *scene_;
+ const std::vector<Benchmark *> &benchmarks_;
+ unsigned int score_;
+ unsigned int benchmarks_run_;
+
+ std::vector<Benchmark *>::const_iterator bench_iter_;
+};
+
+/**
+ * Main loop for benchmarking with decorations (eg FPS, demo)
+ */
+class MainLoopDecoration : public MainLoop
+{
+public:
+ MainLoopDecoration(Canvas &canvas, const std::vector<Benchmark *> &benchmarks);
+ virtual ~MainLoopDecoration();
+
+ virtual void draw();
+ virtual void before_scene_setup();
+
+protected:
+ void fps_renderer_update_text(unsigned int fps);
+ TextRenderer *fps_renderer_;
+ unsigned int last_fps_;
+ uint64_t fps_timestamp_;
+};
+
+/**
+ * Main loop for validation.
+ */
+class MainLoopValidation : public MainLoop
+{
+public:
+ MainLoopValidation(Canvas &canvas, const std::vector<Benchmark *> &benchmarks);
+
+ virtual void draw();
+ virtual void before_scene_teardown();
+};
+
+#endif /* GLMARK2_MAIN_LOOP_H_ */
=== modified file 'src/main.cpp'
@@ -30,6 +30,7 @@
#include "util.h"
#include "default-benchmarks.h"
#include "text-renderer.h"
+#include "main-loop.h"
#include <iostream>
#include <fstream>
@@ -174,115 +175,24 @@
void
do_benchmark(Canvas &canvas, vector<Benchmark *> &benchmarks)
{
- static const unsigned int fps_interval = 500000;
- unsigned score = 0;
- unsigned int last_fps = 0;
- unsigned int benchmarks_run = 0;
- static const string format(Log::continuation_prefix + " FPS: %u\n");
-
- for (vector<Benchmark *>::iterator bench_iter = benchmarks.begin();
- bench_iter != benchmarks.end();
- bench_iter++)
- {
- if (!Options::reuse_context)
- canvas.reset();
-
- TextRenderer fps_renderer(canvas);
- if (Options::show_fps)
- fps_renderer_update_text(fps_renderer, last_fps);
-
- bool keep_running = true;
- Benchmark *bench = *bench_iter;
- uint64_t fps_timestamp = Util::get_timestamp_us();
- Scene &scene = bench->setup_scene();
-
- if (!scene.name().empty()) {
- Log::info("%s", scene.info_string().c_str());
- Log::flush();
-
- while (scene.is_running() &&
- (keep_running = !canvas.should_quit()))
- {
- canvas.clear();
-
- scene.draw();
- scene.update();
-
- if (Options::show_fps) {
- uint64_t now = Util::get_timestamp_us();
- if (now - fps_timestamp >= fps_interval) {
- last_fps = scene.average_fps();
- fps_renderer_update_text(fps_renderer, last_fps);
- fps_timestamp = now;
- }
- fps_renderer.render();
- }
-
- canvas.update();
- }
-
- Log::info(format.c_str(), scene.average_fps());
- score += scene.average_fps();
- benchmarks_run++;
- }
-
- bench->teardown_scene();
-
- if (!keep_running)
- break;
- }
-
- if (benchmarks_run)
- score /= benchmarks_run;
-
- Log::info("=======================================================\n");
- Log::info(" glmark2 Score: %u \n", score);
- Log::info("=======================================================\n");
-
+ MainLoop loop_normal(canvas, benchmarks);
+ MainLoopDecoration loop_decoration(canvas, benchmarks);
+
+ MainLoop &loop(Options::show_fps ? loop_decoration : loop_normal);
+
+ while (loop.step());
+
+ Log::info("=======================================================\n");
+ Log::info(" glmark2 Score: %u \n", loop.score());
+ Log::info("=======================================================\n");
}
void
do_validation(Canvas &canvas, vector<Benchmark *> &benchmarks)
{
- static const string format(Log::continuation_prefix + " Validation: %s\n");
- for (vector<Benchmark *>::iterator bench_iter = benchmarks.begin();
- bench_iter != benchmarks.end();
- bench_iter++)
- {
- if (!Options::reuse_context)
- canvas.reset();
-
- Benchmark *bench = *bench_iter;
- Scene &scene = bench->setup_scene();
-
- if (!scene.name().empty()) {
- Log::info("%s", scene.info_string().c_str());
- Log::flush();
-
- canvas.clear();
- scene.draw();
- canvas.update();
-
- string result;
- switch(scene.validate()) {
- case Scene::ValidationSuccess:
- result = "Success";
- break;
- case Scene::ValidationFailure:
- result = "Failure";
- break;
- case Scene::ValidationUnknown:
- result = "Unknown";
- break;
- default:
- break;
- }
-
- Log::info(format.c_str(), result.c_str());
- }
-
- bench->teardown_scene();
- }
+ MainLoopValidation loop(canvas, benchmarks);
+
+ while (loop.step());
}
int
=== modified file 'src/scene.cpp'
@@ -121,13 +121,6 @@
return currentFrame_ / elapsed_time;
}
-
-bool
-Scene::is_running()
-{
- return running_;
-}
-
bool
Scene::set_option(const string &opt, const string &val)
{
=== modified file 'src/scene.h'
@@ -146,7 +146,14 @@
*
* @return true if running, false otherwise
*/
- bool is_running();
+ bool running() { return running_; }
+
+ /**
+ * Sets whether this scene is running.
+ *
+ * @return true if running, false otherwise
+ */
+ void running(bool r) { running_ = r; }
/**
* Gets the average FPS value for this scene.