Commit 366f094b authored by caseq@chromium.org's avatar caseq@chromium.org

DevTools: added support for image url & node in tracing-based timeline

- add trace event for RenderImage::paintIntoRect;
- fix name of decode & resize image events for tracing vs. old timeline;
- add processing of decode/resize/paint/imageref events to TimelineTraceEventBindings;
- generalize handling of additional event properties when building details, so that
    we avoid extra switches over event type by extracting properties relevant for
    details into TraceEvent properties;
- temporary workaround for crash on record stop in tests by cloning an AtomicString
    (see crbug.com/375242 for more details).

BUG=361045,375242

Review URL: https://codereview.chromium.org/308123008

git-svn-id: svn://svn.chromium.org/blink/trunk@175284 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 273dca96
Tests the instrumentation of a DecodeImage and ResizeImage events
event: Decode Image
imageURL: .../inspector/timeline/resources/test.bmp
backendNodeId: present
event: Decode Image
imageURL: .../inspector/timeline/resources/test.gif
backendNodeId: present
event: Decode Image
imageURL: .../inspector/timeline/resources/test.ico
backendNodeId: present
event: Decode Image
imageURL: .../inspector/timeline/resources/test.jpg
backendNodeId: present
event: Decode Image
imageURL: .../inspector/timeline/resources/test.png
backendNodeId: present
event: Decode Image
imageURL: .../inspector/timeline/resources/test.webp
backendNodeId: present
event: Decode Image
imageURL: .../inspector/timeline/resources/big.png
backendNodeId: present
<html>
<head>
<style>
div#img-container {
position: relative;
width: 99px;
height: 99px;
overflow: clip;
}
</style>
<script src="../../../http/tests/inspector/inspector-test.js"></script>
<script src="../../../http/tests/inspector/timeline-test.js"></script>
<script src="../../tracing-test.js"></script>
<script>
var images = [
["../resources/test.bmp", "25", "25"],
["../resources/test.gif", "25", "25"],
["../resources/test.ico", "25", "25"],
["../resources/test.jpg", "25", "25"],
["../resources/test.png", "25", "25"],
["../resources/test.webp", "25", "25"],
["../resources/big.png", "150", "150"]
];
function showImages(callback)
{
var nextImageIndex = 0;
var imgElement = document.getElementById("img-container").firstElementChild;
imgElement.addEventListener("load", imageLoaded);
addImages();
function addImages()
{
if (nextImageIndex >= images.length) {
imgElement.removeEventListener("load", imageLoaded);
callback();
return;
}
var image = images[nextImageIndex++];
imgElement.width = image[1];
imgElement.height = image[2];
imgElement.src = image[0];
}
function imageLoaded()
{
requestAnimationFrame(function() { testRunner.displayAsyncThen(addImages); } );
}
}
function test()
{
var imageCount = 0;
InspectorTest.invokeWithTracing("-*,devtools,disabled-by-default-devtools.timeline*", "showImages", onTracingComplete);
function onTracingComplete()
{
var traceEventBindings = new WebInspector.TimelineTraceEventBindings();
var events = InspectorTest.tracingModel.inspectedTargetEvents();
traceEventBindings.setEvents(events);
for (var i = 0; i < events.length; ++i) {
var event = events[i];
if (events[i].name !== WebInspector.TimelineTraceEventBindings.RecordType.DecodeImage)
continue;
InspectorTest.addResult("event: " + event.name);
InspectorTest.addResult("imageURL: " + InspectorTest.formatters.formatAsURL(event.imageURL));
InspectorTest.addResult("backendNodeId: " + (event.backendNodeId > 0 ? "present" : "absent"));
}
InspectorTest.completeTest();
}
}
</script>
</head>
<body onload="runTest()">
<p>
Tests the instrumentation of a DecodeImage and ResizeImage events
</p>
<div id="img-container"><img></div>
</body>
</html>
...@@ -11,12 +11,12 @@ InspectorTest.invokeWithTracing = function(categoryFilter, functionName, callbac ...@@ -11,12 +11,12 @@ InspectorTest.invokeWithTracing = function(categoryFilter, functionName, callbac
function onTracingStarted(error) function onTracingStarted(error)
{ {
InspectorTest.invokePageFunctionAsync(functionName, onPageActionsDone) InspectorTest.invokePageFunctionAsync(functionName, onPageActionsDone);
} }
function onPageActionsDone() function onPageActionsDone()
{ {
InspectorTest.tracingModel.stop(callback); InspectorTest.tracingModel.stop(InspectorTest.safeWrap(callback));
} }
} }
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "core/inspector/InspectorNodeIds.h" #include "core/inspector/InspectorNodeIds.h"
#include "core/inspector/ScriptCallStack.h" #include "core/inspector/ScriptCallStack.h"
#include "core/page/Page.h" #include "core/page/Page.h"
#include "core/rendering/RenderImage.h"
#include "core/rendering/RenderObject.h" #include "core/rendering/RenderObject.h"
#include "core/xml/XMLHttpRequest.h" #include "core/xml/XMLHttpRequest.h"
#include "platform/JSONValues.h" #include "platform/JSONValues.h"
...@@ -116,7 +117,7 @@ PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorReceiveResponseEvent:: ...@@ -116,7 +117,7 @@ PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorReceiveResponseEvent::
data->setString("requestId", requestId); data->setString("requestId", requestId);
data->setString("frame", toHexString(frame)); data->setString("frame", toHexString(frame));
data->setNumber("statusCode", response.httpStatusCode()); data->setNumber("statusCode", response.httpStatusCode());
data->setString("mimeType", response.mimeType()); data->setString("mimeType", response.mimeType().string().isolatedCopy());
return TracedValue::fromJSONValue(data); return TracedValue::fromJSONValue(data);
} }
...@@ -295,6 +296,17 @@ PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorFunctionCallEvent::dat ...@@ -295,6 +296,17 @@ PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorFunctionCallEvent::dat
return TracedValue::fromJSONValue(data); return TracedValue::fromJSONValue(data);
} }
PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorPaintImageEvent::data(const RenderImage& renderImage)
{
RefPtr<JSONObject> data = JSONObject::create();
data->setNumber("nodeId", InspectorNodeIds::idForNode(renderImage.generatingNode()));
if (const ImageResource* resource = renderImage.cachedImage())
data->setString("url", resource->url().string());
return TracedValue::fromJSONValue(data);
}
static size_t usedHeapSize() static size_t usedHeapSize()
{ {
HeapInfo info; HeapInfo info;
......
...@@ -20,6 +20,7 @@ class KURL; ...@@ -20,6 +20,7 @@ class KURL;
class LayoutRect; class LayoutRect;
class LocalFrame; class LocalFrame;
class RenderObject; class RenderObject;
class RenderImage;
class ResourceRequest; class ResourceRequest;
class ResourceResponse; class ResourceResponse;
class ScriptSourceCode; class ScriptSourceCode;
...@@ -102,6 +103,11 @@ public: ...@@ -102,6 +103,11 @@ public:
static PassRefPtr<TraceEvent::ConvertableToTraceFormat> data(RenderObject*, const LayoutRect& clipRect, const GraphicsLayer*); static PassRefPtr<TraceEvent::ConvertableToTraceFormat> data(RenderObject*, const LayoutRect& clipRect, const GraphicsLayer*);
}; };
class InspectorPaintImageEvent {
public:
static PassRefPtr<TraceEvent::ConvertableToTraceFormat> data(const RenderImage&);
};
class InspectorMarkLoadEvent { class InspectorMarkLoadEvent {
public: public:
static PassRefPtr<TraceEvent::ConvertableToTraceFormat> data(LocalFrame*); static PassRefPtr<TraceEvent::ConvertableToTraceFormat> data(LocalFrame*);
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "core/html/HTMLInputElement.h" #include "core/html/HTMLInputElement.h"
#include "core/html/HTMLMapElement.h" #include "core/html/HTMLMapElement.h"
#include "core/inspector/InspectorInstrumentation.h" #include "core/inspector/InspectorInstrumentation.h"
#include "core/inspector/InspectorTraceEvents.h"
#include "core/rendering/HitTestResult.h" #include "core/rendering/HitTestResult.h"
#include "core/rendering/PaintInfo.h" #include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderView.h" #include "core/rendering/RenderView.h"
...@@ -455,6 +456,8 @@ void RenderImage::paintIntoRect(GraphicsContext* context, const LayoutRect& rect ...@@ -455,6 +456,8 @@ void RenderImage::paintIntoRect(GraphicsContext* context, const LayoutRect& rect
Image* image = m_imageResource->image().get(); Image* image = m_imageResource->image().get();
InterpolationQuality interpolationQuality = chooseInterpolationQuality(context, image, image, alignedRect.size()); InterpolationQuality interpolationQuality = chooseInterpolationQuality(context, image, image, alignedRect.size());
TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage", "data", InspectorPaintImageEvent::data(*this));
// FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentation::willPaintImage(this); InspectorInstrumentation::willPaintImage(this);
InterpolationQuality previousInterpolationQuality = context->imageInterpolationQuality(); InterpolationQuality previousInterpolationQuality = context->imageInterpolationQuality();
context->setImageInterpolationQuality(interpolationQuality); context->setImageInterpolationQuality(interpolationQuality);
......
...@@ -28,11 +28,10 @@ WebInspector.TimelineTraceEventBindings.RecordType = { ...@@ -28,11 +28,10 @@ WebInspector.TimelineTraceEventBindings.RecordType = {
UpdateLayerTree: "UpdateLayerTree", UpdateLayerTree: "UpdateLayerTree",
PaintSetup: "PaintSetup", PaintSetup: "PaintSetup",
Paint: "Paint", Paint: "Paint",
PaintImage: "PaintImage",
Rasterize: "Rasterize", Rasterize: "Rasterize",
RasterTask: "RasterTask", RasterTask: "RasterTask",
ScrollLayer: "ScrollLayer", ScrollLayer: "ScrollLayer",
DecodeImage: "DecodeImage",
ResizeImage: "ResizeImage",
CompositeLayers: "CompositeLayers", CompositeLayers: "CompositeLayers",
ParseHTML: "ParseHTML", ParseHTML: "ParseHTML",
...@@ -78,6 +77,12 @@ WebInspector.TimelineTraceEventBindings.RecordType = { ...@@ -78,6 +77,12 @@ WebInspector.TimelineTraceEventBindings.RecordType = {
SetLayerTreeId: "SetLayerTreeId", SetLayerTreeId: "SetLayerTreeId",
TracingStartedInPage: "TracingStartedInPage", TracingStartedInPage: "TracingStartedInPage",
DecodeImage: "Decode Image",
ResizeImage: "Resize Image",
DrawLazyPixelRef: "Draw LazyPixelRef",
DecodeLazyPixelRef: "Decode LazyPixelRef",
LazyPixelRef: "LazyPixelRef",
LayerTreeHostImplSnapshot: "cc::LayerTreeHostImpl" LayerTreeHostImplSnapshot: "cc::LayerTreeHostImpl"
}; };
...@@ -105,6 +110,7 @@ WebInspector.TimelineTraceEventBindings.prototype = { ...@@ -105,6 +110,7 @@ WebInspector.TimelineTraceEventBindings.prototype = {
this._layoutInvalidate = {}; this._layoutInvalidate = {};
this._lastScheduleStyleRecalculation = {}; this._lastScheduleStyleRecalculation = {};
this._webSocketCreateEvents = {}; this._webSocketCreateEvents = {};
this._paintImageEventByPixelRefId = {};
this._lastRecalculateStylesEvent = null; this._lastRecalculateStylesEvent = null;
this._currentScriptEvent = null; this._currentScriptEvent = null;
...@@ -154,12 +160,15 @@ WebInspector.TimelineTraceEventBindings.prototype = { ...@@ -154,12 +160,15 @@ WebInspector.TimelineTraceEventBindings.prototype = {
case recordTypes.ResourceSendRequest: case recordTypes.ResourceSendRequest:
this._sendRequestEvents[event.args.data["requestId"]] = event; this._sendRequestEvents[event.args.data["requestId"]] = event;
event.imageURL = event.args.data["url"];
break; break;
case recordTypes.ResourceReceiveResponse: case recordTypes.ResourceReceiveResponse:
case recordTypes.ResourceReceivedData: case recordTypes.ResourceReceivedData:
case recordTypes.ResourceFinish: case recordTypes.ResourceFinish:
event.initiator = this._sendRequestEvents[event.args.data["requestId"]]; event.initiator = this._sendRequestEvents[event.args.data["requestId"]];
if (event.initiator)
event.imageURL = event.initiator.imageURL;
break; break;
case recordTypes.TimerInstall: case recordTypes.TimerInstall:
...@@ -200,6 +209,7 @@ WebInspector.TimelineTraceEventBindings.prototype = { ...@@ -200,6 +209,7 @@ WebInspector.TimelineTraceEventBindings.prototype = {
case recordTypes.Layout: case recordTypes.Layout:
var frameId = event.args["beginData"]["frame"]; var frameId = event.args["beginData"]["frame"];
event.initiator = this._layoutInvalidate[frameId]; event.initiator = this._layoutInvalidate[frameId];
event.backendNodeId = event.args["endData"]["rootNode"];
this._layoutInvalidate[frameId] = null; this._layoutInvalidate[frameId] = null;
if (this._currentScriptEvent) if (this._currentScriptEvent)
event.warning = WebInspector.UIString("Forced synchronous layout is a possible performance bottleneck."); event.warning = WebInspector.UIString("Forced synchronous layout is a possible performance bottleneck.");
...@@ -228,9 +238,55 @@ WebInspector.TimelineTraceEventBindings.prototype = { ...@@ -228,9 +238,55 @@ WebInspector.TimelineTraceEventBindings.prototype = {
case recordTypes.TracingStartedInPage: case recordTypes.TracingStartedInPage:
this._mainThread = event.thread; this._mainThread = event.thread;
break; break;
case recordTypes.Paint:
case recordTypes.ScrollLayer:
event.backendNodeId = event.args["data"]["nodeId"];
break;
case recordTypes.PaintImage:
event.backendNodeId = event.args["data"]["nodeId"];
event.imageURL = event.args["data"]["url"];
break;
case recordTypes.DecodeImage:
case recordTypes.ResizeImage:
var paintImageEvent = this._findAncestorEvent(recordTypes.PaintImage);
if (!paintImageEvent) {
var decodeLazyPixelRefEvent = this._findAncestorEvent(recordTypes.DecodeLazyPixelRef);
paintImageEvent = decodeLazyPixelRefEvent && this._paintImageEventByPixelRefId[decodeLazyPixelRefEvent.args["LazyPixelRef"]];
}
if (!paintImageEvent)
break;
event.backendNodeId = paintImageEvent.backendNodeId;
event.imageURL = paintImageEvent.imageURL;
break;
case recordTypes.DrawLazyPixelRef:
var paintImageEvent = this._findAncestorEvent(recordTypes.PaintImage);
if (!paintImageEvent)
break;
this._paintImageEventByPixelRefId[event.args["LazyPixelRef"]] = paintImageEvent;
event.backendNodeId = paintImageEvent.backendNodeId;
event.imageURL = paintImageEvent.imageURL;
break;
} }
if (this._mainThread === event.thread) if (this._mainThread === event.thread)
this._mainThreadEvents.push(event); this._mainThreadEvents.push(event);
},
/**
* @param {string} name
* @return {?WebInspector.TracingModel.Event}
*/
_findAncestorEvent: function(name)
{
for (var i = this._eventStack.length - 1; i >= 0; --i) {
var event = this._eventStack[i];
if (event.name === name)
return event;
}
return null;
} }
} }
...@@ -678,29 +678,12 @@ WebInspector.TimelineUIUtils._quadWidth = function(quad) ...@@ -678,29 +678,12 @@ WebInspector.TimelineUIUtils._quadWidth = function(quad)
*/ */
WebInspector.TimelineUIUtils.buildTraceEventDetails = function(event, model, linkifier, callback, loadedFromFile, bindings, target) WebInspector.TimelineUIUtils.buildTraceEventDetails = function(event, model, linkifier, callback, loadedFromFile, bindings, target)
{ {
var imageElement = event.previewElement;
var relatedNode = null; var relatedNode = null;
var eventData = event.args.data;
var barrier = new CallbackBarrier(); var barrier = new CallbackBarrier();
if (!imageElement && WebInspector.TimelineUIUtils.needsPreviewElement(event.name)) if (event.imageURL && !event.previewElement)
WebInspector.DOMPresentationUtils.buildImagePreviewContents(target, eventData["url"], false, barrier.createCallback(saveImage)); WebInspector.DOMPresentationUtils.buildImagePreviewContents(target, event.imageURL, false, barrier.createCallback(saveImage));
var backendNodeId; if (event.backendNodeId)
var recordTypes = WebInspector.TimelineModel.RecordType; target.domModel.pushNodesByBackendIdsToFrontend([event.backendNodeId], barrier.createCallback(setRelatedNode));
switch (event.name) {
case recordTypes.Layout:
backendNodeId = event.args["endData"]["rootNode"];
break;
case recordTypes.Paint:
case recordTypes.ScrollLayer:
backendNodeId = eventData["nodeId"];
break;
case recordTypes.DecodeImage:
case recordTypes.ResizeImage:
// FIXME: provide node id.
break;
}
if (backendNodeId)
target.domModel.pushNodesByBackendIdsToFrontend([backendNodeId], barrier.createCallback(setRelatedNode));
barrier.callWhenDone(callbackWrapper); barrier.callWhenDone(callbackWrapper);
/** /**
...@@ -708,8 +691,7 @@ WebInspector.TimelineUIUtils.buildTraceEventDetails = function(event, model, lin ...@@ -708,8 +691,7 @@ WebInspector.TimelineUIUtils.buildTraceEventDetails = function(event, model, lin
*/ */
function saveImage(element) function saveImage(element)
{ {
imageElement = element || null; event.previewElement = element || null;
event.previewElement = imageElement;
} }
/** /**
...@@ -723,7 +705,7 @@ WebInspector.TimelineUIUtils.buildTraceEventDetails = function(event, model, lin ...@@ -723,7 +705,7 @@ WebInspector.TimelineUIUtils.buildTraceEventDetails = function(event, model, lin
function callbackWrapper() function callbackWrapper()
{ {
callback(WebInspector.TimelineUIUtils._buildTraceEventDetailsSynchronously(event, model, linkifier, imageElement, relatedNode, loadedFromFile, bindings, target)); callback(WebInspector.TimelineUIUtils._buildTraceEventDetailsSynchronously(event, model, linkifier, relatedNode, loadedFromFile, bindings, target));
} }
} }
...@@ -731,14 +713,13 @@ WebInspector.TimelineUIUtils.buildTraceEventDetails = function(event, model, lin ...@@ -731,14 +713,13 @@ WebInspector.TimelineUIUtils.buildTraceEventDetails = function(event, model, lin
* @param {!WebInspector.TracingModel.Event} event * @param {!WebInspector.TracingModel.Event} event
* @param {!WebInspector.TracingModel} model * @param {!WebInspector.TracingModel} model
* @param {!WebInspector.Linkifier} linkifier * @param {!WebInspector.Linkifier} linkifier
* @param {?Element} imagePreviewElement
* @param {?WebInspector.DOMNode} relatedNode * @param {?WebInspector.DOMNode} relatedNode
* @param {boolean} loadedFromFile * @param {boolean} loadedFromFile
* @param {?WebInspector.TimelineTraceEventBindings} bindings * @param {?WebInspector.TimelineTraceEventBindings} bindings
* @param {!WebInspector.Target} target * @param {!WebInspector.Target} target
* @return {!DocumentFragment} * @return {!DocumentFragment}
*/ */
WebInspector.TimelineUIUtils._buildTraceEventDetailsSynchronously = function(event, model, linkifier, imagePreviewElement, relatedNode, loadedFromFile, bindings, target) WebInspector.TimelineUIUtils._buildTraceEventDetailsSynchronously = function(event, model, linkifier, relatedNode, loadedFromFile, bindings, target)
{ {
var fragment = document.createDocumentFragment(); var fragment = document.createDocumentFragment();
var stats = WebInspector.TimelineUIUtils._aggregatedStatsForTraceEvent(model, event); var stats = WebInspector.TimelineUIUtils._aggregatedStatsForTraceEvent(model, event);
...@@ -747,7 +728,7 @@ WebInspector.TimelineUIUtils._buildTraceEventDetailsSynchronously = function(eve ...@@ -747,7 +728,7 @@ WebInspector.TimelineUIUtils._buildTraceEventDetailsSynchronously = function(eve
WebInspector.TimelineUIUtils.generatePieChart(stats.aggregatedStats); WebInspector.TimelineUIUtils.generatePieChart(stats.aggregatedStats);
fragment.appendChild(pieChart); fragment.appendChild(pieChart);
var recordTypes = WebInspector.TimelineModel.RecordType; var recordTypes = WebInspector.TimelineTraceEventBindings.RecordType;
// The messages may vary per event.name; // The messages may vary per event.name;
var callSiteStackTraceLabel; var callSiteStackTraceLabel;
...@@ -761,110 +742,114 @@ WebInspector.TimelineUIUtils._buildTraceEventDetailsSynchronously = function(eve ...@@ -761,110 +742,114 @@ WebInspector.TimelineUIUtils._buildTraceEventDetailsSynchronously = function(eve
var initiator = event.initiator; var initiator = event.initiator;
switch (event.name) { switch (event.name) {
case recordTypes.GCEvent: case recordTypes.GCEvent:
var delta = event.args["usedHeapSizeBefore"] - event.args["usedHeapSizeAfter"]; var delta = event.args["usedHeapSizeBefore"] - event.args["usedHeapSizeAfter"];
contentHelper.appendTextRow(WebInspector.UIString("Collected"), Number.bytesToString(delta)); contentHelper.appendTextRow(WebInspector.UIString("Collected"), Number.bytesToString(delta));
break; break;
case recordTypes.TimerFire: case recordTypes.TimerFire:
callSiteStackTraceLabel = WebInspector.UIString("Timer installed"); callSiteStackTraceLabel = WebInspector.UIString("Timer installed");
// Fall-through intended. // Fall-through intended.
case recordTypes.TimerInstall: case recordTypes.TimerInstall:
case recordTypes.TimerRemove: case recordTypes.TimerRemove:
contentHelper.appendTextRow(WebInspector.UIString("Timer ID"), eventData["timerId"]); contentHelper.appendTextRow(WebInspector.UIString("Timer ID"), eventData["timerId"]);
if (event.name === recordTypes.TimerInstall) { if (event.name === recordTypes.TimerInstall) {
contentHelper.appendTextRow(WebInspector.UIString("Timeout"), Number.millisToString(eventData["timeout"])); contentHelper.appendTextRow(WebInspector.UIString("Timeout"), Number.millisToString(eventData["timeout"]));
contentHelper.appendTextRow(WebInspector.UIString("Repeats"), !eventData["singleShot"]); contentHelper.appendTextRow(WebInspector.UIString("Repeats"), !eventData["singleShot"]);
} }
break; break;
case recordTypes.FireAnimationFrame: case recordTypes.FireAnimationFrame:
callSiteStackTraceLabel = WebInspector.UIString("Animation frame requested"); callSiteStackTraceLabel = WebInspector.UIString("Animation frame requested");
contentHelper.appendTextRow(WebInspector.UIString("Callback ID"), eventData["id"]); contentHelper.appendTextRow(WebInspector.UIString("Callback ID"), eventData["id"]);
break; break;
case recordTypes.FunctionCall: case recordTypes.FunctionCall:
if (eventData["scriptName"]) if (eventData["scriptName"])
contentHelper.appendLocationRow(WebInspector.UIString("Location"), eventData["scriptName"], eventData["scriptLine"]); contentHelper.appendLocationRow(WebInspector.UIString("Location"), eventData["scriptName"], eventData["scriptLine"]);
break; break;
case recordTypes.ResourceSendRequest: case recordTypes.ResourceSendRequest:
case recordTypes.ResourceReceiveResponse: case recordTypes.ResourceReceiveResponse:
case recordTypes.ResourceReceivedData: case recordTypes.ResourceReceivedData:
case recordTypes.ResourceFinish: case recordTypes.ResourceFinish:
var url = (event.name === recordTypes.ResourceSendRequest) ? eventData["url"] : initiator.args.data["url"]; var url = (event.name === recordTypes.ResourceSendRequest) ? eventData["url"] : initiator.args.data["url"];
if (url) if (url)
contentHelper.appendElementRow(WebInspector.UIString("Resource"), WebInspector.linkifyResourceAsNode(url)); contentHelper.appendElementRow(WebInspector.UIString("Resource"), WebInspector.linkifyResourceAsNode(url));
if (imagePreviewElement) if (event.previewElement)
contentHelper.appendElementRow(WebInspector.UIString("Preview"), imagePreviewElement); contentHelper.appendElementRow(WebInspector.UIString("Preview"), event.previewElement);
if (eventData["requestMethod"]) if (eventData["requestMethod"])
contentHelper.appendTextRow(WebInspector.UIString("Request Method"), eventData["requestMethod"]); contentHelper.appendTextRow(WebInspector.UIString("Request Method"), eventData["requestMethod"]);
if (typeof eventData["statusCode"] === "number") if (typeof eventData["statusCode"] === "number")
contentHelper.appendTextRow(WebInspector.UIString("Status Code"), eventData["statusCode"]); contentHelper.appendTextRow(WebInspector.UIString("Status Code"), eventData["statusCode"]);
if (eventData["mimeType"]) if (eventData["mimeType"])
contentHelper.appendTextRow(WebInspector.UIString("MIME Type"), eventData["mimeType"]); contentHelper.appendTextRow(WebInspector.UIString("MIME Type"), eventData["mimeType"]);
if (eventData["encodedDataLength"]) if (eventData["encodedDataLength"])
contentHelper.appendTextRow(WebInspector.UIString("Encoded Data Length"), WebInspector.UIString("%d Bytes", eventData["encodedDataLength"])); contentHelper.appendTextRow(WebInspector.UIString("Encoded Data Length"), WebInspector.UIString("%d Bytes", eventData["encodedDataLength"]));
break; break;
case recordTypes.EvaluateScript: case recordTypes.EvaluateScript:
var url = eventData["url"]; var url = eventData["url"];
if (url) if (url)
contentHelper.appendLocationRow(WebInspector.UIString("Script"), url, eventData["lineNumber"]); contentHelper.appendLocationRow(WebInspector.UIString("Script"), url, eventData["lineNumber"]);
break; break;
case recordTypes.Paint: case recordTypes.Paint:
var clip = eventData["clip"]; var clip = eventData["clip"];
contentHelper.appendTextRow(WebInspector.UIString("Location"), WebInspector.UIString("(%d, %d)", clip[0], clip[1])); contentHelper.appendTextRow(WebInspector.UIString("Location"), WebInspector.UIString("(%d, %d)", clip[0], clip[1]));
var clipWidth = WebInspector.TimelineUIUtils._quadWidth(clip); var clipWidth = WebInspector.TimelineUIUtils._quadWidth(clip);
var clipHeight = WebInspector.TimelineUIUtils._quadHeight(clip); var clipHeight = WebInspector.TimelineUIUtils._quadHeight(clip);
contentHelper.appendTextRow(WebInspector.UIString("Dimensions"), WebInspector.UIString("%d × %d", clipWidth, clipHeight)); contentHelper.appendTextRow(WebInspector.UIString("Dimensions"), WebInspector.UIString("%d × %d", clipWidth, clipHeight));
// Fall-through intended. // Fall-through intended.
case recordTypes.PaintSetup: case recordTypes.PaintSetup:
case recordTypes.Rasterize: case recordTypes.Rasterize:
case recordTypes.ScrollLayer: case recordTypes.ScrollLayer:
relatedNodeLabel = WebInspector.UIString("Layer root"); relatedNodeLabel = WebInspector.UIString("Layer root");
break; break;
case recordTypes.DecodeImage: case recordTypes.PaintImage:
case recordTypes.ResizeImage: case recordTypes.DecodeLazyPixelRef:
relatedNodeLabel = WebInspector.UIString("Image element"); case recordTypes.DecodeImage:
var url = eventData["url"]; case recordTypes.ResizeImage:
if (url) case recordTypes.DrawLazyPixelRef:
contentHelper.appendElementRow(WebInspector.UIString("Image URL"), WebInspector.linkifyResourceAsNode(url)); relatedNodeLabel = WebInspector.UIString("Image element");
break; if (event.imageURL)
case recordTypes.RecalculateStyles: // We don't want to see default details. contentHelper.appendElementRow(WebInspector.UIString("Image URL"), WebInspector.linkifyResourceAsNode(event.imageURL));
contentHelper.appendTextRow(WebInspector.UIString("Elements affected"), event.args["elementCount"]); if (event.previewElement)
callStackLabel = WebInspector.UIString("Styles recalculation forced"); contentHelper.appendElementRow(WebInspector.UIString("Preview"), event.previewElement);
break; break;
case recordTypes.Layout: case recordTypes.RecalculateStyles: // We don't want to see default details.
var beginData = event.args["beginData"]; contentHelper.appendTextRow(WebInspector.UIString("Elements affected"), event.args["elementCount"]);
contentHelper.appendTextRow(WebInspector.UIString("Nodes that need layout"), beginData["dirtyObjects"]); callStackLabel = WebInspector.UIString("Styles recalculation forced");
contentHelper.appendTextRow(WebInspector.UIString("Layout tree size"), beginData["totalObjects"]); break;
contentHelper.appendTextRow(WebInspector.UIString("Layout scope"), case recordTypes.Layout:
beginData["partialLayout"] ? WebInspector.UIString("Partial") : WebInspector.UIString("Whole document")); var beginData = event.args["beginData"];
callSiteStackTraceLabel = WebInspector.UIString("Layout invalidated"); contentHelper.appendTextRow(WebInspector.UIString("Nodes that need layout"), beginData["dirtyObjects"]);
callStackLabel = WebInspector.UIString("Layout forced"); contentHelper.appendTextRow(WebInspector.UIString("Layout tree size"), beginData["totalObjects"]);
relatedNodeLabel = WebInspector.UIString("Layout root"); contentHelper.appendTextRow(WebInspector.UIString("Layout scope"),
break; beginData["partialLayout"] ? WebInspector.UIString("Partial") : WebInspector.UIString("Whole document"));
case recordTypes.ConsoleTime: callSiteStackTraceLabel = WebInspector.UIString("Layout invalidated");
callStackLabel = WebInspector.UIString("Layout forced");
relatedNodeLabel = WebInspector.UIString("Layout root");
break;
case recordTypes.ConsoleTime:
contentHelper.appendTextRow(WebInspector.UIString("Message"), eventData["message"]);
break;
case recordTypes.WebSocketCreate:
case recordTypes.WebSocketSendHandshakeRequest:
case recordTypes.WebSocketReceiveHandshakeResponse:
case recordTypes.WebSocketDestroy:
var initiatorData = initiator ? initiator.args.data : eventData;
if (typeof initiatorData["webSocketURL"] !== "undefined")
contentHelper.appendTextRow(WebInspector.UIString("URL"), initiatorData["webSocketURL"]);
if (typeof initiatorData["webSocketProtocol"] !== "undefined")
contentHelper.appendTextRow(WebInspector.UIString("WebSocket Protocol"), initiatorData["webSocketProtocol"]);
if (typeof eventData["message"] !== "undefined")
contentHelper.appendTextRow(WebInspector.UIString("Message"), eventData["message"]); contentHelper.appendTextRow(WebInspector.UIString("Message"), eventData["message"]);
break; break;
case recordTypes.WebSocketCreate: case recordTypes.EmbedderCallback:
case recordTypes.WebSocketSendHandshakeRequest: contentHelper.appendTextRow(WebInspector.UIString("Callback Function"), eventData["callbackName"]);
case recordTypes.WebSocketReceiveHandshakeResponse: break;
case recordTypes.WebSocketDestroy: default:
var initiatorData = initiator ? initiator.args.data : eventData; var detailsNode = WebInspector.TimelineUIUtils.buildDetailsNodeForTraceEvent(event, linkifier, loadedFromFile, bindings, target);
if (typeof initiatorData["webSocketURL"] !== "undefined") if (detailsNode)
contentHelper.appendTextRow(WebInspector.UIString("URL"), initiatorData["webSocketURL"]); contentHelper.appendElementRow(WebInspector.UIString("Details"), detailsNode);
if (typeof initiatorData["webSocketProtocol"] !== "undefined") break;
contentHelper.appendTextRow(WebInspector.UIString("WebSocket Protocol"), initiatorData["webSocketProtocol"]);
if (typeof eventData["message"] !== "undefined")
contentHelper.appendTextRow(WebInspector.UIString("Message"), eventData["message"]);
break;
case recordTypes.EmbedderCallback:
contentHelper.appendTextRow(WebInspector.UIString("Callback Function"), eventData["callbackName"]);
break;
default:
var detailsNode = WebInspector.TimelineUIUtils.buildDetailsNodeForTraceEvent(event, linkifier, loadedFromFile, bindings, target);
if (detailsNode)
contentHelper.appendElementRow(WebInspector.UIString("Details"), detailsNode);
break;
} }
if (relatedNode) if (relatedNode)
...@@ -1080,63 +1065,65 @@ WebInspector.TimelineUIUtils.buildDetailsNode = function(record, linkifier, load ...@@ -1080,63 +1065,65 @@ WebInspector.TimelineUIUtils.buildDetailsNode = function(record, linkifier, load
*/ */
WebInspector.TimelineUIUtils.buildDetailsNodeForTraceEvent = function(event, linkifier, loadedFromFile, bindings, target) WebInspector.TimelineUIUtils.buildDetailsNodeForTraceEvent = function(event, linkifier, loadedFromFile, bindings, target)
{ {
var recordType = WebInspector.TimelineTraceEventBindings.RecordType;
var details; var details;
var detailsText; var detailsText;
var eventData = event.args.data; var eventData = event.args.data;
switch (event.name) { switch (event.name) {
case WebInspector.TimelineModel.RecordType.GCEvent: case recordType.GCEvent:
var delta = event.args["usedHeapSizeBefore"] - event.args["usedHeapSizeAfter"]; var delta = event.args["usedHeapSizeBefore"] - event.args["usedHeapSizeAfter"];
detailsText = WebInspector.UIString("%s collected", Number.bytesToString(delta)); detailsText = WebInspector.UIString("%s collected", Number.bytesToString(delta));
break; break;
case WebInspector.TimelineModel.RecordType.TimerFire: case recordType.TimerFire:
detailsText = eventData["timerId"]; detailsText = eventData["timerId"];
break; break;
case WebInspector.TimelineModel.RecordType.FunctionCall: case recordType.FunctionCall:
details = linkifyLocation(eventData["scriptId"], eventData["scriptName"], eventData["scriptLine"], 0); details = linkifyLocation(eventData["scriptId"], eventData["scriptName"], eventData["scriptLine"], 0);
break; break;
case WebInspector.TimelineModel.RecordType.FireAnimationFrame: case recordType.FireAnimationFrame:
detailsText = eventData["id"]; detailsText = eventData["id"];
break; break;
case WebInspector.TimelineModel.RecordType.EventDispatch: case recordType.EventDispatch:
detailsText = eventData ? eventData["type"] : null; detailsText = eventData ? eventData["type"] : null;
break; break;
case WebInspector.TimelineModel.RecordType.Paint: case recordType.Paint:
var width = WebInspector.TimelineUIUtils._quadWidth(eventData.clip); var width = WebInspector.TimelineUIUtils._quadWidth(eventData.clip);
var height = WebInspector.TimelineUIUtils._quadHeight(eventData.clip); var height = WebInspector.TimelineUIUtils._quadHeight(eventData.clip);
if (width && height) if (width && height)
detailsText = WebInspector.UIString("%d\u2009\u00d7\u2009%d", width, height); detailsText = WebInspector.UIString("%d\u2009\u00d7\u2009%d", width, height);
break; break;
case WebInspector.TimelineModel.RecordType.TimerInstall: case recordType.TimerInstall:
case WebInspector.TimelineModel.RecordType.TimerRemove: case recordType.TimerRemove:
details = linkifyTopCallFrame(); details = linkifyTopCallFrame();
detailsText = eventData["timerId"]; detailsText = eventData["timerId"];
break; break;
case WebInspector.TimelineModel.RecordType.RequestAnimationFrame: case recordType.RequestAnimationFrame:
case WebInspector.TimelineModel.RecordType.CancelAnimationFrame: case recordType.CancelAnimationFrame:
details = linkifyTopCallFrame(); details = linkifyTopCallFrame();
detailsText = eventData["id"]; detailsText = eventData["id"];
break; break;
case WebInspector.TimelineModel.RecordType.ParseHTML: case recordType.ParseHTML:
case WebInspector.TimelineModel.RecordType.RecalculateStyles: case recordType.RecalculateStyles:
details = linkifyTopCallFrame(); details = linkifyTopCallFrame();
break; break;
case WebInspector.TimelineModel.RecordType.EvaluateScript: case recordType.EvaluateScript:
var url = eventData["url"]; var url = eventData["url"];
if (url) if (url)
details = linkifyLocation("", url, eventData["lineNumber"], 0); details = linkifyLocation("", url, eventData["lineNumber"], 0);
break; break;
case WebInspector.TimelineModel.RecordType.XHRReadyStateChange: case recordType.XHRReadyStateChange:
case WebInspector.TimelineModel.RecordType.XHRLoad: case recordType.XHRLoad:
case WebInspector.TimelineModel.RecordType.ResourceSendRequest: case recordType.ResourceSendRequest:
case WebInspector.TimelineModel.RecordType.DecodeImage: case recordType.DecodeImage:
case WebInspector.TimelineModel.RecordType.ResizeImage: case recordType.ResizeImage:
var url = eventData["url"]; var url = eventData["url"];
if (url) if (url)
detailsText = WebInspector.displayNameForURL(url); detailsText = WebInspector.displayNameForURL(url);
break; break;
case WebInspector.TimelineModel.RecordType.ResourceReceivedData: case recordType.ResourceReceivedData:
case WebInspector.TimelineModel.RecordType.ResourceReceiveResponse: case recordType.ResourceReceiveResponse:
case WebInspector.TimelineModel.RecordType.ResourceFinish: case recordType.ResourceFinish:
var initiator = event.initiator; var initiator = event.initiator;
if (initiator) { if (initiator) {
var url = initiator.args.data["url"]; var url = initiator.args.data["url"];
...@@ -1144,12 +1131,22 @@ WebInspector.TimelineUIUtils.buildDetailsNodeForTraceEvent = function(event, lin ...@@ -1144,12 +1131,22 @@ WebInspector.TimelineUIUtils.buildDetailsNodeForTraceEvent = function(event, lin
detailsText = WebInspector.displayNameForURL(url); detailsText = WebInspector.displayNameForURL(url);
} }
break; break;
case WebInspector.TimelineModel.RecordType.ConsoleTime: case recordType.ConsoleTime:
detailsText = eventData["message"]; detailsText = eventData["message"];
break; break;
case WebInspector.TimelineModel.RecordType.EmbedderCallback: case recordType.EmbedderCallback:
detailsText = eventData["callbackName"]; detailsText = eventData["callbackName"];
break; break;
case recordType.PaintImage:
case recordType.DecodeImage:
case recordType.ResizeImage:
case recordType.DecodeLazyPixelRef:
var url = event.imageURL;
if (url)
detailsText = WebInspector.displayNameForURL(url);
break;
default: default:
details = linkifyTopCallFrame(); details = linkifyTopCallFrame();
break; break;
......
...@@ -296,6 +296,11 @@ WebInspector.TracingModel.Event = function(payload, level, thread) ...@@ -296,6 +296,11 @@ WebInspector.TracingModel.Event = function(payload, level, thread)
this.stackTrace = null; this.stackTrace = null;
/** @type {?Element} */ /** @type {?Element} */
this.previewElement = null; this.previewElement = null;
/** @type {?string} */
this.imageURL = null;
/** @type {number} */
this.backendNodeId = 0;
/** @type {number} */ /** @type {number} */
this.selfTime = 0; this.selfTime = 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment