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 "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:
    101     TimelineTimeConverter()
    102         : m_startOffset(0)
    103     {
    104     }
    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 };
    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 
    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 
    152     void setLayerTreeId(int layerTreeId) { m_layerTreeId = layerTreeId; }
    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