diff options
author | nduca@chromium.org <nduca@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-30 05:55:02 +0000 |
---|---|---|
committer | nduca@chromium.org <nduca@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-30 05:55:02 +0000 |
commit | 4d3c5c915340092e54e40382b93d74661830074b (patch) | |
tree | 65ca7308298b25bc6ca71f11a4371467f307c3ba /cc | |
parent | e9bf0649a8a85f3842dbb58797bc3ee64cee6a05 (diff) | |
download | chromium_src-4d3c5c915340092e54e40382b93d74661830074b.zip chromium_src-4d3c5c915340092e54e40382b93d74661830074b.tar.gz chromium_src-4d3c5c915340092e54e40382b93d74661830074b.tar.bz2 |
[cc] Track the rendering & painting cost of impl-side painting.
We record how long the rendering thread takes to render each PicturePile,
accumulate in TileManager, and report through LayerTreeHostImpl; telemetry
queries this information and dumps the output.
BUG=163324
R=reveman
TBR=enne
Review URL: https://codereview.chromium.org/11434033
Review URL: https://codereview.chromium.org/11418250
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@170413 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/layer_tree_host_impl.cc | 3 | ||||
-rw-r--r-- | cc/picture.cc | 2 | ||||
-rw-r--r-- | cc/picture_layer_impl.cc.orig | 153 | ||||
-rw-r--r-- | cc/picture_layer_impl.cc.rej | 34 | ||||
-rw-r--r-- | cc/picture_layer_impl.h.orig | 53 | ||||
-rw-r--r-- | cc/picture_pile_impl.cc | 13 | ||||
-rw-r--r-- | cc/picture_pile_impl.h | 3 | ||||
-rw-r--r-- | cc/tile_manager.cc | 28 | ||||
-rw-r--r-- | cc/tile_manager.h | 8 |
9 files changed, 289 insertions, 8 deletions
diff --git a/cc/layer_tree_host_impl.cc b/cc/layer_tree_host_impl.cc index 4c21430..aa6dd27 100644 --- a/cc/layer_tree_host_impl.cc +++ b/cc/layer_tree_host_impl.cc @@ -1614,6 +1614,9 @@ void LayerTreeHostImpl::renderingStats(RenderingStats* stats) const stats->numImplThreadScrolls = m_numImplThreadScrolls; stats->numMainThreadScrolls = m_numMainThreadScrolls; stats->numLayersDrawn = m_cumulativeNumLayersDrawn; + + if (m_tileManager) + m_tileManager->renderingStats(stats); } void LayerTreeHostImpl::animateScrollbars(base::TimeTicks time) diff --git a/cc/picture.cc b/cc/picture.cc index 4284c39..50eefd8 100644 --- a/cc/picture.cc +++ b/cc/picture.cc @@ -68,6 +68,8 @@ void Picture::Record(ContentLayerClient* painter, gfx::Rect layer_rect, painter->paintContents(canvas, layer_rect, opaque_layer_rect); double delta = (base::TimeTicks::Now() - beginPaintTime).InSecondsF(); stats.totalPaintTimeInSeconds += delta; + stats.totalPixelsPainted += layer_rect.width() * + layer_rect.height(); canvas->restore(); picture_->endRecording(); diff --git a/cc/picture_layer_impl.cc.orig b/cc/picture_layer_impl.cc.orig new file mode 100644 index 0000000..8c53563 --- /dev/null +++ b/cc/picture_layer_impl.cc.orig @@ -0,0 +1,153 @@ +// Copyright 2012 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/picture_layer_impl.h" + +#include "cc/append_quads_data.h" +#include "cc/checkerboard_draw_quad.h" +#include "cc/debug_border_draw_quad.h" +#include "cc/debug_colors.h" +#include "cc/layer_tree_host_impl.h" +#include "cc/math_util.h" +#include "cc/quad_sink.h" +#include "cc/solid_color_draw_quad.h" +#include "cc/tile_draw_quad.h" + +namespace cc { + +PictureLayerImpl::PictureLayerImpl(int id) : + LayerImpl(id), + tilings_(this), + pile_(PicturePileImpl::Create()) { +} + +PictureLayerImpl::~PictureLayerImpl() { +} + +const char* PictureLayerImpl::layerTypeAsString() const { + return "PictureLayer"; +} + +void PictureLayerImpl::appendQuads(QuadSink& quadSink, + AppendQuadsData& appendQuadsData) { + + const gfx::Rect& rect = visibleContentRect(); + gfx::Rect content_rect(gfx::Point(), contentBounds()); + + SharedQuadState* sharedQuadState = + quadSink.useSharedQuadState(createSharedQuadState()); + bool clipped = false; + gfx::QuadF target_quad = MathUtil::mapQuad( + drawTransform(), + gfx::QuadF(rect), + clipped); + bool isAxisAlignedInTarget = !clipped && target_quad.IsRectilinear(); + bool useAA = !isAxisAlignedInTarget; + + if (showDebugBorders()) { + for (PictureLayerTilingSet::Iterator iter(&tilings_, + contentsScaleX(), + rect); + iter; + ++iter) { + SkColor color; + float width; + if (*iter && iter->resource_id()) { + color = DebugColors::TileBorderColor(); + width = DebugColors::TileBorderWidth(layerTreeHostImpl()); + } else { + color = DebugColors::MissingTileBorderColor(); + width = DebugColors::MissingTileBorderWidth(layerTreeHostImpl()); + } + + scoped_ptr<DebugBorderDrawQuad> debugBorderQuad = + DebugBorderDrawQuad::Create(); + gfx::Rect geometry_rect = iter.geometry_rect(); + debugBorderQuad->SetNew(sharedQuadState, geometry_rect, color, width); + quadSink.append(debugBorderQuad.PassAs<DrawQuad>(), appendQuadsData); + } + } + + for (PictureLayerTilingSet::Iterator iter(&tilings_, contentsScaleX(), rect); + iter; + ++iter) { + ResourceProvider::ResourceId resource = 0; + if (*iter) + resource = iter->resource_id(); + + gfx::Rect geometry_rect = iter.geometry_rect(); + + if (!resource) { + if (drawCheckerboardForMissingTiles()) { + // TODO(enne): Figure out how to show debug "invalidated checker" color + scoped_ptr<CheckerboardDrawQuad> quad = CheckerboardDrawQuad::Create(); + SkColor color = DebugColors::DefaultCheckerboardColor(); + quad->SetNew(sharedQuadState, geometry_rect, color); + appendQuadsData.hadMissingTiles |= + quadSink.append(quad.PassAs<DrawQuad>(), appendQuadsData); + } else { + scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create(); + quad->SetNew(sharedQuadState, geometry_rect, backgroundColor()); + appendQuadsData.hadMissingTiles |= + quadSink.append(quad.PassAs<DrawQuad>(), appendQuadsData); + } + continue; + } + + gfx::RectF texture_rect = iter.texture_rect(); + gfx::Rect opaque_rect = iter->opaque_rect(); + opaque_rect.Intersect(content_rect); + + bool outside_left_edge = geometry_rect.x() == content_rect.x(); + bool outside_top_edge = geometry_rect.y() == content_rect.y(); + bool outside_right_edge = geometry_rect.right() == content_rect.right(); + bool outside_bottom_edge = geometry_rect.bottom() == content_rect.bottom(); + + scoped_ptr<TileDrawQuad> quad = TileDrawQuad::Create(); + quad->SetNew(sharedQuadState, + geometry_rect, + opaque_rect, + resource, + texture_rect, + iter.texture_size(), + iter->contents_swizzled(), + outside_left_edge && useAA, + outside_top_edge && useAA, + outside_right_edge && useAA, + outside_bottom_edge && useAA); + quadSink.append(quad.PassAs<DrawQuad>(), appendQuadsData); + } +} + +void PictureLayerImpl::dumpLayerProperties(std::string*, int indent) const { + // TODO(enne): implement me +} + +void PictureLayerImpl::didUpdateTransforms() { + tilings_.SetLayerBounds(bounds()); + // TODO(enne): Add more tilings during pinch zoom. + if (!tilings_.num_tilings()) { + gfx::Size tile_size = layerTreeHostImpl()->settings().defaultTileSize; + tilings_.AddTiling(contentsScaleX(), tile_size); + // TODO(enne): handle invalidations, create new tiles + } +} + +scoped_refptr<Tile> PictureLayerImpl::CreateTile(PictureLayerTiling*, + gfx::Rect rect) { + TileManager* tile_manager = layerTreeHostImpl()->tileManager(); + + return make_scoped_refptr(new Tile( + tile_manager, + pile_.get(), + rect.size(), + GL_RGBA, + rect)); +} + +void PictureLayerImpl::SyncFromActiveLayer(const PictureLayerImpl* other) { + tilings_.CloneFrom(other->tilings_); +} + +} // namespace cc diff --git a/cc/picture_layer_impl.cc.rej b/cc/picture_layer_impl.cc.rej new file mode 100644 index 0000000..bfda845 --- /dev/null +++ b/cc/picture_layer_impl.cc.rej @@ -0,0 +1,34 @@ +*************** +*** 4,9 **** + + #include "cc/picture_layer_impl.h" + + #include "cc/layer_tree_host_impl.h" + #include "cc/math_util.h" + #include "cc/quad_sink.h" +--- 4,10 ---- + + #include "cc/picture_layer_impl.h" + ++ #include "base/time.h" + #include "cc/layer_tree_host_impl.h" + #include "cc/math_util.h" + #include "cc/quad_sink.h" +*************** +*** 13,19 **** + + PictureLayerImpl::PictureLayerImpl(int id) : + LayerImpl(id), +- tilings_(this) { + } + + PictureLayerImpl::~PictureLayerImpl() { +--- 14,21 ---- + + PictureLayerImpl::PictureLayerImpl(int id) : + LayerImpl(id), ++ tilings_(this), ++ last_update_time_(0) { + } + + PictureLayerImpl::~PictureLayerImpl() { diff --git a/cc/picture_layer_impl.h.orig b/cc/picture_layer_impl.h.orig new file mode 100644 index 0000000..30b88d1 --- /dev/null +++ b/cc/picture_layer_impl.h.orig @@ -0,0 +1,53 @@ +// Copyright 2012 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_PICTURE_LAYER_IMPL_H_ +#define CC_PICTURE_LAYER_IMPL_H_ + +#include "cc/layer_impl.h" +#include "cc/picture_layer_tiling.h" +#include "cc/picture_layer_tiling_set.h" +#include "cc/picture_pile_impl.h" +#include "cc/scoped_ptr_vector.h" + +namespace cc { + +struct AppendQuadsData; +class QuadSink; + +class CC_EXPORT PictureLayerImpl : public LayerImpl, + public PictureLayerTilingClient { +public: + static scoped_ptr<PictureLayerImpl> create(int id) + { + return make_scoped_ptr(new PictureLayerImpl(id)); + } + virtual ~PictureLayerImpl(); + + // LayerImpl overrides. + virtual const char* layerTypeAsString() const OVERRIDE; + virtual void appendQuads(QuadSink&, AppendQuadsData&) OVERRIDE; + virtual void dumpLayerProperties(std::string*, int indent) const OVERRIDE; + virtual void didUpdateTransforms() OVERRIDE; + + // PictureLayerTilingClient overrides. + virtual scoped_refptr<Tile> CreateTile(PictureLayerTiling*, + gfx::Rect) OVERRIDE; + + // PushPropertiesTo active tree => pending tree + void SyncFromActiveLayer(const PictureLayerImpl* other); + +protected: + PictureLayerImpl(int id); + + PictureLayerTilingSet tilings_; + scoped_refptr<PicturePileImpl> pile_; + + friend class PictureLayer; + DISALLOW_COPY_AND_ASSIGN(PictureLayerImpl); +}; + +} + +#endif // CC_PICTURE_LAYER_IMPL_H_ diff --git a/cc/picture_pile_impl.cc b/cc/picture_pile_impl.cc index 217a5eb..2f89828 100644 --- a/cc/picture_pile_impl.cc +++ b/cc/picture_pile_impl.cc @@ -4,7 +4,9 @@ #include "base/debug/trace_event.h" #include "cc/picture_pile_impl.h" +#include "cc/rendering_stats.h" #include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkSize.h" namespace cc { @@ -28,7 +30,10 @@ scoped_refptr<PicturePileImpl> PicturePileImpl::CloneForDrawing() const { return clone; } -void PicturePileImpl::Raster(SkCanvas* canvas, gfx::Rect rect) { +void PicturePileImpl::Raster(SkCanvas* canvas, gfx::Rect rect, + RenderingStats* stats) { + base::TimeTicks rasterizeBeginTime = base::TimeTicks::Now(); + // TODO(enne): do this more efficiently, i.e. top down with Skia clips canvas->save(); canvas->translate(-rect.x(), -rect.y()); @@ -39,8 +44,14 @@ void PicturePileImpl::Raster(SkCanvas* canvas, gfx::Rect rect) { if (!pile_[i]->LayerRect().Intersects(rect)) continue; pile_[i]->Raster(canvas); + + SkISize deviceSize = canvas->getDeviceSize(); + stats->totalPixelsRasterized += deviceSize.width() * deviceSize.height(); } canvas->restore(); + + stats->totalRasterizeTimeInSeconds += (base::TimeTicks::Now() - + rasterizeBeginTime).InSecondsF(); } } // namespace cc diff --git a/cc/picture_pile_impl.h b/cc/picture_pile_impl.h index d188623..2ab544d 100644 --- a/cc/picture_pile_impl.h +++ b/cc/picture_pile_impl.h @@ -14,6 +14,7 @@ namespace cc { class PicturePile; +struct RenderingStats; class CC_EXPORT PicturePileImpl : public base::RefCounted<PicturePileImpl> { public: @@ -25,7 +26,7 @@ public: // Raster a subrect of this PicturePileImpl into the given canvas. // It's only safe to call paint on a cloned version. // It is assumed that contentsScale has already been applied to this canvas. - void Raster(SkCanvas* canvas, gfx::Rect rect); + void Raster(SkCanvas* canvas, gfx::Rect rect, RenderingStats* stats); private: friend class PicturePile; diff --git a/cc/tile_manager.cc b/cc/tile_manager.cc index 75deebe..cec7123 100644 --- a/cc/tile_manager.cc +++ b/cc/tile_manager.cc @@ -11,6 +11,7 @@ #include "base/logging.h" #include "base/threading/sequenced_worker_pool.h" #include "cc/platform_color.h" +#include "cc/rendering_stats.h" #include "cc/resource_pool.h" #include "cc/tile.h" #include "third_party/skia/include/core/SkDevice.h" @@ -19,7 +20,8 @@ namespace { void RasterizeTile(cc::PicturePileImpl* picture_pile, uint8_t* mapped_buffer, - const gfx::Rect& rect) { + const gfx::Rect& rect, + cc::RenderingStats* stats) { TRACE_EVENT0("cc", "RasterizeTile"); DCHECK(mapped_buffer); DCHECK(picture_pile); @@ -28,7 +30,7 @@ void RasterizeTile(cc::PicturePileImpl* picture_pile, bitmap.setPixels(mapped_buffer); SkDevice device(bitmap); SkCanvas canvas(&device); - picture_pile->Raster(&canvas, rect); + picture_pile->Raster(&canvas, rect, stats); } const int kMaxRasterThreads = 1; @@ -217,6 +219,12 @@ void TileManager::ManageTiles() { DispatchMoreRasterTasks(); } +void TileManager::renderingStats(RenderingStats* stats) { + stats->totalRasterizeTimeInSeconds = + rendering_stats_.totalRasterizeTimeInSeconds; + stats->totalPixelsRasterized = rendering_stats_.totalPixelsRasterized; +} + void TileManager::AssignGpuMemoryToTiles() { TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); // Some memory cannot be released. Figure out which. @@ -301,6 +309,8 @@ void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) { managed_tile_state.resource_id_is_being_initialized = true; managed_tile_state.can_be_freed = false; + RenderingStats* stats = new RenderingStats(); + ++pending_raster_tasks_; worker_pool_->GetTaskRunnerWithShutdownBehavior( base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)->PostTaskAndReply( @@ -309,21 +319,29 @@ void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) { base::Unretained(cloned_picture_pile.get()), resource_pool_->resource_provider()->mapPixelBuffer( resource_id), - tile->rect_inside_picture_), + tile->rect_inside_picture_, + stats), base::Bind(&TileManager::OnRasterTaskCompleted, base::Unretained(this), tile, resource_id, - cloned_picture_pile)); + cloned_picture_pile, + stats)); } void TileManager::OnRasterTaskCompleted( scoped_refptr<Tile> tile, ResourceProvider::ResourceId resource_id, - scoped_refptr<PicturePileImpl> cloned_picture_pile) { + scoped_refptr<PicturePileImpl> cloned_picture_pile, + RenderingStats* stats) { TRACE_EVENT0("cc", "TileManager::OnRasterTaskCompleted"); --pending_raster_tasks_; + rendering_stats_.totalRasterizeTimeInSeconds += + stats->totalRasterizeTimeInSeconds; + rendering_stats_.totalPixelsRasterized += stats->totalPixelsRasterized; + delete stats; + // Release raster resources. resource_pool_->resource_provider()->unmapPixelBuffer(resource_id); diff --git a/cc/tile_manager.h b/cc/tile_manager.h index fd13d86..2d57f7d 100644 --- a/cc/tile_manager.h +++ b/cc/tile_manager.h @@ -20,6 +20,7 @@ namespace cc { class Tile; class TileVersion; +struct RenderingStats; class ResourceProvider; class CC_EXPORT TileManagerClient { @@ -75,6 +76,8 @@ class CC_EXPORT TileManager { void ManageTiles(); + void renderingStats(RenderingStats* stats); + protected: // Methods called by Tile friend class Tile; @@ -91,7 +94,8 @@ class CC_EXPORT TileManager { void OnRasterTaskCompleted( scoped_refptr<Tile>, ResourceProvider::ResourceId, - scoped_refptr<PicturePileImpl>); + scoped_refptr<PicturePileImpl>, + RenderingStats*); void DidFinishTileInitialization(Tile*, ResourceProvider::ResourceId); TileManagerClient* client_; @@ -105,6 +109,8 @@ class CC_EXPORT TileManager { typedef std::vector<Tile*> TileVector; TileVector tiles_; TileVector tiles_that_need_to_be_rasterized_; + + RenderingStats rendering_stats_; }; } // namespace cc |