Home | History | Annotate | Download | only in debug
      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