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

Side by Side Diff: Source/devtools/front_end/timeline/TracingTimelineModel.js

Issue 654013003: Implement invalidation tracking in devtools (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Address reviewer comments, update how stacks are handled Created 6 years, 2 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * @constructor 6 * @constructor
7 * @param {!WebInspector.TracingManager} tracingManager 7 * @param {!WebInspector.TracingManager} tracingManager
8 * @param {!WebInspector.TracingModel} tracingModel 8 * @param {!WebInspector.TracingModel} tracingModel
9 * @param {!WebInspector.TimelineModel.Filter} recordFilter 9 * @param {!WebInspector.TimelineModel.Filter} recordFilter
10 * @extends {WebInspector.TimelineModel} 10 * @extends {WebInspector.TimelineModel}
(...skipping 29 matching lines...) Expand all
40 UpdateLayer: "UpdateLayer", 40 UpdateLayer: "UpdateLayer",
41 UpdateLayerTree: "UpdateLayerTree", 41 UpdateLayerTree: "UpdateLayerTree",
42 PaintSetup: "PaintSetup", 42 PaintSetup: "PaintSetup",
43 Paint: "Paint", 43 Paint: "Paint",
44 PaintImage: "PaintImage", 44 PaintImage: "PaintImage",
45 Rasterize: "Rasterize", 45 Rasterize: "Rasterize",
46 RasterTask: "RasterTask", 46 RasterTask: "RasterTask",
47 ScrollLayer: "ScrollLayer", 47 ScrollLayer: "ScrollLayer",
48 CompositeLayers: "CompositeLayers", 48 CompositeLayers: "CompositeLayers",
49 49
50 StyleRecalcInvalidationTracking: "StyleRecalcInvalidationTracking",
51 LayoutInvalidationTracking: "LayoutInvalidationTracking",
52 LayerInvalidationTracking: "LayerInvalidationTracking",
53 PaintInvalidationTracking: "PaintInvalidationTracking",
54
50 ParseHTML: "ParseHTML", 55 ParseHTML: "ParseHTML",
51 56
52 TimerInstall: "TimerInstall", 57 TimerInstall: "TimerInstall",
53 TimerRemove: "TimerRemove", 58 TimerRemove: "TimerRemove",
54 TimerFire: "TimerFire", 59 TimerFire: "TimerFire",
55 60
56 XHRReadyStateChange: "XHRReadyStateChange", 61 XHRReadyStateChange: "XHRReadyStateChange",
57 XHRLoad: "XHRLoad", 62 XHRLoad: "XHRLoad",
58 EvaluateScript: "EvaluateScript", 63 EvaluateScript: "EvaluateScript",
59 64
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 WebInspector.TracingModel.ConsoleEventCategory 143 WebInspector.TracingModel.ConsoleEventCategory
139 ]; 144 ];
140 if (captureCauses) { 145 if (captureCauses) {
141 categoriesArray.push(disabledByDefault("devtools.timeline.stack")); 146 categoriesArray.push(disabledByDefault("devtools.timeline.stack"));
142 if (Runtime.experiments.isEnabled("timelineJSCPUProfile")) { 147 if (Runtime.experiments.isEnabled("timelineJSCPUProfile")) {
143 this._jsProfilerStarted = true; 148 this._jsProfilerStarted = true;
144 this._currentTarget = WebInspector.context.flavor(WebInspector.T arget); 149 this._currentTarget = WebInspector.context.flavor(WebInspector.T arget);
145 this._configureCpuProfilerSamplingInterval(); 150 this._configureCpuProfilerSamplingInterval();
146 this._currentTarget.profilerAgent().start(); 151 this._currentTarget.profilerAgent().start();
147 } 152 }
153 if (Runtime.experiments.isEnabled("timelineInvalidationTracking"))
154 categoriesArray.push(disabledByDefault("devtools.timeline.invali dationTracking"));
148 } 155 }
149 if (capturePictures) { 156 if (capturePictures) {
150 categoriesArray = categoriesArray.concat([ 157 categoriesArray = categoriesArray.concat([
151 disabledByDefault("devtools.timeline.layers"), 158 disabledByDefault("devtools.timeline.layers"),
152 disabledByDefault("devtools.timeline.picture"), 159 disabledByDefault("devtools.timeline.picture"),
153 disabledByDefault("blink.graphics_context_annotations")]); 160 disabledByDefault("blink.graphics_context_annotations")]);
154 } 161 }
155 var categories = categoriesArray.join(","); 162 var categories = categoriesArray.join(",");
156 this._startRecordingWithCategories(categories); 163 this._startRecordingWithCategories(categories);
157 }, 164 },
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 if (record.type() === WebInspector.TracingTimelineModel.RecordType.GPUTa sk) 475 if (record.type() === WebInspector.TracingTimelineModel.RecordType.GPUTa sk)
469 this._gpuThreadTasks.push(record); 476 this._gpuThreadTasks.push(record);
470 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordAd ded, record); 477 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordAd ded, record);
471 }, 478 },
472 479
473 _resetProcessingState: function() 480 _resetProcessingState: function()
474 { 481 {
475 this._sendRequestEvents = {}; 482 this._sendRequestEvents = {};
476 this._timerEvents = {}; 483 this._timerEvents = {};
477 this._requestAnimationFrameEvents = {}; 484 this._requestAnimationFrameEvents = {};
485 this._invalidationTracker = new WebInspector.InvalidationTracker();
478 this._layoutInvalidate = {}; 486 this._layoutInvalidate = {};
479 this._lastScheduleStyleRecalculation = {}; 487 this._lastScheduleStyleRecalculation = {};
480 this._webSocketCreateEvents = {}; 488 this._webSocketCreateEvents = {};
481 this._paintImageEventByPixelRefId = {}; 489 this._paintImageEventByPixelRefId = {};
482 this._lastPaintForLayer = {}; 490 this._lastPaintForLayer = {};
483 this._lastRecalculateStylesEvent = null; 491 this._lastRecalculateStylesEvent = null;
484 this._currentScriptEvent = null; 492 this._currentScriptEvent = null;
485 this._eventStack = []; 493 this._eventStack = [];
486 }, 494 },
487 495
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 592
585 case recordTypes.ScheduleStyleRecalculation: 593 case recordTypes.ScheduleStyleRecalculation:
586 this._lastScheduleStyleRecalculation[event.args["frame"]] = event; 594 this._lastScheduleStyleRecalculation[event.args["frame"]] = event;
587 break; 595 break;
588 596
589 case recordTypes.RecalculateStyles: 597 case recordTypes.RecalculateStyles:
590 event.initiator = this._lastScheduleStyleRecalculation[event.args["f rame"]]; 598 event.initiator = this._lastScheduleStyleRecalculation[event.args["f rame"]];
591 this._lastRecalculateStylesEvent = event; 599 this._lastRecalculateStylesEvent = event;
592 break; 600 break;
593 601
602 case recordTypes.StyleRecalcInvalidationTracking:
603 case recordTypes.LayoutInvalidationTracking:
604 case recordTypes.LayerInvalidationTracking:
605 case recordTypes.PaintInvalidationTracking:
606 this._invalidationTracker.addInvalidation(event);
607 break;
608
594 case recordTypes.InvalidateLayout: 609 case recordTypes.InvalidateLayout:
595 // Consider style recalculation as a reason for layout invalidation, 610 // Consider style recalculation as a reason for layout invalidation,
596 // but only if we had no earlier layout invalidation records. 611 // but only if we had no earlier layout invalidation records.
597 var layoutInitator = event; 612 var layoutInitator = event;
598 var frameId = event.args["frame"]; 613 var frameId = event.args["frame"];
599 if (!this._layoutInvalidate[frameId] && this._lastRecalculateStylesE vent && this._lastRecalculateStylesEvent.endTime > event.startTime) 614 if (!this._layoutInvalidate[frameId] && this._lastRecalculateStylesE vent && this._lastRecalculateStylesEvent.endTime > event.startTime)
600 layoutInitator = this._lastRecalculateStylesEvent.initiator; 615 layoutInitator = this._lastRecalculateStylesEvent.initiator;
601 this._layoutInvalidate[frameId] = layoutInitator; 616 this._layoutInvalidate[frameId] = layoutInitator;
602 break; 617 break;
603 618
(...skipping 24 matching lines...) Expand all
628 case recordTypes.FunctionCall: 643 case recordTypes.FunctionCall:
629 if (!this._currentScriptEvent) 644 if (!this._currentScriptEvent)
630 this._currentScriptEvent = event; 645 this._currentScriptEvent = event;
631 break; 646 break;
632 647
633 case recordTypes.SetLayerTreeId: 648 case recordTypes.SetLayerTreeId:
634 this._inspectedTargetLayerTreeId = event.args["layerTreeId"]; 649 this._inspectedTargetLayerTreeId = event.args["layerTreeId"];
635 break; 650 break;
636 651
637 case recordTypes.Paint: 652 case recordTypes.Paint:
653 this._invalidationTracker.didPaint(event);
638 event.highlightQuad = event.args["data"]["clip"]; 654 event.highlightQuad = event.args["data"]["clip"];
639 event.backendNodeId = event.args["data"]["nodeId"]; 655 event.backendNodeId = event.args["data"]["nodeId"];
640 var layerUpdateEvent = this._findAncestorEvent(recordTypes.UpdateLay er); 656 var layerUpdateEvent = this._findAncestorEvent(recordTypes.UpdateLay er);
641 if (!layerUpdateEvent || layerUpdateEvent.args["layerTreeId"] !== th is._inspectedTargetLayerTreeId) 657 if (!layerUpdateEvent || layerUpdateEvent.args["layerTreeId"] !== th is._inspectedTargetLayerTreeId)
642 break; 658 break;
643 // Only keep layer paint events, skip paints for subframes that get painted to the same layer as parent. 659 // Only keep layer paint events, skip paints for subframes that get painted to the same layer as parent.
644 if (!event.args["data"]["layerId"]) 660 if (!event.args["data"]["layerId"])
645 break; 661 break;
646 this._lastPaintForLayer[layerUpdateEvent.args["layerId"]] = event; 662 this._lastPaintForLayer[layerUpdateEvent.args["layerId"]] = event;
647 break; 663 break;
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 * @param {!WebInspector.ChunkedReader} reader 1112 * @param {!WebInspector.ChunkedReader} reader
1097 */ 1113 */
1098 onChunkTransferred: function(reader) { }, 1114 onChunkTransferred: function(reader) { },
1099 1115
1100 /** 1116 /**
1101 * @param {!WebInspector.ChunkedReader} reader 1117 * @param {!WebInspector.ChunkedReader} reader
1102 * @param {!Event} event 1118 * @param {!Event} event
1103 */ 1119 */
1104 onError: function(reader, event) { }, 1120 onError: function(reader, event) { },
1105 } 1121 }
1122
1123 /**
1124 * @constructor
1125 * @param {!Event} event
1126 */
1127 WebInspector.InvalidationTrackingEvent = function(event)
1128 {
1129 this.type = event.name;
1130 this.frameId = event.args["data"]["frame"];
1131 this.nodeId = event.args["data"]["nodeId"];
1132 this.nodeName = event.args["data"]["nodeName"];
1133 this.paintId = event.args["data"]["paintId"];
1134 this.reason = event.args["data"]["reason"];
1135 this.stackTrace = event.args["data"]["stackTrace"];
1136 }
1137
1138 /**
1139 * @constructor
1140 */
1141 WebInspector.InvalidationTracker = function()
1142 {
1143 this._initializePerFrameState();
1144 }
1145
1146 WebInspector.InvalidationTracker.prototype = {
1147 /**
1148 * @param {!Event} event
1149 */
1150 addInvalidation: function(event)
1151 {
1152 var invalidation = new WebInspector.InvalidationTrackingEvent(event);
1153
1154 this._startNewFrameIfNeeded();
1155 if (!invalidation.nodeId && !invalidation.paintId) {
1156 console.error("Invalidation lacks node information.");
1157 console.error(invalidation);
1158 }
1159
1160 // Record the paintIds for style recalc or layout invalidations.
1161 // FIXME: This O(n^2) loop could be optimized with a map.
1162 var recordTypes = WebInspector.TracingTimelineModel.RecordType;
1163 if (invalidation.type == recordTypes.PaintInvalidationTracking)
1164 this._invalidationEvents.forEach(updatePaintId);
1165 else
1166 this._invalidationEvents.push(invalidation);
1167
1168 function updatePaintId(invalidationToUpdate)
1169 {
1170 if (invalidationToUpdate.nodeId !== invalidation.nodeId)
1171 return;
1172 if (invalidationToUpdate.type === recordTypes.StyleRecalcInvalidatio nTracking
1173 || invalidationToUpdate.type === recordTypes.LayoutInvalidat ionTracking) {
1174 invalidationToUpdate.paintId = invalidation.paintId;
1175 }
1176 }
1177 },
1178
1179 /**
1180 * @param {!Event} paintEvent
1181 */
1182 didPaint: function(paintEvent)
1183 {
1184 this._didPaint = true;
1185
1186 // If a paint doesn't have a corresponding graphics layer id, it paints
1187 // into its parent so add an effectivePaintId to these events.
1188 var layerId = paintEvent.args["data"]["layerId"];
1189 if (layerId)
1190 this._lastPaintWithLayer = paintEvent;
1191 if (!this._lastPaintWithLayer) {
1192 console.error("Failed to find the paint container for a paint event. ");
1193 return;
1194 }
1195
1196 var effectivePaintId = this._lastPaintWithLayer.args.data.nodeId;
caseq 2014/10/17 15:48:55 args["data"]["nodeId"]
pdr. 2014/10/20 21:38:05 Done.
1197 var frameId = paintEvent.args["data"]["frame"];
1198 this._invalidationEvents.forEach(recordInvalidationForPaint);
1199
1200 function recordInvalidationForPaint(invalidation)
1201 {
1202 if (invalidation.paintId === effectivePaintId && invalidation.frameI d === frameId) {
1203 if (!paintEvent.invalidationTrackingEvents)
1204 paintEvent.invalidationTrackingEvents = [];
1205 paintEvent.invalidationTrackingEvents.push(invalidation);
1206 }
1207 }
1208 },
1209
1210 _startNewFrameIfNeeded: function()
1211 {
1212 if (!this._didPaint)
1213 return;
1214
1215 this._initializePerFrameState();
1216 },
1217
1218 _initializePerFrameState: function()
1219 {
1220 this._invalidationEvents = [];
1221 this._lastPaintWithLayer = undefined;
1222 this._didPaint = false;
1223 }
1224 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698