From patchwork Tue Feb 14 11:28:09 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: alexandros.frantzis@linaro.org X-Patchwork-Id: 6773 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 95F2D23EB0 for ; Tue, 14 Feb 2012 11:36:38 +0000 (UTC) Received: from mail-iy0-f180.google.com (mail-iy0-f180.google.com [209.85.210.180]) by fiordland.canonical.com (Postfix) with ESMTP id 27673A1885B for ; Tue, 14 Feb 2012 11:36:38 +0000 (UTC) Received: by iabz7 with SMTP id z7so7541941iab.11 for ; Tue, 14 Feb 2012 03:36:37 -0800 (PST) Received: by 10.50.85.231 with SMTP id k7mr3031667igz.25.1329219397593; Tue, 14 Feb 2012 03:36:37 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.66.135 with SMTP id n7cs86965ibi; Tue, 14 Feb 2012 03:36:36 -0800 (PST) Received: by 10.216.133.85 with SMTP id p63mr701220wei.52.1329219395753; Tue, 14 Feb 2012 03:36:35 -0800 (PST) Received: from indium.canonical.com (indium.canonical.com. [91.189.90.7]) by mx.google.com with ESMTPS id bz6si11001119wib.44.2012.02.14.03.36.35 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 14 Feb 2012 03:36:35 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) client-ip=91.189.90.7; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) smtp.mail=bounces@canonical.com Received: from ackee.canonical.com ([91.189.89.26]) by indium.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1RxGgU-0006Jd-4O for ; Tue, 14 Feb 2012 11:36:34 +0000 Received: from ackee.canonical.com (localhost [127.0.0.1]) by ackee.canonical.com (Postfix) with ESMTP id C8102E16EE for ; Tue, 14 Feb 2012 11:28:09 +0000 (UTC) MIME-Version: 1.0 X-Launchpad-Project: glmark2 X-Launchpad-Branch: ~glmark2-dev/glmark2/trunk X-Launchpad-Message-Rationale: Subscriber X-Launchpad-Branch-Revision-Number: 197 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~glmark2-dev/glmark2/trunk] Rev 197: Consolidation of X11 and Android main loops. Message-Id: <20120214112809.11285.41842.launchpad@ackee.canonical.com> Date: Tue, 14 Feb 2012 11:28:09 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="14781"; Instance="launchpad-lazr.conf" X-Launchpad-Hash: 5c01749d96b0c8731de8c562fccb3faf4c020e56 X-Gm-Message-State: ALoCoQmXhDDBUk9jyFEn2egHuCilfifPsnskODVKgFANriEo98vuQSO1rk1NAK1gr0EswQEsGRnd Merge authors: Alexandros Frantzis (afrantzis) Related merge proposals: https://code.launchpad.net/~linaro-graphics-wg/glmark2/main-loop-consolidation/+merge/92734 proposed by: Alexandros Frantzis (afrantzis) review: Approve - Jesse Barker (jesse-barker) ------------------------------------------------------------ revno: 197 [merge] committer: Alexandros Frantzis branch nick: trunk timestamp: Tue 2012-02-14 13:22:43 +0200 message: Consolidation of X11 and Android main loops. added: src/main-loop.cpp src/main-loop.h modified: src/android.cpp src/main.cpp src/scene.cpp src/scene.h --- lp:glmark2 https://code.launchpad.net/~glmark2-dev/glmark2/trunk You are subscribed to branch lp:glmark2. To unsubscribe from this branch go to https://code.launchpad.net/~glmark2-dev/glmark2/trunk/+edit-subscription === modified file 'src/android.cpp' --- src/android.cpp 2012-02-13 09:53:57 +0000 +++ src/android.cpp 2012-02-13 10:45:41 +0000 @@ -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 g_benchmarks; +static MainLoop *g_loop; + +class MainLoopAndroid : public MainLoop +{ +public: + MainLoopAndroid(Canvas &canvas, const std::vector &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 &benchmarks) @@ -53,6 +70,7 @@ { static_cast(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(env); + delete g_loop; delete g_canvas; } @@ -103,50 +123,10 @@ Java_org_linaro_glmark2_Glmark2Renderer_nativeRender(JNIEnv* env) { static_cast(env); - static std::vector::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' --- src/main-loop.cpp 1970-01-01 00:00:00 +0000 +++ src/main-loop.cpp 2012-02-13 10:44:42 +0000 @@ -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 . + * + * Authors: + * Alexandros Frantzis + */ +#include "options.h" +#include "main-loop.h" +#include "util.h" +#include "log.h" + +#include +#include + +/************ + * MainLoop * + ************/ + +MainLoop::MainLoop(Canvas &canvas, const std::vector &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 &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 &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' --- src/main-loop.h 1970-01-01 00:00:00 +0000 +++ src/main-loop.h 2012-02-13 10:44:42 +0000 @@ -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 . + * + * Authors: + * Alexandros Frantzis + */ +#ifndef GLMARK2_MAIN_LOOP_H_ +#define GLMARK2_MAIN_LOOP_H_ + +#include "canvas.h" +#include "benchmark.h" +#include "text-renderer.h" +#include + +/** + * Main loop for benchmarking. + */ +class MainLoop +{ +public: + MainLoop(Canvas &canvas, const std::vector &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 &benchmarks_; + unsigned int score_; + unsigned int benchmarks_run_; + + std::vector::const_iterator bench_iter_; +}; + +/** + * Main loop for benchmarking with decorations (eg FPS, demo) + */ +class MainLoopDecoration : public MainLoop +{ +public: + MainLoopDecoration(Canvas &canvas, const std::vector &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 &benchmarks); + + virtual void draw(); + virtual void before_scene_teardown(); +}; + +#endif /* GLMARK2_MAIN_LOOP_H_ */ === modified file 'src/main.cpp' --- src/main.cpp 2012-01-27 22:01:59 +0000 +++ src/main.cpp 2012-02-13 10:45:33 +0000 @@ -30,6 +30,7 @@ #include "util.h" #include "default-benchmarks.h" #include "text-renderer.h" +#include "main-loop.h" #include #include @@ -174,115 +175,24 @@ void do_benchmark(Canvas &canvas, vector &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::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 &benchmarks) { - static const string format(Log::continuation_prefix + " Validation: %s\n"); - for (vector::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' --- src/scene.cpp 2011-12-08 13:19:41 +0000 +++ src/scene.cpp 2012-02-09 01:28:16 +0000 @@ -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' --- src/scene.h 2011-12-08 13:19:41 +0000 +++ src/scene.h 2012-02-09 01:28:16 +0000 @@ -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.