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/picture_record_benchmark.h"
      6 
      7 #include <algorithm>
      8 
      9 #include "base/basictypes.h"
     10 #include "base/values.h"
     11 #include "cc/layers/layer.h"
     12 #include "cc/layers/picture_layer.h"
     13 #include "cc/trees/layer_tree_host.h"
     14 #include "cc/trees/layer_tree_host_common.h"
     15 #include "ui/gfx/rect.h"
     16 
     17 namespace cc {
     18 
     19 namespace {
     20 
     21 const int kPositionIncrement = 100;
     22 const int kTileGridSize = 512;
     23 const int kTileGridBorder = 1;
     24 
     25 }  // namespace
     26 
     27 PictureRecordBenchmark::PictureRecordBenchmark(
     28     scoped_ptr<base::Value> value,
     29     const MicroBenchmark::DoneCallback& callback)
     30     : MicroBenchmark(callback) {
     31   if (!value)
     32     return;
     33 
     34   base::ListValue* list = NULL;
     35   value->GetAsList(&list);
     36   if (!list)
     37     return;
     38 
     39   for (base::ListValue::iterator it = list->begin(); it != list->end(); ++it) {
     40     base::DictionaryValue* dictionary = NULL;
     41     (*it)->GetAsDictionary(&dictionary);
     42     if (!dictionary ||
     43         !dictionary->HasKey("width") ||
     44         !dictionary->HasKey("height"))
     45       continue;
     46 
     47     int width, height;
     48     dictionary->GetInteger("width", &width);
     49     dictionary->GetInteger("height", &height);
     50 
     51     dimensions_.push_back(std::make_pair(width, height));
     52   }
     53 }
     54 
     55 PictureRecordBenchmark::~PictureRecordBenchmark() {}
     56 
     57 void PictureRecordBenchmark::DidUpdateLayers(LayerTreeHost* host) {
     58   LayerTreeHostCommon::CallFunctionForSubtree(
     59       host->root_layer(),
     60       base::Bind(&PictureRecordBenchmark::Run, base::Unretained(this)));
     61 
     62   scoped_ptr<base::ListValue> results(new base::ListValue());
     63   for (std::map<std::pair<int, int>, TotalTime>::iterator it = times_.begin();
     64        it != times_.end();
     65        ++it) {
     66     std::pair<int, int> dimensions = it->first;
     67     base::TimeDelta total_time = it->second.first;
     68     unsigned total_count = it->second.second;
     69 
     70     double average_time = 0.0;
     71     if (total_count > 0)
     72       average_time = total_time.InMillisecondsF() / total_count;
     73 
     74     scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue());
     75     result->SetInteger("width", dimensions.first);
     76     result->SetInteger("height", dimensions.second);
     77     result->SetInteger("samples_count", total_count);
     78     result->SetDouble("time_ms", average_time);
     79 
     80     results->Append(result.release());
     81   }
     82 
     83   NotifyDone(results.PassAs<base::Value>());
     84 }
     85 
     86 void PictureRecordBenchmark::Run(Layer* layer) {
     87   layer->RunMicroBenchmark(this);
     88 }
     89 
     90 void PictureRecordBenchmark::RunOnLayer(PictureLayer* layer) {
     91   ContentLayerClient* painter = layer->client();
     92   gfx::Size content_bounds = layer->content_bounds();
     93 
     94   SkTileGridFactory::TileGridInfo tile_grid_info;
     95   tile_grid_info.fTileInterval.set(kTileGridSize - 2 * kTileGridBorder,
     96                                    kTileGridSize - 2 * kTileGridBorder);
     97   tile_grid_info.fMargin.set(kTileGridBorder, kTileGridBorder);
     98   tile_grid_info.fOffset.set(-kTileGridBorder, -kTileGridBorder);
     99 
    100   for (size_t i = 0; i < dimensions_.size(); ++i) {
    101     std::pair<int, int> dimensions = dimensions_[i];
    102     int width = dimensions.first;
    103     int height = dimensions.second;
    104 
    105     int y_limit = std::max(1, content_bounds.height() - height);
    106     int x_limit = std::max(1, content_bounds.width() - width);
    107     for (int y = 0; y < y_limit; y += kPositionIncrement) {
    108       for (int x = 0; x < x_limit; x += kPositionIncrement) {
    109         gfx::Rect rect = gfx::Rect(x, y, width, height);
    110 
    111         base::TimeTicks start = base::TimeTicks::HighResNow();
    112 
    113         scoped_refptr<Picture> picture = Picture::Create(
    114             rect, painter, tile_grid_info, false, Picture::RECORD_NORMALLY);
    115 
    116         base::TimeTicks end = base::TimeTicks::HighResNow();
    117         base::TimeDelta duration = end - start;
    118         TotalTime& total_time = times_[dimensions];
    119         total_time.first += duration;
    120         total_time.second++;
    121       }
    122     }
    123   }
    124 }
    125 
    126 }  // namespace cc
    127