diff options
author | vmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-18 20:32:08 +0000 |
---|---|---|
committer | vmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-18 20:32:08 +0000 |
commit | 8cac9fe3496911e1e4dacd94cb2073b59cfa86d4 (patch) | |
tree | df5f7a59c054fe7cc7316c2aff4a17a1a4ee64a3 /cc | |
parent | 7b06b28ab5e49cc32075a9a28db6d91c381967a9 (diff) | |
download | chromium_src-8cac9fe3496911e1e4dacd94cb2073b59cfa86d4.zip chromium_src-8cac9fe3496911e1e4dacd94cb2073b59cfa86d4.tar.gz chromium_src-8cac9fe3496911e1e4dacd94cb2073b59cfa86d4.tar.bz2 |
cc: Add rasterize and record micro benchmark.
This patch adds a rasterize and record micro benchmark.
It depends on
https://codereview.chromium.org/67563002/
R=enne@chromium.org, nduca@chromium.org, ernstm@chromium.org
Review URL: https://codereview.chromium.org/66213007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@235805 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/cc.gyp | 4 | ||||
-rw-r--r-- | cc/debug/micro_benchmark_controller.cc | 4 | ||||
-rw-r--r-- | cc/debug/rasterize_and_record_benchmark.cc | 142 | ||||
-rw-r--r-- | cc/debug/rasterize_and_record_benchmark.h | 66 | ||||
-rw-r--r-- | cc/debug/rasterize_and_record_benchmark_impl.cc | 117 | ||||
-rw-r--r-- | cc/debug/rasterize_and_record_benchmark_impl.h | 49 | ||||
-rw-r--r-- | cc/resources/picture_pile_base.cc | 25 | ||||
-rw-r--r-- | cc/resources/picture_pile_base.h | 3 |
8 files changed, 400 insertions, 10 deletions
@@ -94,6 +94,10 @@ 'debug/paint_time_counter.h', 'debug/picture_record_benchmark.cc', 'debug/picture_record_benchmark.h', + 'debug/rasterize_and_record_benchmark.cc', + 'debug/rasterize_and_record_benchmark.h', + 'debug/rasterize_and_record_benchmark_impl.cc', + 'debug/rasterize_and_record_benchmark_impl.h', 'debug/rendering_stats.cc', 'debug/rendering_stats.h', 'debug/rendering_stats_instrumentation.cc', diff --git a/cc/debug/micro_benchmark_controller.cc b/cc/debug/micro_benchmark_controller.cc index 52e91ae..7d9025c 100644 --- a/cc/debug/micro_benchmark_controller.cc +++ b/cc/debug/micro_benchmark_controller.cc @@ -10,6 +10,7 @@ #include "base/message_loop/message_loop_proxy.h" #include "base/values.h" #include "cc/debug/picture_record_benchmark.h" +#include "cc/debug/rasterize_and_record_benchmark.h" #include "cc/debug/unittest_only_benchmark.h" #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_host_impl.h" @@ -25,6 +26,9 @@ scoped_ptr<MicroBenchmark> CreateBenchmark( if (name == "picture_record_benchmark") { return scoped_ptr<MicroBenchmark>( new PictureRecordBenchmark(value.Pass(), callback)); + } else if (name == "rasterize_and_record_benchmark") { + return scoped_ptr<MicroBenchmark>( + new RasterizeAndRecordBenchmark(value.Pass(), callback)); } else if (name == "unittest_only_benchmark") { return scoped_ptr<MicroBenchmark>( new UnittestOnlyBenchmark(value.Pass(), callback)); diff --git a/cc/debug/rasterize_and_record_benchmark.cc b/cc/debug/rasterize_and_record_benchmark.cc new file mode 100644 index 0000000..4646afd --- /dev/null +++ b/cc/debug/rasterize_and_record_benchmark.cc @@ -0,0 +1,142 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/debug/rasterize_and_record_benchmark.h" + +#include <algorithm> +#include <limits> + +#include "base/basictypes.h" +#include "base/values.h" +#include "cc/debug/rasterize_and_record_benchmark_impl.h" +#include "cc/layers/layer.h" +#include "cc/layers/picture_layer.h" +#include "cc/trees/layer_tree_host.h" +#include "cc/trees/layer_tree_host_common.h" +#include "ui/gfx/rect.h" + +namespace cc { + +namespace { + +const int kDefaultRecordRepeatCount = 100; + +base::TimeTicks Now() { + return base::TimeTicks::IsThreadNowSupported() + ? base::TimeTicks::ThreadNow() + : base::TimeTicks::HighResNow(); +} + +} // namespace + +RasterizeAndRecordBenchmark::RasterizeAndRecordBenchmark( + scoped_ptr<base::Value> value, + const MicroBenchmark::DoneCallback& callback) + : MicroBenchmark(callback), + record_repeat_count_(kDefaultRecordRepeatCount), + settings_(value.Pass()), + main_thread_benchmark_done_(false), + host_(NULL), + weak_ptr_factory_(this) { + base::DictionaryValue* settings = NULL; + settings_->GetAsDictionary(&settings); + if (!settings) + return; + + if (settings->HasKey("record_repeat_count")) + settings->GetInteger("record_repeat_count", &record_repeat_count_); +} + +RasterizeAndRecordBenchmark::~RasterizeAndRecordBenchmark() { + weak_ptr_factory_.InvalidateWeakPtrs(); +} + +void RasterizeAndRecordBenchmark::DidUpdateLayers(LayerTreeHost* host) { + host_ = host; + LayerTreeHostCommon::CallFunctionForSubtree( + host->root_layer(), + base::Bind(&RasterizeAndRecordBenchmark::Run, base::Unretained(this))); + + DCHECK(!results_.get()); + results_ = make_scoped_ptr(new base::DictionaryValue); + results_->SetInteger("pixels_recorded", record_results_.pixels_recorded); + results_->SetDouble("record_time_ms", + record_results_.total_best_time.InMillisecondsF()); + main_thread_benchmark_done_ = true; +} + +void RasterizeAndRecordBenchmark::RecordRasterResults( + scoped_ptr<base::Value> results_value) { + DCHECK(main_thread_benchmark_done_); + + base::DictionaryValue* results = NULL; + results_value->GetAsDictionary(&results); + + DCHECK(results); + DCHECK(results->HasKey("pixels_rasterized")); + DCHECK(results->HasKey("rasterize_time_ms")); + + int pixels_rasterized; + results->GetInteger("pixels_rasterized", &pixels_rasterized); + double rasterize_time_ms; + results->GetDouble("rasterize_time_ms", &rasterize_time_ms); + + results_->SetInteger("pixels_rasterized", pixels_rasterized); + results_->SetDouble("rasterize_time_ms", rasterize_time_ms); + + NotifyDone(results_.PassAs<base::Value>()); +} + +scoped_ptr<MicroBenchmarkImpl> RasterizeAndRecordBenchmark::CreateBenchmarkImpl( + scoped_refptr<base::MessageLoopProxy> origin_loop) { + return scoped_ptr<MicroBenchmarkImpl>(new RasterizeAndRecordBenchmarkImpl( + origin_loop, + settings_.get(), + base::Bind(&RasterizeAndRecordBenchmark::RecordRasterResults, + weak_ptr_factory_.GetWeakPtr()))); +} + +void RasterizeAndRecordBenchmark::Run(Layer* layer) { + layer->RunMicroBenchmark(this); +} + +void RasterizeAndRecordBenchmark::RunOnLayer(PictureLayer* layer) { + ContentLayerClient* painter = layer->client(); + gfx::Size content_bounds = layer->content_bounds(); + + DCHECK(host_); + gfx::Size tile_grid_size = host_->settings().default_tile_size; + + SkTileGridPicture::TileGridInfo tile_grid_info; + PicturePileBase::ComputeTileGridInfo(tile_grid_size, &tile_grid_info); + + gfx::Rect visible_content_rect = gfx::ScaleToEnclosingRect( + layer->visible_content_rect(), 1.f / layer->contents_scale_x()); + if (visible_content_rect.IsEmpty()) + return; + + scoped_refptr<Picture> picture = Picture::Create(visible_content_rect); + + base::TimeDelta min_time = + base::TimeDelta::FromInternalValue(std::numeric_limits<int64>::max()); + for (int i = 0; i < record_repeat_count_; ++i) { + base::TimeTicks start = Now(); + picture->Record(painter, tile_grid_info); + base::TimeTicks end = Now(); + base::TimeDelta duration = end - start; + if (duration < min_time) + min_time = duration; + } + + record_results_.pixels_recorded += + visible_content_rect.width() * visible_content_rect.height(); + record_results_.total_best_time += min_time; +} + +RasterizeAndRecordBenchmark::RecordResults::RecordResults() + : pixels_recorded(0) {} + +RasterizeAndRecordBenchmark::RecordResults::~RecordResults() {} + +} // namespace cc diff --git a/cc/debug/rasterize_and_record_benchmark.h b/cc/debug/rasterize_and_record_benchmark.h new file mode 100644 index 0000000..2cea16a --- /dev/null +++ b/cc/debug/rasterize_and_record_benchmark.h @@ -0,0 +1,66 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CC_DEBUG_RASTERIZE_AND_RECORD_BENCHMARK_H_ +#define CC_DEBUG_RASTERIZE_AND_RECORD_BENCHMARK_H_ + +#include <map> +#include <utility> +#include <vector> + +#include "base/memory/weak_ptr.h" +#include "base/time/time.h" +#include "cc/debug/micro_benchmark_controller.h" + +namespace base { +class DictionaryValue; +} + +namespace cc { + +class LayerTreeHost; +class Layer; +class RasterizeAndRecordBenchmark : public MicroBenchmark { + public: + explicit RasterizeAndRecordBenchmark( + scoped_ptr<base::Value> value, + const MicroBenchmark::DoneCallback& callback); + virtual ~RasterizeAndRecordBenchmark(); + + // Implements MicroBenchmark interface. + virtual void DidUpdateLayers(LayerTreeHost* host) OVERRIDE; + virtual void RunOnLayer(PictureLayer* layer) OVERRIDE; + + virtual scoped_ptr<MicroBenchmarkImpl> CreateBenchmarkImpl( + scoped_refptr<base::MessageLoopProxy> origin_loop) OVERRIDE; + + private: + void Run(Layer* layer); + + void RecordRasterResults(scoped_ptr<base::Value> results); + + struct RecordResults { + RecordResults(); + ~RecordResults(); + + int pixels_recorded; + base::TimeDelta total_best_time; + }; + + RecordResults record_results_; + int record_repeat_count_; + scoped_ptr<base::Value> settings_; + scoped_ptr<base::DictionaryValue> results_; + + // The following is used in DCHECKs. + bool main_thread_benchmark_done_; + + LayerTreeHost* host_; + + base::WeakPtrFactory<RasterizeAndRecordBenchmark> weak_ptr_factory_; +}; + +} // namespace cc + +#endif // CC_DEBUG_RASTERIZE_AND_RECORD_BENCHMARK_H_ diff --git a/cc/debug/rasterize_and_record_benchmark_impl.cc b/cc/debug/rasterize_and_record_benchmark_impl.cc new file mode 100644 index 0000000..ecf2688 --- /dev/null +++ b/cc/debug/rasterize_and_record_benchmark_impl.cc @@ -0,0 +1,117 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/debug/rasterize_and_record_benchmark_impl.h" + +#include <algorithm> +#include <limits> + +#include "base/basictypes.h" +#include "base/values.h" +#include "cc/layers/layer_impl.h" +#include "cc/layers/picture_layer_impl.h" +#include "cc/trees/layer_tree_host_common.h" +#include "cc/trees/layer_tree_host_impl.h" +#include "ui/gfx/rect.h" + +namespace cc { + +namespace { + +const int kDefaultRasterizeRepeatCount = 100; + +base::TimeTicks Now() { + return base::TimeTicks::IsThreadNowSupported() + ? base::TimeTicks::ThreadNow() + : base::TimeTicks::HighResNow(); +} + +} // namespace + +RasterizeAndRecordBenchmarkImpl::RasterizeAndRecordBenchmarkImpl( + scoped_refptr<base::MessageLoopProxy> origin_loop, + base::Value* value, + const MicroBenchmarkImpl::DoneCallback& callback) + : MicroBenchmarkImpl(callback, origin_loop), + rasterize_repeat_count_(kDefaultRasterizeRepeatCount) { + base::DictionaryValue* settings = NULL; + value->GetAsDictionary(&settings); + if (!settings) + return; + + if (settings->HasKey("rasterize_repeat_count")) + settings->GetInteger("rasterize_repeat_count", &rasterize_repeat_count_); +} + +RasterizeAndRecordBenchmarkImpl::~RasterizeAndRecordBenchmarkImpl() {} + +void RasterizeAndRecordBenchmarkImpl::DidCompleteCommit( + LayerTreeHostImpl* host) { + LayerTreeHostCommon::CallFunctionForSubtree( + host->RootLayer(), + base::Bind(&RasterizeAndRecordBenchmarkImpl::Run, + base::Unretained(this))); + + scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue()); + result->SetInteger("pixels_rasterized", rasterize_results_.pixels_rasterized); + result->SetDouble("rasterize_time_ms", + rasterize_results_.total_best_time.InMillisecondsF()); + + NotifyDone(result.PassAs<base::Value>()); +} + +void RasterizeAndRecordBenchmarkImpl::Run(LayerImpl* layer) { + layer->RunMicroBenchmark(this); +} + +void RasterizeAndRecordBenchmarkImpl::RunOnLayer(PictureLayerImpl* layer) { + if (layer->visible_content_rect().IsEmpty()) + return; + + PictureLayerTilingSet tiling_set(layer, layer->content_bounds()); + + PictureLayerTiling* tiling = tiling_set.AddTiling(layer->contents_scale_x()); + tiling->CreateAllTilesForTesting(); + for (PictureLayerTiling::CoverageIterator it( + tiling, layer->contents_scale_x(), layer->visible_content_rect()); + it; + ++it) { + DCHECK(*it); + + PicturePileImpl* picture_pile = (*it)->picture_pile(); + gfx::Rect content_rect = (*it)->content_rect(); + float contents_scale = (*it)->contents_scale(); + + base::TimeDelta min_time = + base::TimeDelta::FromInternalValue(std::numeric_limits<int64>::max()); + for (int i = 0; i < rasterize_repeat_count_; ++i) { + SkBitmap bitmap; + bitmap.setConfig(SkBitmap::kARGB_8888_Config, + content_rect.width(), + content_rect.height()); + bitmap.allocPixels(); + + SkBitmapDevice device(bitmap); + SkCanvas canvas(&device); + + base::TimeTicks start = Now(); + picture_pile->RasterToBitmap(&canvas, content_rect, contents_scale, NULL); + base::TimeTicks end = Now(); + base::TimeDelta duration = end - start; + if (duration < min_time) + min_time = duration; + } + + rasterize_results_.pixels_rasterized += + content_rect.width() * content_rect.height(); + rasterize_results_.total_best_time += min_time; + } +} + +RasterizeAndRecordBenchmarkImpl::RasterizeResults::RasterizeResults() + : pixels_rasterized(0) {} + +RasterizeAndRecordBenchmarkImpl::RasterizeResults::~RasterizeResults() {} + +} // namespace cc diff --git a/cc/debug/rasterize_and_record_benchmark_impl.h b/cc/debug/rasterize_and_record_benchmark_impl.h new file mode 100644 index 0000000..0f9de9b --- /dev/null +++ b/cc/debug/rasterize_and_record_benchmark_impl.h @@ -0,0 +1,49 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CC_DEBUG_RASTERIZE_AND_RECORD_BENCHMARK_IMPL_H_ +#define CC_DEBUG_RASTERIZE_AND_RECORD_BENCHMARK_IMPL_H_ + +#include <map> +#include <utility> +#include <vector> + +#include "base/time/time.h" +#include "cc/debug/micro_benchmark_impl.h" + +namespace cc { + +class LayerTreeHostImpl; +class PictureLayerImpl; +class LayerImpl; +class RasterizeAndRecordBenchmarkImpl : public MicroBenchmarkImpl { + public: + explicit RasterizeAndRecordBenchmarkImpl( + scoped_refptr<base::MessageLoopProxy> origin_loop, + base::Value* value, + const MicroBenchmarkImpl::DoneCallback& callback); + virtual ~RasterizeAndRecordBenchmarkImpl(); + + // Implements MicroBenchmark interface. + virtual void DidCompleteCommit(LayerTreeHostImpl* host) OVERRIDE; + virtual void RunOnLayer(PictureLayerImpl* layer) OVERRIDE; + + private: + void Run(LayerImpl* layer); + + struct RasterizeResults { + RasterizeResults(); + ~RasterizeResults(); + + int pixels_rasterized; + base::TimeDelta total_best_time; + }; + + RasterizeResults rasterize_results_; + int rasterize_repeat_count_; +}; + +} // namespace cc + +#endif // CC_DEBUG_RASTERIZE_AND_RECORD_BENCHMARK_IMPL_H_ diff --git a/cc/resources/picture_pile_base.cc b/cc/resources/picture_pile_base.cc index 69e6143..b6e1aa5 100644 --- a/cc/resources/picture_pile_base.cc +++ b/cc/resources/picture_pile_base.cc @@ -128,19 +128,24 @@ void PicturePileBase::SetMinContentsScale(float min_contents_scale) { min_contents_scale_ = min_contents_scale; } -void PicturePileBase::SetTileGridSize(gfx::Size tile_grid_size) { - tile_grid_info_.fTileInterval.set( - tile_grid_size.width() - 2 * kTileGridBorderPixels, - tile_grid_size.height() - 2 * kTileGridBorderPixels); - DCHECK_GT(tile_grid_info_.fTileInterval.width(), 0); - DCHECK_GT(tile_grid_info_.fTileInterval.height(), 0); - tile_grid_info_.fMargin.set(kTileGridBorderPixels, - kTileGridBorderPixels); +// static +void PicturePileBase::ComputeTileGridInfo( + gfx::Size tile_grid_size, + SkTileGridPicture::TileGridInfo* info) { + DCHECK(info); + info->fTileInterval.set(tile_grid_size.width() - 2 * kTileGridBorderPixels, + tile_grid_size.height() - 2 * kTileGridBorderPixels); + DCHECK_GT(info->fTileInterval.width(), 0); + DCHECK_GT(info->fTileInterval.height(), 0); + info->fMargin.set(kTileGridBorderPixels, kTileGridBorderPixels); // Offset the tile grid coordinate space to take into account the fact // that the top-most and left-most tiles do not have top and left borders // respectively. - tile_grid_info_.fOffset.set(-kTileGridBorderPixels, - -kTileGridBorderPixels); + info->fOffset.set(-kTileGridBorderPixels, -kTileGridBorderPixels); +} + +void PicturePileBase::SetTileGridSize(gfx::Size tile_grid_size) { + ComputeTileGridInfo(tile_grid_size, &tile_grid_info_); } void PicturePileBase::SetBufferPixels(int new_buffer_pixels) { diff --git a/cc/resources/picture_pile_base.h b/cc/resources/picture_pile_base.h index 325feff..d7b7e9c 100644 --- a/cc/resources/picture_pile_base.h +++ b/cc/resources/picture_pile_base.h @@ -41,6 +41,9 @@ class CC_EXPORT PicturePileBase : public base::RefCounted<PicturePileBase> { bool HasRecordingAt(int x, int y); bool CanRaster(float contents_scale, gfx::Rect content_rect); + static void ComputeTileGridInfo(gfx::Size tile_grid_size, + SkTileGridPicture::TileGridInfo* info); + void SetTileGridSize(gfx::Size tile_grid_size); TilingData& tiling() { return tiling_; } |