diff options
Diffstat (limited to 'chromium/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp')
-rw-r--r-- | chromium/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp | 191 |
1 files changed, 132 insertions, 59 deletions
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp index 5f92bb00c0a..0c138c15774 100644 --- a/chromium/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp +++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp @@ -33,33 +33,49 @@ #include "core/inspector/InspectorLayerTreeAgent.h" -#include "InspectorFrontend.h" #include "core/inspector/IdentifiersFactory.h" #include "core/inspector/InspectorDOMAgent.h" #include "core/inspector/InspectorState.h" #include "core/inspector/InstrumentingAgents.h" #include "core/loader/DocumentLoader.h" -#include "core/page/Frame.h" +#include "core/frame/Frame.h" #include "core/page/Page.h" -#include "core/platform/graphics/IntRect.h" -#include "core/platform/graphics/transforms/TransformationMatrix.h" -#include "core/rendering/RenderLayer.h" -#include "core/rendering/RenderLayerBacking.h" +#include "core/rendering/CompositedLayerMapping.h" #include "core/rendering/RenderLayerCompositor.h" #include "core/rendering/RenderView.h" +#include "platform/geometry/IntRect.h" +#include "platform/graphics/GraphicsContextRecorder.h" +#include "platform/transforms/TransformationMatrix.h" #include "public/platform/WebCompositingReasons.h" #include "public/platform/WebLayer.h" namespace WebCore { -namespace LayerTreeAgentState { -static const char layerTreeAgentEnabled[] = "layerTreeAgentEnabled"; +unsigned InspectorLayerTreeAgent::s_lastSnapshotId; + +struct LayerSnapshot { + LayerSnapshot() + : layerId(0) + { + } + LayerSnapshot(int layerId, PassRefPtr<GraphicsContextSnapshot> graphicsSnapshot) + : layerId(layerId) + , graphicsSnapshot(graphicsSnapshot) + { + } + int layerId; + RefPtr<GraphicsContextSnapshot> graphicsSnapshot; }; +inline String idForLayer(const GraphicsLayer* graphicsLayer) +{ + return String::number(graphicsLayer->platformLayer()->id()); +} + static PassRefPtr<TypeBuilder::LayerTree::Layer> buildObjectForLayer(GraphicsLayer* graphicsLayer, int nodeId) { RefPtr<TypeBuilder::LayerTree::Layer> layerObject = TypeBuilder::LayerTree::Layer::create() - .setLayerId(String::number(graphicsLayer->platformLayer()->id())) + .setLayerId(idForLayer(graphicsLayer)) .setOffsetX(graphicsLayer->position().x()) .setOffsetY(graphicsLayer->position().y()) .setWidth(graphicsLayer->size().width()) @@ -73,7 +89,7 @@ static PassRefPtr<TypeBuilder::LayerTree::Layer> buildObjectForLayer(GraphicsLay if (!parent) parent = graphicsLayer->replicatedLayer(); if (parent) - layerObject->setParentLayerId(String::number(parent->platformLayer()->id())); + layerObject->setParentLayerId(idForLayer(parent)); if (!graphicsLayer->contentsAreVisible()) layerObject->setInvisible(true); const TransformationMatrix& transform = graphicsLayer->transform(); @@ -127,87 +143,80 @@ void InspectorLayerTreeAgent::clearFrontend() void InspectorLayerTreeAgent::restore() { - if (m_state->getBoolean(LayerTreeAgentState::layerTreeAgentEnabled)) - enable(0); + // We do not re-enable layer agent automatically after navigation. This is because + // it depends on DOMAgent and node ids in particular, so we let front-end request document + // and re-enable the agent manually after this. } void InspectorLayerTreeAgent::enable(ErrorString*) { - m_state->setBoolean(LayerTreeAgentState::layerTreeAgentEnabled, true); m_instrumentingAgents->setInspectorLayerTreeAgent(this); + layerTreeDidChange(); } void InspectorLayerTreeAgent::disable(ErrorString*) { - if (!m_state->getBoolean(LayerTreeAgentState::layerTreeAgentEnabled)) - return; - m_state->setBoolean(LayerTreeAgentState::layerTreeAgentEnabled, false); m_instrumentingAgents->setInspectorLayerTreeAgent(0); + m_snapshotById.clear(); } void InspectorLayerTreeAgent::layerTreeDidChange() { - m_frontend->layerTreeDidChange(); + m_frontend->layerTreeDidChange(buildLayerTree()); } -void InspectorLayerTreeAgent::getLayers(ErrorString* errorString, const int* nodeId, RefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::Layer> >& layers) +void InspectorLayerTreeAgent::didPaint(RenderObject*, const GraphicsLayer* graphicsLayer, GraphicsContext*, const LayoutRect& rect) { - LayerIdToNodeIdMap layerIdToNodeIdMap; - layers = TypeBuilder::Array<TypeBuilder::LayerTree::Layer>::create(); + // Should only happen for FrameView paints when compositing is off. Consider different instrumentation method for that. + if (!graphicsLayer) + return; + RefPtr<TypeBuilder::DOM::Rect> domRect = TypeBuilder::DOM::Rect::create() + .setX(rect.x()) + .setY(rect.y()) + .setWidth(rect.width()) + .setHeight(rect.height()); + m_frontend->layerPainted(idForLayer(graphicsLayer), domRect.release()); +} + +PassRefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::Layer> > InspectorLayerTreeAgent::buildLayerTree() +{ RenderLayerCompositor* compositor = renderLayerCompositor(); - if (!compositor || !compositor->inCompositingMode()) { - *errorString = "Not in the compositing mode"; - return; - } - if (!nodeId) { - buildLayerIdToNodeIdMap(errorString, compositor->rootRenderLayer(), layerIdToNodeIdMap); - gatherGraphicsLayers(compositor->rootGraphicsLayer(), layerIdToNodeIdMap, layers); - return; - } - Node* node = m_instrumentingAgents->inspectorDOMAgent()->nodeForId(*nodeId); - if (!node) { - *errorString = "Provided node id doesn't match any known node"; - return; - } - RenderObject* renderer = node->renderer(); - if (!renderer) { - *errorString = "Node for provided node id doesn't have a renderer"; - return; - } - RenderLayer* enclosingLayer = renderer->enclosingLayer(); - GraphicsLayer* enclosingGraphicsLayer = enclosingLayer->enclosingCompositingLayer()->backing()->childForSuperlayers(); - buildLayerIdToNodeIdMap(errorString, enclosingLayer, layerIdToNodeIdMap); - gatherGraphicsLayers(enclosingGraphicsLayer, layerIdToNodeIdMap, layers); + if (!compositor || !compositor->inCompositingMode()) + return 0; + LayerIdToNodeIdMap layerIdToNodeIdMap; + RefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::Layer> > layers = TypeBuilder::Array<TypeBuilder::LayerTree::Layer>::create(); + buildLayerIdToNodeIdMap(compositor->rootRenderLayer(), layerIdToNodeIdMap); + gatherGraphicsLayers(compositor->rootGraphicsLayer(), layerIdToNodeIdMap, layers); + return layers.release(); } -void InspectorLayerTreeAgent::buildLayerIdToNodeIdMap(ErrorString* errorString, RenderLayer* root, LayerIdToNodeIdMap& layerIdToNodeIdMap) +void InspectorLayerTreeAgent::buildLayerIdToNodeIdMap(RenderLayer* root, LayerIdToNodeIdMap& layerIdToNodeIdMap) { - if (root->isComposited()) { + if (root->hasCompositedLayerMapping()) { if (Node* node = root->renderer()->generatingNode()) { - GraphicsLayer* graphicsLayer = root->backing()->childForSuperlayers(); - layerIdToNodeIdMap.set(graphicsLayer->platformLayer()->id(), idForNode(errorString, node)); + GraphicsLayer* graphicsLayer = root->compositedLayerMapping()->childForSuperlayers(); + layerIdToNodeIdMap.set(graphicsLayer->platformLayer()->id(), idForNode(node)); } } for (RenderLayer* child = root->firstChild(); child; child = child->nextSibling()) - buildLayerIdToNodeIdMap(errorString, child, layerIdToNodeIdMap); + buildLayerIdToNodeIdMap(child, layerIdToNodeIdMap); if (!root->renderer()->isRenderIFrame()) return; FrameView* childFrameView = toFrameView(toRenderWidget(root->renderer())->widget()); if (RenderView* childRenderView = childFrameView->renderView()) { if (RenderLayerCompositor* childCompositor = childRenderView->compositor()) - buildLayerIdToNodeIdMap(errorString, childCompositor->rootRenderLayer(), layerIdToNodeIdMap); + buildLayerIdToNodeIdMap(childCompositor->rootRenderLayer(), layerIdToNodeIdMap); } } -int InspectorLayerTreeAgent::idForNode(ErrorString* errorString, Node* node) +int InspectorLayerTreeAgent::idForNode(Node* node) { - InspectorDOMAgent* domAgent = m_instrumentingAgents->inspectorDOMAgent(); - - int nodeId = domAgent->boundNodeId(node); - if (!nodeId) - nodeId = domAgent->pushNodeToFrontend(errorString, domAgent->boundNodeId(&node->document()), node); - + int nodeId = m_domAgent->boundNodeId(node); + if (!nodeId) { + ErrorString ignoredError; + nodeId = m_domAgent->pushNodeToFrontend(&ignoredError, m_domAgent->boundNodeId(&node->document()), node); + } return nodeId; } @@ -242,8 +251,10 @@ GraphicsLayer* InspectorLayerTreeAgent::layerById(ErrorString* errorString, cons return 0; } RenderLayerCompositor* compositor = renderLayerCompositor(); - if (!compositor) + if (!compositor) { + *errorString = "Not in compositing mode"; return 0; + } GraphicsLayer* result = findLayerById(compositor->rootGraphicsLayer(), id); if (!result) @@ -290,13 +301,14 @@ void InspectorLayerTreeAgent::compositingReasons(ErrorString* errorString, const { CompositingReasonLayerForForeground, "layerForForeground" }, { CompositingReasonLayerForBackground, "layerForBackground" }, { CompositingReasonLayerForMask, "layerForMask" }, - { CompositingReasonLayerForVideoOverlay, "layerForVideoOverlay" } + { CompositingReasonLayerForVideoOverlay, "layerForVideoOverlay" }, + { CompositingReasonIsolateCompositedDescendants, "isolateCompositedDescendants" } }; const GraphicsLayer* graphicsLayer = layerById(errorString, layerId); if (!graphicsLayer) return; - WebKit::WebCompositingReasons reasonsBitmask = graphicsLayer->compositingReasons(); + blink::WebCompositingReasons reasonsBitmask = graphicsLayer->compositingReasons(); reasonStrings = TypeBuilder::Array<String>::create(); for (size_t i = 0; i < WTF_ARRAY_LENGTH(compositingReasonNames); ++i) { if (!(reasonsBitmask & compositingReasonNames[i].mask)) @@ -309,4 +321,65 @@ void InspectorLayerTreeAgent::compositingReasons(ErrorString* errorString, const ASSERT(!reasonsBitmask); } +void InspectorLayerTreeAgent::makeSnapshot(ErrorString* errorString, const String& layerId, String* snapshotId) +{ + GraphicsLayer* layer = layerById(errorString, layerId); + if (!layer) + return; + + GraphicsContextRecorder recorder; + IntSize size = expandedIntSize(layer->size()); + GraphicsContext* context = recorder.record(size, layer->contentsOpaque()); + layer->paint(*context, IntRect(IntPoint(0, 0), size)); + RefPtr<GraphicsContextSnapshot> snapshot = recorder.stop(); + *snapshotId = String::number(++s_lastSnapshotId); + bool newEntry = m_snapshotById.add(*snapshotId, LayerSnapshot(layer->platformLayer()->id(), snapshot)).isNewEntry; + ASSERT_UNUSED(newEntry, newEntry); +} + +void InspectorLayerTreeAgent::releaseSnapshot(ErrorString* errorString, const String& snapshotId) +{ + SnapshotById::iterator it = m_snapshotById.find(snapshotId); + if (it == m_snapshotById.end()) { + *errorString = "Snapshot not found"; + return; + } + m_snapshotById.remove(it); +} + +const LayerSnapshot* InspectorLayerTreeAgent::snapshotById(ErrorString* errorString, const String& snapshotId) +{ + SnapshotById::iterator it = m_snapshotById.find(snapshotId); + if (it == m_snapshotById.end()) { + *errorString = "Snapshot not found"; + return 0; + } + return &it->value; +} + +void InspectorLayerTreeAgent::replaySnapshot(ErrorString* errorString, const String& snapshotId, const int* fromStep, const int* toStep, String* dataURL) +{ + const LayerSnapshot* snapshot = snapshotById(errorString, snapshotId); + if (!snapshot) + return; + OwnPtr<ImageBuffer> imageBuffer = snapshot->graphicsSnapshot->replay(fromStep ? *fromStep : 0, toStep ? *toStep : 0); + *dataURL = imageBuffer->toDataURL("image/png"); +} + +void InspectorLayerTreeAgent::profileSnapshot(ErrorString* errorString, const String& snapshotId, const int* minRepeatCount, const double* minDuration, RefPtr<TypeBuilder::Array<TypeBuilder::Array<double> > >& outTimings) +{ + const LayerSnapshot* snapshot = snapshotById(errorString, snapshotId); + if (!snapshot) + return; + OwnPtr<GraphicsContextSnapshot::Timings> timings = snapshot->graphicsSnapshot->profile(minRepeatCount ? *minRepeatCount : 1, minDuration ? *minDuration : 0); + outTimings = TypeBuilder::Array<TypeBuilder::Array<double> >::create(); + for (size_t i = 0; i < timings->size(); ++i) { + const Vector<double>& row = (*timings)[i]; + RefPtr<TypeBuilder::Array<double> > outRow = TypeBuilder::Array<double>::create(); + for (size_t j = 1; j < row.size(); ++j) + outRow->addItem(row[j] - row[j - 1]); + outTimings->addItem(outRow.release()); + } +} + } // namespace WebCore |