| Index: gpu/tools/compositor_model_bench/compositor_model_bench.cc
|
| ===================================================================
|
| --- gpu/tools/compositor_model_bench/compositor_model_bench.cc (revision 98709)
|
| +++ gpu/tools/compositor_model_bench/compositor_model_bench.cc (working copy)
|
| @@ -1,406 +0,0 @@
|
| -// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -// This tool is used to benchmark the render model used by the compositor
|
| -
|
| -// Most of this file is derived from the source of the tile_render_bench tool,
|
| -// and has been changed to support running a sequence of independent
|
| -// simulations for our different render models and test cases.
|
| -
|
| -#include <stdio.h>
|
| -#include <sys/dir.h>
|
| -#include <sys/file.h>
|
| -#include <sys/stat.h>
|
| -#include <sys/types.h>
|
| -#include <X11/keysym.h>
|
| -#include <X11/Xlib.h>
|
| -#include <X11/Xutil.h>
|
| -
|
| -#include <queue>
|
| -#include <string>
|
| -#include <vector>
|
| -
|
| -#include "base/at_exit.h"
|
| -#include "base/basictypes.h"
|
| -#include "base/command_line.h"
|
| -#include "base/file_path.h"
|
| -#include "base/file_util.h"
|
| -#include "base/memory/scoped_ptr.h"
|
| -#include "base/message_loop.h"
|
| -#include "base/task.h"
|
| -#include "base/time.h"
|
| -
|
| -#include "gpu/tools/compositor_model_bench/render_model_utils.h"
|
| -#include "gpu/tools/compositor_model_bench/render_models.h"
|
| -#include "gpu/tools/compositor_model_bench/render_tree.h"
|
| -
|
| -
|
| -using base::TimeTicks;
|
| -using file_util::CloseFile;
|
| -using file_util::DirectoryExists;
|
| -using file_util::FileEnumerator;
|
| -using file_util::OpenFile;
|
| -using file_util::PathExists;
|
| -using std::queue;
|
| -using std::string;
|
| -
|
| -struct SimulationSpecification {
|
| - string simulation_name;
|
| - FilePath input_path;
|
| - RenderModel model_under_test;
|
| - TimeTicks simulation_start_time;
|
| - int frames_rendered;
|
| -};
|
| -
|
| -// Forward declarations
|
| -class Simulator;
|
| -void _process_events(Simulator* sim);
|
| -void _update_loop(Simulator* sim);
|
| -
|
| -class Simulator {
|
| - public:
|
| - Simulator(int seconds_per_test, const FilePath& output_path)
|
| - : running_(false),
|
| - current_sim_(NULL),
|
| - output_path_(output_path),
|
| - seconds_per_test_(seconds_per_test),
|
| - ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
|
| - display_(NULL),
|
| - window_(0),
|
| - gl_context_(NULL),
|
| - window_width_(WINDOW_WIDTH),
|
| - window_height_(WINDOW_HEIGHT) {
|
| - }
|
| -
|
| - ~Simulator() {
|
| - // Cleanup GL.
|
| - glXMakeCurrent(display_, 0, NULL);
|
| - glXDestroyContext(display_, gl_context_);
|
| -
|
| - // Destroy window and display.
|
| - XDestroyWindow(display_, window_);
|
| - XCloseDisplay(display_);
|
| - }
|
| -
|
| - void QueueTest(const FilePath& path) {
|
| - SimulationSpecification spec;
|
| -
|
| - // To get a std::string, we'll try to get an ASCII simulation name.
|
| - // If the name of the file wasn't ASCII, this will give an empty simulation
|
| - // name, but that's not really harmful (we'll still warn about it though.)
|
| - spec.simulation_name = path.BaseName().RemoveExtension().MaybeAsASCII();
|
| - if (spec.simulation_name == "") {
|
| - LOG(WARNING) << "Simulation for path " << path.LossyDisplayName() <<
|
| - " will have a blank simulation name, since the file name isn't ASCII";
|
| - }
|
| - spec.input_path = path;
|
| - spec.model_under_test = ForwardRenderModel;
|
| - spec.frames_rendered = 0;
|
| -
|
| - sims_remaining_.push(spec);
|
| -
|
| - // The following lines are commented out pending the addition
|
| - // of the new render model once this version gets fully checked in.
|
| - //
|
| - // spec.model_under_test = KDTreeRenderModel;
|
| - // sims_remaining_.push(spec);
|
| - }
|
| -
|
| - void Run() {
|
| - if (!sims_remaining_.size()) {
|
| - LOG(WARNING) << "No configuration files loaded.";
|
| - return;
|
| - }
|
| -
|
| - base::AtExitManager at_exit;
|
| - MessageLoop loop;
|
| - if (!InitX11() || !InitGLContext()) {
|
| - LOG(FATAL) << "Failed to set up GUI.";
|
| - }
|
| -
|
| - InitBuffers();
|
| -
|
| - LOG(INFO) << "Running " << sims_remaining_.size() << " simulations.";
|
| -
|
| - loop.PostTask(FROM_HERE,
|
| - method_factory_.NewRunnableMethod(&Simulator::ProcessEvents));
|
| - loop.Run();
|
| - }
|
| -
|
| - void ProcessEvents() {
|
| - // Consume all the X events.
|
| - while (XPending(display_)) {
|
| - XEvent e;
|
| - XNextEvent(display_, &e);
|
| - switch (e.type) {
|
| - case Expose:
|
| - UpdateLoop();
|
| - break;
|
| - case ConfigureNotify:
|
| - Resize(e.xconfigure.width, e.xconfigure.height);
|
| - break;
|
| - default:
|
| - break;
|
| - }
|
| - }
|
| - }
|
| -
|
| - void UpdateLoop() {
|
| - if (UpdateTestStatus())
|
| - UpdateCurrentTest();
|
| - }
|
| -
|
| - private:
|
| - // Initialize X11. Returns true if successful. This method creates the
|
| - // X11 window. Further initialization is done in X11VideoRenderer.
|
| - bool InitX11() {
|
| - display_ = XOpenDisplay(NULL);
|
| - if (!display_) {
|
| - LOG(FATAL) << "Cannot open display";
|
| - return false;
|
| - }
|
| -
|
| - // Get properties of the screen.
|
| - int screen = DefaultScreen(display_);
|
| - int root_window = RootWindow(display_, screen);
|
| -
|
| - // Creates the window.
|
| - window_ = XCreateSimpleWindow(display_,
|
| - root_window,
|
| - 1,
|
| - 1,
|
| - window_width_,
|
| - window_height_,
|
| - 0,
|
| - BlackPixel(display_, screen),
|
| - BlackPixel(display_, screen));
|
| - XStoreName(display_, window_, "Compositor Model Bench");
|
| -
|
| - XSelectInput(display_, window_,
|
| - ExposureMask | KeyPressMask | StructureNotifyMask);
|
| - XMapWindow(display_, window_);
|
| -
|
| - XResizeWindow(display_, window_, WINDOW_WIDTH, WINDOW_HEIGHT);
|
| -
|
| - return true;
|
| - }
|
| -
|
| - // Initialize the OpenGL context.
|
| - bool InitGLContext() {
|
| - if (!InitializeGLBindings(gfx::kGLImplementationDesktopGL)) {
|
| - LOG(FATAL) << "InitializeGLBindings failed";
|
| - return false;
|
| - }
|
| -
|
| - XWindowAttributes attributes;
|
| - XGetWindowAttributes(display_, window_, &attributes);
|
| - XVisualInfo visual_info_template;
|
| - visual_info_template.visualid = XVisualIDFromVisual(attributes.visual);
|
| - int visual_info_count = 0;
|
| - XVisualInfo* visual_info_list = XGetVisualInfo(display_, VisualIDMask,
|
| - &visual_info_template,
|
| - &visual_info_count);
|
| -
|
| - for (int i = 0; i < visual_info_count && !gl_context_; ++i) {
|
| - gl_context_ = glXCreateContext(display_, visual_info_list + i, 0,
|
| - True /* Direct rendering */);
|
| - }
|
| -
|
| - XFree(visual_info_list);
|
| - if (!gl_context_) {
|
| - return false;
|
| - }
|
| -
|
| - if (!glXMakeCurrent(display_, window_, gl_context_)) {
|
| - glXDestroyContext(display_, gl_context_);
|
| - gl_context_ = NULL;
|
| - return false;
|
| - }
|
| -
|
| - return true;
|
| - }
|
| -
|
| - bool InitializeNextTest() {
|
| - SimulationSpecification& spec = sims_remaining_.front();
|
| - LOG(INFO) << "Initializing test for " << spec.simulation_name <<
|
| - "(" << ModelToString(spec.model_under_test) << ")";
|
| - const FilePath& path = spec.input_path;
|
| -
|
| - RenderNode* root = NULL;
|
| - if (!(root = BuildRenderTreeFromFile(path))) {
|
| - LOG(ERROR) << "Couldn't parse test configuration file " <<
|
| - path.LossyDisplayName();
|
| - return false;
|
| - }
|
| -
|
| - current_sim_ = ConstructSimulationModel(spec.model_under_test,
|
| - root,
|
| - window_width_,
|
| - window_height_);
|
| - if (!current_sim_)
|
| - return false;
|
| -
|
| - return true;
|
| - }
|
| -
|
| - void CleanupCurrentTest() {
|
| - LOG(INFO) << "Finished test " << sims_remaining_.front().simulation_name;
|
| -
|
| - delete current_sim_;
|
| - current_sim_ = NULL;
|
| - }
|
| -
|
| - void UpdateCurrentTest() {
|
| - ++sims_remaining_.front().frames_rendered;
|
| -
|
| - if (current_sim_)
|
| - current_sim_->Update();
|
| -
|
| - glXSwapBuffers(display_, window_);
|
| -
|
| - XExposeEvent ev = { Expose, 0, 1, display_, window_,
|
| - 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0 };
|
| - XSendEvent(display_,
|
| - window_,
|
| - False,
|
| - ExposureMask,
|
| - reinterpret_cast<XEvent*>(&ev));
|
| -
|
| - MessageLoop::current()->PostTask(
|
| - FROM_HERE,
|
| - method_factory_.NewRunnableMethod(&Simulator::UpdateLoop));
|
| - }
|
| -
|
| - void DumpOutput() {
|
| - LOG(INFO) << "Successfully ran " << sims_completed_.size() << " tests";
|
| -
|
| - FILE* f = OpenFile(output_path_, "w");
|
| -
|
| - if (!f) {
|
| - LOG(ERROR) << "Failed to open output file " <<
|
| - output_path_.LossyDisplayName();
|
| - exit(-1);
|
| - }
|
| -
|
| - LOG(INFO) << "Writing results to " << output_path_.LossyDisplayName();
|
| -
|
| - fputs("{\n\t\"results\": [\n", f);
|
| -
|
| - while (sims_completed_.size()) {
|
| - SimulationSpecification i = sims_completed_.front();
|
| - fprintf(f,
|
| - "\t\t{\"simulation_name\":\"%s\",\n"
|
| - "\t\t\t\"render_model\":\"%s\",\n"
|
| - "\t\t\t\"frames_drawn\":%d\n"
|
| - "\t\t},\n",
|
| - i.simulation_name.c_str(),
|
| - ModelToString(i.model_under_test),
|
| - i.frames_rendered);
|
| - sims_completed_.pop();
|
| - }
|
| -
|
| - fputs("\t]\n}", f);
|
| - CloseFile(f);
|
| - }
|
| -
|
| - bool UpdateTestStatus() {
|
| - TimeTicks& current_start = sims_remaining_.front().simulation_start_time;
|
| - base::TimeDelta d = TimeTicks::Now() - current_start;
|
| - if (!current_start.is_null() && d.InSeconds() > seconds_per_test_) {
|
| - CleanupCurrentTest();
|
| - sims_completed_.push(sims_remaining_.front());
|
| - sims_remaining_.pop();
|
| - }
|
| -
|
| - if (sims_remaining_.size() &&
|
| - sims_remaining_.front().simulation_start_time.is_null()) {
|
| - while (sims_remaining_.size() && !InitializeNextTest()) {
|
| - sims_remaining_.pop();
|
| - }
|
| - if (sims_remaining_.size()) {
|
| - sims_remaining_.front().simulation_start_time = TimeTicks::Now();
|
| - }
|
| - }
|
| -
|
| - if (!sims_remaining_.size()) {
|
| - DumpOutput();
|
| - MessageLoop::current()->Quit();
|
| - return false;
|
| - }
|
| -
|
| - return true;
|
| - }
|
| -
|
| - void Resize(int width, int height) {
|
| - window_width_ = width;
|
| - window_height_ = height;
|
| - if (current_sim_)
|
| - current_sim_->Resize(window_width_, window_height_);
|
| - }
|
| -
|
| - // Simulation task list for this execution
|
| - bool running_;
|
| - RenderModelSimulator* current_sim_;
|
| - queue<SimulationSpecification> sims_remaining_;
|
| - queue<SimulationSpecification> sims_completed_;
|
| - FilePath output_path_;
|
| - // Amount of time to run each simulation
|
| - int seconds_per_test_;
|
| - // GUI data
|
| - ScopedRunnableMethodFactory<Simulator> method_factory_;
|
| - Display* display_;
|
| - Window window_;
|
| - GLXContext gl_context_;
|
| - int window_width_;
|
| - int window_height_;
|
| -};
|
| -
|
| -int main(int argc, char* argv[]) {
|
| - CommandLine::Init(argc, argv);
|
| - const CommandLine* cl = CommandLine::ForCurrentProcess();
|
| -
|
| - if (argc != 3 && argc != 4) {
|
| - LOG(INFO) << "Usage: \n" <<
|
| - cl->GetProgram().BaseName().LossyDisplayName() <<
|
| - "--in=[input path] --out=[output path] (duration=[seconds])\n"
|
| - "The input path specifies either a JSON configuration file or\n"
|
| - "a directory containing only these files\n"
|
| - "(if a directory is specified, simulations will be run for\n"
|
| - "all files in that directory and subdirectories)\n"
|
| - "The optional duration parameter specifies the (integer)\n"
|
| - "number of seconds to be spent on each simulation.\n"
|
| - "Performance measurements for the specified simulation(s) are\n"
|
| - "written to the output path.";
|
| - return -1;
|
| - }
|
| -
|
| - int seconds_per_test = 1;
|
| - if (cl->HasSwitch("duration")) {
|
| - seconds_per_test = atoi(cl->GetSwitchValueASCII("duration").c_str());
|
| - }
|
| -
|
| - Simulator sim(seconds_per_test, cl->GetSwitchValuePath("out"));
|
| - FilePath inPath = cl->GetSwitchValuePath("in");
|
| -
|
| - if (!PathExists(inPath)) {
|
| - LOG(FATAL) << "Path does not exist: " << inPath.LossyDisplayName();
|
| - return -1;
|
| - }
|
| -
|
| - if (DirectoryExists(inPath)) {
|
| - LOG(INFO) << "(input path is a directory)";
|
| - FileEnumerator dirItr(inPath, true, FileEnumerator::FILES);
|
| - for (FilePath f = dirItr.Next(); !f.empty(); f = dirItr.Next()) {
|
| - sim.QueueTest(f);
|
| - }
|
| - } else {
|
| - LOG(INFO) << "(input path is a file)";
|
| - sim.QueueTest(inPath);
|
| - }
|
| -
|
| - sim.Run();
|
| -
|
| - return 0;
|
| -}
|
| -
|
|
|