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/rasterize_and_record_benchmark.h"
      6 
      7 #include <algorithm>
      8 #include <limits>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/values.h"
     12 #include "cc/debug/rasterize_and_record_benchmark_impl.h"
     13 #include "cc/layers/layer.h"
     14 #include "cc/layers/picture_layer.h"
     15 #include "cc/trees/layer_tree_host.h"
     16 #include "cc/trees/layer_tree_host_common.h"
     17 #include "ui/gfx/rect.h"
     18 
     19 namespace cc {
     20 
     21 namespace {
     22 
     23 const int kDefaultRecordRepeatCount = 100;
     24 
     25 base::TimeTicks Now() {
     26   return base::TimeTicks::IsThreadNowSupported()
     27              ? base::TimeTicks::ThreadNow()
     28              : base::TimeTicks::HighResNow();
     29 }
     30 
     31 }  // namespace
     32 
     33 RasterizeAndRecordBenchmark::RasterizeAndRecordBenchmark(
     34     scoped_ptr<base::Value> value,
     35     const MicroBenchmark::DoneCallback& callback)
     36     : MicroBenchmark(callback),
     37       record_repeat_count_(kDefaultRecordRepeatCount),
     38       settings_(value.Pass()),
     39       main_thread_benchmark_done_(false),
     40       host_(NULL),
     41       weak_ptr_factory_(this) {
     42   base::DictionaryValue* settings = NULL;
     43   settings_->GetAsDictionary(&settings);
     44   if (!settings)
     45     return;
     46 
     47   if (settings->HasKey("record_repeat_count"))
     48     settings->GetInteger("record_repeat_count", &record_repeat_count_);
     49 }
     50 
     51 RasterizeAndRecordBenchmark::~RasterizeAndRecordBenchmark() {
     52   weak_ptr_factory_.InvalidateWeakPtrs();
     53 }
     54 
     55 void RasterizeAndRecordBenchmark::DidUpdateLayers(LayerTreeHost* host) {
     56   host_ = host;
     57   LayerTreeHostCommon::CallFunctionForSubtree(
     58       host->root_layer(),
     59       base::Bind(&RasterizeAndRecordBenchmark::Run, base::Unretained(this)));
     60 
     61   DCHECK(!results_.get());
     62   results_ = make_scoped_ptr(new base::DictionaryValue);
     63   results_->SetInteger("pixels_recorded", record_results_.pixels_recorded);
     64   results_->SetDouble("record_time_ms",
     65                       record_results_.total_best_time.InMillisecondsF());
     66   main_thread_benchmark_done_ = true;
     67 }
     68 
     69 void RasterizeAndRecordBenchmark::RecordRasterResults(
     70     scoped_ptr<base::Value> results_value) {
     71   DCHECK(main_thread_benchmark_done_);
     72 
     73   base::DictionaryValue* results = NULL;
     74   results_value->GetAsDictionary(&results);
     75 
     76   DCHECK(results);
     77   DCHECK(results->HasKey("pixels_rasterized"));
     78   DCHECK(results->HasKey("rasterize_time_ms"));
     79 
     80   int pixels_rasterized;
     81   results->GetInteger("pixels_rasterized", &pixels_rasterized);
     82   double rasterize_time_ms;
     83   results->GetDouble("rasterize_time_ms", &rasterize_time_ms);
     84 
     85   results_->SetInteger("pixels_rasterized", pixels_rasterized);
     86   results_->SetDouble("rasterize_time_ms", rasterize_time_ms);
     87 
     88   NotifyDone(results_.PassAs<base::Value>());
     89 }
     90 
     91 scoped_ptr<MicroBenchmarkImpl> RasterizeAndRecordBenchmark::CreateBenchmarkImpl(
     92     scoped_refptr<base::MessageLoopProxy> origin_loop) {
     93   return scoped_ptr<MicroBenchmarkImpl>(new RasterizeAndRecordBenchmarkImpl(
     94       origin_loop,
     95       settings_.get(),
     96       base::Bind(&RasterizeAndRecordBenchmark::RecordRasterResults,
     97                  weak_ptr_factory_.GetWeakPtr())));
     98 }
     99 
    100 void RasterizeAndRecordBenchmark::Run(Layer* layer) {
    101   layer->RunMicroBenchmark(this);
    102 }
    103 
    104 void RasterizeAndRecordBenchmark::RunOnLayer(PictureLayer* layer) {
    105   ContentLayerClient* painter = layer->client();
    106   gfx::Size content_bounds = layer->content_bounds();
    107 
    108   DCHECK(host_);
    109   gfx::Size tile_grid_size = host_->settings().default_tile_size;
    110 
    111   SkTileGridPicture::TileGridInfo tile_grid_info;
    112   PicturePileBase::ComputeTileGridInfo(tile_grid_size, &tile_grid_info);
    113 
    114   gfx::Rect visible_content_rect = gfx::ScaleToEnclosingRect(
    115       layer->visible_content_rect(), 1.f / layer->contents_scale_x());
    116   if (visible_content_rect.IsEmpty())
    117     return;
    118 
    119   scoped_refptr<Picture> picture = Picture::Create(visible_content_rect);
    120 
    121   base::TimeDelta min_time =
    122       base::TimeDelta::FromInternalValue(std::numeric_limits<int64>::max());
    123   for (int i = 0; i < record_repeat_count_; ++i) {
    124     base::TimeTicks start = Now();
    125     picture->Record(painter, tile_grid_info);
    126     base::TimeTicks end = Now();
    127     base::TimeDelta duration = end - start;
    128     if (duration < min_time)
    129       min_time = duration;
    130   }
    131 
    132   record_results_.pixels_recorded +=
    133       visible_content_rect.width() * visible_content_rect.height();
    134   record_results_.total_best_time += min_time;
    135 }
    136 
    137 RasterizeAndRecordBenchmark::RecordResults::RecordResults()
    138     : pixels_recorded(0) {}
    139 
    140 RasterizeAndRecordBenchmark::RecordResults::~RecordResults() {}
    141 
    142 }  // namespace cc
    143