OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |