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; |
-} |
- |