1 // Copyright 2013 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 #include "cc/debug/micro_benchmark_controller.h" 6 7 #include <limits> 8 #include <string> 9 10 #include "base/callback.h" 11 #include "base/message_loop/message_loop_proxy.h" 12 #include "base/values.h" 13 #include "cc/debug/invalidation_benchmark.h" 14 #include "cc/debug/picture_record_benchmark.h" 15 #include "cc/debug/rasterize_and_record_benchmark.h" 16 #include "cc/debug/unittest_only_benchmark.h" 17 #include "cc/trees/layer_tree_host.h" 18 #include "cc/trees/layer_tree_host_impl.h" 19 20 namespace cc { 21 22 int MicroBenchmarkController::next_id_ = 1; 23 24 namespace { 25 26 scoped_ptr<MicroBenchmark> CreateBenchmark( 27 const std::string& name, 28 scoped_ptr<base::Value> value, 29 const MicroBenchmark::DoneCallback& callback) { 30 if (name == "invalidation_benchmark") { 31 return scoped_ptr<MicroBenchmark>( 32 new InvalidationBenchmark(value.Pass(), callback)); 33 } else if (name == "picture_record_benchmark") { 34 return scoped_ptr<MicroBenchmark>( 35 new PictureRecordBenchmark(value.Pass(), callback)); 36 } else if (name == "rasterize_and_record_benchmark") { 37 return scoped_ptr<MicroBenchmark>( 38 new RasterizeAndRecordBenchmark(value.Pass(), callback)); 39 } else if (name == "unittest_only_benchmark") { 40 return scoped_ptr<MicroBenchmark>( 41 new UnittestOnlyBenchmark(value.Pass(), callback)); 42 } 43 return scoped_ptr<MicroBenchmark>(); 44 } 45 46 class IsDonePredicate { 47 public: 48 typedef const MicroBenchmark* argument_type; 49 typedef bool result_type; 50 51 result_type operator()(argument_type benchmark) const { 52 return benchmark->IsDone(); 53 } 54 }; 55 56 } // namespace 57 58 MicroBenchmarkController::MicroBenchmarkController(LayerTreeHost* host) 59 : host_(host), 60 main_controller_message_loop_(base::MessageLoopProxy::current().get()) { 61 DCHECK(host_); 62 } 63 64 MicroBenchmarkController::~MicroBenchmarkController() {} 65 66 int MicroBenchmarkController::ScheduleRun( 67 const std::string& micro_benchmark_name, 68 scoped_ptr<base::Value> value, 69 const MicroBenchmark::DoneCallback& callback) { 70 scoped_ptr<MicroBenchmark> benchmark = 71 CreateBenchmark(micro_benchmark_name, value.Pass(), callback); 72 if (benchmark.get()) { 73 int id = GetNextIdAndIncrement(); 74 benchmark->set_id(id); 75 benchmarks_.push_back(benchmark.Pass()); 76 host_->SetNeedsCommit(); 77 return id; 78 } 79 return 0; 80 } 81 82 int MicroBenchmarkController::GetNextIdAndIncrement() { 83 int id = next_id_++; 84 // Wrap around to 1 if we overflow (very unlikely). 85 if (next_id_ == std::numeric_limits<int>::max()) 86 next_id_ = 1; 87 return id; 88 } 89 90 bool MicroBenchmarkController::SendMessage(int id, 91 scoped_ptr<base::Value> value) { 92 for (ScopedPtrVector<MicroBenchmark>::iterator it = benchmarks_.begin(); 93 it != benchmarks_.end(); 94 ++it) { 95 if ((*it)->id() == id) 96 return (*it)->ProcessMessage(value.Pass()); 97 } 98 return false; 99 } 100 101 void MicroBenchmarkController::ScheduleImplBenchmarks( 102 LayerTreeHostImpl* host_impl) { 103 for (ScopedPtrVector<MicroBenchmark>::iterator it = benchmarks_.begin(); 104 it != benchmarks_.end(); 105 ++it) { 106 scoped_ptr<MicroBenchmarkImpl> benchmark_impl; 107 if (!(*it)->ProcessedForBenchmarkImpl()) { 108 benchmark_impl = 109 (*it)->GetBenchmarkImpl(main_controller_message_loop_); 110 } 111 112 if (benchmark_impl.get()) 113 host_impl->ScheduleMicroBenchmark(benchmark_impl.Pass()); 114 } 115 } 116 117 void MicroBenchmarkController::DidUpdateLayers() { 118 for (ScopedPtrVector<MicroBenchmark>::iterator it = benchmarks_.begin(); 119 it != benchmarks_.end(); 120 ++it) { 121 if (!(*it)->IsDone()) 122 (*it)->DidUpdateLayers(host_); 123 } 124 125 CleanUpFinishedBenchmarks(); 126 } 127 128 void MicroBenchmarkController::CleanUpFinishedBenchmarks() { 129 benchmarks_.erase( 130 benchmarks_.partition(std::not1(IsDonePredicate())), 131 benchmarks_.end()); 132 } 133 134 } // namespace cc 135