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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: Source/devtools/front_end/timeline/TracingTimelineModel.js
diff --git a/Source/devtools/front_end/timeline/TracingTimelineModel.js b/Source/devtools/front_end/timeline/TracingTimelineModel.js
index 2cd5efd8681d9011c0faab9ec83ef93ac7d996b8..fa2894db584fef2d2fc56e0792f892f09b78a228 100644
--- a/Source/devtools/front_end/timeline/TracingTimelineModel.js
+++ b/Source/devtools/front_end/timeline/TracingTimelineModel.js
@@ -47,6 +47,11 @@ WebInspector.TracingTimelineModel.RecordType = {
ScrollLayer: "ScrollLayer",
CompositeLayers: "CompositeLayers",
+ StyleRecalcInvalidationTracking: "StyleRecalcInvalidationTracking",
+ LayoutInvalidationTracking: "LayoutInvalidationTracking",
+ LayerInvalidationTracking: "LayerInvalidationTracking",
+ PaintInvalidationTracking: "PaintInvalidationTracking",
+
ParseHTML: "ParseHTML",
TimerInstall: "TimerInstall",
@@ -138,7 +143,9 @@ WebInspector.TracingTimelineModel.prototype = {
WebInspector.TracingModel.ConsoleEventCategory
];
if (captureCauses) {
- categoriesArray.push(disabledByDefault("devtools.timeline.stack"));
+ categoriesArray = categoriesArray.concat([
+ disabledByDefault("devtools.timeline.stack"),
+ disabledByDefault("devtools.timeline.invalidationTracking")]);
if (Runtime.experiments.isEnabled("timelineJSCPUProfile")) {
this._jsProfilerStarted = true;
this._currentTarget = WebInspector.context.flavor(WebInspector.Target);
@@ -475,6 +482,7 @@ WebInspector.TracingTimelineModel.prototype = {
this._sendRequestEvents = {};
this._timerEvents = {};
this._requestAnimationFrameEvents = {};
+ this._invalidationTracker = new WebInspector.InvalidationTracker();
this._layoutInvalidate = {};
this._lastScheduleStyleRecalculation = {};
this._webSocketCreateEvents = {};
@@ -591,6 +599,46 @@ WebInspector.TracingTimelineModel.prototype = {
this._lastRecalculateStylesEvent = event;
break;
+ case recordTypes.StyleRecalcInvalidationTracking:
+ this._invalidationTracker.addInvalidation({
+ type: recordTypes.StyleRecalcInvalidationTracking,
+ frameId: event.args.data.frame,
+ nodeId: event.args.data.nodeId,
+ nodeName: event.args.data.nodeName,
+ reason: event.args.data.reason,
+ callstack: event.args.data.callstack
+ });
+ break;
+
+ case recordTypes.LayoutInvalidationTracking:
+ this._invalidationTracker.addInvalidation({
+ type: recordTypes.LayoutInvalidationTracking,
+ frameId: event.args.data.frame,
+ nodeId: event.args.data.nodeId,
+ nodeName: event.args.data.nodeName,
+ callstack: event.args.data.callstack
+ });
+ break;
+
+ case recordTypes.LayerInvalidationTracking:
+ this._invalidationTracker.addInvalidation({
+ type: recordTypes.LayerInvalidationTracking,
+ frameId: event.args.data.frame,
+ paintId: event.args.data.paintId,
+ reason: event.args.data.reason
+ });
+ break;
+
+ case recordTypes.PaintInvalidationTracking:
+ this._invalidationTracker.addInvalidation({
+ type: recordTypes.PaintInvalidationTracking,
+ frameId: event.args.data.frame,
+ nodeId: event.args.data.nodeId,
+ nodeName: event.args.data.nodeName,
+ paintId: event.args.data.paintId
+ });
+ break;
+
case recordTypes.InvalidateLayout:
// Consider style recalculation as a reason for layout invalidation,
// but only if we had no earlier layout invalidation records.
@@ -635,6 +683,7 @@ WebInspector.TracingTimelineModel.prototype = {
break;
case recordTypes.Paint:
+ this._invalidationTracker.didPaint(event);
event.highlightQuad = event.args["data"]["clip"];
event.backendNodeId = event.args["data"]["nodeId"];
var layerUpdateEvent = this._findAncestorEvent(recordTypes.UpdateLayer);
@@ -1103,3 +1152,88 @@ WebInspector.TracingTimelineSaver.prototype = {
*/
onError: function(reader, event) { },
}
+
+/**
+ * Track invalidation events across frames.
+ */
+WebInspector.InvalidationTracker = function()
+{
+ this._invalidationEvents = [];
+ this._lastPaintWithLayer = undefined;
+ this._didPaint = false;
+}
+
+WebInspector.InvalidationTracker.prototype = {
+
+ addInvalidation: function(invalidation)
+ {
+ this._startNewFrameIfNeeded();
+ if (!invalidation.nodeId && !invalidation.paintId) {
+ console.error('Invalidation lacks node information.');
+ console.error(invalidation);
+ }
+
+ // Record the paintIds for style recalc or layout invalidations.
+ // FIXME: This O(n^2) loop could be optimized with a map.
+ if (invalidation.type == WebInspector.TracingTimelineModel.RecordType.PaintInvalidationTracking) {
+ this._invalidationEvents.forEach(function(invalidationToUpdate) {
+ if (invalidationToUpdate.nodeId != invalidation.nodeId)
+ return;
+ switch (invalidationToUpdate.type) {
+ case WebInspector.TracingTimelineModel.RecordType.StyleRecalcInvalidationTracking:
+ invalidationToUpdate.paintId = invalidation.paintId;
+ break;
+ case WebInspector.TracingTimelineModel.RecordType.LayoutInvalidationTracking:
+ invalidationToUpdate.paintId = invalidation.paintId;
+ break;
+ }
+ });
+ } else {
+ this._invalidationEvents.push(invalidation);
+ }
+ },
+
+ didPaint: function(paintEvent)
+ {
+ this._didPaint = true;
+
+ // If a paint doesn't have a corresponding graphics layer id, it paints into it's parent so
+ // add an effectivePaintId to these events.
+ // FIXME: The parent layer is assumed to be the last paint event that had a layerId set. Is that right?
+ var layerId = paintEvent.args.data.layerId;
+ if (layerId)
+ this._lastPaintWithLayer = paintEvent;
+
+ if (!this._lastPaintWithLayer) {
+ console.error("Failed to find the paint container for a paint event.");
+ return;
+ }
+
+ var effectivePaintId = this._lastPaintWithLayer.args.data.nodeId;
+ this._processPaint(paintEvent, effectivePaintId);
+ },
+
+ _processPaint: function(paintEvent, effectivePaintId)
+ {
+ var frameId = paintEvent.args.data.frame;
+
+ this._invalidationEvents.forEach(function(invalidation) {
+ if (invalidation.paintId == effectivePaintId && invalidation.frameId == frameId) {
+ if (!paintEvent.invalidationTrackingEvents)
+ paintEvent.invalidationTrackingEvents = [];
+ paintEvent.invalidationTrackingEvents.push(invalidation);
+ }
+ });
+ },
+
+ _startNewFrameIfNeeded: function()
+ {
+ if (!this._didPaint)
+ return;
+
+ // Prepare for the next frame.
+ this._invalidationEvents = [];
+ this._lastPaintWithLayer = undefined;
+ this._didPaint = false;
+ }
+}
« 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