• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 *     * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *     * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 *     * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30 
31 #ifndef InspectorTimelineAgent_h
32 #define InspectorTimelineAgent_h
33 
34 
35 #include "InspectorFrontend.h"
36 #include "bindings/v8/ScriptGCEvent.h"
37 #include "core/events/EventPath.h"
38 #include "core/inspector/InspectorBaseAgent.h"
39 #include "core/inspector/ScriptGCEventListener.h"
40 #include "core/inspector/TraceEventDispatcher.h"
41 #include "platform/JSONValues.h"
42 #include "platform/PlatformInstrumentation.h"
43 #include "platform/geometry/LayoutRect.h"
44 #include "wtf/PassOwnPtr.h"
45 #include "wtf/Vector.h"
46 #include "wtf/WeakPtr.h"
47 
48 namespace WebCore {
49 struct FetchInitiatorInfo;
50 struct TimelineGCEvent;
51 struct TimelineImageInfo;
52 struct TimelineThreadState;
53 struct TimelineRecordEntry;
54 
55 class DOMWindow;
56 class Document;
57 class DocumentLoader;
58 class Event;
59 class FloatQuad;
60 class Frame;
61 class GraphicsContext;
62 class GraphicsLayer;
63 class InspectorClient;
64 class InspectorDOMAgent;
65 class InspectorFrontend;
66 class InspectorMemoryAgent;
67 class InspectorOverlay;
68 class InspectorPageAgent;
69 class InstrumentingAgents;
70 class KURL;
71 class Node;
72 class Page;
73 class RenderImage;
74 class RenderObject;
75 class ResourceError;
76 class ResourceLoader;
77 class ResourceRequest;
78 class ResourceResponse;
79 class ScriptArguments;
80 class ScriptCallStack;
81 class TimelineRecordStack;
82 class ExecutionContext;
83 class ScriptState;
84 class WebSocketHandshakeRequest;
85 class WebSocketHandshakeResponse;
86 class XMLHttpRequest;
87 
88 typedef String ErrorString;
89 
90 namespace TimelineRecordType {
91 extern const char ActivateLayerTree[];
92 extern const char BeginFrame[];
93 extern const char DecodeImage[];
94 extern const char GPUTask[];
95 extern const char PaintSetup[];
96 extern const char Rasterize[];
97 };
98 
99 class TimelineTimeConverter {
100 public:
TimelineTimeConverter()101     TimelineTimeConverter()
102         : m_startOffset(0)
103     {
104     }
fromMonotonicallyIncreasingTime(double time)105     double fromMonotonicallyIncreasingTime(double time) const  { return (time - m_startOffset) * 1000.0; }
106     void reset();
107 
108 private:
109     double m_startOffset;
110 };
111 
112 class InspectorTimelineAgent
113     : public TraceEventTarget<InspectorTimelineAgent>
114     , public InspectorBaseAgent<InspectorTimelineAgent>
115     , public ScriptGCEventListener
116     , public InspectorBackendDispatcher::TimelineCommandHandler
117     , public PlatformInstrumentationClient {
118     WTF_MAKE_NONCOPYABLE(InspectorTimelineAgent);
119 public:
120     enum InspectorType { PageInspector, WorkerInspector };
121 
122     class GPUEvent {
123     public:
124         enum Phase { PhaseBegin, PhaseEnd };
GPUEvent(double timestamp,int phase,bool foreign,size_t usedGPUMemoryBytes)125         GPUEvent(double timestamp, int phase, bool foreign, size_t usedGPUMemoryBytes) :
126             timestamp(timestamp),
127             phase(static_cast<Phase>(phase)),
128             foreign(foreign),
129             usedGPUMemoryBytes(usedGPUMemoryBytes) { }
130         double timestamp;
131         Phase phase;
132         bool foreign;
133         size_t usedGPUMemoryBytes;
134     };
135 
create(InstrumentingAgents * instrumentingAgents,InspectorPageAgent * pageAgent,InspectorMemoryAgent * memoryAgent,InspectorDOMAgent * domAgent,InspectorOverlay * overlay,InspectorCompositeState * state,InspectorType type,InspectorClient * client)136     static PassOwnPtr<InspectorTimelineAgent> create(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent, InspectorMemoryAgent* memoryAgent, InspectorDOMAgent* domAgent, InspectorOverlay* overlay, InspectorCompositeState* state, InspectorType type, InspectorClient* client)
137     {
138         return adoptPtr(new InspectorTimelineAgent(instrumentingAgents, pageAgent, memoryAgent, domAgent, overlay, state, type, client));
139     }
140 
141     ~InspectorTimelineAgent();
142 
143     virtual void setFrontend(InspectorFrontend*);
144     virtual void clearFrontend();
145     virtual void restore();
146 
147     virtual void enable(ErrorString*);
148     virtual void disable(ErrorString*);
149     virtual void start(ErrorString*, const int* maxCallStackDepth, const bool* bufferEvents, const bool* includeDomCounters, const bool* includeGPUEvents);
150     virtual void stop(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Timeline::TimelineEvent> >& events);
151 
setLayerTreeId(int layerTreeId)152     void setLayerTreeId(int layerTreeId) { m_layerTreeId = layerTreeId; }
id()153     int id() const { return m_id; }
154 
155     void didCommitLoad();
156 
157     // Methods called from WebCore.
158     bool willCallFunction(ExecutionContext*, const String& scriptName, int scriptLine);
159     void didCallFunction();
160 
161     bool willDispatchEvent(Document* document, const Event& event, DOMWindow* window, Node* node, const EventPath& eventPath);
162     bool willDispatchEventOnWindow(const Event& event, DOMWindow* window);
163     void didDispatchEvent();
164     void didDispatchEventOnWindow();
165 
166     void didBeginFrame(int frameId);
167     void didCancelFrame();
168 
169     void didInvalidateLayout(Frame*);
170     bool willLayout(Frame*);
171     void didLayout(RenderObject*);
172 
173     void willAutosizeText(RenderObject*);
174     void didAutosizeText(RenderObject*);
175 
176     void didScheduleStyleRecalculation(Document*);
177     bool willRecalculateStyle(Document*);
178     void didRecalculateStyle();
179     void didRecalculateStyleForElement();
180 
181     void willPaint(RenderObject*, const GraphicsLayer*);
182     void didPaint(RenderObject*, const GraphicsLayer*, GraphicsContext*, const LayoutRect&);
183 
184     void willPaintImage(RenderImage*);
185     void didPaintImage();
186 
187     void willScrollLayer(RenderObject*);
188     void didScrollLayer();
189 
190     void willComposite();
191     void didComposite();
192 
193     bool willWriteHTML(Document*, unsigned startLine);
194     void didWriteHTML(unsigned endLine);
195 
196     void didInstallTimer(ExecutionContext*, int timerId, int timeout, bool singleShot);
197     void didRemoveTimer(ExecutionContext*, int timerId);
198     bool willFireTimer(ExecutionContext*, int timerId);
199     void didFireTimer();
200 
201     bool willDispatchXHRReadyStateChangeEvent(ExecutionContext*, XMLHttpRequest*);
202     void didDispatchXHRReadyStateChangeEvent();
203     bool willDispatchXHRLoadEvent(ExecutionContext*, XMLHttpRequest*);
204     void didDispatchXHRLoadEvent();
205 
206     bool willEvaluateScript(Frame*, const String&, int);
207     void didEvaluateScript();
208 
209     void consoleTimeStamp(ExecutionContext*, const String& title);
210     void domContentLoadedEventFired(Frame*);
211     void loadEventFired(Frame*);
212 
213     void consoleTime(ExecutionContext*, const String&);
214     void consoleTimeEnd(ExecutionContext*, const String&, ScriptState*);
215     void consoleTimeline(ExecutionContext*, const String& title, ScriptState*);
216     void consoleTimelineEnd(ExecutionContext*, const String& title, ScriptState*);
217 
218     void didScheduleResourceRequest(Document*, const String& url);
219     void willSendRequest(unsigned long, DocumentLoader*, const ResourceRequest&, const ResourceResponse&, const FetchInitiatorInfo&);
220     void didReceiveResourceResponse(Frame*, unsigned long, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
221     void didFinishLoading(unsigned long, DocumentLoader*, double monotonicFinishTime);
222     void didFailLoading(unsigned long identifier, DocumentLoader* loader, const ResourceError& error);
223     bool willReceiveResourceData(Frame*, unsigned long identifier, int length);
224     void didReceiveResourceData();
225 
226     void didRequestAnimationFrame(Document*, int callbackId);
227     void didCancelAnimationFrame(Document*, int callbackId);
228     bool willFireAnimationFrame(Document*, int callbackId);
229     void didFireAnimationFrame();
230 
231     void willProcessTask();
232     void didProcessTask();
233 
234     void didCreateWebSocket(Document*, unsigned long identifier, const KURL&, const String& protocol);
235     void willSendWebSocketHandshakeRequest(Document*, unsigned long identifier, const WebSocketHandshakeRequest&);
236     void didReceiveWebSocketHandshakeResponse(Document*, unsigned long identifier, const WebSocketHandshakeResponse&);
237     void didCloseWebSocket(Document*, unsigned long identifier);
238 
239     void processGPUEvent(const GPUEvent&);
240 
241     // ScriptGCEventListener methods.
242     virtual void didGC(double, double, size_t);
243 
244     // PlatformInstrumentationClient methods.
245     virtual void willDecodeImage(const String& imageType) OVERRIDE;
246     virtual void didDecodeImage() OVERRIDE;
247     virtual void willResizeImage(bool shouldCache) OVERRIDE;
248     virtual void didResizeImage() OVERRIDE;
249 
250 private:
251 
252     friend class TimelineRecordStack;
253 
254     InspectorTimelineAgent(InstrumentingAgents*, InspectorPageAgent*, InspectorMemoryAgent*, InspectorDOMAgent*, InspectorOverlay*, InspectorCompositeState*, InspectorType, InspectorClient*);
255 
256     // Trace event handlers
257     void onBeginImplSideFrame(const TraceEventDispatcher::TraceEvent&);
258     void onPaintSetupBegin(const TraceEventDispatcher::TraceEvent&);
259     void onPaintSetupEnd(const TraceEventDispatcher::TraceEvent&);
260     void onRasterTaskBegin(const TraceEventDispatcher::TraceEvent&);
261     void onRasterTaskEnd(const TraceEventDispatcher::TraceEvent&);
262     void onImageDecodeBegin(const TraceEventDispatcher::TraceEvent&);
263     void onImageDecodeEnd(const TraceEventDispatcher::TraceEvent&);
264     void onLayerDeleted(const TraceEventDispatcher::TraceEvent&);
265     void onDrawLazyPixelRef(const TraceEventDispatcher::TraceEvent&);
266     void onDecodeLazyPixelRefBegin(const TraceEventDispatcher::TraceEvent&);
267     void onDecodeLazyPixelRefEnd(const TraceEventDispatcher::TraceEvent&);
268     void onActivateLayerTree(const TraceEventDispatcher::TraceEvent&);
269     void onLazyPixelRefDeleted(const TraceEventDispatcher::TraceEvent&);
270 
271     void didFinishLoadingResource(unsigned long, bool didFail, double finishTime, Frame*);
272 
273     void sendEvent(PassRefPtr<JSONObject>);
274     void appendRecord(PassRefPtr<JSONObject> data, const String& type, bool captureCallStack, Frame*);
275     void pushCurrentRecord(PassRefPtr<JSONObject>, const String& type, bool captureCallStack, Frame*, bool hasLowLevelDetails = false);
276     TimelineThreadState& threadState(ThreadIdentifier);
277 
278     void setDOMCounters(TypeBuilder::Timeline::TimelineEvent*);
279     void setFrameIdentifier(JSONObject* record, Frame*);
280     void populateImageDetails(JSONObject* data, const RenderImage&);
281 
282     void pushGCEventRecords();
283 
284     void didCompleteCurrentRecord(const String& type);
285     void unwindRecordStack();
286 
287     void commitFrameRecord();
288 
289     void addRecordToTimeline(PassRefPtr<JSONObject>);
290     void innerAddRecordToTimeline(PassRefPtr<JSONObject>);
291     void clearRecordStack();
292     PassRefPtr<JSONObject> createRecordForEvent(const TraceEventDispatcher::TraceEvent&, const String& type, PassRefPtr<JSONObject> data = 0);
293 
294     void localToPageQuad(const RenderObject& renderer, const LayoutRect&, FloatQuad*);
295     long long nodeId(Node*);
296     long long nodeId(RenderObject*);
297     void releaseNodeIds();
298 
299     double timestamp();
300     Page* page();
301 
302     bool isStarted();
303     void innerStart();
304     void innerStop(bool fromConsole);
305 
306     InspectorPageAgent* m_pageAgent;
307     InspectorMemoryAgent* m_memoryAgent;
308     InspectorDOMAgent* m_domAgent;
309     InspectorFrontend::Timeline* m_frontend;
310     InspectorClient* m_client;
311     InspectorOverlay* m_overlay;
312     InspectorType m_inspectorType;
313 
314     int m_id;
315     unsigned long long m_layerTreeId;
316 
317     TimelineTimeConverter m_timeConverter;
318     int m_maxCallStackDepth;
319 
320     Vector<TimelineRecordEntry> m_recordStack;
321     RefPtr<TypeBuilder::Array<TypeBuilder::Timeline::TimelineEvent> > m_bufferedEvents;
322     Vector<String> m_consoleTimelines;
323 
324     typedef Vector<TimelineGCEvent> GCEvents;
325     GCEvents m_gcEvents;
326     unsigned m_platformInstrumentationClientInstalledAtStackDepth;
327     RefPtr<JSONObject> m_pendingFrameRecord;
328     RefPtr<JSONObject> m_pendingGPURecord;
329     typedef HashMap<unsigned long long, TimelineImageInfo> PixelRefToImageInfoMap;
330     PixelRefToImageInfoMap m_pixelRefToImageInfo;
331     RenderImage* m_imageBeingPainted;
332     HashMap<unsigned long long, long long> m_layerToNodeMap;
333     double m_paintSetupStart;
334     double m_paintSetupEnd;
335     RefPtr<JSONObject> m_gpuTask;
336     unsigned m_styleRecalcElementCounter;
337     typedef HashMap<ThreadIdentifier, TimelineThreadState> ThreadStateMap;
338     ThreadStateMap m_threadStates;
339     bool m_mayEmitFirstPaint;
340 };
341 
342 } // namespace WebCore
343 
344 #endif // !defined(InspectorTimelineAgent_h)
345