1926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)/*
2926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Copyright (C) 2012 Apple Inc. All rights reserved.
33c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch * Copyright (C) 2013 Google Inc. All rights reserved.
4926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *
5926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without
6926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * modification, are permitted provided that the following conditions are
7926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * met:
8926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *
9926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *     * Redistributions of source code must retain the above copyright
10926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * notice, this list of conditions and the following disclaimer.
11926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *     * Redistributions in binary form must reproduce the above
12926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer
13926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * in the documentation and/or other materials provided with the
14926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * distribution.
15926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *     * Neither the name of Google Inc. nor the names of its
16926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * contributors may be used to endorse or promote products derived from
17926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * this software without specific prior written permission.
18926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *
19926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) */
31926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
32926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#include "config.h"
33926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/InspectorLayerTreeAgent.h"
35926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
36197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/dom/Document.h"
37d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/frame/LocalFrame.h"
3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/IdentifiersFactory.h"
39323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#include "core/inspector/InspectorNodeIds.h"
4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/InspectorState.h"
4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/InstrumentingAgents.h"
4293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "core/loader/DocumentLoader.h"
4393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "core/page/Page.h"
443c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include "core/rendering/RenderView.h"
45197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/rendering/RenderWidget.h"
46d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/rendering/compositing/CompositedLayerMapping.h"
47d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/rendering/compositing/RenderLayerCompositor.h"
481e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/IntRect.h"
4909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "platform/graphics/CompositingReasons.h"
50a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/GraphicsContextRecorder.h"
51197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "platform/image-encoders/skia/PNGImageEncoder.h"
521e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/transforms/TransformationMatrix.h"
53d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "public/platform/WebFloatPoint.h"
543c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include "public/platform/WebLayer.h"
5510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch#include "wtf/text/Base64.h"
567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "wtf/text/StringBuilder.h"
57926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
58c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
59926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
60a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)unsigned InspectorLayerTreeAgent::s_lastSnapshotId;
61a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
6251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline String idForLayer(const GraphicsLayer* graphicsLayer)
631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){
641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return String::number(graphicsLayer->platformLayer()->id());
651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
661e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
6707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochstatic PassRefPtr<TypeBuilder::LayerTree::ScrollRect> buildScrollRect(const blink::WebRect& rect, const TypeBuilder::LayerTree::ScrollRect::Type::Enum& type)
6807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{
6907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    RefPtr<TypeBuilder::DOM::Rect> rectObject = TypeBuilder::DOM::Rect::create()
7007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        .setX(rect.x)
7107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        .setY(rect.y)
7207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        .setHeight(rect.height)
7307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        .setWidth(rect.width);
7407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    RefPtr<TypeBuilder::LayerTree::ScrollRect> scrollRectObject = TypeBuilder::LayerTree::ScrollRect::create()
7507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        .setRect(rectObject.release())
7607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        .setType(type);
7707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    return scrollRectObject.release();
7807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch}
7907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
8007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochstatic PassRefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::ScrollRect> > buildScrollRectsForLayer(GraphicsLayer* graphicsLayer)
8107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{
8207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    RefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::ScrollRect> > scrollRects = TypeBuilder::Array<TypeBuilder::LayerTree::ScrollRect>::create();
8307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    blink::WebLayer* webLayer = graphicsLayer->platformLayer();
8407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (size_t i = 0; i < webLayer->nonFastScrollableRegion().size(); ++i) {
8507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        scrollRects->addItem(buildScrollRect(webLayer->nonFastScrollableRegion()[i], TypeBuilder::LayerTree::ScrollRect::Type::RepaintsOnScroll));
8607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    }
8707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (size_t i = 0; i < webLayer->touchEventHandlerRegion().size(); ++i) {
8807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        scrollRects->addItem(buildScrollRect(webLayer->touchEventHandlerRegion()[i], TypeBuilder::LayerTree::ScrollRect::Type::TouchEventHandler));
8907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    }
9007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    if (webLayer->haveWheelEventHandlers()) {
9107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        blink::WebRect webRect(webLayer->position().x, webLayer->position().y, webLayer->bounds().width, webLayer->bounds().height);
9207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        scrollRects->addItem(buildScrollRect(webRect, TypeBuilder::LayerTree::ScrollRect::Type::WheelEventHandler));
9307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    }
9407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    return scrollRects->length() ? scrollRects.release() : nullptr;
9507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch}
9607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
97323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)static PassRefPtr<TypeBuilder::LayerTree::Layer> buildObjectForLayer(GraphicsLayer* graphicsLayer, int nodeId)
983c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{
99d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    blink::WebLayer* webLayer = graphicsLayer->platformLayer();
1003c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    RefPtr<TypeBuilder::LayerTree::Layer> layerObject = TypeBuilder::LayerTree::Layer::create()
1011e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        .setLayerId(idForLayer(graphicsLayer))
102d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        .setOffsetX(webLayer->position().x)
103d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        .setOffsetY(webLayer->position().y)
104d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        .setWidth(webLayer->bounds().width)
105d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        .setHeight(webLayer->bounds().height)
106c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        .setPaintCount(graphicsLayer->paintCount());
1073c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
1088abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (nodeId)
109d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        layerObject->setBackendNodeId(nodeId);
1108abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
1118abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    GraphicsLayer* parent = graphicsLayer->parent();
1128abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (!parent)
1138abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        parent = graphicsLayer->replicatedLayer();
1148abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (parent)
1151e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        layerObject->setParentLayerId(idForLayer(parent));
116c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    if (!graphicsLayer->contentsAreVisible())
117c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        layerObject->setInvisible(true);
118e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    const TransformationMatrix& transform = graphicsLayer->transform();
119e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    if (!transform.isIdentity()) {
120e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        TransformationMatrix::FloatMatrix4 flattenedMatrix;
121e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        transform.toColumnMajorFloatArray(flattenedMatrix);
122e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        RefPtr<TypeBuilder::Array<double> > transformArray = TypeBuilder::Array<double>::create();
123e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        for (size_t i = 0; i < WTF_ARRAY_LENGTH(flattenedMatrix); ++i)
124e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            transformArray->addItem(flattenedMatrix[i]);
125e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        layerObject->setTransform(transformArray);
1265d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        const FloatPoint3D& transformOrigin = graphicsLayer->transformOrigin();
1275d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        // FIXME: rename these to setTransformOrigin*
1285d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        if (webLayer->bounds().width > 0)
1295d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            layerObject->setAnchorX(transformOrigin.x() / webLayer->bounds().width);
1305d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        else
1315d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            layerObject->setAnchorX(0.0);
1325d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        if (webLayer->bounds().height > 0)
1335d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            layerObject->setAnchorY(transformOrigin.y() / webLayer->bounds().height);
1345d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        else
1355d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            layerObject->setAnchorY(0.0);
1365d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        layerObject->setAnchorZ(transformOrigin.z());
137e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    }
13807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    RefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::ScrollRect> > scrollRects = buildScrollRectsForLayer(graphicsLayer);
13907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    if (scrollRects)
14007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        layerObject->setScrollRects(scrollRects.release());
1413c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    return layerObject;
1423c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch}
1433c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
144323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)InspectorLayerTreeAgent::InspectorLayerTreeAgent(Page* page)
14509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    : InspectorBaseAgent<InspectorLayerTreeAgent>("LayerTree")
146926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    , m_frontend(0)
1473c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    , m_page(page)
148926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
149926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
150926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
151926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)InspectorLayerTreeAgent::~InspectorLayerTreeAgent()
152926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
153926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
154926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
155c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void InspectorLayerTreeAgent::trace(Visitor* visitor)
156c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
157c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    visitor->trace(m_page);
158c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    InspectorBaseAgent::trace(visitor);
159c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
160c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
161926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void InspectorLayerTreeAgent::setFrontend(InspectorFrontend* frontend)
162926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
163926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_frontend = frontend->layertree();
164926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
165926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
166926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void InspectorLayerTreeAgent::clearFrontend()
167926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
168926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_frontend = 0;
169926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    disable(0);
170926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
171926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
172926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void InspectorLayerTreeAgent::restore()
173926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
174f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    // We do not re-enable layer agent automatically after navigation. This is because
175f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    // it depends on DOMAgent and node ids in particular, so we let front-end request document
176f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    // and re-enable the agent manually after this.
177926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
178926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
179926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void InspectorLayerTreeAgent::enable(ErrorString*)
180926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
181926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_instrumentingAgents->setInspectorLayerTreeAgent(this);
1825d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (LocalFrame* frame = m_page->deprecatedLocalMainFrame()) {
18310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        Document* document = frame->document();
18410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        if (document && document->lifecycle().state() >= DocumentLifecycle::CompositingClean)
18510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch            layerTreeDidChange();
18610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    }
187926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
188926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
189926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void InspectorLayerTreeAgent::disable(ErrorString*)
190926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
191926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_instrumentingAgents->setInspectorLayerTreeAgent(0);
192a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    m_snapshotById.clear();
193d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ErrorString unused;
194926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
195926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
196926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void InspectorLayerTreeAgent::layerTreeDidChange()
197926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
198323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    m_frontend->layerTreeDidChange(buildLayerTree());
199926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
200926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
20151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void InspectorLayerTreeAgent::didPaint(RenderObject*, const GraphicsLayer* graphicsLayer, GraphicsContext*, const LayoutRect& rect)
2021e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){
2031e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    // Should only happen for FrameView paints when compositing is off. Consider different instrumentation method for that.
20451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (!graphicsLayer)
2051e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return;
20651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
2071e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    RefPtr<TypeBuilder::DOM::Rect> domRect = TypeBuilder::DOM::Rect::create()
2081e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        .setX(rect.x())
2091e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        .setY(rect.y())
2101e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        .setWidth(rect.width())
2111e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        .setHeight(rect.height());
2121e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    m_frontend->layerPainted(idForLayer(graphicsLayer), domRect.release());
2131e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
2141e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
215323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)PassRefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::Layer> > InspectorLayerTreeAgent::buildLayerTree()
216926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
2178abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    RenderLayerCompositor* compositor = renderLayerCompositor();
218f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    if (!compositor || !compositor->inCompositingMode())
219d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
220d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
221f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    LayerIdToNodeIdMap layerIdToNodeIdMap;
222f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    RefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::Layer> > layers = TypeBuilder::Array<TypeBuilder::LayerTree::Layer>::create();
223323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    buildLayerIdToNodeIdMap(compositor->rootRenderLayer(), layerIdToNodeIdMap);
224f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    gatherGraphicsLayers(compositor->rootGraphicsLayer(), layerIdToNodeIdMap, layers);
225f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    return layers.release();
226926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
227926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
228323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)void InspectorLayerTreeAgent::buildLayerIdToNodeIdMap(RenderLayer* root, LayerIdToNodeIdMap& layerIdToNodeIdMap)
2293c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{
23051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (root->hasCompositedLayerMapping()) {
2318abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        if (Node* node = root->renderer()->generatingNode()) {
2321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            GraphicsLayer* graphicsLayer = root->compositedLayerMapping()->childForSuperlayers();
233323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            layerIdToNodeIdMap.set(graphicsLayer->platformLayer()->id(), idForNode(node));
2348abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        }
2353c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    }
2368abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    for (RenderLayer* child = root->firstChild(); child; child = child->nextSibling())
237323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        buildLayerIdToNodeIdMap(child, layerIdToNodeIdMap);
2388abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (!root->renderer()->isRenderIFrame())
239926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
2408abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    FrameView* childFrameView = toFrameView(toRenderWidget(root->renderer())->widget());
2418abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (RenderView* childRenderView = childFrameView->renderView()) {
2428abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        if (RenderLayerCompositor* childCompositor = childRenderView->compositor())
243323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            buildLayerIdToNodeIdMap(childCompositor->rootRenderLayer(), layerIdToNodeIdMap);
244926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
245926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
246926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
247d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void InspectorLayerTreeAgent::gatherGraphicsLayers(GraphicsLayer* root, HashMap<int, int>& layerIdToNodeIdMap, RefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::Layer> >& layers)
248926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
249d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    int layerId = root->platformLayer()->id();
250d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (m_pageOverlayLayerIds.find(layerId) != WTF::kNotFound)
251d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
252d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    layers->addItem(buildObjectForLayer(root, layerIdToNodeIdMap.get(layerId)));
253d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (GraphicsLayer* replica = root->replicaLayer())
254d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        gatherGraphicsLayers(replica, layerIdToNodeIdMap, layers);
255d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    for (size_t i = 0, size = root->children().size(); i < size; ++i)
256d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        gatherGraphicsLayers(root->children()[i], layerIdToNodeIdMap, layers);
257d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
258d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
259323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)int InspectorLayerTreeAgent::idForNode(Node* node)
260d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
261323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    return InspectorNodeIds::idForNode(node);
262926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
263926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
2648abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)RenderLayerCompositor* InspectorLayerTreeAgent::renderLayerCompositor()
265c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles){
2665d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    RenderView* renderView = m_page->deprecatedLocalMainFrame()->contentRenderer();
267c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    RenderLayerCompositor* compositor = renderView ? renderView->compositor() : 0;
268c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    return compositor;
269c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)}
270c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
271c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)static GraphicsLayer* findLayerById(GraphicsLayer* root, int layerId)
272c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles){
273c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    if (root->platformLayer()->id() == layerId)
274c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        return root;
2758abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (root->replicaLayer()) {
2768abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        if (GraphicsLayer* layer = findLayerById(root->replicaLayer(), layerId))
2778abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            return layer;
2788abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    }
279c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    for (size_t i = 0, size = root->children().size(); i < size; ++i) {
280c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        if (GraphicsLayer* layer = findLayerById(root->children()[i], layerId))
281c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)            return layer;
282c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    }
283c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    return 0;
284c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)}
285c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
286c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)GraphicsLayer* InspectorLayerTreeAgent::layerById(ErrorString* errorString, const String& layerId)
287c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles){
288c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    bool ok;
289c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    int id = layerId.toInt(&ok);
290c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    if (!ok) {
291c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        *errorString = "Invalid layer id";
292c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        return 0;
293c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    }
2948abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    RenderLayerCompositor* compositor = renderLayerCompositor();
295a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if (!compositor) {
296a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        *errorString = "Not in compositing mode";
297c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        return 0;
298a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    }
299c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
300c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    GraphicsLayer* result = findLayerById(compositor->rootGraphicsLayer(), id);
301c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    if (!result)
302c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        *errorString = "No layer matching given id found";
303c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    return result;
304c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)}
305c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
306c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)void InspectorLayerTreeAgent::compositingReasons(ErrorString* errorString, const String& layerId, RefPtr<TypeBuilder::Array<String> >& reasonStrings)
307c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles){
308c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    const GraphicsLayer* graphicsLayer = layerById(errorString, layerId);
309c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    if (!graphicsLayer)
310c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        return;
31109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    CompositingReasons reasonsBitmask = graphicsLayer->compositingReasons();
312c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    reasonStrings = TypeBuilder::Array<String>::create();
313197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    for (size_t i = 0; i < kNumberOfCompositingReasons; ++i) {
314197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (!(reasonsBitmask & kCompositingReasonStringMap[i].reason))
315c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)            continue;
316197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        reasonStrings->addItem(kCompositingReasonStringMap[i].shortName);
317c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#ifndef _NDEBUG
318197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        reasonsBitmask &= ~kCompositingReasonStringMap[i].reason;
319c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#endif
320c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    }
321c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    ASSERT(!reasonsBitmask);
322c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)}
323c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
324a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)void InspectorLayerTreeAgent::makeSnapshot(ErrorString* errorString, const String& layerId, String* snapshotId)
325a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){
326a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    GraphicsLayer* layer = layerById(errorString, layerId);
327a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if (!layer)
328a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return;
329a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
330a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    GraphicsContextRecorder recorder;
331a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    IntSize size = expandedIntSize(layer->size());
332a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    GraphicsContext* context = recorder.record(size, layer->contentsOpaque());
333a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    layer->paint(*context, IntRect(IntPoint(0, 0), size));
334a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    RefPtr<GraphicsContextSnapshot> snapshot = recorder.stop();
335a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    *snapshotId = String::number(++s_lastSnapshotId);
33610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    bool newEntry = m_snapshotById.add(*snapshotId, snapshot).isNewEntry;
33710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    ASSERT_UNUSED(newEntry, newEntry);
33810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch}
33910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch
34010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdochvoid InspectorLayerTreeAgent::loadSnapshot(ErrorString* errorString, const String& data, String* snapshotId)
34110f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch{
34210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    Vector<char> snapshotData;
34310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    if (!base64Decode(data, snapshotData)) {
34410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        *errorString = "Invalid base64 encoding";
34510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        return;
34610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    }
34710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    RefPtr<GraphicsContextSnapshot> snapshot = GraphicsContextSnapshot::load(snapshotData.data(), snapshotData.size());
34810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    if (!snapshot) {
34910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        *errorString = "Invalida snapshot format";
35010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        return;
35110f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    }
35210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    *snapshotId = String::number(++s_lastSnapshotId);
35310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    bool newEntry = m_snapshotById.add(*snapshotId, snapshot).isNewEntry;
354a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    ASSERT_UNUSED(newEntry, newEntry);
355a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)}
356a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
357a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)void InspectorLayerTreeAgent::releaseSnapshot(ErrorString* errorString, const String& snapshotId)
358a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){
359a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    SnapshotById::iterator it = m_snapshotById.find(snapshotId);
360a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if (it == m_snapshotById.end()) {
361a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        *errorString = "Snapshot not found";
362a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return;
363a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    }
364a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    m_snapshotById.remove(it);
365a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)}
366a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
36710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdochconst GraphicsContextSnapshot* InspectorLayerTreeAgent::snapshotById(ErrorString* errorString, const String& snapshotId)
368a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){
369a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    SnapshotById::iterator it = m_snapshotById.find(snapshotId);
370a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if (it == m_snapshotById.end()) {
371a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        *errorString = "Snapshot not found";
372a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return 0;
373a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    }
37410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    return it->value.get();
375a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)}
376a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
377197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid InspectorLayerTreeAgent::replaySnapshot(ErrorString* errorString, const String& snapshotId, const int* fromStep, const int* toStep, const double* scale, String* dataURL)
378a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){
37910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    const GraphicsContextSnapshot* snapshot = snapshotById(errorString, snapshotId);
380a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if (!snapshot)
381a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return;
382197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    OwnPtr<Vector<char> > base64Data = snapshot->replay(fromStep ? *fromStep : 0, toStep ? *toStep : 0, scale ? *scale : 1.0);
383197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (!base64Data) {
384197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        *errorString = "Image encoding failed";
385197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return;
386197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
3877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    StringBuilder url;
3887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    url.appendLiteral("data:image/png;base64,");
3897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    url.reserveCapacity(url.length() + base64Data->size());
3907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    url.append(base64Data->begin(), base64Data->size());
3917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    *dataURL = url.toString();
392a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)}
393a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
394a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)void InspectorLayerTreeAgent::profileSnapshot(ErrorString* errorString, const String& snapshotId, const int* minRepeatCount, const double* minDuration, RefPtr<TypeBuilder::Array<TypeBuilder::Array<double> > >& outTimings)
395a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){
39610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    const GraphicsContextSnapshot* snapshot = snapshotById(errorString, snapshotId);
397a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if (!snapshot)
398a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return;
39910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    OwnPtr<GraphicsContextSnapshot::Timings> timings = snapshot->profile(minRepeatCount ? *minRepeatCount : 1, minDuration ? *minDuration : 0);
400a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    outTimings = TypeBuilder::Array<TypeBuilder::Array<double> >::create();
401a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    for (size_t i = 0; i < timings->size(); ++i) {
402a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        const Vector<double>& row = (*timings)[i];
403a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        RefPtr<TypeBuilder::Array<double> > outRow = TypeBuilder::Array<double>::create();
404197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        for (size_t j = 0; j < row.size(); ++j)
405197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            outRow->addItem(row[j]);
406a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        outTimings->addItem(outRow.release());
407a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    }
408a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)}
409a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
410323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)void InspectorLayerTreeAgent::snapshotCommandLog(ErrorString* errorString, const String& snapshotId, RefPtr<TypeBuilder::Array<JSONObject> >& commandLog)
411323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles){
412323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    const GraphicsContextSnapshot* snapshot = snapshotById(errorString, snapshotId);
413323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (!snapshot)
414323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        return;
415323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    commandLog = TypeBuilder::Array<JSONObject>::runtimeCast(snapshot->snapshotCommandLog());
416323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)}
417323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
418d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void InspectorLayerTreeAgent::willAddPageOverlay(const GraphicsLayer* layer)
419d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
420d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_pageOverlayLayerIds.append(layer->platformLayer()->id());
421d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
422d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
423d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void InspectorLayerTreeAgent::didRemovePageOverlay(const GraphicsLayer* layer)
424d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
425d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    size_t index = m_pageOverlayLayerIds.find(layer->platformLayer()->id());
426d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (index == WTF::kNotFound)
427d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
428d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_pageOverlayLayerIds.remove(index);
429d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
430d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
431d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
432c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
433