| 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 |