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 "bindings/core/v8/ScriptGCEvent.h"
36#include "core/InspectorFrontend.h"
37#include "core/InspectorTypeBuilder.h"
38#include "core/events/EventPath.h"
39#include "core/inspector/InspectorBaseAgent.h"
40#include "core/inspector/ScriptGCEventListener.h"
41#include "core/inspector/TraceEventDispatcher.h"
42#include "platform/JSONValues.h"
43#include "platform/PlatformInstrumentation.h"
44#include "platform/geometry/LayoutRect.h"
45#include "wtf/HashMap.h"
46#include "wtf/HashSet.h"
47#include "wtf/PassOwnPtr.h"
48#include "wtf/Vector.h"
49#include "wtf/WeakPtr.h"
50
51namespace blink {
52struct FetchInitiatorInfo;
53struct TimelineImageInfo;
54struct TimelineRecordEntry;
55struct TimelineThreadState;
56
57class LocalDOMWindow;
58class Document;
59class DocumentLoader;
60class Event;
61class ExecutionContext;
62class FloatQuad;
63class LocalFrame;
64class FrameHost;
65class GraphicsContext;
66class GraphicsLayer;
67class InspectorClient;
68class InspectorFrontend;
69class InspectorOverlay;
70class InspectorPageAgent;
71class InspectorLayerTreeAgent;
72class InstrumentingAgents;
73class KURL;
74class ScriptState;
75class Node;
76class RenderImage;
77class RenderObject;
78class ResourceError;
79class ResourceLoader;
80class ResourceRequest;
81class ResourceResponse;
82class ScriptArguments;
83class ScriptCallStack;
84class TimelineRecordStack;
85class WebSocketHandshakeRequest;
86class WebSocketHandshakeResponse;
87class XMLHttpRequest;
88
89typedef String ErrorString;
90
91class InspectorTimelineAgent FINAL
92    : public InspectorBaseAgent<InspectorTimelineAgent>
93    , public ScriptGCEventListener
94    , public InspectorBackendDispatcher::TimelineCommandHandler
95    , public PlatformInstrumentationClient {
96    WTF_MAKE_NONCOPYABLE(InspectorTimelineAgent);
97public:
98    enum InspectorType { PageInspector, WorkerInspector };
99
100    class GPUEvent {
101    public:
102        enum Phase { PhaseBegin, PhaseEnd };
103        GPUEvent(double timestamp, int phase, bool foreign, uint64_t usedGPUMemoryBytes, uint64_t limitGPUMemoryBytes) :
104            timestamp(timestamp),
105            phase(static_cast<Phase>(phase)),
106            foreign(foreign),
107            usedGPUMemoryBytes(usedGPUMemoryBytes),
108            limitGPUMemoryBytes(limitGPUMemoryBytes) { }
109        double timestamp;
110        Phase phase;
111        bool foreign;
112        uint64_t usedGPUMemoryBytes;
113        uint64_t limitGPUMemoryBytes;
114    };
115
116    static PassOwnPtrWillBeRawPtr<InspectorTimelineAgent> create(InspectorPageAgent* pageAgent, InspectorLayerTreeAgent* layerTreeAgent,
117        InspectorOverlay* overlay, InspectorType type, InspectorClient* client)
118    {
119        return adoptPtrWillBeNoop(new InspectorTimelineAgent(pageAgent, layerTreeAgent, overlay, type, client));
120    }
121
122    virtual ~InspectorTimelineAgent();
123    virtual void trace(Visitor*) OVERRIDE;
124
125    virtual void setFrontend(InspectorFrontend*) OVERRIDE;
126    virtual void clearFrontend() OVERRIDE;
127    virtual void restore() OVERRIDE;
128
129    virtual void enable(ErrorString*) OVERRIDE;
130    virtual void disable(ErrorString*) OVERRIDE;
131    virtual void start(ErrorString*, const int* maxCallStackDepth, const bool* bufferEvents, const String* liveEvents, const bool* includeCounters, const bool* includeGPUEvents) OVERRIDE;
132    virtual void stop(ErrorString*) OVERRIDE;
133
134    void setLayerTreeId(int layerTreeId) { m_layerTreeId = layerTreeId; }
135    int id() const { return m_id; }
136
137    void didCommitLoad();
138
139    // Methods called from WebCore.
140    bool willCallFunction(ExecutionContext*, int scriptId, const String& scriptName, int scriptLine);
141    void didCallFunction();
142
143    bool willDispatchEvent(Document* document, const Event& event, LocalDOMWindow* window, Node* node, const EventPath& eventPath);
144    bool willDispatchEventOnWindow(const Event& event, LocalDOMWindow* window);
145    void didDispatchEvent();
146    void didDispatchEventOnWindow();
147
148    void didBeginFrame(int frameId);
149    void didCancelFrame();
150
151    void didInvalidateLayout(LocalFrame*);
152    bool willLayout(LocalFrame*);
153    void didLayout(RenderObject*);
154
155    void willUpdateLayerTree();
156    void layerTreeDidChange();
157    void didUpdateLayerTree();
158
159    void didScheduleStyleRecalculation(Document*);
160    bool willRecalculateStyle(Document*);
161    void didRecalculateStyle(int elementCount);
162
163    void willPaint(RenderObject*, const GraphicsLayer*);
164    void didPaint(RenderObject*, const GraphicsLayer*, GraphicsContext*, const LayoutRect&);
165
166    void willPaintImage(RenderImage*);
167    void didPaintImage();
168
169    void willScrollLayer(RenderObject*);
170    void didScrollLayer();
171
172    void willComposite();
173    void didComposite();
174
175    bool willWriteHTML(Document*, unsigned startLine);
176    void didWriteHTML(unsigned endLine);
177
178    void didInstallTimer(ExecutionContext*, int timerId, int timeout, bool singleShot);
179    void didRemoveTimer(ExecutionContext*, int timerId);
180    bool willFireTimer(ExecutionContext*, int timerId);
181    void didFireTimer();
182
183    bool willDispatchXHRReadyStateChangeEvent(ExecutionContext*, XMLHttpRequest*);
184    void didDispatchXHRReadyStateChangeEvent();
185    bool willDispatchXHRLoadEvent(ExecutionContext*, XMLHttpRequest*);
186    void didDispatchXHRLoadEvent();
187
188    bool willEvaluateScript(LocalFrame*, const String&, int);
189    void didEvaluateScript();
190
191    void consoleTimeStamp(ExecutionContext*, const String& title);
192    void domContentLoadedEventFired(LocalFrame*);
193    void loadEventFired(LocalFrame*);
194
195    void consoleTime(ExecutionContext*, const String&);
196    void consoleTimeEnd(ExecutionContext*, const String&, ScriptState*);
197    void consoleTimeline(ExecutionContext*, const String& title, ScriptState*);
198    void consoleTimelineEnd(ExecutionContext*, const String& title, ScriptState*);
199
200    void willSendRequest(unsigned long, DocumentLoader*, const ResourceRequest&, const ResourceResponse&, const FetchInitiatorInfo&);
201    void didReceiveResourceResponse(LocalFrame*, unsigned long, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
202    void didFinishLoading(unsigned long, DocumentLoader*, double monotonicFinishTime, int64_t);
203    void didFailLoading(unsigned long identifier, const ResourceError&);
204    void didReceiveData(LocalFrame*, unsigned long identifier, const char* data, int dataLength, int encodedDataLength);
205
206    void didRequestAnimationFrame(Document*, int callbackId);
207    void didCancelAnimationFrame(Document*, int callbackId);
208    bool willFireAnimationFrame(Document*, int callbackId);
209    void didFireAnimationFrame();
210
211    void willProcessTask();
212    void didProcessTask();
213
214    void didCreateWebSocket(Document*, unsigned long identifier, const KURL&, const String& protocol);
215    void willSendWebSocketHandshakeRequest(Document*, unsigned long identifier, const WebSocketHandshakeRequest*);
216    void didReceiveWebSocketHandshakeResponse(Document*, unsigned long identifier, const WebSocketHandshakeRequest*, const WebSocketHandshakeResponse*);
217    void didCloseWebSocket(Document*, unsigned long identifier);
218
219    void processGPUEvent(const GPUEvent&);
220
221    // ScriptGCEventListener methods.
222    virtual void didGC(double, double, size_t) OVERRIDE;
223
224    // PlatformInstrumentationClient methods.
225    virtual void willDecodeImage(const String& imageType) OVERRIDE;
226    virtual void didDecodeImage() OVERRIDE;
227    virtual void willResizeImage(bool shouldCache) OVERRIDE;
228    virtual void didResizeImage() OVERRIDE;
229
230private:
231
232    friend class TimelineRecordStack;
233
234    InspectorTimelineAgent(InspectorPageAgent*, InspectorLayerTreeAgent*, InspectorOverlay*, InspectorType, InspectorClient*);
235
236    // Trace event handlers
237    void onBeginImplSideFrame(const TraceEventDispatcher::TraceEvent&);
238    void onPaintSetupBegin(const TraceEventDispatcher::TraceEvent&);
239    void onPaintSetupEnd(const TraceEventDispatcher::TraceEvent&);
240    void onRasterTaskBegin(const TraceEventDispatcher::TraceEvent&);
241    void onRasterTaskEnd(const TraceEventDispatcher::TraceEvent&);
242    void onImageDecodeBegin(const TraceEventDispatcher::TraceEvent&);
243    void onImageDecodeEnd(const TraceEventDispatcher::TraceEvent&);
244    void onLayerDeleted(const TraceEventDispatcher::TraceEvent&);
245    void onDrawLazyPixelRef(const TraceEventDispatcher::TraceEvent&);
246    void onDecodeLazyPixelRefBegin(const TraceEventDispatcher::TraceEvent&);
247    void onDecodeLazyPixelRefEnd(const TraceEventDispatcher::TraceEvent&);
248    void onRequestMainThreadFrame(const TraceEventDispatcher::TraceEvent&);
249    void onActivateLayerTree(const TraceEventDispatcher::TraceEvent&);
250    void onDrawFrame(const TraceEventDispatcher::TraceEvent&);
251    void onLazyPixelRefDeleted(const TraceEventDispatcher::TraceEvent&);
252    void onEmbedderCallbackBegin(const TraceEventDispatcher::TraceEvent&);
253    void onEmbedderCallbackEnd(const TraceEventDispatcher::TraceEvent&);
254
255    void didFinishLoadingResource(unsigned long, bool didFail, double finishTime);
256
257    void sendEvent(PassRefPtr<TypeBuilder::Timeline::TimelineEvent>);
258    void appendRecord(PassRefPtr<JSONObject> data, const String& type, bool captureCallStack, LocalFrame*);
259    void pushCurrentRecord(PassRefPtr<JSONObject> data, const String& type, bool captureCallStack, LocalFrame*, bool hasLowLevelDetails = false);
260    TimelineThreadState& threadState(ThreadIdentifier);
261
262    void setFrameIdentifier(TypeBuilder::Timeline::TimelineEvent* record, LocalFrame*);
263    void populateImageDetails(JSONObject* data, const RenderImage&);
264
265    void didCompleteCurrentRecord(const String& type);
266    void unwindRecordStack();
267
268    void commitFrameRecord();
269
270    void addRecordToTimeline(PassRefPtr<TypeBuilder::Timeline::TimelineEvent>, double ts);
271    void innerAddRecordToTimeline(PassRefPtr<TypeBuilder::Timeline::TimelineEvent>);
272    PassRefPtr<TypeBuilder::Timeline::TimelineEvent> createCountersUpdate();
273    void clearRecordStack();
274    PassRefPtr<TypeBuilder::Timeline::TimelineEvent> createRecordForEvent(const TraceEventDispatcher::TraceEvent&, const String& type, PassRefPtr<JSONObject> data);
275
276    void localToPageQuad(const RenderObject& renderer, const LayoutRect&, FloatQuad*);
277    long long nodeId(Node*);
278    long long nodeId(RenderObject*);
279
280    double timestamp();
281
282    LocalFrame* mainFrame() const;
283
284    bool isStarted();
285    void innerStart();
286    void innerStop(bool fromConsole);
287    void setLiveEvents(const String&);
288
289    RawPtrWillBeMember<InspectorPageAgent> m_pageAgent;
290    RawPtrWillBeMember<InspectorLayerTreeAgent> m_layerTreeAgent;
291    InspectorFrontend::Timeline* m_frontend;
292    InspectorClient* m_client;
293    InspectorOverlay* m_overlay;
294    InspectorType m_inspectorType;
295
296    int m_id;
297    unsigned long long m_layerTreeId;
298
299    int m_maxCallStackDepth;
300
301    Vector<TimelineRecordEntry> m_recordStack;
302    RefPtr<TypeBuilder::Array<TypeBuilder::Timeline::TimelineEvent> > m_bufferedEvents;
303    Vector<String> m_consoleTimelines;
304
305    unsigned m_platformInstrumentationClientInstalledAtStackDepth;
306    RefPtr<TypeBuilder::Timeline::TimelineEvent> m_pendingFrameRecord;
307    RefPtr<TypeBuilder::Timeline::TimelineEvent> m_pendingGPURecord;
308    typedef HashMap<unsigned long long, TimelineImageInfo> PixelRefToImageInfoMap;
309    PixelRefToImageInfoMap m_pixelRefToImageInfo;
310    RenderImage* m_imageBeingPainted;
311    HashMap<unsigned long long, long long> m_layerToNodeMap;
312    double m_paintSetupStart;
313    double m_paintSetupEnd;
314    RefPtr<JSONObject> m_gpuTask;
315    RefPtr<JSONValue> m_pendingLayerTreeData;
316    typedef WillBeHeapHashMap<ThreadIdentifier, TimelineThreadState> ThreadStateMap;
317    ThreadStateMap m_threadStates;
318    bool m_mayEmitFirstPaint;
319    HashSet<String> m_liveEvents;
320    double m_lastProgressTimestamp;
321};
322
323} // namespace blink
324
325#endif // !defined(InspectorTimelineAgent_h)
326