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