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

Side by Side 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, 3 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.TracingModel} tracingModel 7 * @param {!WebInspector.TracingModel} tracingModel
8 * @param {!WebInspector.TimelineModel.Filter} recordFilter 8 * @param {!WebInspector.TimelineModel.Filter} recordFilter
9 * @extends {WebInspector.TimelineModel} 9 * @extends {WebInspector.TimelineModel}
10 */ 10 */
(...skipping 14 matching lines...) Expand all
25 25
26 GPUTask: "GPUTask", 26 GPUTask: "GPUTask",
27 27
28 RequestMainThreadFrame: "RequestMainThreadFrame", 28 RequestMainThreadFrame: "RequestMainThreadFrame",
29 BeginFrame: "BeginFrame", 29 BeginFrame: "BeginFrame",
30 BeginMainThreadFrame: "BeginMainThreadFrame", 30 BeginMainThreadFrame: "BeginMainThreadFrame",
31 ActivateLayerTree: "ActivateLayerTree", 31 ActivateLayerTree: "ActivateLayerTree",
32 DrawFrame: "DrawFrame", 32 DrawFrame: "DrawFrame",
33 ScheduleStyleRecalculation: "ScheduleStyleRecalculation", 33 ScheduleStyleRecalculation: "ScheduleStyleRecalculation",
34 RecalculateStyles: "RecalculateStyles", 34 RecalculateStyles: "RecalculateStyles",
35 StyleInvalidationTracking: "StyleInvalidationTracking",
36 LayoutInvalidationTracking: "LayoutInvalidationTracking",
37 PaintInvalidationTracking: "PaintInvalidationTracking",
35 InvalidateLayout: "InvalidateLayout", 38 InvalidateLayout: "InvalidateLayout",
36 Layout: "Layout", 39 Layout: "Layout",
37 UpdateLayer: "UpdateLayer", 40 UpdateLayer: "UpdateLayer",
38 UpdateLayerTree: "UpdateLayerTree", 41 UpdateLayerTree: "UpdateLayerTree",
39 PaintSetup: "PaintSetup", 42 PaintSetup: "PaintSetup",
40 Paint: "Paint", 43 Paint: "Paint",
41 PaintImage: "PaintImage", 44 PaintImage: "PaintImage",
42 Rasterize: "Rasterize", 45 Rasterize: "Rasterize",
43 RasterTask: "RasterTask", 46 RasterTask: "RasterTask",
44 ScrollLayer: "ScrollLayer", 47 ScrollLayer: "ScrollLayer",
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 this.name = name; 111 this.name = name;
109 /** @type {!Array.<!WebInspector.TracingModel.Event>} */ 112 /** @type {!Array.<!WebInspector.TracingModel.Event>} */
110 this.events = []; 113 this.events = [];
111 } 114 }
112 115
113 WebInspector.TracingTimelineModel.prototype = { 116 WebInspector.TracingTimelineModel.prototype = {
114 /** 117 /**
115 * @param {boolean} captureStacks 118 * @param {boolean} captureStacks
116 * @param {boolean} captureMemory 119 * @param {boolean} captureMemory
117 * @param {boolean} capturePictures 120 * @param {boolean} capturePictures
121 * @param {boolean} captureInvalidationTracking
118 */ 122 */
119 startRecording: function(captureStacks, captureMemory, capturePictures) 123 startRecording: function(captureStacks, captureMemory, capturePictures, capt ureInvalidationTracking)
120 { 124 {
121 function disabledByDefault(category) 125 function disabledByDefault(category)
122 { 126 {
123 return "disabled-by-default-" + category; 127 return "disabled-by-default-" + category;
124 } 128 }
125 var categoriesArray = [ 129 var categoriesArray = [
126 "-*", 130 "-*",
127 disabledByDefault("devtools.timeline"), 131 disabledByDefault("devtools.timeline"),
128 disabledByDefault("devtools.timeline.frame"), 132 disabledByDefault("devtools.timeline.frame"),
129 WebInspector.TracingModel.ConsoleEventCategory 133 WebInspector.TracingModel.ConsoleEventCategory
130 ]; 134 ];
131 if (captureStacks) { 135 if (captureStacks) {
132 categoriesArray.push(disabledByDefault("devtools.timeline.stack")); 136 categoriesArray.push(disabledByDefault("devtools.timeline.stack"));
133 if (WebInspector.experimentsSettings.timelineJSCPUProfile.isEnabled( )) { 137 if (WebInspector.experimentsSettings.timelineJSCPUProfile.isEnabled( )) {
134 this._jsProfilerStarted = true; 138 this._jsProfilerStarted = true;
135 this._currentTarget = WebInspector.context.flavor(WebInspector.T arget); 139 this._currentTarget = WebInspector.context.flavor(WebInspector.T arget);
136 this._configureCpuProfilerSamplingInterval(); 140 this._configureCpuProfilerSamplingInterval();
137 this._currentTarget.profilerAgent().start(); 141 this._currentTarget.profilerAgent().start();
138 } 142 }
139 } 143 }
140 if (capturePictures) { 144 if (capturePictures) {
141 categoriesArray = categoriesArray.concat([ 145 categoriesArray = categoriesArray.concat([
142 disabledByDefault("devtools.timeline.layers"), 146 disabledByDefault("devtools.timeline.layers"),
143 disabledByDefault("devtools.timeline.picture"), 147 disabledByDefault("devtools.timeline.picture"),
144 disabledByDefault("blink.graphics_context_annotations")]); 148 disabledByDefault("blink.graphics_context_annotations")]);
145 } 149 }
150 if (captureInvalidationTracking) {
151 categoriesArray = categoriesArray.concat([
152 disabledByDefault("devtools.timeline.styleInvalidationTracking") ,
153 disabledByDefault("devtools.timeline.layoutInvalidationTracking" ),
154 disabledByDefault("devtools.timeline.paintInvalidationTracking")
155 ]);
156 }
146 var categories = categoriesArray.join(","); 157 var categories = categoriesArray.join(",");
147 this._startRecordingWithCategories(categories); 158 this._startRecordingWithCategories(categories);
148 }, 159 },
149 160
150 stopRecording: function() 161 stopRecording: function()
151 { 162 {
152 this._stopCallbackBarrier = new CallbackBarrier(); 163 this._stopCallbackBarrier = new CallbackBarrier();
153 if (this._jsProfilerStarted) { 164 if (this._jsProfilerStarted) {
154 this._currentTarget.profilerAgent().stop(this._stopCallbackBarrier.c reateCallback(this._didStopRecordingJSSamples.bind(this))); 165 this._currentTarget.profilerAgent().stop(this._stopCallbackBarrier.c reateCallback(this._didStopRecordingJSSamples.bind(this)));
155 this._jsProfilerStarted = false; 166 this._jsProfilerStarted = false;
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 if (record.type() === WebInspector.TracingTimelineModel.RecordType.GPUTa sk) 382 if (record.type() === WebInspector.TracingTimelineModel.RecordType.GPUTa sk)
372 this._gpuThreadTasks.push(record); 383 this._gpuThreadTasks.push(record);
373 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordAd ded, record); 384 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordAd ded, record);
374 }, 385 },
375 386
376 _resetProcessingState: function() 387 _resetProcessingState: function()
377 { 388 {
378 this._sendRequestEvents = {}; 389 this._sendRequestEvents = {};
379 this._timerEvents = {}; 390 this._timerEvents = {};
380 this._requestAnimationFrameEvents = {}; 391 this._requestAnimationFrameEvents = {};
392 this._invalidationTracker = new WebInspector.InvalidationTracker();
381 this._layoutInvalidate = {}; 393 this._layoutInvalidate = {};
382 this._lastScheduleStyleRecalculation = {}; 394 this._lastScheduleStyleRecalculation = {};
383 this._webSocketCreateEvents = {}; 395 this._webSocketCreateEvents = {};
384 this._paintImageEventByPixelRefId = {}; 396 this._paintImageEventByPixelRefId = {};
385 this._lastPaintForLayer = {}; 397 this._lastPaintForLayer = {};
386 this._lastRecalculateStylesEvent = null; 398 this._lastRecalculateStylesEvent = null;
387 this._currentScriptEvent = null; 399 this._currentScriptEvent = null;
388 this._eventStack = []; 400 this._eventStack = [];
389 }, 401 },
390 402
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 493
482 case recordTypes.ScheduleStyleRecalculation: 494 case recordTypes.ScheduleStyleRecalculation:
483 this._lastScheduleStyleRecalculation[event.args["frame"]] = event; 495 this._lastScheduleStyleRecalculation[event.args["frame"]] = event;
484 break; 496 break;
485 497
486 case recordTypes.RecalculateStyles: 498 case recordTypes.RecalculateStyles:
487 event.initiator = this._lastScheduleStyleRecalculation[event.args["f rame"]]; 499 event.initiator = this._lastScheduleStyleRecalculation[event.args["f rame"]];
488 this._lastRecalculateStylesEvent = event; 500 this._lastRecalculateStylesEvent = event;
489 break; 501 break;
490 502
503 case recordTypes.StyleInvalidationTracking:
504 this._invalidationTracker.addStyleInvalidation({
505 frameId: event.args.data.frame,
506 nodeId: event.args.data.nodeId,
507 nodeName: event.args.data.nodeName,
508 callstack: event.args.data.callstack
509 });
510 break;
511
512 case recordTypes.LayoutInvalidationTracking:
513 this._invalidationTracker.addLayoutInvalidation({
514 frameId: event.args.data.frame,
515 nodeId: event.args.data.nodeId,
516 callstack: event.args.data.callstack
517 });
518 break;
519
520 case recordTypes.PaintInvalidationTracking:
521 this._invalidationTracker.addPaintInvalidation({
522 frameId: event.args.data.frame,
523 nodeId: event.args.data.nodeId
524 });
525 break;
526
491 case recordTypes.InvalidateLayout: 527 case recordTypes.InvalidateLayout:
492 // Consider style recalculation as a reason for layout invalidation, 528 // Consider style recalculation as a reason for layout invalidation,
493 // but only if we had no earlier layout invalidation records. 529 // but only if we had no earlier layout invalidation records.
494 var layoutInitator = event; 530 var layoutInitator = event;
495 var frameId = event.args["frame"]; 531 var frameId = event.args["frame"];
496 if (!this._layoutInvalidate[frameId] && this._lastRecalculateStylesE vent && this._lastRecalculateStylesEvent.endTime > event.startTime) 532 if (!this._layoutInvalidate[frameId] && this._lastRecalculateStylesE vent && this._lastRecalculateStylesEvent.endTime > event.startTime)
497 layoutInitator = this._lastRecalculateStylesEvent.initiator; 533 layoutInitator = this._lastRecalculateStylesEvent.initiator;
498 this._layoutInvalidate[frameId] = layoutInitator; 534 this._layoutInvalidate[frameId] = layoutInitator;
499 break; 535 break;
500 536
(...skipping 21 matching lines...) Expand all
522 case recordTypes.FunctionCall: 558 case recordTypes.FunctionCall:
523 if (!this._currentScriptEvent) 559 if (!this._currentScriptEvent)
524 this._currentScriptEvent = event; 560 this._currentScriptEvent = event;
525 break; 561 break;
526 562
527 case recordTypes.SetLayerTreeId: 563 case recordTypes.SetLayerTreeId:
528 this._inspectedTargetLayerTreeId = event.args["layerTreeId"]; 564 this._inspectedTargetLayerTreeId = event.args["layerTreeId"];
529 break; 565 break;
530 566
531 case recordTypes.Paint: 567 case recordTypes.Paint:
568 this._invalidationTracker.setCurrentPaint(event);
532 event.highlightQuad = event.args["data"]["clip"]; 569 event.highlightQuad = event.args["data"]["clip"];
533 event.backendNodeId = event.args["data"]["nodeId"]; 570 event.backendNodeId = event.args["data"]["nodeId"];
534 var layerUpdateEvent = this._findAncestorEvent(recordTypes.UpdateLay er); 571 var layerUpdateEvent = this._findAncestorEvent(recordTypes.UpdateLay er);
535 if (!layerUpdateEvent || layerUpdateEvent.args["layerTreeId"] !== th is._inspectedTargetLayerTreeId) 572 if (!layerUpdateEvent || layerUpdateEvent.args["layerTreeId"] !== th is._inspectedTargetLayerTreeId)
536 break; 573 break;
537 // Only keep layer paint events, skip paints for subframes that get painted to the same layer as parent. 574 // Only keep layer paint events, skip paints for subframes that get painted to the same layer as parent.
538 if (!event.args["data"]["layerId"]) 575 if (!event.args["data"]["layerId"])
539 break; 576 break;
540 this._lastPaintForLayer[layerUpdateEvent.args["layerId"]] = event; 577 this._lastPaintForLayer[layerUpdateEvent.args["layerId"]] = event;
541 break; 578 break;
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
1009 }, 1046 },
1010 1047
1011 _didWriteNextChunk: function(stream) 1048 _didWriteNextChunk: function(stream)
1012 { 1049 {
1013 if (this._recordIndex === this._payloads.length) 1050 if (this._recordIndex === this._payloads.length)
1014 stream.close(); 1051 stream.close();
1015 else 1052 else
1016 this._writeNextChunk(stream); 1053 this._writeNextChunk(stream);
1017 } 1054 }
1018 } 1055 }
1056
1057 /**
1058 * TODO: Properly doc this class.
1059 *
1060 * Track style, layout, and paint invalidation events.
1061 *
1062 * As style or layout tracking invalidation events come in, they should be
1063 * registered here with add{Style,Layout}Invalidation.
1064 * When a paint event occurs (not invalidation tracking event), setCurrentPaint
1065 * should be called.
1066 * As paint tracking invalidation events come in, they should be registered
1067 * here with addPaintInvalidation. This function will annote the correct
1068 * paint event with style and layout invalidations.
1069 *
1070 * This class assumes events will come in the following order (expressed in pdr- bnf):
1071 * 1) (one or more) layout or style invalidation tracking events.
1072 * 2) (one or more) paint event followed by one or more paint invalidation tra cking events.
1073 */
1074 WebInspector.InvalidationTracker = function()
1075 {
1076 // Invalidation events for the current frame.
1077 this._styleTrackingEvents = {};
1078 this._layoutTrackingEvents = {};
1079
1080 // Invalidation events for the currently painting frame.
1081 // FIXME: these maps grow over time and need to be cleared after the frame e nds.
1082 this._paintingStyleInvalidationMap = {};
1083 this._paintingLayoutInvalidationMap = {};
1084
1085 this._currentPaintEvent = undefined;
1086 }
1087
1088 WebInspector.InvalidationTracker.prototype = {
1089
1090 addStyleInvalidation: function(invalidation)
1091 {
1092 this._currentPaintEvent = undefined;
1093
1094 var frameId = invalidation.frameId;
1095 if (this._styleTrackingEvents[frameId] === undefined)
1096 this._styleTrackingEvents[frameId] = [];
1097 this._styleTrackingEvents[frameId].push(invalidation);
1098 },
1099
1100 addLayoutInvalidation: function(invalidation)
1101 {
1102 this._currentPaintEvent = undefined;
1103
1104 var frameId = invalidation.frameId;
1105 if (this._layoutTrackingEvents[frameId] === undefined)
1106 this._layoutTrackingEvents[frameId] = [];
1107 this._layoutTrackingEvents[frameId].push(invalidation);
1108 },
1109
1110 addPaintInvalidation: function(invalidation)
1111 {
1112 var frameId = invalidation.frameId;
1113 var paintEvent = this._currentPaintEvent;
1114
1115 if (paintEvent === undefined) {
1116 console.warn("Received paint event with no style or layout invalidat ions.");
1117 return;
1118 }
1119
1120 var styleNodeIdMap = this._paintingStyleInvalidationMap[frameId];
1121 if (styleNodeIdMap && styleNodeIdMap[invalidation.nodeId]) {
1122 styleNodeIdMap[invalidation.nodeId].forEach(function(styleEvent) {
1123 if (paintEvent.styleInvalidationTrackingEvents.indexOf(styleEven t) == -1)
1124 paintEvent.styleInvalidationTrackingEvents.push(styleEvent);
1125 });
1126 }
1127 var layoutNodeIdMap = this._paintingLayoutInvalidationMap[frameId];
1128 if (layoutNodeIdMap && layoutNodeIdMap[invalidation.nodeId]) {
1129 layoutNodeIdMap[invalidation.nodeId].forEach(function(layoutEvent) {
1130 if (paintEvent.layoutInvalidationTrackingEvents.indexOf(layoutEv ent) == -1)
1131 paintEvent.layoutInvalidationTrackingEvents.push(layoutEvent );
1132 });
1133 }
1134 },
1135
1136 setCurrentPaint: function(event)
1137 {
1138 this._startNewFrameIfNeeded(event.args.data.frame);
1139
1140 event.styleInvalidationTrackingEvents = [];
1141 event.layoutInvalidationTrackingEvents = [];
1142 this._currentPaintEvent = event;
1143 },
1144
1145 // If there's a new frame, save off all current invalidations.
1146 _startNewFrameIfNeeded: function(frameId)
1147 {
1148 // FIXME: Need to track compositor events as well, as they can cause
1149 // paints without style or layout invalidating. For now, we
1150 // assume that the existance of style or layout invalidations
1151 // after paint begins indicates a new frame has started.
1152 if (this._styleTrackingEvents[frameId] === undefined &&
1153 this._layoutTrackingEvents[frameId] === undefined)
1154 return;
1155
1156 var styleTrackingEvents = this._styleTrackingEvents[frameId] || [];
1157 var layoutTrackingEvents = this._layoutTrackingEvents[frameId] || [];
1158 this._styleTrackingEvents[frameId] = undefined;
1159 this._layoutTrackingEvents[frameId] = undefined;
1160
1161 var styleInvalidationMap = {};
1162 styleTrackingEvents.forEach(function(styleEvent) {
1163 if (styleInvalidationMap[styleEvent.nodeId] === undefined)
1164 styleInvalidationMap[styleEvent.nodeId] = [];
1165 styleInvalidationMap[styleEvent.nodeId].push(styleEvent);
1166 });
1167 this._paintingStyleInvalidationMap[frameId] = styleInvalidationMap;
1168
1169 var layoutInvalidationMap = {};
1170 layoutTrackingEvents.forEach(function(layoutEvent) {
1171 if (layoutInvalidationMap[layoutEvent.nodeId] === undefined)
1172 layoutInvalidationMap[layoutEvent.nodeId] = [];
1173 layoutInvalidationMap[layoutEvent.nodeId].push(layoutEvent);
1174 });
1175 this._paintingLayoutInvalidationMap[frameId] = layoutInvalidationMap;
1176 }
1177 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698