diff options
author | nduca@chromium.org <nduca@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-12 18:31:08 +0000 |
---|---|---|
committer | nduca@chromium.org <nduca@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-12 18:31:08 +0000 |
commit | 131a0c245d22336b9c6c6abf78902f5833e5baeb (patch) | |
tree | 546e5a89d4c6988fb4491b63efd5b611c193ceb3 | |
parent | 3849fb743df6e05f6fd08da8734d1cf2e2285bd4 (diff) | |
download | chromium_src-131a0c245d22336b9c6c6abf78902f5833e5baeb.zip chromium_src-131a0c245d22336b9c6c6abf78902f5833e5baeb.tar.gz chromium_src-131a0c245d22336b9c6c6abf78902f5833e5baeb.tar.bz2 |
[cc] Trace detailed tile info when --trace-all-rendered-frames
With this command line flag, this store a detailed dump of all tile data into the trace buffer, including tile quads in screenspace. This provides enough foundation for cc-frame-viewer to visualize what impl-side painting is doing.
NOTRY=True
Review URL: https://chromiumcodereview.appspot.com/12096112
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@181956 0039d316-1c4b-4281-b951-d872f2087c98
30 files changed, 306 insertions, 37 deletions
diff --git a/cc/layer_tree_debug_state.cc b/cc/layer_tree_debug_state.cc index 0f68b6a..8a0e8ae 100644 --- a/cc/layer_tree_debug_state.cc +++ b/cc/layer_tree_debug_state.cc @@ -22,7 +22,8 @@ LayerTreeDebugState::LayerTreeDebugState() , showOccludingRects(false) , showNonOccludingRects(false) , slowDownRasterScaleFactor(0) - , m_recordRenderingStats(false) { } + , m_recordRenderingStats(false) + , traceAllRenderedFrames(false) { } LayerTreeDebugState::~LayerTreeDebugState() { } @@ -60,7 +61,8 @@ bool LayerTreeDebugState::equal(const LayerTreeDebugState& a, const LayerTreeDeb a.showOccludingRects == b.showOccludingRects && a.showNonOccludingRects == b.showNonOccludingRects && a.slowDownRasterScaleFactor == b.slowDownRasterScaleFactor && - a.m_recordRenderingStats == b.m_recordRenderingStats); + a.m_recordRenderingStats == b.m_recordRenderingStats && + a.traceAllRenderedFrames == b.traceAllRenderedFrames); } LayerTreeDebugState LayerTreeDebugState::unite(const LayerTreeDebugState& a, const LayerTreeDebugState& b) { @@ -83,6 +85,7 @@ LayerTreeDebugState LayerTreeDebugState::unite(const LayerTreeDebugState& a, con r.slowDownRasterScaleFactor = b.slowDownRasterScaleFactor; r.m_recordRenderingStats |= b.m_recordRenderingStats; + r.traceAllRenderedFrames |= b.traceAllRenderedFrames; return r; } diff --git a/cc/layer_tree_debug_state.h b/cc/layer_tree_debug_state.h index 9abda30..fe632cd 100644 --- a/cc/layer_tree_debug_state.h +++ b/cc/layer_tree_debug_state.h @@ -32,6 +32,8 @@ class CC_EXPORT LayerTreeDebugState { void setRecordRenderingStats(bool); bool recordRenderingStats() const; + bool traceAllRenderedFrames; + bool showHudInfo() const; bool showHudRects() const; bool hudNeedsFont() const; diff --git a/cc/layer_tree_host.cc b/cc/layer_tree_host.cc index 76915d3e..fb99807 100644 --- a/cc/layer_tree_host.cc +++ b/cc/layer_tree_host.cc @@ -837,6 +837,13 @@ bool LayerTreeHost::blocksPendingCommit() const return m_rootLayer->blocksPendingCommitRecursive(); } +scoped_ptr<base::Value> LayerTreeHost::asValue() const +{ + scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); + state->Set("proxy", m_proxy->asValue().release()); + return state.PassAs<base::Value>(); +} + void LayerTreeHost::animateLayers(base::TimeTicks time) { if (!m_settings.acceleratedAnimationEnabled || m_animationRegistrar->active_animation_controllers().empty()) diff --git a/cc/layer_tree_host.h b/cc/layer_tree_host.h index a45c1c1..b3881f7 100644 --- a/cc/layer_tree_host.h +++ b/cc/layer_tree_host.h @@ -200,6 +200,9 @@ public: bool blocksPendingCommit() const; + // Obtains a thorough dump of the LayerTreeHost as a value. + scoped_ptr<base::Value> asValue() const; + protected: LayerTreeHost(LayerTreeHostClient*, const LayerTreeSettings&); bool initialize(scoped_ptr<Thread> implThread); diff --git a/cc/layer_tree_host_impl.cc b/cc/layer_tree_host_impl.cc index 607a50c..e357999 100644 --- a/cc/layer_tree_host_impl.cc +++ b/cc/layer_tree_host_impl.cc @@ -11,6 +11,7 @@ #include "base/json/json_writer.h" #include "base/metrics/histogram.h" #include "base/stl_util.h" +#include "base/stringprintf.h" #include "cc/append_quads_data.h" #include "cc/compositor_frame_metadata.h" #include "cc/damage_tracker.h" @@ -29,6 +30,7 @@ #include "cc/overdraw_metrics.h" #include "cc/page_scale_animation.h" #include "cc/paint_time_counter.h" +#include "cc/picture_layer_tiling.h" #include "cc/prioritized_resource_manager.h" #include "cc/quad_culler.h" #include "cc/render_pass_draw_quad.h" @@ -58,6 +60,13 @@ void didVisibilityChange(cc::LayerTreeHostImpl* id, bool visible) TRACE_EVENT_ASYNC_END0("webkit", "LayerTreeHostImpl::setVisible", id); } +std::string ValueToString(scoped_ptr<base::Value> value) +{ + std::string str; + base::JSONWriter::Write(value.get(), &str); + return str; +} + } // namespace namespace cc { @@ -163,6 +172,8 @@ LayerTreeHostImpl::LayerTreeHostImpl(const LayerTreeSettings& settings, LayerTre DCHECK(m_proxy->isImplThread()); didVisibilityChange(this, m_visible); + setDebugState(settings.initialDebugState); + if (settings.calculateTopControlsPosition) m_topControlsManager = TopControlsManager::Create(this, settings.topControlsHeight); @@ -801,6 +812,11 @@ void LayerTreeHostImpl::drawLayers(FrameData& frame) if (m_debugState.showHudRects()) m_debugRectHistory->saveDebugRectsForCurrentFrame(rootLayer(), *frame.renderSurfaceLayerList, frame.occludingScreenSpaceRects, frame.nonOccludingScreenSpaceRects, m_debugState); + if (m_debugState.traceAllRenderedFrames) { + TRACE_EVENT_INSTANT1("cc.debug", "Frame", + "frame", ValueToString(frameStateAsValue())); + } + // Because the contents of the HUD depend on everything else in the frame, the contents // of its texture are updated as the last thing before the frame is drawn. if (m_activeTree->hud_layer()) @@ -928,6 +944,8 @@ void LayerTreeHostImpl::createPendingTree() m_client->onCanDrawStateChanged(canDraw()); m_client->onHasPendingTreeStateChanged(pendingTree()); TRACE_EVENT_ASYNC_BEGIN0("cc", "PendingTree", m_pendingTree.get()); + TRACE_EVENT_ASYNC_STEP0("cc", + "PendingTree", m_pendingTree.get(), "waiting"); } void LayerTreeHostImpl::checkForCompletedTileUploads() @@ -937,25 +955,6 @@ void LayerTreeHostImpl::checkForCompletedTileUploads() m_tileManager->CheckForCompletedTileUploads(); } -scoped_ptr<base::Value> LayerTreeHostImpl::activationStateAsValue() const -{ - scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); - state->SetBoolean("visible_resources_ready", pendingTree()->AreVisibleResourcesReady()); - state->Set("tile_manager", m_tileManager->AsValue().release()); - return state.PassAs<base::Value>(); -} - -namespace { - -std::string ValueToString(scoped_ptr<base::Value> value) -{ - std::string str; - base::JSONWriter::Write(value.get(), &str); - return str; -} - -} - void LayerTreeHostImpl::activatePendingTreeIfNeeded() { if (!pendingTree()) @@ -974,8 +973,11 @@ void LayerTreeHostImpl::activatePendingTreeIfNeeded() // or tile manager has no work scheduled for pending tree. if (activeTree()->RootLayer() && !pendingTree()->AreVisibleResourcesReady() && - m_tileManager->HasPendingWorkScheduled(PENDING_TREE)) + m_tileManager->HasPendingWorkScheduled(PENDING_TREE)) { + TRACE_EVENT_ASYNC_STEP0("cc", + "PendingTree", m_pendingTree.get(), "waiting"); return; + } activatePendingTree(); } @@ -1695,6 +1697,33 @@ base::TimeTicks LayerTreeHostImpl::currentFrameTime() return m_currentFrameTime; } +scoped_ptr<base::Value> LayerTreeHostImpl::asValue() const +{ + scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); + state->Set("activation_state", activationStateAsValue().release()); + state->Set("frame_state", frameStateAsValue().release()); + return state.PassAs<base::Value>(); +} + +scoped_ptr<base::Value> LayerTreeHostImpl::activationStateAsValue() const +{ + scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); + state->SetString("lthi_id", StringPrintf("%p", this)); + state->SetBoolean("visible_resources_ready", pendingTree()->AreVisibleResourcesReady()); + state->Set("tile_manager", m_tileManager->BasicStateAsValue().release()); + return state.PassAs<base::Value>(); +} + +scoped_ptr<base::Value> LayerTreeHostImpl::frameStateAsValue() const +{ + scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); + state->SetString("lthi_id", StringPrintf("%p", this)); + state->Set("device_viewport_size", MathUtil::asValue(m_deviceViewportSize).release()); + if (m_tileManager) + state->Set("tiles", m_tileManager->AllTilesAsValue().release()); + return state.PassAs<base::Value>(); +} + // static LayerImpl* LayerTreeHostImpl::getNonCompositedContentLayerRecursive(LayerImpl* layer) { diff --git a/cc/layer_tree_host_impl.h b/cc/layer_tree_host_impl.h index 0d51dbf..b956074 100644 --- a/cc/layer_tree_host_impl.h +++ b/cc/layer_tree_host_impl.h @@ -173,7 +173,6 @@ public: const LayerTreeImpl* recycleTree() const { return m_recycleTree.get(); } void createPendingTree(); void checkForCompletedTileUploads(); - scoped_ptr<base::Value> activationStateAsValue() const; virtual void activatePendingTreeIfNeeded(); // Shortcuts to layers on the active tree. @@ -260,6 +259,10 @@ public: void beginNextFrame(); base::TimeTicks currentFrameTime(); + scoped_ptr<base::Value> asValue() const; + scoped_ptr<base::Value> activationStateAsValue() const; + scoped_ptr<base::Value> frameStateAsValue() const; + protected: LayerTreeHostImpl(const LayerTreeSettings&, LayerTreeHostImplClient*, Proxy*); void activatePendingTree(); diff --git a/cc/math_util.cc b/cc/math_util.cc index 481c4d6..ff24fa2 100644 --- a/cc/math_util.cc +++ b/cc/math_util.cc @@ -7,6 +7,7 @@ #include <cmath> #include <limits> +#include "base/values.h" #include "ui/gfx/quad_f.h" #include "ui/gfx/rect.h" #include "ui/gfx/rect_conversions.h" @@ -385,4 +386,27 @@ gfx::Vector2dF MathUtil::projectVector(gfx::Vector2dF source, gfx::Vector2dF des return gfx::Vector2dF(projectedLength * destination.x(), projectedLength * destination.y()); } +scoped_ptr<base::Value> MathUtil::asValue(gfx::Size s) { + scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue()); + res->SetDouble("width", s.width()); + res->SetDouble("height", s.height()); + return res.PassAs<base::Value>(); +} + +scoped_ptr<base::Value> MathUtil::asValue(gfx::PointF pt) { + scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue()); + res->SetDouble("x", pt.x()); + res->SetDouble("y", pt.y()); + return res.PassAs<base::Value>(); +} + +scoped_ptr<base::Value> MathUtil::asValue(gfx::QuadF q) { + scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue()); + res->Set("p1", asValue(q.p1()).release()); + res->Set("p2", asValue(q.p2()).release()); + res->Set("p3", asValue(q.p3()).release()); + res->Set("p4", asValue(q.p4()).release()); + return res.PassAs<base::Value>(); +} + } // namespace cc diff --git a/cc/math_util.h b/cc/math_util.h index 0d9984e..de6288a 100644 --- a/cc/math_util.h +++ b/cc/math_util.h @@ -6,11 +6,17 @@ #define CC_MATH_UTIL_H_ #include "base/logging.h" +#include "base/memory/scoped_ptr.h" #include "cc/cc_export.h" #include "ui/gfx/point_f.h" #include "ui/gfx/point3_f.h" +#include "ui/gfx/size.h" #include "ui/gfx/transform.h" +namespace base { +class Value; +} + namespace gfx { class QuadF; class Rect; @@ -112,6 +118,11 @@ public: // Projects the |source| vector onto |destination|. Neither vector is assumed to be normalized. static gfx::Vector2dF projectVector(gfx::Vector2dF source, gfx::Vector2dF destination); + + // Conversion to value. + static scoped_ptr<base::Value> asValue(gfx::Size s); + static scoped_ptr<base::Value> asValue(gfx::PointF q); + static scoped_ptr<base::Value> asValue(gfx::QuadF q); }; } // namespace cc diff --git a/cc/picture_layer_impl.cc b/cc/picture_layer_impl.cc index 1af6e68..25b84bf 100644 --- a/cc/picture_layer_impl.cc +++ b/cc/picture_layer_impl.cc @@ -225,6 +225,8 @@ void PictureLayerImpl::updateTilePriorities() { } WhichTree tree = layerTreeImpl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE; + bool store_screen_space_quads_on_tiles = + layerTreeImpl()->debug_state().traceAllRenderedFrames; tilings_->UpdateTilePriorities( tree, layerTreeImpl()->device_viewport_size(), @@ -238,7 +240,8 @@ void PictureLayerImpl::updateTilePriorities() { last_screen_space_transform_, current_screen_space_transform, current_source_frame_number, - current_frame_time); + current_frame_time, + store_screen_space_quads_on_tiles); last_screen_space_transform_ = current_screen_space_transform; last_bounds_ = bounds(); diff --git a/cc/picture_layer_tiling.cc b/cc/picture_layer_tiling.cc index 0a339a3..b63e0cc 100644 --- a/cc/picture_layer_tiling.cc +++ b/cc/picture_layer_tiling.cc @@ -342,7 +342,8 @@ void PictureLayerTiling::UpdateTilePriorities( const gfx::Transform& last_screen_transform, const gfx::Transform& current_screen_transform, int current_source_frame_number, - double current_frame_time) { + double current_frame_time, + bool store_screen_space_quads_on_tiles) { TRACE_EVENT0("cc", "PictureLayerTiling::UpdateTilePriorities"); if (ContentRect().IsEmpty()) return; @@ -445,11 +446,11 @@ void PictureLayerTiling::UpdateTilePriorities( resolution_, time_to_visible_in_seconds, distance_to_visible_in_pixels); + if (store_screen_space_quads_on_tiles) + priority.set_current_screen_quad(gfx::QuadF(current_screen_rect)); tile->set_priority(tree, priority); } - } - else - { + } else { for (TilingData::Iterator iter(&tiling_data_, inflated_rect); iter; ++iter) { TileMap::iterator find = tiles_.find(iter.index()); @@ -483,6 +484,13 @@ void PictureLayerTiling::UpdateTilePriorities( resolution_, time_to_visible_in_seconds, distance_to_visible_in_pixels); + if (store_screen_space_quads_on_tiles) { + bool clipped; + priority.set_current_screen_quad( + MathUtil::mapQuad(current_screen_transform, + gfx::QuadF(current_layer_content_rect), + clipped)); + } tile->set_priority(tree, priority); } } diff --git a/cc/picture_layer_tiling.h b/cc/picture_layer_tiling.h index 58883af..e357dfd 100644 --- a/cc/picture_layer_tiling.h +++ b/cc/picture_layer_tiling.h @@ -130,7 +130,8 @@ class CC_EXPORT PictureLayerTiling { const gfx::Transform& last_screen_transform, const gfx::Transform& current_screen_transform, int current_source_frame_number, - double current_frame_time); + double current_frame_time, + bool store_screen_space_quads_on_tiles); // Copies the src_tree priority into the dst_tree priority for all tiles. // The src_tree priority is reset to the lowest priority possible. This diff --git a/cc/picture_layer_tiling_set.cc b/cc/picture_layer_tiling_set.cc index d181451..c8ce5f4 100644 --- a/cc/picture_layer_tiling_set.cc +++ b/cc/picture_layer_tiling_set.cc @@ -266,7 +266,8 @@ void PictureLayerTilingSet::UpdateTilePriorities( const gfx::Transform& last_screen_transform, const gfx::Transform& current_screen_transform, int current_source_frame_number, - double current_frame_time) { + double current_frame_time, + bool store_screen_space_quads_on_tiles) { gfx::RectF viewport_in_layer_space = gfx::ScaleRect( viewport_in_content_space, 1.f / current_layer_contents_scale, @@ -286,7 +287,8 @@ void PictureLayerTilingSet::UpdateTilePriorities( last_screen_transform, current_screen_transform, current_source_frame_number, - current_frame_time); + current_frame_time, + store_screen_space_quads_on_tiles); } } diff --git a/cc/picture_layer_tiling_set.h b/cc/picture_layer_tiling_set.h index 14e6722..ef24e41 100644 --- a/cc/picture_layer_tiling_set.h +++ b/cc/picture_layer_tiling_set.h @@ -60,7 +60,8 @@ class CC_EXPORT PictureLayerTilingSet { const gfx::Transform& last_screen_transform, const gfx::Transform& current_screen_transform, int current_source_frame_number, - double current_frame_time); + double current_frame_time, + bool store_screen_space_quads_on_tiles); void DidBecomeActive(); @@ -9,6 +9,7 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/time.h" +#include "base/values.h" #include "cc/cc_export.h" #include "skia/ext/refptr.h" #include "third_party/skia/include/core/SkPicture.h" @@ -99,6 +100,7 @@ public: virtual void acquireLayerTextures() = 0; virtual skia::RefPtr<SkPicture> capturePicture() = 0; + virtual scoped_ptr<base::Value> asValue() const = 0; // Testing hooks virtual bool commitPendingForTesting() = 0; diff --git a/cc/single_thread_proxy.cc b/cc/single_thread_proxy.cc index 40b7ad2..1301355 100644 --- a/cc/single_thread_proxy.cc +++ b/cc/single_thread_proxy.cc @@ -347,6 +347,20 @@ void SingleThreadProxy::compositeImmediately() } } +scoped_ptr<base::Value> SingleThreadProxy::asValue() const +{ + scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); + { + // The following line casts away const modifiers because it is just + // setting debug state. We still want the asValue() function and its + // call chain to be const throughout. + DebugScopedSetImplThread impl(const_cast<SingleThreadProxy*>(this)); + + state->Set("layer_tree_host_impl", m_layerTreeHostImpl->asValue().release()); + } + return state.PassAs<base::Value>(); +} + void SingleThreadProxy::forceSerializeOnSwapBuffers() { { diff --git a/cc/single_thread_proxy.h b/cc/single_thread_proxy.h index 0fae4dc..a499501 100644 --- a/cc/single_thread_proxy.h +++ b/cc/single_thread_proxy.h @@ -44,8 +44,9 @@ public: virtual size_t maxPartialTextureUpdates() const OVERRIDE; virtual void acquireLayerTextures() OVERRIDE { } virtual void forceSerializeOnSwapBuffers() OVERRIDE; - virtual bool commitPendingForTesting() OVERRIDE; virtual skia::RefPtr<SkPicture> capturePicture() OVERRIDE; + virtual scoped_ptr<base::Value> asValue() const OVERRIDE; + virtual bool commitPendingForTesting() OVERRIDE; // LayerTreeHostImplClient implementation virtual void didLoseOutputSurfaceOnImplThread() OVERRIDE; diff --git a/cc/switches.cc b/cc/switches.cc index ec74e83..1352f3a 100644 --- a/cc/switches.cc +++ b/cc/switches.cc @@ -63,6 +63,9 @@ const char kShowNonOccludingRects[] = "show-nonoccluding-rects"; // of pixels culled, and the number of pixels drawn, for each frame. const char kTraceOverdraw[] = "trace-overdraw"; +// Logs all rendered frames. +const char kTraceAllRenderedFrames[] = "trace-all-rendered-frames"; + // Re-rasters everything multiple times to simulate a much slower machine. // Give a scale factor to cause raster to take that many times longer to // complete, such as --slow-down-raster-scale-factor=25. diff --git a/cc/switches.h b/cc/switches.h index 7e0bfee..83ffa6d 100644 --- a/cc/switches.h +++ b/cc/switches.h @@ -33,6 +33,7 @@ CC_EXPORT extern const char kShowOccludingRects[]; CC_EXPORT extern const char kShowNonOccludingRects[]; CC_EXPORT extern const char kTraceOverdraw[]; CC_EXPORT extern const char kTopControlsHeight[]; +CC_EXPORT extern const char kTraceAllRenderedFrames[]; CC_EXPORT extern const char kSlowDownRasterScaleFactor[]; CC_EXPORT extern const char kUseCheapnessEstimator[]; diff --git a/cc/test/fake_proxy.cc b/cc/test/fake_proxy.cc index df382b8..f8587ef 100644 --- a/cc/test/fake_proxy.cc +++ b/cc/test/fake_proxy.cc @@ -66,4 +66,10 @@ skia::RefPtr<SkPicture> FakeProxy::capturePicture() return skia::RefPtr<SkPicture>(); } +scoped_ptr<base::Value> FakeProxy::asValue() const { + scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); + return state.PassAs<base::Value>(); +} + + } // namespace cc diff --git a/cc/test/fake_proxy.h b/cc/test/fake_proxy.h index 6951a6c..a74e303 100644 --- a/cc/test/fake_proxy.h +++ b/cc/test/fake_proxy.h @@ -39,6 +39,7 @@ public: virtual void acquireLayerTextures() OVERRIDE { } virtual bool commitPendingForTesting() OVERRIDE; virtual skia::RefPtr<SkPicture> capturePicture() OVERRIDE; + virtual scoped_ptr<base::Value> asValue() const OVERRIDE; virtual RendererCapabilities& rendererCapabilities(); void setMaxPartialTextureUpdates(size_t); diff --git a/cc/thread_proxy.cc b/cc/thread_proxy.cc index adb9d01..fe92817 100644 --- a/cc/thread_proxy.cc +++ b/cc/thread_proxy.cc @@ -1088,6 +1088,29 @@ ThreadProxy::BeginFrameAndCommitState::~BeginFrameAndCommitState() { } +scoped_ptr<base::Value> ThreadProxy::asValue() const +{ + scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); + + CompletionEvent completion; + { + DebugScopedSetMainThreadBlocked mainThreadBlocked( + const_cast<ThreadProxy*>(this)); + Proxy::implThread()->postTask(base::Bind(&ThreadProxy::asValueOnImplThread, + m_implThreadWeakPtr, + &completion, + state.get())); + completion.wait(); + } + return state.PassAs<base::Value>(); +} + +void ThreadProxy::asValueOnImplThread(CompletionEvent* completion, base::DictionaryValue* state) const +{ + state->Set("layer_tree_host_impl", m_layerTreeHostImpl->asValue().release()); + completion->signal(); +} + bool ThreadProxy::commitPendingForTesting() { DCHECK(isMainThread()); diff --git a/cc/thread_proxy.h b/cc/thread_proxy.h index bf7d445..9e383bb 100644 --- a/cc/thread_proxy.h +++ b/cc/thread_proxy.h @@ -53,8 +53,9 @@ public: virtual size_t maxPartialTextureUpdates() const OVERRIDE; virtual void acquireLayerTextures() OVERRIDE; virtual void forceSerializeOnSwapBuffers() OVERRIDE; - virtual bool commitPendingForTesting() OVERRIDE; virtual skia::RefPtr<SkPicture> capturePicture() OVERRIDE; + virtual scoped_ptr<base::Value> asValue() const OVERRIDE; + virtual bool commitPendingForTesting() OVERRIDE; // LayerTreeHostImplClient implementation virtual void didLoseOutputSurfaceOnImplThread() OVERRIDE; @@ -144,6 +145,7 @@ private: void checkOutputSurfaceStatusOnImplThread(); void commitPendingOnImplThreadForTesting(CommitPendingRequest* request); void capturePictureOnImplThread(CompletionEvent*, skia::RefPtr<SkPicture>*); + void asValueOnImplThread(CompletionEvent*, base::DictionaryValue*) const; void renewTreePriorityOnImplThread(); void didSwapUseIncompleteTileOnImplThread(); @@ -4,6 +4,7 @@ #include "cc/tile.h" +#include "base/stringprintf.h" #include "cc/tile_manager.h" #include "third_party/khronos/GLES2/gl2.h" @@ -28,4 +29,16 @@ Tile::~Tile() { tile_manager_->UnregisterTile(this); } +scoped_ptr<base::Value> Tile::AsValue() const { + scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue()); + res->SetString("id", base::StringPrintf("%p", this)); + res->SetString("picture_pile", base::StringPrintf("%p", + picture_pile_.get())); + res->SetDouble("contents_scale", contents_scale_); + res->Set("priority.0", priority_[ACTIVE_TREE].AsValue().release()); + res->Set("priority.1", priority_[PENDING_TREE].AsValue().release()); + res->Set("managed_state", managed_state_.AsValue().release()); + return res.PassAs<base::Value>(); +} + } // namespace cc @@ -47,6 +47,8 @@ class CC_EXPORT Tile : public base::RefCounted<Tile> { priority_[tree] = priority; } + scoped_ptr<base::Value> AsValue() const; + // Returns 0 if not drawable. ResourceProvider::ResourceId GetResourceId() const { if (!managed_state_.resource) diff --git a/cc/tile_manager.cc b/cc/tile_manager.cc index 1da6c98..3bbcbe3 100644 --- a/cc/tile_manager.cc +++ b/cc/tile_manager.cc @@ -95,6 +95,44 @@ scoped_ptr<base::Value> TileManagerBinAsValue(TileManagerBin bin) { } } +scoped_ptr<base::Value> TileManagerBinPriorityAsValue( + TileManagerBinPriority bin_priority) { + switch (bin_priority) { + case HIGH_PRIORITY_BIN: + return scoped_ptr<base::Value>(base::Value::CreateStringValue( + "HIGH_PRIORITY_BIN")); + case LOW_PRIORITY_BIN: + return scoped_ptr<base::Value>(base::Value::CreateStringValue( + "LOW_PRIORITY_BIN")); + default: + DCHECK(false) << "Unrecognized TileManagerBinPriority value"; + return scoped_ptr<base::Value>(base::Value::CreateStringValue( + "<unknown TileManagerBinPriority value>")); + } +} + +scoped_ptr<base::Value> TileRasterStateAsValue( + TileRasterState raster_state) { + switch (raster_state) { + case IDLE_STATE: + return scoped_ptr<base::Value>(base::Value::CreateStringValue( + "IDLE_STATE")); + case WAITING_FOR_RASTER_STATE: + return scoped_ptr<base::Value>(base::Value::CreateStringValue( + "WAITING_FOR_RASTER_STATE")); + case RASTER_STATE: + return scoped_ptr<base::Value>(base::Value::CreateStringValue( + "RASTER_STATE")); + case SET_PIXELS_STATE: + return scoped_ptr<base::Value>(base::Value::CreateStringValue( + "SET_PIXELS_STATE")); + default: + DCHECK(false) << "Unrecognized TileRasterState value"; + return scoped_ptr<base::Value>(base::Value::CreateStringValue( + "<unknown TileRasterState value>")); + } +} + ManagedTileState::ManagedTileState() : can_use_gpu_memory(false), can_be_freed(true), @@ -112,6 +150,21 @@ ManagedTileState::~ManagedTileState() { DCHECK(!resource_is_being_initialized); } +scoped_ptr<base::Value> ManagedTileState::AsValue() const { + scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); + state->SetBoolean("can_use_gpu_memory", can_use_gpu_memory); + state->SetBoolean("can_be_freed", can_be_freed); + state->SetBoolean("has_resource", resource.get() != 0); + state->SetBoolean("resource_is_being_initialized", resource_is_being_initialized); + state->Set("raster_state", TileRasterStateAsValue(raster_state).release()); + state->Set("bin.0", TileManagerBinAsValue(bin[0]).release()); + state->Set("bin.1", TileManagerBinAsValue(bin[0]).release()); + state->Set("gpu_memmgr_stats_bin", TileManagerBinAsValue(bin[0]).release()); + state->Set("resolution", TileResolutionAsValue(resolution).release()); + state->SetDouble("time_to_needed_in_seconds", time_to_needed_in_seconds); + return state.PassAs<base::Value>(); +} + TileManager::TileManager( TileManagerClient* client, ResourceProvider* resource_provider, @@ -338,7 +391,8 @@ void TileManager::ManageTiles() { // Assign gpu memory and determine what tiles need to be rasterized. AssignGpuMemoryToTiles(); - TRACE_EVENT_INSTANT1("cc", "DidManage", "state", ValueToString(AsValue())); + TRACE_EVENT_INSTANT1("cc", "DidManage", "state", + ValueToString(BasicStateAsValue())); // Finally, kick the rasterizer. DispatchMoreTasks(); @@ -415,7 +469,7 @@ void TileManager::GetMemoryStats( } } -scoped_ptr<base::Value> TileManager::AsValue() const { +scoped_ptr<base::Value> TileManager::BasicStateAsValue() const { scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); state->SetInteger("tile_count", tiles_.size()); @@ -424,6 +478,12 @@ scoped_ptr<base::Value> TileManager::AsValue() const { state->Set("memory_requirements", GetMemoryRequirementsAsValue().release()); return state.PassAs<base::Value>(); } +scoped_ptr<base::Value> TileManager::AllTilesAsValue() const { + scoped_ptr<base::ListValue> state(new base::ListValue()); + for (size_t i = 0; i < tiles_.size(); i++) + state->Append(tiles_[i]->AsValue().release()); + return state.PassAs<base::Value>(); +} scoped_ptr<base::Value> TileManager::GetMemoryRequirementsAsValue() const { scoped_ptr<base::DictionaryValue> requirements( diff --git a/cc/tile_manager.h b/cc/tile_manager.h index 8334266..d559036 100644 --- a/cc/tile_manager.h +++ b/cc/tile_manager.h @@ -50,6 +50,8 @@ enum TileManagerBinPriority { LOW_PRIORITY_BIN = 1, NUM_BIN_PRIORITIES = 2 }; +scoped_ptr<base::Value> TileManagerBinPriorityAsValue( + TileManagerBinPriority bin); enum TileRasterState { IDLE_STATE = 0, @@ -58,6 +60,8 @@ enum TileRasterState { SET_PIXELS_STATE = 3, NUM_STATES = 4 }; +scoped_ptr<base::Value> TileRasterStateAsValue( + TileRasterState bin); // This is state that is specific to a tile that is // managed by the TileManager. @@ -65,6 +69,7 @@ class CC_EXPORT ManagedTileState { public: ManagedTileState(); ~ManagedTileState(); + scoped_ptr<base::Value> AsValue() const; // Persisted state: valid all the time. bool can_use_gpu_memory; @@ -107,7 +112,8 @@ class CC_EXPORT TileManager { void CheckForCompletedTileUploads(); void AbortPendingTileUploads(); - scoped_ptr<base::Value> AsValue() const; + scoped_ptr<base::Value> BasicStateAsValue() const; + scoped_ptr<base::Value> AllTilesAsValue() const; void GetMemoryStats(size_t* memoryRequiredBytes, size_t* memoryNiceToHaveBytes, size_t* memoryUsedBytes) const; diff --git a/cc/tile_priority.cc b/cc/tile_priority.cc index cb5e956..6934624 100644 --- a/cc/tile_priority.cc +++ b/cc/tile_priority.cc @@ -5,6 +5,7 @@ #include "cc/tile_priority.h" #include "base/values.h" +#include "cc/math_util.h" namespace { @@ -70,6 +71,31 @@ scoped_ptr<base::Value> WhichTreeAsValue(WhichTree tree) { } } +scoped_ptr<base::Value> TileResolutionAsValue( + TileResolution resolution) { + switch (resolution) { + case LOW_RESOLUTION: + return scoped_ptr<base::Value>(base::Value::CreateStringValue( + "LOW_RESOLUTION")); + case HIGH_RESOLUTION: + return scoped_ptr<base::Value>(base::Value::CreateStringValue( + "HIGH_RESOLUTION")); + default: + DCHECK(false) << "Unrecognized TileResolution value"; + return scoped_ptr<base::Value>(base::Value::CreateStringValue( + "<unknown TileResolution value>")); + } +} + +scoped_ptr<base::Value> TilePriority::AsValue() const { + scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); + state->SetBoolean("is_live", is_live); + state->Set("resolution", TileResolutionAsValue(resolution).release()); + state->SetDouble("time_to_visible_in_seconds", time_to_visible_in_seconds); + state->SetDouble("distance_to_visible_in_pixels", distance_to_visible_in_pixels); + state->Set("current_screen_quad", MathUtil::asValue(current_screen_quad).release()); + return state.PassAs<base::Value>(); +} float TilePriority::TimeForBoundsToIntersect(const gfx::RectF& previous_bounds, const gfx::RectF& current_bounds, diff --git a/cc/tile_priority.h b/cc/tile_priority.h index 2b60de3..7e03c92 100644 --- a/cc/tile_priority.h +++ b/cc/tile_priority.h @@ -10,6 +10,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "cc/picture_pile.h" +#include "ui/gfx/quad_f.h" #include "ui/gfx/rect.h" #include "ui/gfx/size.h" @@ -35,6 +36,8 @@ enum TileResolution { HIGH_RESOLUTION = 1, NON_IDEAL_RESOLUTION = 2, }; +scoped_ptr<base::Value> TileResolutionAsValue( + TileResolution resolution); struct CC_EXPORT TilePriority { TilePriority() @@ -88,6 +91,9 @@ struct CC_EXPORT TilePriority { std::min(active.distance_to_visible_in_pixels, pending.distance_to_visible_in_pixels); } + void set_current_screen_quad(const gfx::QuadF& q) { current_screen_quad = q; } + + scoped_ptr<base::Value> AsValue() const; static const float kMaxDistanceInContentSpace; @@ -119,6 +125,9 @@ struct CC_EXPORT TilePriority { TileResolution resolution; float time_to_visible_in_seconds; float distance_to_visible_in_pixels; + +private: + gfx::QuadF current_screen_quad; }; enum TileMemoryLimitPolicy { diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 11c5d9a..83933a4 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc @@ -860,6 +860,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( cc::switches::kShowReplicaScreenSpaceRects, cc::switches::kShowNonOccludingRects, cc::switches::kShowOccludingRects, + cc::switches::kTraceAllRenderedFrames, cc::switches::kTraceOverdraw, cc::switches::kTopControlsHeight, cc::switches::kSlowDownRasterScaleFactor, diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc index 9435b5b..066f6e0 100644 --- a/content/renderer/gpu/render_widget_compositor.cc +++ b/content/renderer/gpu/render_widget_compositor.cc @@ -106,6 +106,8 @@ scoped_ptr<RenderWidgetCompositor> RenderWidgetCompositor::Create( cmd->HasSwitch(cc::switches::kShowNonOccludingRects); settings.initialDebugState.setRecordRenderingStats( web_settings.recordRenderingStats); + settings.initialDebugState.traceAllRenderedFrames = + cmd->HasSwitch(cc::switches::kTraceAllRenderedFrames); if (cmd->HasSwitch(cc::switches::kSlowDownRasterScaleFactor)) { std::string slow_down_scale_str = |