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/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 51 namespace WebCore { 52 struct FetchInitiatorInfo; 53 struct TimelineImageInfo; 54 struct TimelineThreadState; 55 struct TimelineRecordEntry; 56 57 class LocalDOMWindow; 58 class Document; 59 class DocumentLoader; 60 class Event; 61 class ExecutionContext; 62 class FloatQuad; 63 class LocalFrame; 64 class FrameHost; 65 class GraphicsContext; 66 class GraphicsLayer; 67 class InspectorClient; 68 class InspectorFrontend; 69 class InspectorOverlay; 70 class InspectorPageAgent; 71 class InspectorLayerTreeAgent; 72 class InstrumentingAgents; 73 class KURL; 74 class ScriptState; 75 class Node; 76 class RenderImage; 77 class RenderObject; 78 class ResourceError; 79 class ResourceLoader; 80 class ResourceRequest; 81 class ResourceResponse; 82 class ScriptArguments; 83 class ScriptCallStack; 84 class TimelineRecordStack; 85 class WebSocketHandshakeRequest; 86 class WebSocketHandshakeResponse; 87 class XMLHttpRequest; 88 89 typedef String ErrorString; 90 91 class InspectorTimelineAgent FINAL 92 : public TraceEventTarget<InspectorTimelineAgent> 93 , public InspectorBaseAgent<InspectorTimelineAgent> 94 , public ScriptGCEventListener 95 , public InspectorBackendDispatcher::TimelineCommandHandler 96 , public PlatformInstrumentationClient { 97 WTF_MAKE_NONCOPYABLE(InspectorTimelineAgent); 98 public: 99 enum InspectorType { PageInspector, WorkerInspector }; 100 101 class GPUEvent { 102 public: 103 enum Phase { PhaseBegin, PhaseEnd }; 104 GPUEvent(double timestamp, int phase, bool foreign, uint64_t usedGPUMemoryBytes, uint64_t limitGPUMemoryBytes) : 105 timestamp(timestamp), 106 phase(static_cast<Phase>(phase)), 107 foreign(foreign), 108 usedGPUMemoryBytes(usedGPUMemoryBytes), 109 limitGPUMemoryBytes(limitGPUMemoryBytes) { } 110 double timestamp; 111 Phase phase; 112 bool foreign; 113 uint64_t usedGPUMemoryBytes; 114 uint64_t limitGPUMemoryBytes; 115 }; 116 117 static PassOwnPtr<InspectorTimelineAgent> create(InspectorPageAgent* pageAgent, InspectorLayerTreeAgent* layerTreeAgent, 118 InspectorOverlay* overlay, InspectorType type, InspectorClient* client) 119 { 120 return adoptPtr(new InspectorTimelineAgent(pageAgent, layerTreeAgent, overlay, type, client)); 121 } 122 123 virtual ~InspectorTimelineAgent(); 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*, RefPtr<TypeBuilder::Array<TypeBuilder::Timeline::TimelineEvent> >& events) 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 230 private: 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 InspectorPageAgent* m_pageAgent; 290 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 HashMap<ThreadIdentifier, TimelineThreadState> ThreadStateMap; 317 ThreadStateMap m_threadStates; 318 bool m_mayEmitFirstPaint; 319 HashSet<String> m_liveEvents; 320 double m_lastProgressTimestamp; 321 }; 322 323 } // namespace WebCore 324 325 #endif // !defined(InspectorTimelineAgent_h) 326