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

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: Update for review: cleanup sloppy algorithms, update tests 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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 { 136 {
132 return "disabled-by-default-" + category; 137 return "disabled-by-default-" + category;
133 } 138 }
134 var categoriesArray = [ 139 var categoriesArray = [
135 "-*", 140 "-*",
136 disabledByDefault("devtools.timeline"), 141 disabledByDefault("devtools.timeline"),
137 disabledByDefault("devtools.timeline.frame"), 142 disabledByDefault("devtools.timeline.frame"),
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 = categoriesArray.concat([
147 disabledByDefault("devtools.timeline.stack"),
148 disabledByDefault("devtools.timeline.invalidationTracking")]);
142 if (Runtime.experiments.isEnabled("timelineJSCPUProfile")) { 149 if (Runtime.experiments.isEnabled("timelineJSCPUProfile")) {
143 this._jsProfilerStarted = true; 150 this._jsProfilerStarted = true;
144 this._currentTarget = WebInspector.context.flavor(WebInspector.T arget); 151 this._currentTarget = WebInspector.context.flavor(WebInspector.T arget);
145 this._configureCpuProfilerSamplingInterval(); 152 this._configureCpuProfilerSamplingInterval();
146 this._currentTarget.profilerAgent().start(); 153 this._currentTarget.profilerAgent().start();
147 } 154 }
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"),
(...skipping 316 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 this._invalidationTracker.addInvalidation({
604 type: recordTypes.StyleRecalcInvalidationTracking,
605 frameId: event.args.data.frame,
606 nodeId: event.args.data.nodeId,
607 nodeName: event.args.data.nodeName,
608 reason: event.args.data.reason,
609 callstack: event.args.data.callstack
610 });
611 break;
612
613 case recordTypes.LayoutInvalidationTracking:
614 this._invalidationTracker.addInvalidation({
615 type: recordTypes.LayoutInvalidationTracking,
616 frameId: event.args.data.frame,
617 nodeId: event.args.data.nodeId,
618 nodeName: event.args.data.nodeName,
619 callstack: event.args.data.callstack
620 });
621 break;
622
623 case recordTypes.LayerInvalidationTracking:
624 this._invalidationTracker.addInvalidation({
625 type: recordTypes.LayerInvalidationTracking,
626 frameId: event.args.data.frame,
627 paintId: event.args.data.paintId,
628 reason: event.args.data.reason
629 });
630 break;
631
632 case recordTypes.PaintInvalidationTracking:
633 this._invalidationTracker.addInvalidation({
634 type: recordTypes.PaintInvalidationTracking,
635 frameId: event.args.data.frame,
636 nodeId: event.args.data.nodeId,
637 nodeName: event.args.data.nodeName,
638 paintId: event.args.data.paintId
639 });
640 break;
641
594 case recordTypes.InvalidateLayout: 642 case recordTypes.InvalidateLayout:
595 // Consider style recalculation as a reason for layout invalidation, 643 // Consider style recalculation as a reason for layout invalidation,
596 // but only if we had no earlier layout invalidation records. 644 // but only if we had no earlier layout invalidation records.
597 var layoutInitator = event; 645 var layoutInitator = event;
598 var frameId = event.args["frame"]; 646 var frameId = event.args["frame"];
599 if (!this._layoutInvalidate[frameId] && this._lastRecalculateStylesE vent && this._lastRecalculateStylesEvent.endTime > event.startTime) 647 if (!this._layoutInvalidate[frameId] && this._lastRecalculateStylesE vent && this._lastRecalculateStylesEvent.endTime > event.startTime)
600 layoutInitator = this._lastRecalculateStylesEvent.initiator; 648 layoutInitator = this._lastRecalculateStylesEvent.initiator;
601 this._layoutInvalidate[frameId] = layoutInitator; 649 this._layoutInvalidate[frameId] = layoutInitator;
602 break; 650 break;
603 651
(...skipping 24 matching lines...) Expand all
628 case recordTypes.FunctionCall: 676 case recordTypes.FunctionCall:
629 if (!this._currentScriptEvent) 677 if (!this._currentScriptEvent)
630 this._currentScriptEvent = event; 678 this._currentScriptEvent = event;
631 break; 679 break;
632 680
633 case recordTypes.SetLayerTreeId: 681 case recordTypes.SetLayerTreeId:
634 this._inspectedTargetLayerTreeId = event.args["layerTreeId"]; 682 this._inspectedTargetLayerTreeId = event.args["layerTreeId"];
635 break; 683 break;
636 684
637 case recordTypes.Paint: 685 case recordTypes.Paint:
686 this._invalidationTracker.didPaint(event);
638 event.highlightQuad = event.args["data"]["clip"]; 687 event.highlightQuad = event.args["data"]["clip"];
639 event.backendNodeId = event.args["data"]["nodeId"]; 688 event.backendNodeId = event.args["data"]["nodeId"];
640 var layerUpdateEvent = this._findAncestorEvent(recordTypes.UpdateLay er); 689 var layerUpdateEvent = this._findAncestorEvent(recordTypes.UpdateLay er);
641 if (!layerUpdateEvent || layerUpdateEvent.args["layerTreeId"] !== th is._inspectedTargetLayerTreeId) 690 if (!layerUpdateEvent || layerUpdateEvent.args["layerTreeId"] !== th is._inspectedTargetLayerTreeId)
642 break; 691 break;
643 // Only keep layer paint events, skip paints for subframes that get painted to the same layer as parent. 692 // Only keep layer paint events, skip paints for subframes that get painted to the same layer as parent.
644 if (!event.args["data"]["layerId"]) 693 if (!event.args["data"]["layerId"])
645 break; 694 break;
646 this._lastPaintForLayer[layerUpdateEvent.args["layerId"]] = event; 695 this._lastPaintForLayer[layerUpdateEvent.args["layerId"]] = event;
647 break; 696 break;
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 * @param {!WebInspector.ChunkedReader} reader 1145 * @param {!WebInspector.ChunkedReader} reader
1097 */ 1146 */
1098 onChunkTransferred: function(reader) { }, 1147 onChunkTransferred: function(reader) { },
1099 1148
1100 /** 1149 /**
1101 * @param {!WebInspector.ChunkedReader} reader 1150 * @param {!WebInspector.ChunkedReader} reader
1102 * @param {!Event} event 1151 * @param {!Event} event
1103 */ 1152 */
1104 onError: function(reader, event) { }, 1153 onError: function(reader, event) { },
1105 } 1154 }
1155
1156 /**
1157 * Track invalidation events across frames.
1158 */
1159 WebInspector.InvalidationTracker = function()
1160 {
1161 this._invalidationEvents = [];
1162 this._lastPaintWithLayer = undefined;
1163 this._didPaint = false;
1164 }
1165
1166 WebInspector.InvalidationTracker.prototype = {
1167
1168 addInvalidation: function(invalidation)
1169 {
1170 this._startNewFrameIfNeeded();
1171 if (!invalidation.nodeId && !invalidation.paintId) {
1172 console.error('Invalidation lacks node information.');
1173 console.error(invalidation);
1174 }
1175
1176 // Record the paintIds for style recalc or layout invalidations.
1177 // FIXME: This O(n^2) loop could be optimized with a map.
1178 if (invalidation.type == WebInspector.TracingTimelineModel.RecordType.Pa intInvalidationTracking) {
1179 this._invalidationEvents.forEach(function(invalidationToUpdate) {
1180 if (invalidationToUpdate.nodeId != invalidation.nodeId)
1181 return;
1182 switch (invalidationToUpdate.type) {
1183 case WebInspector.TracingTimelineModel.RecordType.StyleRecalcInv alidationTracking:
1184 invalidationToUpdate.paintId = invalidation.paintId;
1185 break;
1186 case WebInspector.TracingTimelineModel.RecordType.LayoutInvalida tionTracking:
1187 invalidationToUpdate.paintId = invalidation.paintId;
1188 break;
1189 }
1190 });
1191 } else {
1192 this._invalidationEvents.push(invalidation);
1193 }
1194 },
1195
1196 didPaint: function(paintEvent)
1197 {
1198 this._didPaint = true;
1199
1200 // If a paint doesn't have a corresponding graphics layer id, it paints into it's parent so
1201 // add an effectivePaintId to these events.
1202 // FIXME: The parent layer is assumed to be the last paint event that ha d a layerId set. Is that right?
1203 var layerId = paintEvent.args.data.layerId;
1204 if (layerId)
1205 this._lastPaintWithLayer = paintEvent;
1206
1207 if (!this._lastPaintWithLayer) {
1208 console.error("Failed to find the paint container for a paint event. ");
1209 return;
1210 }
1211
1212 var effectivePaintId = this._lastPaintWithLayer.args.data.nodeId;
1213 this._processPaint(paintEvent, effectivePaintId);
1214 },
1215
1216 _processPaint: function(paintEvent, effectivePaintId)
1217 {
1218 var frameId = paintEvent.args.data.frame;
1219
1220 this._invalidationEvents.forEach(function(invalidation) {
1221 if (invalidation.paintId == effectivePaintId && invalidation.frameId == frameId) {
1222 if (!paintEvent.invalidationTrackingEvents)
1223 paintEvent.invalidationTrackingEvents = [];
1224 paintEvent.invalidationTrackingEvents.push(invalidation);
1225 }
1226 });
1227 },
1228
1229 _startNewFrameIfNeeded: function()
1230 {
1231 if (!this._didPaint)
1232 return;
1233
1234 // Prepare for the next frame.
1235 this._invalidationEvents = [];
1236 this._lastPaintWithLayer = undefined;
1237 this._didPaint = false;
1238 }
1239 }
OLDNEW
« no previous file with comments | « Source/devtools/front_end/main/Main.js ('k') | Source/devtools/front_end/timeline/TracingTimelineUIUtils.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698