14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file. 44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "cc/debug/micro_benchmark_controller.h" 64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <limits> 84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <string> 94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/callback.h" 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/values.h" 1346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "cc/debug/invalidation_benchmark.h" 144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "cc/debug/picture_record_benchmark.h" 15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "cc/debug/rasterize_and_record_benchmark.h" 164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "cc/debug/unittest_only_benchmark.h" 174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "cc/trees/layer_tree_host.h" 18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "cc/trees/layer_tree_host_impl.h" 194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace cc { 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int MicroBenchmarkController::next_id_ = 1; 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace { 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)scoped_ptr<MicroBenchmark> CreateBenchmark( 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& name, 288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) scoped_ptr<base::Value> value, 294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const MicroBenchmark::DoneCallback& callback) { 3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (name == "invalidation_benchmark") { 3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return scoped_ptr<MicroBenchmark>( 3246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) new InvalidationBenchmark(value.Pass(), callback)); 3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } else if (name == "picture_record_benchmark") { 348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return scoped_ptr<MicroBenchmark>( 358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) new PictureRecordBenchmark(value.Pass(), callback)); 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else if (name == "rasterize_and_record_benchmark") { 37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return scoped_ptr<MicroBenchmark>( 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new RasterizeAndRecordBenchmark(value.Pass(), callback)); 398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } else if (name == "unittest_only_benchmark") { 408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return scoped_ptr<MicroBenchmark>( 418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) new UnittestOnlyBenchmark(value.Pass(), callback)); 428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return scoped_ptr<MicroBenchmark>(); 444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class IsDonePredicate { 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public: 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) typedef const MicroBenchmark* argument_type; 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) typedef bool result_type; 504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) result_type operator()(argument_type benchmark) const { 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return benchmark->IsDone(); 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace 574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)MicroBenchmarkController::MicroBenchmarkController(LayerTreeHost* host) 59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : host_(host), 60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) main_controller_message_loop_(base::MessageLoopProxy::current().get()) { 614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(host_); 624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)MicroBenchmarkController::~MicroBenchmarkController() {} 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int MicroBenchmarkController::ScheduleRun( 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& micro_benchmark_name, 688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) scoped_ptr<base::Value> value, 694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const MicroBenchmark::DoneCallback& callback) { 704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<MicroBenchmark> benchmark = 718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) CreateBenchmark(micro_benchmark_name, value.Pass(), callback); 724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (benchmark.get()) { 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int id = GetNextIdAndIncrement(); 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) benchmark->set_id(id); 754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) benchmarks_.push_back(benchmark.Pass()); 764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) host_->SetNeedsCommit(); 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return id; 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return 0; 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int MicroBenchmarkController::GetNextIdAndIncrement() { 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int id = next_id_++; 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Wrap around to 1 if we overflow (very unlikely). 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (next_id_ == std::numeric_limits<int>::max()) 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) next_id_ = 1; 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return id; 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool MicroBenchmarkController::SendMessage(int id, 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<base::Value> value) { 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (ScopedPtrVector<MicroBenchmark>::iterator it = benchmarks_.begin(); 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) it != benchmarks_.end(); 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ++it) { 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if ((*it)->id() == id) 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return (*it)->ProcessMessage(value.Pass()); 974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void MicroBenchmarkController::ScheduleImplBenchmarks( 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) LayerTreeHostImpl* host_impl) { 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (ScopedPtrVector<MicroBenchmark>::iterator it = benchmarks_.begin(); 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) it != benchmarks_.end(); 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ++it) { 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<MicroBenchmarkImpl> benchmark_impl; 107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!(*it)->ProcessedForBenchmarkImpl()) { 108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) benchmark_impl = 109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (*it)->GetBenchmarkImpl(main_controller_message_loop_); 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (benchmark_impl.get()) 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) host_impl->ScheduleMicroBenchmark(benchmark_impl.Pass()); 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void MicroBenchmarkController::DidUpdateLayers() { 1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (ScopedPtrVector<MicroBenchmark>::iterator it = benchmarks_.begin(); 1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) it != benchmarks_.end(); 1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ++it) { 121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!(*it)->IsDone()) 122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (*it)->DidUpdateLayers(host_); 1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CleanUpFinishedBenchmarks(); 1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void MicroBenchmarkController::CleanUpFinishedBenchmarks() { 1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) benchmarks_.erase( 1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) benchmarks_.partition(std::not1(IsDonePredicate())), 1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) benchmarks_.end()); 1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace cc 135