Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(393)

Side by Side Diff: gpu/tools/compositor_model_bench/compositor_model_bench.cc

Issue 7792002: Initial checkin of the compositor_model_bench tool (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: more clang fixes Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « build/all.gyp ('k') | gpu/tools/compositor_model_bench/forward_render_model.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // This tool is used to benchmark the render model used by the compositor
6
7 // Most of this file is derived from the source of the tile_render_bench tool,
8 // and has been changed to support running a sequence of independent
9 // simulations for our different render models and test cases.
10
11 #include <stdio.h>
12 #include <sys/dir.h>
13 #include <sys/file.h>
14 #include <sys/stat.h>
15 #include <sys/types.h>
16 #include <X11/keysym.h>
17 #include <X11/Xlib.h>
18 #include <X11/Xutil.h>
19
20 #include <queue>
21 #include <string>
22 #include <vector>
23
24 #include "base/at_exit.h"
25 #include "base/basictypes.h"
26 #include "base/command_line.h"
27 #include "base/file_path.h"
28 #include "base/file_util.h"
29 #include "base/memory/scoped_ptr.h"
30 #include "base/message_loop.h"
31 #include "base/task.h"
32 #include "base/time.h"
33
34 #include "gpu/tools/compositor_model_bench/render_model_utils.h"
35 #include "gpu/tools/compositor_model_bench/render_models.h"
36 #include "gpu/tools/compositor_model_bench/render_tree.h"
37
38
39 using base::TimeTicks;
40 using file_util::CloseFile;
41 using file_util::DirectoryExists;
42 using file_util::FileEnumerator;
43 using file_util::OpenFile;
44 using file_util::PathExists;
45 using std::queue;
46 using std::string;
47
48 struct SimulationSpecification {
49 string simulation_name;
50 FilePath input_path;
51 RenderModel model_under_test;
52 TimeTicks simulation_start_time;
53 int frames_rendered;
54 };
55
56 // Forward declarations
57 class Simulator;
58 void _process_events(Simulator* sim);
59 void _update_loop(Simulator* sim);
60
61 class Simulator {
62 public:
63 Simulator(int seconds_per_test, const FilePath& output_path)
64 : running_(false),
65 current_sim_(NULL),
66 output_path_(output_path),
67 seconds_per_test_(seconds_per_test),
68 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
69 display_(NULL),
70 window_(0),
71 gl_context_(NULL),
72 window_width_(WINDOW_WIDTH),
73 window_height_(WINDOW_HEIGHT) {
74 }
75
76 ~Simulator() {
77 // Cleanup GL.
78 glXMakeCurrent(display_, 0, NULL);
79 glXDestroyContext(display_, gl_context_);
80
81 // Destroy window and display.
82 XDestroyWindow(display_, window_);
83 XCloseDisplay(display_);
84 }
85
86 void QueueTest(const FilePath& path) {
87 SimulationSpecification spec;
88
89 // To get a std::string, we'll try to get an ASCII simulation name.
90 // If the name of the file wasn't ASCII, this will give an empty simulation
91 // name, but that's not really harmful (we'll still warn about it though.)
92 spec.simulation_name = path.BaseName().RemoveExtension().MaybeAsASCII();
93 if (spec.simulation_name == "") {
94 LOG(WARNING) << "Simulation for path " << path.LossyDisplayName() <<
95 " will have a blank simulation name, since the file name isn't ASCII";
96 }
97 spec.input_path = path;
98 spec.model_under_test = ForwardRenderModel;
99 spec.frames_rendered = 0;
100
101 sims_remaining_.push(spec);
102
103 // The following lines are commented out pending the addition
104 // of the new render model once this version gets fully checked in.
105 //
106 // spec.model_under_test = KDTreeRenderModel;
107 // sims_remaining_.push(spec);
108 }
109
110 void Run() {
111 if (!sims_remaining_.size()) {
112 LOG(WARNING) << "No configuration files loaded.";
113 return;
114 }
115
116 base::AtExitManager at_exit;
117 MessageLoop loop;
118 if (!InitX11() || !InitGLContext()) {
119 LOG(FATAL) << "Failed to set up GUI.";
120 }
121
122 InitBuffers();
123
124 LOG(INFO) << "Running " << sims_remaining_.size() << " simulations.";
125
126 loop.PostTask(FROM_HERE,
127 method_factory_.NewRunnableMethod(&Simulator::ProcessEvents));
128 loop.Run();
129 }
130
131 void ProcessEvents() {
132 // Consume all the X events.
133 while (XPending(display_)) {
134 XEvent e;
135 XNextEvent(display_, &e);
136 switch (e.type) {
137 case Expose:
138 UpdateLoop();
139 break;
140 case ConfigureNotify:
141 Resize(e.xconfigure.width, e.xconfigure.height);
142 break;
143 default:
144 break;
145 }
146 }
147 }
148
149 void UpdateLoop() {
150 if (UpdateTestStatus())
151 UpdateCurrentTest();
152 }
153
154 private:
155 // Initialize X11. Returns true if successful. This method creates the
156 // X11 window. Further initialization is done in X11VideoRenderer.
157 bool InitX11() {
158 display_ = XOpenDisplay(NULL);
159 if (!display_) {
160 LOG(FATAL) << "Cannot open display";
161 return false;
162 }
163
164 // Get properties of the screen.
165 int screen = DefaultScreen(display_);
166 int root_window = RootWindow(display_, screen);
167
168 // Creates the window.
169 window_ = XCreateSimpleWindow(display_,
170 root_window,
171 1,
172 1,
173 window_width_,
174 window_height_,
175 0,
176 BlackPixel(display_, screen),
177 BlackPixel(display_, screen));
178 XStoreName(display_, window_, "Compositor Model Bench");
179
180 XSelectInput(display_, window_,
181 ExposureMask | KeyPressMask | StructureNotifyMask);
182 XMapWindow(display_, window_);
183
184 XResizeWindow(display_, window_, WINDOW_WIDTH, WINDOW_HEIGHT);
185
186 return true;
187 }
188
189 // Initialize the OpenGL context.
190 bool InitGLContext() {
191 if (!InitializeGLBindings(gfx::kGLImplementationDesktopGL)) {
192 LOG(FATAL) << "InitializeGLBindings failed";
193 return false;
194 }
195
196 XWindowAttributes attributes;
197 XGetWindowAttributes(display_, window_, &attributes);
198 XVisualInfo visual_info_template;
199 visual_info_template.visualid = XVisualIDFromVisual(attributes.visual);
200 int visual_info_count = 0;
201 XVisualInfo* visual_info_list = XGetVisualInfo(display_, VisualIDMask,
202 &visual_info_template,
203 &visual_info_count);
204
205 for (int i = 0; i < visual_info_count && !gl_context_; ++i) {
206 gl_context_ = glXCreateContext(display_, visual_info_list + i, 0,
207 True /* Direct rendering */);
208 }
209
210 XFree(visual_info_list);
211 if (!gl_context_) {
212 return false;
213 }
214
215 if (!glXMakeCurrent(display_, window_, gl_context_)) {
216 glXDestroyContext(display_, gl_context_);
217 gl_context_ = NULL;
218 return false;
219 }
220
221 return true;
222 }
223
224 bool InitializeNextTest() {
225 SimulationSpecification& spec = sims_remaining_.front();
226 LOG(INFO) << "Initializing test for " << spec.simulation_name <<
227 "(" << ModelToString(spec.model_under_test) << ")";
228 const FilePath& path = spec.input_path;
229
230 RenderNode* root = NULL;
231 if (!(root = BuildRenderTreeFromFile(path))) {
232 LOG(ERROR) << "Couldn't parse test configuration file " <<
233 path.LossyDisplayName();
234 return false;
235 }
236
237 current_sim_ = ConstructSimulationModel(spec.model_under_test,
238 root,
239 window_width_,
240 window_height_);
241 if (!current_sim_)
242 return false;
243
244 return true;
245 }
246
247 void CleanupCurrentTest() {
248 LOG(INFO) << "Finished test " << sims_remaining_.front().simulation_name;
249
250 delete current_sim_;
251 current_sim_ = NULL;
252 }
253
254 void UpdateCurrentTest() {
255 ++sims_remaining_.front().frames_rendered;
256
257 if (current_sim_)
258 current_sim_->Update();
259
260 glXSwapBuffers(display_, window_);
261
262 XExposeEvent ev = { Expose, 0, 1, display_, window_,
263 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0 };
264 XSendEvent(display_,
265 window_,
266 False,
267 ExposureMask,
268 reinterpret_cast<XEvent*>(&ev));
269
270 MessageLoop::current()->PostTask(
271 FROM_HERE,
272 method_factory_.NewRunnableMethod(&Simulator::UpdateLoop));
273 }
274
275 void DumpOutput() {
276 LOG(INFO) << "Successfully ran " << sims_completed_.size() << " tests";
277
278 FILE* f = OpenFile(output_path_, "w");
279
280 if (!f) {
281 LOG(ERROR) << "Failed to open output file " <<
282 output_path_.LossyDisplayName();
283 exit(-1);
284 }
285
286 LOG(INFO) << "Writing results to " << output_path_.LossyDisplayName();
287
288 fputs("{\n\t\"results\": [\n", f);
289
290 while (sims_completed_.size()) {
291 SimulationSpecification i = sims_completed_.front();
292 fprintf(f,
293 "\t\t{\"simulation_name\":\"%s\",\n"
294 "\t\t\t\"render_model\":\"%s\",\n"
295 "\t\t\t\"frames_drawn\":%d\n"
296 "\t\t},\n",
297 i.simulation_name.c_str(),
298 ModelToString(i.model_under_test),
299 i.frames_rendered);
300 sims_completed_.pop();
301 }
302
303 fputs("\t]\n}", f);
304 CloseFile(f);
305 }
306
307 bool UpdateTestStatus() {
308 TimeTicks& current_start = sims_remaining_.front().simulation_start_time;
309 base::TimeDelta d = TimeTicks::Now() - current_start;
310 if (!current_start.is_null() && d.InSeconds() > seconds_per_test_) {
311 CleanupCurrentTest();
312 sims_completed_.push(sims_remaining_.front());
313 sims_remaining_.pop();
314 }
315
316 if (sims_remaining_.size() &&
317 sims_remaining_.front().simulation_start_time.is_null()) {
318 while (sims_remaining_.size() && !InitializeNextTest()) {
319 sims_remaining_.pop();
320 }
321 if (sims_remaining_.size()) {
322 sims_remaining_.front().simulation_start_time = TimeTicks::Now();
323 }
324 }
325
326 if (!sims_remaining_.size()) {
327 DumpOutput();
328 MessageLoop::current()->Quit();
329 return false;
330 }
331
332 return true;
333 }
334
335 void Resize(int width, int height) {
336 window_width_ = width;
337 window_height_ = height;
338 if (current_sim_)
339 current_sim_->Resize(window_width_, window_height_);
340 }
341
342 // Simulation task list for this execution
343 bool running_;
344 RenderModelSimulator* current_sim_;
345 queue<SimulationSpecification> sims_remaining_;
346 queue<SimulationSpecification> sims_completed_;
347 FilePath output_path_;
348 // Amount of time to run each simulation
349 int seconds_per_test_;
350 // GUI data
351 ScopedRunnableMethodFactory<Simulator> method_factory_;
352 Display* display_;
353 Window window_;
354 GLXContext gl_context_;
355 int window_width_;
356 int window_height_;
357 };
358
359 int main(int argc, char* argv[]) {
360 CommandLine::Init(argc, argv);
361 const CommandLine* cl = CommandLine::ForCurrentProcess();
362
363 if (argc != 3 && argc != 4) {
364 LOG(INFO) << "Usage: \n" <<
365 cl->GetProgram().BaseName().LossyDisplayName() <<
366 "--in=[input path] --out=[output path] (duration=[seconds])\n"
367 "The input path specifies either a JSON configuration file or\n"
368 "a directory containing only these files\n"
369 "(if a directory is specified, simulations will be run for\n"
370 "all files in that directory and subdirectories)\n"
371 "The optional duration parameter specifies the (integer)\n"
372 "number of seconds to be spent on each simulation.\n"
373 "Performance measurements for the specified simulation(s) are\n"
374 "written to the output path.";
375 return -1;
376 }
377
378 int seconds_per_test = 1;
379 if (cl->HasSwitch("duration")) {
380 seconds_per_test = atoi(cl->GetSwitchValueASCII("duration").c_str());
381 }
382
383 Simulator sim(seconds_per_test, cl->GetSwitchValuePath("out"));
384 FilePath inPath = cl->GetSwitchValuePath("in");
385
386 if (!PathExists(inPath)) {
387 LOG(FATAL) << "Path does not exist: " << inPath.LossyDisplayName();
388 return -1;
389 }
390
391 if (DirectoryExists(inPath)) {
392 LOG(INFO) << "(input path is a directory)";
393 FileEnumerator dirItr(inPath, true, FileEnumerator::FILES);
394 for (FilePath f = dirItr.Next(); !f.empty(); f = dirItr.Next()) {
395 sim.QueueTest(f);
396 }
397 } else {
398 LOG(INFO) << "(input path is a file)";
399 sim.QueueTest(inPath);
400 }
401
402 sim.Run();
403
404 return 0;
405 }
406
OLDNEW
« no previous file with comments | « build/all.gyp ('k') | gpu/tools/compositor_model_bench/forward_render_model.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698