Home | History | Annotate | Download | only in inspector
      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 
     51 namespace blink {
     52 struct FetchInitiatorInfo;
     53 struct TimelineImageInfo;
     54 struct TimelineRecordEntry;
     55 struct TimelineThreadState;
     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 InspectorBaseAgent<InspectorTimelineAgent>
     93     , public ScriptGCEventListener
     94     , public InspectorBackendDispatcher::TimelineCommandHandler
     95     , public PlatformInstrumentationClient {
     96     WTF_MAKE_NONCOPYABLE(InspectorTimelineAgent);
     97 public:
     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 
    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     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