=== added file 'src/benchmark.cc'
@@ -0,0 +1,142 @@
+/*
+ * Copyright © 2011 Linaro Limited
+ *
+ * This file is part of glcompbench.
+ *
+ * glcompbench 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.
+ *
+ * glcompbench 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 glcompbench. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis <alexandros.frantzis@linaro.org>
+ * Jesse Barker <jesse.barker@linaro.org>
+ */
+
+#include "benchmark.h"
+#include "log.h"
+#include <sstream>
+
+using std::string;
+using std::vector;
+using std::map;
+
+std::map<string, CompositeTest *> Benchmark::test_map_;
+
+static void
+split(const string &s, char delim, vector<string> &elems)
+{
+ std::stringstream ss(s);
+
+ string item;
+ while(std::getline(ss, item, delim))
+ elems.push_back(item);
+}
+
+static CompositeTest &
+get_test_from_description(const string &s)
+{
+ vector<string> elems;
+
+ split(s, ':', elems);
+
+ const string &name = !elems.empty() ? elems[0] : "";
+
+ return Benchmark::get_test_by_name(name);
+}
+
+static vector<Benchmark::OptionPair>
+get_options_from_description(const string &s)
+{
+ vector<Benchmark::OptionPair> options;
+ vector<string> elems;
+
+ split(s, ':', elems);
+
+ for (vector<string>::const_iterator iter = ++elems.begin();
+ iter != elems.end();
+ iter++)
+ {
+ vector<string> opt;
+
+ split(*iter, '=', opt);
+ if (opt.size() == 2)
+ options.push_back(Benchmark::OptionPair(opt[0], opt[1]));
+ else
+ Log::info("Warning: ignoring invalid option string '%s' "
+ "in benchmark description\n",
+ iter->c_str());
+ }
+
+ return options;
+}
+
+void
+Benchmark::register_test(CompositeTest &test)
+{
+ test_map_[test.name()] = &test;
+}
+
+CompositeTest &
+Benchmark::get_test_by_name(const string &name)
+{
+ map<string, CompositeTest *>::const_iterator iter;
+
+ if ((iter = test_map_.find(name)) != test_map_.end())
+ return *(iter->second);
+ else
+ return CompositeTest::dummy();
+}
+
+Benchmark::Benchmark(CompositeTest &test, const vector<OptionPair> &options) :
+ test_(test), options_(options)
+{
+}
+
+Benchmark::Benchmark(const string &name, const vector<OptionPair> &options) :
+ test_(Benchmark::get_test_by_name(name)), options_(options)
+{
+}
+
+Benchmark::Benchmark(const string &s) :
+ test_(get_test_from_description(s)),
+ options_(get_options_from_description(s))
+{
+}
+
+CompositeTest &
+Benchmark::setup_test()
+{
+ test_.reset_options();
+ load_options();
+
+ test_.prepare_for_run();
+
+ return test_;
+}
+
+void
+Benchmark::teardown_test()
+{
+ test_.cleanup();
+}
+
+void
+Benchmark::load_options()
+{
+ for (vector<OptionPair>::iterator iter = options_.begin();
+ iter != options_.end();
+ iter++)
+ {
+ test_.set_option(iter->first, iter->second);
+ }
+}
+
=== added file 'src/benchmark.h'
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2011 Linaro Limited
+ *
+ * This file is part of glcompbench.
+ *
+ * glcompbench 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.
+ *
+ * glcompbench 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 glcompbench. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis <alexandros.frantzis@linaro.org>
+ * Jesse Barker <jesse.barker@linaro.org>
+ */
+#ifndef BENCHMARK_H_
+#define BENCHMARK_H_
+
+#include <vector>
+#include <string>
+#include <map>
+
+#include "composite-test.h"
+
+class Benchmark
+{
+public:
+ typedef std::pair<std::string, std::string> OptionPair;
+
+ Benchmark(CompositeTest &test, const std::vector<OptionPair> &options);
+ Benchmark(const std::string &name, const std::vector<OptionPair> &options);
+ // Create a benchmark from a description string of the form:
+ // test[:opt1=val1:opt2=val2...]
+ Benchmark(const std::string &s);
+
+ CompositeTest &setup_test();
+ void teardown_test();
+
+ static void register_test(CompositeTest &test);
+ static CompositeTest &get_test_by_name(const std::string &name);
+ static const std::map<std::string, CompositeTest *> &tests() { return test_map_; }
+
+private:
+ CompositeTest &test_;
+ std::vector<OptionPair> options_;
+
+ void load_options();
+
+ static std::map<std::string, CompositeTest *> test_map_;
+};
+
+#endif
=== modified file 'src/composite-canvas.cc'
@@ -34,6 +34,7 @@
#include "composite-canvas.h"
#include "composite-window.h"
+#include "benchmark.h"
#include "options.h"
#include "log.h"
#include "profiler.h"
@@ -443,9 +444,6 @@
iteration_complete = false;
- if (!Options::benchmark)
- return;
-
Profiler &profiler = Profiler::instance();
profiler_cycle_pair_.sample_end();
@@ -476,29 +474,13 @@
}
}
-void
-CompositeCanvas::next_test(const std::list<CompositeTest*>& test_list, bool& back_to_beginning)
+static void
+next_benchmark(std::list<Benchmark*>& benchmarks,
+ std::list<Benchmark*>::iterator &benchIt)
{
- back_to_beginning = false;
- if (test_list.back() == current_test_) {
- current_test_ = test_list.front();
- back_to_beginning = true;
- return;
- }
- bool foundIt(false);
- for (std::list<CompositeTest*>::const_iterator testIt = test_list.begin();
- testIt != test_list.end();
- testIt++)
- {
- CompositeTest* curTest = *testIt;
- if (foundIt) {
- current_test_ = curTest;
- break;
- }
- if (curTest == current_test_) {
- foundIt = true;
- }
- }
+ benchIt++;
+ if (benchIt == benchmarks.end() && Options::run_forever)
+ benchIt = benchmarks.begin();
}
/******************
@@ -546,12 +528,12 @@
/**
* Runs a list of tests.
*
- * @param test_list the list of tests to run
+ * @param benchmarks the list of benchmarks to run
*/
void
-CompositeCanvas::run_tests(std::list<CompositeTest*> &test_list)
+CompositeCanvas::run_tests(std::list<Benchmark*> &benchmarks)
{
- if (test_list.empty()) {
+ if (benchmarks.empty()) {
Log::error("Test list is empty!\n");
return;
}
@@ -567,11 +549,12 @@
// Initialize all tests so that the benchmarking is not biased by
// setup time (loading and building shaders, etc.)
- for (std::list<CompositeTest*>::iterator testIt = test_list.begin();
- testIt != test_list.end();
+ for (std::map<std::string, CompositeTest*>::const_iterator testIt =
+ Benchmark::tests().begin();
+ testIt != Benchmark::tests().end();
testIt++)
{
- CompositeTest* curTest = *testIt;
+ CompositeTest* curTest = testIt->second;
if (!curTest) {
Log::error("Found a NULL test pointer!\n");
return;
@@ -579,19 +562,23 @@
curTest->init();
}
- current_test_ = test_list.front();
- current_test_->prepare_for_run();
- Log::info("Running test: '%s' %susing vertex buffer objects\n",
- current_test_->name().c_str(),
- (Options::use_vbo) ? "" : "NOT ");
- reshape(width_, height_);
-
benchmark_init();
bool next_iteration(false);
- while (true) {
- if (handle_xevent()) {
- if (current_test_) {
+
+ for (std::list<Benchmark *>::iterator benchIt = benchmarks.begin();
+ benchIt != benchmarks.end();
+ next_benchmark(benchmarks, benchIt))
+ {
+ Benchmark *benchmark = *benchIt;
+ current_test_ = &benchmark->setup_test();
+ reshape(width_, height_);
+ Log::info("Running test: '%s' %susing vertex buffer objects\n",
+ current_test_->name().c_str(),
+ (Options::use_vbo) ? "" : "NOT ");
+
+ while (true) {
+ if (handle_xevent()) {
if (Options::force_tex_update)
update_all_textures();
@@ -606,20 +593,13 @@
benchmark_update(next_iteration);
if (next_iteration) {
- current_test_->cleanup();
- bool back_to_beginning(false);
- next_test(test_list, back_to_beginning);
- if (!Options::run_forever && back_to_beginning) {
- break;
- }
- Log::info("Running test: '%s' %susing vertex buffer objects\n",
- current_test_->name().c_str(),
- (Options::use_vbo) ? "" : "NOT ");
- current_test_->prepare_for_run();
- current_test_->reshape(width_, height_);
+ break;
}
+
}
}
+
+ benchmark->teardown_test();
}
}
=== modified file 'src/composite-canvas.h'
@@ -34,6 +34,7 @@
#include "composite-window.h"
#include "composite-test.h"
+#include "benchmark.h"
#include "profiler.h"
class CompositeCanvas
@@ -49,7 +50,7 @@
{}
bool init();
- void run_tests(std::list<CompositeTest*> &test_list);
+ void run_tests(std::list<Benchmark*> &benchmarks);
protected:
virtual XVisualInfo *get_canvas_xvisualinfo() = 0;
@@ -82,7 +83,6 @@
void benchmark_init();
void benchmark_update(bool& iteration_complete);
void update_all_textures();
- void next_test(const std::list<CompositeTest*>& test_list, bool& back_to_beginning);
void sample_point(int i);
unsigned int iterations_;
unsigned int width_;
=== modified file 'src/composite-test.h'
@@ -60,6 +60,12 @@
void reset_options();
const std::map<std::string, Option> &options() { return options_; }
+ static CompositeTest &dummy()
+ {
+ static CompositeTest dummy_test("");
+ return dummy_test;
+ }
+
protected:
CompositeTest();
//
=== modified file 'src/gl-composite-benchmark'
@@ -113,6 +113,6 @@
start_xterms $NWINDOWS
-$GLCOMPBENCH_EXEC --benchmark --ids $wids $GLCOMPBENCH_OPTS
+$GLCOMPBENCH_EXEC --ids $wids $GLCOMPBENCH_OPTS
stop_xterms
=== modified file 'src/glcompbench.cc'
@@ -30,7 +30,63 @@
#endif
#include "composite-test.h"
+#include "benchmark.h"
#include "options.h"
+#include "log.h"
+
+static const char *default_benchmarks[] = {
+ "default",
+ "brick",
+ NULL
+};
+
+static void
+list_tests()
+{
+ const map<string, CompositeTest *> &tests = Benchmark::tests();
+
+ for (map<string, CompositeTest *>::const_iterator test_iter = tests.begin();
+ test_iter != tests.end();
+ test_iter++)
+ {
+ CompositeTest *test = test_iter->second;
+ Log::info("[Test] %s\n", test->name().c_str());
+
+ const map<string, CompositeTest::Option> &options = test->options();
+
+ for (map<string, CompositeTest::Option>::const_iterator opt_iter = options.begin();
+ opt_iter != options.end();
+ opt_iter++)
+ {
+ const CompositeTest::Option &opt = opt_iter->second;
+ Log::info(" [Option] %s\n"
+ " Description : %s\n"
+ " Default Value: %s\n",
+ opt.name.c_str(),
+ opt.description.c_str(),
+ opt.default_value.c_str());
+ }
+ }
+}
+
+static void
+add_default_benchmarks(std::list<Benchmark*> &benchmarks)
+{
+ for (const char **s = default_benchmarks; *s != NULL; s++)
+ benchmarks.push_back(new Benchmark(*s));
+}
+
+static void
+add_custom_benchmarks(std::list<Benchmark *> &benchmarks)
+{
+ for (std::list<string>::const_iterator iter = Options::benchmarks.begin();
+ iter != Options::benchmarks.end();
+ iter++)
+ {
+ Log::info("Adding benchmark %s\n", iter->c_str());
+ benchmarks.push_back(new Benchmark(*iter));
+ }
+}
int
main(int argc, char **argv)
@@ -41,7 +97,7 @@
CompositeCanvasGLX canvas;
#endif
- std::list<CompositeTest*> tests;
+ std::list<Benchmark*> benchmarks;
if (!Options::parse_args(argc, argv))
return 1;
@@ -51,11 +107,22 @@
return 0;
}
- tests.push_back(new CompositeTestDefault());
- tests.push_back(new CompositeTestBrick());
+ Benchmark::register_test(*new CompositeTestDefault());
+ Benchmark::register_test(*new CompositeTestBrick());
+
+ if (Options::list_tests) {
+ list_tests();
+ return 0;
+ }
+
+ // Add the benchmarks to run
+ if (Options::benchmarks.empty())
+ add_default_benchmarks(benchmarks);
+ else
+ add_custom_benchmarks(benchmarks);
canvas.init();
- canvas.run_tests(tests);
+ canvas.run_tests(benchmarks);
return 0;
}
=== modified file 'src/options.cc'
@@ -34,7 +34,7 @@
std::list<Window> Options::window_ids;
bool Options::run_forever = false;
bool Options::use_accel_tfp = true;
-bool Options::benchmark = false;
+std::list<std::string> Options::benchmarks;
bool Options::draw = true;
bool Options::idle_redraw = false;
bool Options::force_tex_update = false;
@@ -42,19 +42,21 @@
bool Options::show_debug = false;
bool Options::show_help = false;
bool Options::use_vbo = true;
+bool Options::list_tests = false;
static struct option long_options[] = {
{"ids", 1, 0, 0},
{"size", 1, 0, 0},
{"no-accel-tfp", 0, 0, 0},
{"no-vbo", 0, 0, 0},
- {"benchmark", 0, 0, 0},
+ {"benchmark", 1, 0, 0},
{"no-draw", 0, 0, 0},
{"idle-redraw", 0, 0, 0},
{"force-tex-update", 0, 0, 0},
{"manual-redirect", 0, 0, 0},
{"run-forever", 0, 0, 0},
{"num-iters", 1, 0, 0},
+ {"list-tests", 0, 0, 0},
{"debug", 0, 0, 0},
{"help", 0, 0, 0},
{0, 0, 0, 0}
@@ -86,7 +88,8 @@
" [default: 512]\n"
" --no-accel-tfp Don't use accelerated TFP (use glTexImage2D)\n"
" --no-vbo Don't use vertex buffer objects for drawing (use client vertex arrays)\n"
- " --benchmark Display benchmarking statistics\n"
+ " --benchmark BENCH A benchmark to run: 'test(:opt1=val1)*'\n"
+ " (the option can be used multiple times)\n"
" --no-draw Process the windows but don't draw anything on screen\n"
" --idle-redraw Redraw when idle, even when nothing has changed\n"
" --force-tex-update Force texture updates even when they are unchanged\n"
@@ -94,6 +97,7 @@
" --run-forever Run indefinitely, looping from the last test back to the first\n"
" --num-iters <NUM> The number of iterations run for each test\n"
" [default: 5]\n"
+ " --list-tests List the avalaible tests and their options\n"
" --debug Display debug messages\n"
" --help Display help\n");
}
@@ -125,7 +129,7 @@
else if (!strcmp(optname, "no-vbo"))
Options::use_vbo = false;
else if (!strcmp(optname, "benchmark"))
- Options::benchmark = true;
+ Options::benchmarks.push_back(optarg);
else if (!strcmp(optname, "no-draw"))
Options::draw = false;
else if (!strcmp(optname, "idle-redraw"))
@@ -136,6 +140,8 @@
Options::run_forever = true;
else if (!strcmp(optname, "num-iters"))
Options::num_iterations = strtol(optarg, NULL, 10);
+ else if (!strcmp(optname, "list-tests"))
+ Options::list_tests = true;
else if (!strcmp(optname, "manual-redirect"))
Options::manual_redirect = true;
else if (!strcmp(optname, "debug"))
=== modified file 'src/options.h'
@@ -26,6 +26,7 @@
#include <X11/Xlib.h>
#include <list>
+#include <string>
struct Options {
static bool parse_args(int argc, char **argv);
@@ -36,7 +37,7 @@
static unsigned int num_iterations;
static bool run_forever;
static bool use_accel_tfp;
- static bool benchmark;
+ static std::list<std::string> benchmarks;
static bool draw;
static bool idle_redraw;
static bool force_tex_update;
@@ -44,6 +45,7 @@
static bool show_debug;
static bool show_help;
static bool use_vbo;
+ static bool list_tests;
};
#endif /* OPTIONS_H_ */