Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Unified Diff: Source/devtools/front_end/timeline/TracingTimelineModel.js

Issue 465223002: [ Do not submit ] Prototype for invalidation analysis Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fix multiple paint bug, fix bug where nodes did not linkify properly, minor cleanups Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/devtools/front_end/timeline/TracingTimelineModel.js
diff --git a/Source/devtools/front_end/timeline/TracingTimelineModel.js b/Source/devtools/front_end/timeline/TracingTimelineModel.js
index 4ad7f03b0e177afaeb7fac52c2ba97ce2d4936c1..5b4fed00229e28680bc6855ac7541773c2117e1e 100644
--- a/Source/devtools/front_end/timeline/TracingTimelineModel.js
+++ b/Source/devtools/front_end/timeline/TracingTimelineModel.js
@@ -32,6 +32,9 @@ WebInspector.TracingTimelineModel.RecordType = {
DrawFrame: "DrawFrame",
ScheduleStyleRecalculation: "ScheduleStyleRecalculation",
RecalculateStyles: "RecalculateStyles",
+ StyleInvalidationTracking: "StyleInvalidationTracking",
+ LayoutInvalidationTracking: "LayoutInvalidationTracking",
+ PaintInvalidationTracking: "PaintInvalidationTracking",
InvalidateLayout: "InvalidateLayout",
Layout: "Layout",
UpdateLayer: "UpdateLayer",
@@ -115,8 +118,9 @@ WebInspector.TracingTimelineModel.prototype = {
* @param {boolean} captureStacks
* @param {boolean} captureMemory
* @param {boolean} capturePictures
+ * @param {boolean} captureInvalidationTracking
*/
- startRecording: function(captureStacks, captureMemory, capturePictures)
+ startRecording: function(captureStacks, captureMemory, capturePictures, captureInvalidationTracking)
{
function disabledByDefault(category)
{
@@ -143,6 +147,13 @@ WebInspector.TracingTimelineModel.prototype = {
disabledByDefault("devtools.timeline.picture"),
disabledByDefault("blink.graphics_context_annotations")]);
}
+ if (captureInvalidationTracking) {
+ categoriesArray = categoriesArray.concat([
+ disabledByDefault("devtools.timeline.styleInvalidationTracking"),
+ disabledByDefault("devtools.timeline.layoutInvalidationTracking"),
+ disabledByDefault("devtools.timeline.paintInvalidationTracking")
+ ]);
+ }
var categories = categoriesArray.join(",");
this._startRecordingWithCategories(categories);
},
@@ -378,6 +389,7 @@ WebInspector.TracingTimelineModel.prototype = {
this._sendRequestEvents = {};
this._timerEvents = {};
this._requestAnimationFrameEvents = {};
+ this._invalidationTracker = new WebInspector.InvalidationTracker();
this._layoutInvalidate = {};
this._lastScheduleStyleRecalculation = {};
this._webSocketCreateEvents = {};
@@ -488,6 +500,30 @@ WebInspector.TracingTimelineModel.prototype = {
this._lastRecalculateStylesEvent = event;
break;
+ case recordTypes.StyleInvalidationTracking:
+ this._invalidationTracker.addStyleInvalidation({
+ frameId: event.args.data.frame,
+ nodeId: event.args.data.nodeId,
+ nodeName: event.args.data.nodeName,
+ callstack: event.args.data.callstack
+ });
+ break;
+
+ case recordTypes.LayoutInvalidationTracking:
+ this._invalidationTracker.addLayoutInvalidation({
+ frameId: event.args.data.frame,
+ nodeId: event.args.data.nodeId,
+ callstack: event.args.data.callstack
+ });
+ break;
+
+ case recordTypes.PaintInvalidationTracking:
+ this._invalidationTracker.addPaintInvalidation({
+ frameId: event.args.data.frame,
+ nodeId: event.args.data.nodeId
+ });
+ break;
+
case recordTypes.InvalidateLayout:
// Consider style recalculation as a reason for layout invalidation,
// but only if we had no earlier layout invalidation records.
@@ -529,6 +565,7 @@ WebInspector.TracingTimelineModel.prototype = {
break;
case recordTypes.Paint:
+ this._invalidationTracker.setCurrentPaint(event);
event.highlightQuad = event.args["data"]["clip"];
event.backendNodeId = event.args["data"]["nodeId"];
var layerUpdateEvent = this._findAncestorEvent(recordTypes.UpdateLayer);
@@ -1016,3 +1053,125 @@ WebInspector.TracingTimelineSaver.prototype = {
this._writeNextChunk(stream);
}
}
+
+/**
+ * TODO: Properly doc this class.
+ *
+ * Track style, layout, and paint invalidation events.
+ *
+ * As style or layout tracking invalidation events come in, they should be
+ * registered here with add{Style,Layout}Invalidation.
+ * When a paint event occurs (not invalidation tracking event), setCurrentPaint
+ * should be called.
+ * As paint tracking invalidation events come in, they should be registered
+ * here with addPaintInvalidation. This function will annote the correct
+ * paint event with style and layout invalidations.
+ *
+ * This class assumes events will come in the following order (expressed in pdr-bnf):
+ * 1) (one or more) layout or style invalidation tracking events.
+ * 2) (one or more) paint event followed by one or more paint invalidation tracking events.
+ */
+WebInspector.InvalidationTracker = function()
+{
+ // Invalidation events for the current frame.
+ this._styleTrackingEvents = {};
+ this._layoutTrackingEvents = {};
+
+ // Invalidation events for the currently painting frame.
+ // FIXME: these maps grow over time and need to be cleared after the frame ends.
+ this._paintingStyleInvalidationMap = {};
+ this._paintingLayoutInvalidationMap = {};
+
+ this._currentPaintEvent = undefined;
+}
+
+WebInspector.InvalidationTracker.prototype = {
+
+ addStyleInvalidation: function(invalidation)
+ {
+ this._currentPaintEvent = undefined;
+
+ var frameId = invalidation.frameId;
+ if (this._styleTrackingEvents[frameId] === undefined)
+ this._styleTrackingEvents[frameId] = [];
+ this._styleTrackingEvents[frameId].push(invalidation);
+ },
+
+ addLayoutInvalidation: function(invalidation)
+ {
+ this._currentPaintEvent = undefined;
+
+ var frameId = invalidation.frameId;
+ if (this._layoutTrackingEvents[frameId] === undefined)
+ this._layoutTrackingEvents[frameId] = [];
+ this._layoutTrackingEvents[frameId].push(invalidation);
+ },
+
+ addPaintInvalidation: function(invalidation)
+ {
+ var frameId = invalidation.frameId;
+ var paintEvent = this._currentPaintEvent;
+
+ if (paintEvent === undefined) {
+ console.warn("Received paint event with no style or layout invalidations.");
+ return;
+ }
+
+ var styleNodeIdMap = this._paintingStyleInvalidationMap[frameId];
+ if (styleNodeIdMap && styleNodeIdMap[invalidation.nodeId]) {
+ styleNodeIdMap[invalidation.nodeId].forEach(function(styleEvent) {
+ if (paintEvent.styleInvalidationTrackingEvents.indexOf(styleEvent) == -1)
+ paintEvent.styleInvalidationTrackingEvents.push(styleEvent);
+ });
+ }
+ var layoutNodeIdMap = this._paintingLayoutInvalidationMap[frameId];
+ if (layoutNodeIdMap && layoutNodeIdMap[invalidation.nodeId]) {
+ layoutNodeIdMap[invalidation.nodeId].forEach(function(layoutEvent) {
+ if (paintEvent.layoutInvalidationTrackingEvents.indexOf(layoutEvent) == -1)
+ paintEvent.layoutInvalidationTrackingEvents.push(layoutEvent);
+ });
+ }
+ },
+
+ setCurrentPaint: function(event)
+ {
+ this._startNewFrameIfNeeded(event.args.data.frame);
+
+ event.styleInvalidationTrackingEvents = [];
+ event.layoutInvalidationTrackingEvents = [];
+ this._currentPaintEvent = event;
+ },
+
+ // If there's a new frame, save off all current invalidations.
+ _startNewFrameIfNeeded: function(frameId)
+ {
+ // FIXME: Need to track compositor events as well, as they can cause
+ // paints without style or layout invalidating. For now, we
+ // assume that the existance of style or layout invalidations
+ // after paint begins indicates a new frame has started.
+ if (this._styleTrackingEvents[frameId] === undefined &&
+ this._layoutTrackingEvents[frameId] === undefined)
+ return;
+
+ var styleTrackingEvents = this._styleTrackingEvents[frameId] || [];
+ var layoutTrackingEvents = this._layoutTrackingEvents[frameId] || [];
+ this._styleTrackingEvents[frameId] = undefined;
+ this._layoutTrackingEvents[frameId] = undefined;
+
+ var styleInvalidationMap = {};
+ styleTrackingEvents.forEach(function(styleEvent) {
+ if (styleInvalidationMap[styleEvent.nodeId] === undefined)
+ styleInvalidationMap[styleEvent.nodeId] = [];
+ styleInvalidationMap[styleEvent.nodeId].push(styleEvent);
+ });
+ this._paintingStyleInvalidationMap[frameId] = styleInvalidationMap;
+
+ var layoutInvalidationMap = {};
+ layoutTrackingEvents.forEach(function(layoutEvent) {
+ if (layoutInvalidationMap[layoutEvent.nodeId] === undefined)
+ layoutInvalidationMap[layoutEvent.nodeId] = [];
+ layoutInvalidationMap[layoutEvent.nodeId].push(layoutEvent);
+ });
+ this._paintingLayoutInvalidationMap[frameId] = layoutInvalidationMap;
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698