summaryrefslogtreecommitdiff
path: root/chromium/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp')
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp191
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