aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Burchell <robin+git@viroteck.net>2015-06-30 14:53:29 +0200
committerGunnar Sletta <gunnar.sletta@jollamobile.com>2015-06-30 14:53:29 +0200
commit9c8ae91b383bc90d4573d0e31eb8f3d4afbabb2c (patch)
tree005d2faba70e3de37c6d0d05dc1dea6f72a99c90
parentaef98ff0fe30c8e0c38deb858df70f0c0d58f935 (diff)
Add the capability to dump JSON of a run. (via --json)
Report benchmark info about runs in a map, as well as generic information about the environment the benchmark was running in. Also adds a --id command line option to uniquely identify the run.
-rw-r--r--main.cpp137
1 files changed, 129 insertions, 8 deletions
diff --git a/main.cpp b/main.cpp
index 2d1753d..a361120 100644
--- a/main.cpp
+++ b/main.cpp
@@ -6,6 +6,107 @@
#include "qcommandlineparser.h"
+static bool onlyPrintJson = false;
+
+class ResultRecorder
+{
+ static QVariantMap m_results;
+
+public:
+ static void startResults(const QString &id)
+ {
+ m_results["id"] = id;
+
+ QVariantMap osMap;
+ osMap["prettyProductName"] = QSysInfo::prettyProductName();
+ osMap["platformPlugin"] = QGuiApplication::platformName();
+ m_results["os"] = osMap;
+
+ // The following code makes the assumption that an OpenGL context the GUI
+ // thread will get the same capabilities as the render thread's OpenGL
+ // context. Not 100% accurate, but it works...
+ QOpenGLContext context;
+ context.create();
+ QOffscreenSurface surface;
+ // In very odd cases, we can get incompatible configs here unless we pass the
+ // GL context's format on to the offscreen format.
+ surface.setFormat(context.format());
+ surface.create();
+ if (!context.makeCurrent(&surface)) {
+ qWarning() << "failed to acquire GL context to get version info.";
+ return;
+ }
+
+ QOpenGLFunctions *func = context.functions();
+#if QT_VERSION >= 0x050300
+ const char *vendor = (const char *) func->glGetString(GL_VENDOR);
+ const char *renderer = (const char *) func->glGetString(GL_RENDERER);
+ const char *version = (const char *) func->glGetString(GL_VERSION);
+#else
+ Q_UNUSED(func);
+ const char *vendor = (const char *) glGetString(GL_VENDOR);
+ const char *renderer = (const char *) glGetString(GL_RENDERER);
+ const char *version = (const char *) glGetString(GL_VERSION);
+#endif
+
+ if (!onlyPrintJson) {
+ std::cout << "ID: " << id.toStdString() << std::endl;
+ std::cout << "OS: " << QSysInfo::prettyProductName().toStdString() << std::endl;
+ std::cout << "QPA: " << QGuiApplication::platformName().toStdString() << std::endl;
+ std::cout << "GL_VENDOR: " << vendor << std::endl;
+ std::cout << "GL_RENDERER: " << renderer << std::endl;
+ std::cout << "GL_VERSION: " << version << std::endl;
+ }
+
+ QVariantMap glInfo;
+ glInfo["vendor"] = vendor;
+ glInfo["renderer"] = renderer;
+ glInfo["version"] = version;
+
+ m_results["opengl"] = glInfo;
+
+ context.doneCurrent();
+ }
+
+ static void recordWindowSize(const QSize &windowSize)
+ {
+ m_results["windowSize"] = QString::number(windowSize.width()) + "x" + QString::number(windowSize.height());
+ }
+
+ static void recordOperationsPerFrame(const QString &benchmark, int ops)
+ {
+ QVariantMap benchMap = m_results[benchmark].toMap();
+ QVariantList benchResults = benchMap["results"].toList();
+ benchResults.append(ops);
+
+ benchMap["results"] = benchResults;
+ m_results[benchmark] = benchMap;
+
+ if (!onlyPrintJson)
+ std::cout << " " << ops << " ops/frame" << std::endl;
+ }
+
+ static void recordOperationsPerFrameAverage(const QString &benchmark, int ops)
+ {
+ QVariantMap benchMap = m_results[benchmark].toMap();
+ benchMap["average"] = ops;
+ m_results[benchmark] = benchMap;
+
+ if (!onlyPrintJson)
+ std::cout << " " << ops << " ops/frame average" << std::endl;
+ }
+
+ static void finish()
+ {
+ if (onlyPrintJson) {
+ QJsonDocument results = QJsonDocument::fromVariant(m_results);
+ std::cout << results.toJson().toStdString();
+ }
+ m_results.clear();
+ }
+};
+QVariantMap ResultRecorder::m_results;
+
class FpsDecider : public QWindow
{
public:
@@ -202,7 +303,6 @@ int main(int argc, char **argv)
qmlRegisterType<QQuickView>();
QGuiApplication app(argc, argv);
- std::cout << "Running against " << QT_VERSION_STR << std::endl;
QCommandLineParser parser;
@@ -213,6 +313,16 @@ int main(int argc, char **argv)
QStringLiteral("Verbose mode"));
parser.addOption(verboseOption);
+ QCommandLineOption idOption(QStringLiteral("id"),
+ QStringLiteral("Provides a unique identifier for this run in the JSON output."),
+ QStringLiteral("identifier"),
+ QStringLiteral(""));
+ parser.addOption(idOption);
+
+ QCommandLineOption jsonOption(QStringLiteral("json"),
+ QStringLiteral("Switches to provide JSON output of benchmark runs."));
+ parser.addOption(jsonOption);
+
QCommandLineOption repeatOption(QStringLiteral("repeat"),
QStringLiteral("Sets the number of times to repeat the benchmark, to get more stable results"),
QStringLiteral("iterations"),
@@ -275,6 +385,10 @@ int main(int argc, char **argv)
parser.process(app);
+ if (parser.isSet(jsonOption)) {
+ onlyPrintJson = true;
+ }
+
if (parser.isSet(decideFpsOption)) {
FpsDecider fpsDecider;
if (parser.isSet(fullscreenOption))
@@ -305,6 +419,9 @@ int main(int argc, char **argv)
if (size.isValid())
runner.options.windowSize = size;
+ ResultRecorder::startResults(parser.value(idOption));
+ ResultRecorder::recordWindowSize(runner.options.windowSize);
+
if (parser.isSet(fpsOverrideOption))
runner.options.fpsOverride = parser.value(fpsOverrideOption).toFloat();
@@ -345,7 +462,9 @@ int main(int argc, char **argv)
if (!runner.execute())
return 0;
- return app.exec();
+ int ret = app.exec();
+ ResultRecorder::finish();
+ return ret;
}
BenchmarkRunner::BenchmarkRunner()
@@ -392,7 +511,7 @@ void BenchmarkRunner::start()
{
Benchmark &bm = benchmarks[m_currentBenchmark];
- if (bm.operationsPerFrame.size() == 0)
+ if (bm.operationsPerFrame.size() == 0 && !onlyPrintJson)
std::cout << "running: " << bm.fileName.toStdString() << std::endl;
m_component = new QQmlComponent(m_view->engine(), bm.fileName);
@@ -419,7 +538,8 @@ void BenchmarkRunner::maybeStartNext()
if (m_currentBenchmark < benchmarks.size()) {
QMetaObject::invokeMethod(this, "start", Qt::QueuedConnection);
} else {
- std::cout << "All done..." << std::endl;
+ if (!onlyPrintJson)
+ std::cout << "All done..." << std::endl;
qApp->quit();
}
}
@@ -431,7 +551,7 @@ void BenchmarkRunner::abort()
void BenchmarkRunner::abortAll()
{
- std::cout << "Aborting all benchmarks..." << std::endl;
+ qWarning() << "Aborting all benchmarks...";
qApp->quit();
}
@@ -440,11 +560,12 @@ void BenchmarkRunner::recordOperationsPerFrame(qreal ops)
Benchmark &bm = benchmarks[m_currentBenchmark];
bm.completed = true;
bm.operationsPerFrame << ops;
- std::cout << " " << ops << " ops/frame" << std::endl;
+ ResultRecorder::recordOperationsPerFrame(bm.fileName, ops);
if (bm.operationsPerFrame.size() == options.repeat && options.repeat > 1) {
qreal avg = 0;
- foreach (qreal r, bm.operationsPerFrame) avg += r;
- std::cout << " " << (avg / options.repeat) << " ops/frame average" << std::endl;
+ foreach (qreal r, bm.operationsPerFrame)
+ avg += r;
+ ResultRecorder::recordOperationsPerFrameAverage(bm.fileName, avg / options.repeat);
}
complete();
}