OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 /** | |
6 * @constructor | |
7 */ | |
8 WebInspector.TimelineTraceEventBindings = function() | |
9 { | |
10 this._reset(); | |
11 } | |
12 | |
13 WebInspector.TimelineTraceEventBindings.RecordType = { | |
14 Program: "Program", | |
15 EventDispatch: "EventDispatch", | |
16 | |
17 GPUTask: "GPUTask", | |
18 | |
19 RequestMainThreadFrame: "RequestMainThreadFrame", | |
20 BeginFrame: "BeginFrame", | |
21 BeginMainThreadFrame: "BeginMainThreadFrame", | |
22 ActivateLayerTree: "ActivateLayerTree", | |
23 DrawFrame: "DrawFrame", | |
24 ScheduleStyleRecalculation: "ScheduleStyleRecalculation", | |
25 RecalculateStyles: "RecalculateStyles", | |
26 InvalidateLayout: "InvalidateLayout", | |
27 Layout: "Layout", | |
28 UpdateLayerTree: "UpdateLayerTree", | |
29 PaintSetup: "PaintSetup", | |
30 Paint: "Paint", | |
31 PaintImage: "PaintImage", | |
32 Rasterize: "Rasterize", | |
33 RasterTask: "RasterTask", | |
34 ScrollLayer: "ScrollLayer", | |
35 CompositeLayers: "CompositeLayers", | |
36 | |
37 ParseHTML: "ParseHTML", | |
38 | |
39 TimerInstall: "TimerInstall", | |
40 TimerRemove: "TimerRemove", | |
41 TimerFire: "TimerFire", | |
42 | |
43 XHRReadyStateChange: "XHRReadyStateChange", | |
44 XHRLoad: "XHRLoad", | |
45 EvaluateScript: "EvaluateScript", | |
46 | |
47 MarkLoad: "MarkLoad", | |
48 MarkDOMContent: "MarkDOMContent", | |
49 MarkFirstPaint: "MarkFirstPaint", | |
50 | |
51 TimeStamp: "TimeStamp", | |
52 ConsoleTime: "ConsoleTime", | |
53 | |
54 ResourceSendRequest: "ResourceSendRequest", | |
55 ResourceReceiveResponse: "ResourceReceiveResponse", | |
56 ResourceReceivedData: "ResourceReceivedData", | |
57 ResourceFinish: "ResourceFinish", | |
58 | |
59 FunctionCall: "FunctionCall", | |
60 GCEvent: "GCEvent", | |
61 JSFrame: "JSFrame", | |
62 | |
63 UpdateCounters: "UpdateCounters", | |
64 | |
65 RequestAnimationFrame: "RequestAnimationFrame", | |
66 CancelAnimationFrame: "CancelAnimationFrame", | |
67 FireAnimationFrame: "FireAnimationFrame", | |
68 | |
69 WebSocketCreate : "WebSocketCreate", | |
70 WebSocketSendHandshakeRequest : "WebSocketSendHandshakeRequest", | |
71 WebSocketReceiveHandshakeResponse : "WebSocketReceiveHandshakeResponse", | |
72 WebSocketDestroy : "WebSocketDestroy", | |
73 | |
74 EmbedderCallback : "EmbedderCallback", | |
75 | |
76 CallStack: "CallStack", | |
77 SetLayerTreeId: "SetLayerTreeId", | |
78 TracingStartedInPage: "TracingStartedInPage", | |
79 | |
80 DecodeImage: "Decode Image", | |
81 ResizeImage: "Resize Image", | |
82 DrawLazyPixelRef: "Draw LazyPixelRef", | |
83 DecodeLazyPixelRef: "Decode LazyPixelRef", | |
84 | |
85 LazyPixelRef: "LazyPixelRef", | |
86 LayerTreeHostImplSnapshot: "cc::LayerTreeHostImpl" | |
87 }; | |
88 | |
89 | |
90 WebInspector.TimelineTraceEventBindings.prototype = { | |
91 /** | |
92 * @return {!Array.<!WebInspector.TracingModel.Event>} | |
93 */ | |
94 mainThreadEvents: function() | |
95 { | |
96 return this._mainThreadEvents; | |
97 }, | |
98 | |
99 _reset: function() | |
100 { | |
101 this._resetProcessingState(); | |
102 this._mainThreadEvents = []; | |
103 }, | |
104 | |
105 _resetProcessingState: function() | |
106 { | |
107 this._sendRequestEvents = {}; | |
108 this._timerEvents = {}; | |
109 this._requestAnimationFrameEvents = {}; | |
110 this._layoutInvalidate = {}; | |
111 this._lastScheduleStyleRecalculation = {}; | |
112 this._webSocketCreateEvents = {}; | |
113 this._paintImageEventByPixelRefId = {}; | |
114 | |
115 this._lastRecalculateStylesEvent = null; | |
116 this._currentScriptEvent = null; | |
117 this._eventStack = []; | |
118 }, | |
119 | |
120 /** | |
121 * @param {!Array.<!WebInspector.TracingModel.Event>} events | |
122 */ | |
123 setEvents: function(events) | |
124 { | |
125 this._resetProcessingState(); | |
126 for (var i = 0, length = events.length; i < length; i++) | |
127 this._processEvent(events[i]); | |
128 this._resetProcessingState(); | |
129 }, | |
130 | |
131 /** | |
132 * @param {!WebInspector.TracingModel.Event} event | |
133 */ | |
134 _processEvent: function(event) | |
135 { | |
136 var recordTypes = WebInspector.TimelineTraceEventBindings.RecordType; | |
137 | |
138 var eventStack = this._eventStack; | |
139 while (eventStack.length && eventStack.peekLast().endTime < event.startT
ime) | |
140 eventStack.pop(); | |
141 var duration = event.duration; | |
142 if (duration) { | |
143 if (eventStack.length) { | |
144 var parent = eventStack.peekLast(); | |
145 parent.selfTime -= duration; | |
146 } | |
147 event.selfTime = duration; | |
148 eventStack.push(event); | |
149 } | |
150 | |
151 if (this._currentScriptEvent && event.startTime > this._currentScriptEve
nt.endTime) | |
152 this._currentScriptEvent = null; | |
153 | |
154 switch (event.name) { | |
155 case recordTypes.CallStack: | |
156 var lastMainThreadEvent = this._mainThreadEvents.peekLast(); | |
157 if (lastMainThreadEvent) | |
158 lastMainThreadEvent.stackTrace = event.args.stack; | |
159 break; | |
160 | |
161 case recordTypes.ResourceSendRequest: | |
162 this._sendRequestEvents[event.args.data["requestId"]] = event; | |
163 event.imageURL = event.args.data["url"]; | |
164 break; | |
165 | |
166 case recordTypes.ResourceReceiveResponse: | |
167 case recordTypes.ResourceReceivedData: | |
168 case recordTypes.ResourceFinish: | |
169 event.initiator = this._sendRequestEvents[event.args.data["requestId
"]]; | |
170 if (event.initiator) | |
171 event.imageURL = event.initiator.imageURL; | |
172 break; | |
173 | |
174 case recordTypes.TimerInstall: | |
175 this._timerEvents[event.args.data["timerId"]] = event; | |
176 break; | |
177 | |
178 case recordTypes.TimerFire: | |
179 event.initiator = this._timerEvents[event.args.data["timerId"]]; | |
180 break; | |
181 | |
182 case recordTypes.RequestAnimationFrame: | |
183 this._requestAnimationFrameEvents[event.args.data["id"]] = event; | |
184 break; | |
185 | |
186 case recordTypes.FireAnimationFrame: | |
187 event.initiator = this._requestAnimationFrameEvents[event.args.data[
"id"]]; | |
188 break; | |
189 | |
190 case recordTypes.ScheduleStyleRecalculation: | |
191 this._lastScheduleStyleRecalculation[event.args.frame] = event; | |
192 break; | |
193 | |
194 case recordTypes.RecalculateStyles: | |
195 event.initiator = this._lastScheduleStyleRecalculation[event.args.fr
ame]; | |
196 this._lastRecalculateStylesEvent = event; | |
197 break; | |
198 | |
199 case recordTypes.InvalidateLayout: | |
200 // Consider style recalculation as a reason for layout invalidation, | |
201 // but only if we had no earlier layout invalidation records. | |
202 var layoutInitator = event; | |
203 var frameId = event.args.frame; | |
204 if (!this._layoutInvalidate[frameId] && this._lastRecalculateStylesE
vent && this._lastRecalculateStylesEvent.endTime > event.startTime) | |
205 layoutInitator = this._lastRecalculateStylesEvent.initiator; | |
206 this._layoutInvalidate[frameId] = layoutInitator; | |
207 break; | |
208 | |
209 case recordTypes.Layout: | |
210 var frameId = event.args["beginData"]["frame"]; | |
211 event.initiator = this._layoutInvalidate[frameId]; | |
212 event.backendNodeId = event.args["endData"]["rootNode"]; | |
213 this._layoutInvalidate[frameId] = null; | |
214 if (this._currentScriptEvent) | |
215 event.warning = WebInspector.UIString("Forced synchronous layout
is a possible performance bottleneck."); | |
216 break; | |
217 | |
218 case recordTypes.WebSocketCreate: | |
219 this._webSocketCreateEvents[event.args.data["identifier"]] = event; | |
220 break; | |
221 | |
222 case recordTypes.WebSocketSendHandshakeRequest: | |
223 case recordTypes.WebSocketReceiveHandshakeResponse: | |
224 case recordTypes.WebSocketDestroy: | |
225 event.initiator = this._webSocketCreateEvents[event.args.data["ident
ifier"]]; | |
226 break; | |
227 | |
228 case recordTypes.EvaluateScript: | |
229 case recordTypes.FunctionCall: | |
230 if (!this._currentScriptEvent) | |
231 this._currentScriptEvent = event; | |
232 break; | |
233 | |
234 case recordTypes.SetLayerTreeId: | |
235 this._inspectedTargetLayerTreeId = event.args["layerTreeId"]; | |
236 break; | |
237 | |
238 case recordTypes.TracingStartedInPage: | |
239 this._mainThread = event.thread; | |
240 break; | |
241 | |
242 case recordTypes.Paint: | |
243 case recordTypes.ScrollLayer: | |
244 event.backendNodeId = event.args["data"]["nodeId"]; | |
245 break; | |
246 | |
247 case recordTypes.PaintImage: | |
248 event.backendNodeId = event.args["data"]["nodeId"]; | |
249 event.imageURL = event.args["data"]["url"]; | |
250 break; | |
251 | |
252 case recordTypes.DecodeImage: | |
253 case recordTypes.ResizeImage: | |
254 var paintImageEvent = this._findAncestorEvent(recordTypes.PaintImage
); | |
255 if (!paintImageEvent) { | |
256 var decodeLazyPixelRefEvent = this._findAncestorEvent(recordType
s.DecodeLazyPixelRef); | |
257 paintImageEvent = decodeLazyPixelRefEvent && this._paintImageEve
ntByPixelRefId[decodeLazyPixelRefEvent.args["LazyPixelRef"]]; | |
258 } | |
259 if (!paintImageEvent) | |
260 break; | |
261 event.backendNodeId = paintImageEvent.backendNodeId; | |
262 event.imageURL = paintImageEvent.imageURL; | |
263 break; | |
264 | |
265 case recordTypes.DrawLazyPixelRef: | |
266 var paintImageEvent = this._findAncestorEvent(recordTypes.PaintImage
); | |
267 if (!paintImageEvent) | |
268 break; | |
269 this._paintImageEventByPixelRefId[event.args["LazyPixelRef"]] = pain
tImageEvent; | |
270 event.backendNodeId = paintImageEvent.backendNodeId; | |
271 event.imageURL = paintImageEvent.imageURL; | |
272 break; | |
273 } | |
274 if (this._mainThread === event.thread) | |
275 this._mainThreadEvents.push(event); | |
276 }, | |
277 | |
278 /** | |
279 * @param {string} name | |
280 * @return {?WebInspector.TracingModel.Event} | |
281 */ | |
282 _findAncestorEvent: function(name) | |
283 { | |
284 for (var i = this._eventStack.length - 1; i >= 0; --i) { | |
285 var event = this._eventStack[i]; | |
286 if (event.name === name) | |
287 return event; | |
288 } | |
289 return null; | |
290 } | |
291 } | |
292 | |
OLD | NEW |