2011-09-18 Ilya Tikhonovsky <loislo@chromium.org>
authorloislo@chromium.org <loislo@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 19 Sep 2011 07:36:12 +0000 (07:36 +0000)
committerloislo@chromium.org <loislo@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 19 Sep 2011 07:36:12 +0000 (07:36 +0000)
        Web Inspector: requestAnimationFrame callbacks don't show up in the timeline panel.
        https://bugs.webkit.org/show_bug.cgi?id=67986

        Reviewed by Pavel Feldman.

        Test: inspector/timeline/timeline-animation-frame.html

WebCore:

        * English.lproj/localizedStrings.js:
        * bindings/v8/V8Proxy.cpp:
        (WebCore::V8Proxy::callFunction):
        (WebCore::V8Proxy::callFunctionWithoutFrame):
        (WebCore::V8Proxy::instrumentedCallFunction):
        * bindings/v8/V8Proxy.h:
        * bindings/v8/custom/V8CustomVoidCallback.cpp:
        (WebCore::invokeCallback):
        * dom/ScriptedAnimationController.cpp:
        (WebCore::ScriptedAnimationController::registerCallback):
        (WebCore::ScriptedAnimationController::cancelCallback):
        (WebCore::ScriptedAnimationController::serviceScriptedAnimations):
        * inspector/InspectorInstrumentation.cpp:
        (WebCore::InspectorInstrumentation::didRegisterAnimationFrameCallbackImpl):
        (WebCore::InspectorInstrumentation::didCancelAnimationFrameCallbackImpl):
        (WebCore::InspectorInstrumentation::willFireAnimationFrameEventImpl):
        (WebCore::InspectorInstrumentation::didFireAnimationFrameEventImpl):
        * inspector/InspectorInstrumentation.h:
        (WebCore::InspectorInstrumentation::willCallFunction):
        (WebCore::InspectorInstrumentation::didRegisterAnimationFrameCallback):
        (WebCore::InspectorInstrumentation::didCancelAnimationFrameCallback):
        (WebCore::InspectorInstrumentation::willFireAnimationFrameEvent):
        (WebCore::InspectorInstrumentation::didFireAnimationFrameEvent):
        * inspector/InspectorTimelineAgent.cpp:
        (WebCore::InspectorTimelineAgent::didRegisterAnimationFrameCallback):
        (WebCore::InspectorTimelineAgent::didCancelAnimationFrameCallback):
        (WebCore::InspectorTimelineAgent::willFireAnimationFrameEvent):
        (WebCore::InspectorTimelineAgent::didFireAnimationFrameEvent):
        * inspector/InspectorTimelineAgent.h:
        * inspector/TimelineRecordFactory.cpp:
        (WebCore::TimelineRecordFactory::createAnimationFrameCallbackData):
        * inspector/TimelineRecordFactory.h:
        * inspector/front-end/TimelineAgent.js:
        * inspector/front-end/TimelinePanel.js:
        (WebInspector.TimelinePanel):
        (WebInspector.TimelinePanel.prototype.get _recordStyles):
        (WebInspector.TimelinePanel.prototype._innerAddRecordToTimeline):
        (WebInspector.TimelinePanel.prototype._clearPanel):
        (WebInspector.TimelinePanel.FormattedRecord):
        (WebInspector.TimelinePanel.FormattedRecord.prototype._generatePopupContent):
        (WebInspector.TimelinePanel.FormattedRecord.prototype._getRecordDetails):

        LayoutTests:

        * inspector/timeline/timeline-animation-frame-expected.txt: Added.
        * inspector/timeline/timeline-animation-frame.html: Added.
        * inspector/timeline/timeline-enum-stability-expected.txt:
        * platform/chromium/inspector/timeline/timeline-enum-stability-expected.txt:
        * platform/qt/Skipped: inspector/timeline/timeline-animation-frame.html was added to the skip list.
        * inspector/timeline/timeline-test.js:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@95404 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
LayoutTests/ChangeLog
LayoutTests/inspector/timeline/timeline-animation-frame-expected.txt [new file with mode: 0644]
LayoutTests/inspector/timeline/timeline-animation-frame.html [new file with mode: 0644]
LayoutTests/inspector/timeline/timeline-enum-stability-expected.txt
LayoutTests/inspector/timeline/timeline-test.js
LayoutTests/platform/chromium/inspector/timeline/timeline-animation-frame-expected.txt [new file with mode: 0644]
LayoutTests/platform/qt/Skipped
Source/WebCore/ChangeLog
Source/WebCore/English.lproj/localizedStrings.js
Source/WebCore/bindings/v8/V8Proxy.cpp
Source/WebCore/bindings/v8/V8Proxy.h
Source/WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp
Source/WebCore/dom/ScriptedAnimationController.cpp
Source/WebCore/inspector/InspectorInstrumentation.cpp
Source/WebCore/inspector/InspectorInstrumentation.h
Source/WebCore/inspector/InspectorTimelineAgent.cpp
Source/WebCore/inspector/InspectorTimelineAgent.h
Source/WebCore/inspector/TimelineRecordFactory.cpp
Source/WebCore/inspector/TimelineRecordFactory.h
Source/WebCore/inspector/front-end/TimelineAgent.js
Source/WebCore/inspector/front-end/TimelinePanel.js

index ddff755e77000680745e5a04aa4ce840be68260f..768c44a416778a1b4c24a7390540683485acbba9 100644 (file)
@@ -1,3 +1,17 @@
+2011-09-18  Ilya Tikhonovsky  <loislo@chromium.org>
+
+        Web Inspector: requestAnimationFrame callbacks don't show up in the timeline panel.
+        https://bugs.webkit.org/show_bug.cgi?id=67986
+
+        Reviewed by Pavel Feldman.
+
+        * inspector/timeline/timeline-animation-frame-expected.txt: Added.
+        * inspector/timeline/timeline-animation-frame.html: Added.
+        * inspector/timeline/timeline-enum-stability-expected.txt:
+        * platform/chromium/inspector/timeline/timeline-enum-stability-expected.txt:
+        * platform/qt/Skipped: inspector/timeline/timeline-animation-frame.html was added to the skip list.
+        * inspector/timeline/timeline-test.js:
+
 2011-09-18  James Kozianski  <koz@chromium.org>
 
         Rebaseline navigator test for chromium-win-vista.
diff --git a/LayoutTests/inspector/timeline/timeline-animation-frame-expected.txt b/LayoutTests/inspector/timeline/timeline-animation-frame-expected.txt
new file mode 100644 (file)
index 0000000..8dd12ac
--- /dev/null
@@ -0,0 +1,35 @@
+Tests the Timeline events for Animation Frame feature
+
+RegisterAnimationFrameCallback Properties:
+{
+    startTime : <number>
+    data : {
+        id : <number>
+    }
+    type : "RegisterAnimationFrameCallback"
+    usedHeapSize : <number>
+    totalHeapSize : <number>
+}
+FireAnimationFrameEvent Properties:
+{
+    startTime : <number>
+    data : {
+        id : <number>
+    }
+    children : <object>
+    endTime : <number>
+    type : "FireAnimationFrameEvent"
+    usedHeapSize : <number>
+    totalHeapSize : <number>
+}
+CancelAnimationFrameCallback Properties:
+{
+    startTime : <number>
+    data : {
+        id : <number>
+    }
+    type : "CancelAnimationFrameCallback"
+    usedHeapSize : <number>
+    totalHeapSize : <number>
+}
+
diff --git a/LayoutTests/inspector/timeline/timeline-animation-frame.html b/LayoutTests/inspector/timeline/timeline-animation-frame.html
new file mode 100644 (file)
index 0000000..5fdf3db
--- /dev/null
@@ -0,0 +1,60 @@
+<html>
+<head>
+<script src="../../http/tests/inspector/inspector-test.js"></script>
+<script src="timeline-test.js"></script>
+<script>
+
+function performActions()
+{
+    var element = document.getElementById("animation");
+    var requestId = window.webkitRequestAnimationFrame(animationFrameCallback, element);
+    function animationFrameCallback()
+    {
+        window.webkitCancelRequestAnimationFrame(requestId);
+    }
+
+    if (window.layoutTestController)
+        layoutTestController.display();
+}
+
+function test()
+{
+    InspectorTest.startTimeline(function() {
+        InspectorTest.evaluateInPage("performActions()");
+    });
+
+    WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded, function(event) {
+        addRecord(event.data);
+    });
+
+    function addRecord(record)
+    {
+        if (record.type !== WebInspector.TimelineAgent.RecordType["CancelAnimationFrameCallback"]) {
+            for (var i = 0; record.children && i < record.children.length; ++i)
+                addRecord(record.children[i]);
+            return ;
+        }
+
+        InspectorTest.printTimelineRecords("RegisterAnimationFrameCallback");
+        InspectorTest.printTimelineRecords("FireAnimationFrameEvent");
+        InspectorTest.printTimelineRecords("CancelAnimationFrameCallback");
+        InspectorTest.completeTest();
+    }
+}
+
+if (!window.layoutTestController)
+    setTimeout(performActions, 2000);
+
+</script>
+</head>
+
+<body onload="runTest()">
+<p>
+Tests the Timeline events for Animation Frame feature
+</p>
+<div id="animation">
+
+</div>
+
+</body>
+</html>
index 9b880d2d3df49c741d17a2d1528f1d784889d8b5..7ff10ace6e1b45f122144dfe92c9f7f381dc919e 100644 (file)
@@ -24,5 +24,8 @@ Applications outside of WebKit depend on the stability of the mapping of these t
     ResourceFinish : "ResourceFinish"
     FunctionCall : "FunctionCall"
     GCEvent : "GCEvent"
+    RegisterAnimationFrameCallback : "RegisterAnimationFrameCallback"
+    CancelAnimationFrameCallback : "CancelAnimationFrameCallback"
+    FireAnimationFrameEvent : "FireAnimationFrameEvent"
 }
 
index 6c7c99dcfbae7d8c51bda04fc58d6bcedddebc1c..d20a54a27955c8b081846128c7f82cd46f333f34 100644 (file)
@@ -2,17 +2,18 @@ var initialize_Timeline = function() {
 
 // Scrub values when printing out these properties in the record or data field.
 InspectorTest.timelineNonDeterministicProps = { 
-    children : 1,
-    endTime : 1, 
-    height : 1,
-    requestId : 1,
-    startTime : 1,
-    width : 1,
+    children: 1,
+    endTime: 1,
+    height: 1,
+    requestId: 1,
+    startTime: 1,
+    width: 1,
     stackTrace: 1,
-    url : 1,
+    url: 1,
     usedHeapSize: 1,
     totalHeapSize: 1,
-    mimeType : 1
+    mimeType: 1,
+    id: 1
 };
 
 InspectorTest.startTimeline = function(callback)
diff --git a/LayoutTests/platform/chromium/inspector/timeline/timeline-animation-frame-expected.txt b/LayoutTests/platform/chromium/inspector/timeline/timeline-animation-frame-expected.txt
new file mode 100644 (file)
index 0000000..5206cc9
--- /dev/null
@@ -0,0 +1,38 @@
+Tests the Timeline events for Animation Frame feature
+
+RegisterAnimationFrameCallback Properties:
+{
+    startTime : <number>
+    stackTrace : <object>
+    data : {
+        id : <number>
+    }
+    type : "RegisterAnimationFrameCallback"
+    usedHeapSize : <number>
+    totalHeapSize : <number>
+}
+FireAnimationFrameEvent Properties:
+{
+    startTime : <number>
+    stackTrace : <object>
+    data : {
+        id : <number>
+    }
+    children : <object>
+    endTime : <number>
+    type : "FireAnimationFrameEvent"
+    usedHeapSize : <number>
+    totalHeapSize : <number>
+}
+CancelAnimationFrameCallback Properties:
+{
+    startTime : <number>
+    stackTrace : <object>
+    data : {
+        id : <number>
+    }
+    type : "CancelAnimationFrameCallback"
+    usedHeapSize : <number>
+    totalHeapSize : <number>
+}
+
index 6d2061e8199396ed4dd710fe0a4afe098eacc434..26e6c4d0c7aa87e4006d3fb2352a56ba2f970a9e 100644 (file)
@@ -86,6 +86,7 @@ storage/indexeddb
 
 # ENABLE(REQUEST_ANIMATION_FRAME) is disabled.
 fast/animation
+inspector/timeline/timeline-animation-frame.html
 
 # ENABLE(ANIMATION_API) is disabled.
 animations/animation-api-1.html
index 55dddaaaae9cf5a629be0ef0f01f7b5c6c49e4a5..40bbf60600d12e15690da1f6c682b649c86e3923 100644 (file)
@@ -1,3 +1,54 @@
+2011-09-18  Ilya Tikhonovsky  <loislo@chromium.org>
+
+        Web Inspector: requestAnimationFrame callbacks don't show up in the timeline panel.
+        https://bugs.webkit.org/show_bug.cgi?id=67986
+
+        Reviewed by Pavel Feldman.
+
+        Test: inspector/timeline/timeline-animation-frame.html
+
+        * English.lproj/localizedStrings.js:
+        * bindings/v8/V8Proxy.cpp:
+        (WebCore::V8Proxy::callFunction):
+        (WebCore::V8Proxy::callFunctionWithoutFrame):
+        (WebCore::V8Proxy::instrumentedCallFunction):
+        * bindings/v8/V8Proxy.h:
+        * bindings/v8/custom/V8CustomVoidCallback.cpp:
+        (WebCore::invokeCallback):
+        * dom/ScriptedAnimationController.cpp:
+        (WebCore::ScriptedAnimationController::registerCallback):
+        (WebCore::ScriptedAnimationController::cancelCallback):
+        (WebCore::ScriptedAnimationController::serviceScriptedAnimations):
+        * inspector/InspectorInstrumentation.cpp:
+        (WebCore::InspectorInstrumentation::didRegisterAnimationFrameCallbackImpl):
+        (WebCore::InspectorInstrumentation::didCancelAnimationFrameCallbackImpl):
+        (WebCore::InspectorInstrumentation::willFireAnimationFrameEventImpl):
+        (WebCore::InspectorInstrumentation::didFireAnimationFrameEventImpl):
+        * inspector/InspectorInstrumentation.h:
+        (WebCore::InspectorInstrumentation::willCallFunction):
+        (WebCore::InspectorInstrumentation::didRegisterAnimationFrameCallback):
+        (WebCore::InspectorInstrumentation::didCancelAnimationFrameCallback):
+        (WebCore::InspectorInstrumentation::willFireAnimationFrameEvent):
+        (WebCore::InspectorInstrumentation::didFireAnimationFrameEvent):
+        * inspector/InspectorTimelineAgent.cpp:
+        (WebCore::InspectorTimelineAgent::didRegisterAnimationFrameCallback):
+        (WebCore::InspectorTimelineAgent::didCancelAnimationFrameCallback):
+        (WebCore::InspectorTimelineAgent::willFireAnimationFrameEvent):
+        (WebCore::InspectorTimelineAgent::didFireAnimationFrameEvent):
+        * inspector/InspectorTimelineAgent.h:
+        * inspector/TimelineRecordFactory.cpp:
+        (WebCore::TimelineRecordFactory::createAnimationFrameCallbackData):
+        * inspector/TimelineRecordFactory.h:
+        * inspector/front-end/TimelineAgent.js:
+        * inspector/front-end/TimelinePanel.js:
+        (WebInspector.TimelinePanel):
+        (WebInspector.TimelinePanel.prototype.get _recordStyles):
+        (WebInspector.TimelinePanel.prototype._innerAddRecordToTimeline):
+        (WebInspector.TimelinePanel.prototype._clearPanel):
+        (WebInspector.TimelinePanel.FormattedRecord):
+        (WebInspector.TimelinePanel.FormattedRecord.prototype._generatePopupContent):
+        (WebInspector.TimelinePanel.FormattedRecord.prototype._getRecordDetails):
+
 2011-09-19  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [GTK] Fix distcheck build
index 172f21fcdc1a0bb36a3964ef5ed8cf123d48d2ed..dc93a80e32e5e0af670d96ee6af441fad181dabb 100644 (file)
Binary files a/Source/WebCore/English.lproj/localizedStrings.js and b/Source/WebCore/English.lproj/localizedStrings.js differ
index 6acf6e133827440f45dc74d11e081773095bfe71..a39cfaf57ae4bd7a511acf4bbc7a00d826654e5a 100644 (file)
@@ -477,23 +477,9 @@ v8::Local<v8::Value> V8Proxy::callFunction(v8::Handle<v8::Function> function, v8
             return result;
         }
 
-        InspectorInstrumentationCookie cookie;
-        if (InspectorInstrumentation::hasFrontends()) {
-            v8::ScriptOrigin origin = function->GetScriptOrigin();
-            String resourceName("undefined");
-            int lineNumber = 1;
-            if (!origin.ResourceName().IsEmpty()) {
-                resourceName = toWebCoreString(origin.ResourceName());
-                lineNumber = function->GetScriptLineNumber() + 1;
-            }
-            cookie = InspectorInstrumentation::willCallFunction(m_frame, resourceName, lineNumber);
-        }
-
         m_recursion++;
-        result = function->Call(receiver, argc, args);
+        result = V8Proxy::instrumentedCallFunction(m_frame->page(), function, receiver, argc, args);
         m_recursion--;
-
-        InspectorInstrumentation::didCallFunction(cookie);
     }
 
     // Release the storage mutex if applicable.
@@ -516,6 +502,24 @@ v8::Local<v8::Value> V8Proxy::callFunctionWithoutFrame(v8::Handle<v8::Function>
     return result;
 }
 
+v8::Local<v8::Value> V8Proxy::instrumentedCallFunction(Page* page, v8::Handle<v8::Function> function, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> args[])
+{
+    InspectorInstrumentationCookie cookie;
+    if (InspectorInstrumentation::hasFrontends()) {
+        String resourceName("undefined");
+        int lineNumber = 1;
+        v8::ScriptOrigin origin = function->GetScriptOrigin();
+        if (!origin.ResourceName().IsEmpty()) {
+            resourceName = toWebCoreString(origin.ResourceName());
+            lineNumber = function->GetScriptLineNumber() + 1;
+        }
+        cookie = InspectorInstrumentation::willCallFunction(page, resourceName, lineNumber);
+    }
+    v8::Local<v8::Value> result = function->Call(receiver, argc, args);
+    InspectorInstrumentation::didCallFunction(cookie);
+    return result;
+}
+
 v8::Local<v8::Value> V8Proxy::newInstance(v8::Handle<v8::Function> constructor, int argc, v8::Handle<v8::Value> args[])
 {
     // No artificial limitations on the depth of recursion, see comment in
index 9db4fdf913d12e5f5d9b06dcbdd30d2f0cc28e54..6e876e2d846cda176917163c918c2dc2b7ba4058 100644 (file)
@@ -57,6 +57,7 @@ namespace WebCore {
     class DOMWindow;
     class Frame;
     class Node;
+    class Page;
     class ScriptExecutionContext;
     class ScriptSourceCode;
     class SecurityOrigin;
@@ -173,6 +174,9 @@ namespace WebCore {
         // Call the function with the given receiver and arguments.
         static v8::Local<v8::Value> callFunctionWithoutFrame(v8::Handle<v8::Function>, v8::Handle<v8::Object>, int argc, v8::Handle<v8::Value> argv[]);
 
+        // call the function with the given receiver and arguments and report times to DevTools.
+        static v8::Local<v8::Value> instrumentedCallFunction(Page*, v8::Handle<v8::Function>, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> args[]);
+
         // Call the function as constructor with the given arguments.
         v8::Local<v8::Value> newInstance(v8::Handle<v8::Function>, int argc, v8::Handle<v8::Value> argv[]);
 
index 11f309b6994a1089002a112b5ff0594877ade979..e3a2a037db34de246fed4d82974104da5fec8797 100644 (file)
@@ -83,7 +83,9 @@ bool invokeCallback(v8::Persistent<v8::Object> callback, int argc, v8::Handle<v8
 
     v8::Handle<v8::Object> thisObject = v8::Context::GetCurrent()->Global();
 
-    v8::Handle<v8::Value> result = callbackFunction->Call(thisObject, argc, argv);
+    Page* page = scriptExecutionContext && scriptExecutionContext->isDocument() ? static_cast<Document*>(scriptExecutionContext)->page() : 0;
+    v8::Handle<v8::Value> result = V8Proxy::instrumentedCallFunction(page, callbackFunction, thisObject, argc, argv);
+
     callbackReturnValue = !result.IsEmpty() && result->BooleanValue();
     return exceptionCatcher.HasCaught();
 }
index 5d31d9db65056a6f9594d81fd2a9c4aaa5011982..96cde8a9dd9001b9a9c1cc4fdde7c493adce3319 100644 (file)
@@ -31,6 +31,7 @@
 #include "Document.h"
 #include "Element.h"
 #include "FrameView.h"
+#include "InspectorInstrumentation.h"
 #include "RequestAnimationFrameCallback.h"
 
 #if USE(REQUEST_ANIMATION_FRAME_TIMER)
@@ -75,6 +76,9 @@ ScriptedAnimationController::CallbackId ScriptedAnimationController::registerCal
     callback->m_id = id;
     callback->m_element = animationElement;
     m_callbacks.append(callback);
+
+    InspectorInstrumentation::didRegisterAnimationFrameCallback(m_document, id);
+
     if (!m_suspendCount)
         scheduleAnimation();
     return id;
@@ -85,6 +89,7 @@ void ScriptedAnimationController::cancelCallback(CallbackId id)
     for (size_t i = 0; i < m_callbacks.size(); ++i) {
         if (m_callbacks[i]->m_id == id) {
             m_callbacks[i]->m_firedOrCancelled = true;
+            InspectorInstrumentation::didCancelAnimationFrameCallback(m_document, id);
             m_callbacks.remove(i);
             return;
         }
@@ -119,7 +124,9 @@ void ScriptedAnimationController::serviceScriptedAnimations(DOMTimeStamp time)
             RequestAnimationFrameCallback* callback = callbacks[i].get();
             if (!callback->m_firedOrCancelled && (!callback->m_element || callback->m_element->renderer())) {
                 callback->m_firedOrCancelled = true;
+                InspectorInstrumentationCookie cookie = InspectorInstrumentation::willFireAnimationFrameEvent(m_document, callback->m_id);
                 callback->handleEvent(time);
+                InspectorInstrumentation::didFireAnimationFrameEvent(cookie);
                 firedCallback = true;
                 callbacks.remove(i);
                 break;
index af1866f9b5f71174067bf7e45cae8cffd86928c2..49ddfc5302f4a2de1a365a7a03940e6e14645b98 100644 (file)
@@ -865,6 +865,34 @@ void InspectorInstrumentation::cancelPauseOnNativeEvent(InstrumentingAgents* ins
 #endif
 }
 
+void InspectorInstrumentation::didRegisterAnimationFrameCallbackImpl(InstrumentingAgents* instrumentingAgents, int callbackId)
+{
+    if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent())
+        timelineAgent->didRegisterAnimationFrameCallback(callbackId);
+}
+
+void InspectorInstrumentation::didCancelAnimationFrameCallbackImpl(InstrumentingAgents* instrumentingAgents, int callbackId)
+{
+    if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent())
+        timelineAgent->didCancelAnimationFrameCallback(callbackId);
+}
+
+InspectorInstrumentationCookie InspectorInstrumentation::willFireAnimationFrameEventImpl(InstrumentingAgents* instrumentingAgents, int callbackId)
+{
+    int timelineAgentId = 0;
+    if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) {
+        timelineAgent->willFireAnimationFrameEvent(callbackId);
+        timelineAgentId = timelineAgent->id();
+    }
+    return InspectorInstrumentationCookie(instrumentingAgents, timelineAgentId);
+}
+
+void InspectorInstrumentation::didFireAnimationFrameEventImpl(const InspectorInstrumentationCookie& cookie)
+{
+    if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie))
+        timelineAgent->didFireAnimationFrameEvent();
+}
+
 InspectorTimelineAgent* InspectorInstrumentation::retrieveTimelineAgent(const InspectorInstrumentationCookie& cookie)
 {
     if (!cookie.first)
index eab17ef2dedfe46dc43dea2fa8fb0796f6ef1029..b698125a876df882f3d123a7cee2543a0e475e4e 100644 (file)
@@ -95,7 +95,7 @@ public:
     static void didInstallTimer(ScriptExecutionContext*, int timerId, int timeout, bool singleShot);
     static void didRemoveTimer(ScriptExecutionContext*, int timerId);
 
-    static InspectorInstrumentationCookie willCallFunction(Frame*, const String& scriptName, int scriptLine);
+    static InspectorInstrumentationCookie willCallFunction(Page*, const String& scriptName, int scriptLine);
     static void didCallFunction(const InspectorInstrumentationCookie&);
     static InspectorInstrumentationCookie willChangeXHRReadyState(ScriptExecutionContext*, XMLHttpRequest* request);
     static void didChangeXHRReadyState(const InspectorInstrumentationCookie&);
@@ -154,6 +154,11 @@ public:
     static void stopConsoleTiming(Page*, const String& title, PassRefPtr<ScriptCallStack>);
     static void consoleTimeStamp(Page*, PassRefPtr<ScriptArguments>);
 
+    static void didRegisterAnimationFrameCallback(Document*, int callbackId);
+    static void didCancelAnimationFrameCallback(Document*, int callbackId);
+    static InspectorInstrumentationCookie willFireAnimationFrameEvent(Document*, int callbackId);
+    static void didFireAnimationFrameEvent(const InspectorInstrumentationCookie&);
+
 #if ENABLE(JAVASCRIPT_DEBUGGER)
     static void addStartProfilingMessageToConsole(Page*, const String& title, unsigned lineNumber, const String& sourceURL);
     static void addProfile(Page*, RefPtr<ScriptProfile>, PassRefPtr<ScriptCallStack>);
@@ -283,6 +288,11 @@ private:
     static void stopConsoleTimingImpl(InstrumentingAgents*, const String& title, PassRefPtr<ScriptCallStack>);
     static void consoleTimeStampImpl(InstrumentingAgents*, PassRefPtr<ScriptArguments>);
 
+    static void didRegisterAnimationFrameCallbackImpl(InstrumentingAgents*, int callbackId);
+    static void didCancelAnimationFrameCallbackImpl(InstrumentingAgents*, int callbackId);
+    static InspectorInstrumentationCookie willFireAnimationFrameEventImpl(InstrumentingAgents*, int callbackId);
+    static void didFireAnimationFrameEventImpl(const InspectorInstrumentationCookie&);
+
 #if ENABLE(JAVASCRIPT_DEBUGGER)
     static void addStartProfilingMessageToConsoleImpl(InstrumentingAgents*, const String& title, unsigned lineNumber, const String& sourceURL);
     static void addProfileImpl(InstrumentingAgents*, RefPtr<ScriptProfile>, PassRefPtr<ScriptCallStack>);
@@ -485,12 +495,11 @@ inline void InspectorInstrumentation::didRemoveTimer(ScriptExecutionContext* con
 #endif
 }
 
-
-inline InspectorInstrumentationCookie InspectorInstrumentation::willCallFunction(Frame* frame, const String& scriptName, int scriptLine)
+inline InspectorInstrumentationCookie InspectorInstrumentation::willCallFunction(Page* page, const String& scriptName, int scriptLine)
 {
 #if ENABLE(INSPECTOR)
     FAST_RETURN_IF_NO_FRONTENDS(InspectorInstrumentationCookie());
-    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame))
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page))
         return willCallFunctionImpl(instrumentingAgents, scriptName, scriptLine);
 #endif
     return InspectorInstrumentationCookie();
@@ -1025,6 +1034,40 @@ inline void InspectorInstrumentation::updateApplicationCacheStatus(Frame* frame)
 }
 #endif
 
+inline void InspectorInstrumentation::didRegisterAnimationFrameCallback(Document* document, int callbackId)
+{
+#if ENABLE(INSPECTOR)
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document))
+        didRegisterAnimationFrameCallbackImpl(instrumentingAgents, callbackId);
+#endif
+}
+
+inline void InspectorInstrumentation::didCancelAnimationFrameCallback(Document* document, int callbackId)
+{
+#if ENABLE(INSPECTOR)
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document))
+        didCancelAnimationFrameCallbackImpl(instrumentingAgents, callbackId);
+#endif
+}
+
+inline InspectorInstrumentationCookie InspectorInstrumentation::willFireAnimationFrameEvent(Document* document, int callbackId)
+{
+#if ENABLE(INSPECTOR)
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document))
+        return willFireAnimationFrameEventImpl(instrumentingAgents, callbackId);
+#endif
+    return InspectorInstrumentationCookie();
+}
+
+inline void InspectorInstrumentation::didFireAnimationFrameEvent(const InspectorInstrumentationCookie& cookie)
+{
+#if ENABLE(INSPECTOR)
+    FAST_RETURN_IF_NO_FRONTENDS(void());
+    if (cookie.first)
+        didFireAnimationFrameEventImpl(cookie);
+#endif
+}
+
 #if ENABLE(INSPECTOR)
 inline bool InspectorInstrumentation::collectingHTMLParseErrors(Page* page)
 {
index 17b0f5427236aa2cb15921b4db327dfa101da0c8..861df149ed3923367f95327e453b0f4ebc0f24ec 100644 (file)
@@ -52,6 +52,7 @@ static const char timelineAgentEnabled[] = "timelineAgentEnabled";
 static const char timelineMaxCallStackDepth[] = "timelineMaxCallStackDepth";
 }
 
+// Must be kept in sync with TimelineAgent.js
 namespace TimelineRecordType {
 static const char EventDispatch[] = "EventDispatch";
 static const char Layout[] = "Layout";
@@ -81,6 +82,10 @@ static const char XHRLoad[] = "XHRLoad";
 
 static const char FunctionCall[] = "FunctionCall";
 static const char GCEvent[] = "GCEvent";
+
+static const char RegisterAnimationFrameCallback[] = "RegisterAnimationFrameCallback";
+static const char CancelAnimationFrameCallback[] = "CancelAnimationFrameCallback";
+static const char FireAnimationFrameEvent[] = "FireAnimationFrameEvent";
 }
 
 void InspectorTimelineAgent::pushGCEventRecords()
@@ -344,6 +349,26 @@ void InspectorTimelineAgent::didCommitLoad()
     clearRecordStack();
 }
 
+void InspectorTimelineAgent::didRegisterAnimationFrameCallback(int callbackId)
+{
+    appendRecord(TimelineRecordFactory::createAnimationFrameCallbackData(callbackId), TimelineRecordType::RegisterAnimationFrameCallback);
+}
+
+void InspectorTimelineAgent::didCancelAnimationFrameCallback(int callbackId)
+{
+    appendRecord(TimelineRecordFactory::createAnimationFrameCallbackData(callbackId), TimelineRecordType::CancelAnimationFrameCallback);
+}
+
+void InspectorTimelineAgent::willFireAnimationFrameEvent(int callbackId)
+{
+    pushCurrentRecord(TimelineRecordFactory::createAnimationFrameCallbackData(callbackId), TimelineRecordType::FireAnimationFrameEvent);
+}
+
+void InspectorTimelineAgent::didFireAnimationFrameEvent()
+{
+    didCompleteCurrentRecord(TimelineRecordType::FireAnimationFrameEvent);
+}
+
 void InspectorTimelineAgent::addRecordToTimeline(PassRefPtr<InspectorObject> prpRecord, const String& type)
 {
     RefPtr<InspectorObject> record(prpRecord);
index 4e77b661be4a06a139e8989e10be95ae05d62b1d..ecb177f31c7d96ecb22a1e0a9c8dd65f09c8c828 100644 (file)
@@ -119,7 +119,12 @@ public:
     void didFinishLoadingResource(unsigned long, bool didFail, double finishTime);
     void willReceiveResourceData(unsigned long identifier);
     void didReceiveResourceData();
-        
+
+    void didRegisterAnimationFrameCallback(int callbackId);
+    void didCancelAnimationFrameCallback(int callbackId);
+    void willFireAnimationFrameEvent(int callbackId);
+    void didFireAnimationFrameEvent();
+
     virtual void didGC(double, double, size_t);
 
 private:
index 73d495a853ace8b769623d7a23dd273a9df3d5d5..97af434c041d1271fe6b7cae595bf2c2b0b1e754 100644 (file)
@@ -182,6 +182,13 @@ PassRefPtr<InspectorObject> TimelineRecordFactory::createParseHTMLData(unsigned
     return data.release();
 }
 
+PassRefPtr<InspectorObject> TimelineRecordFactory::createAnimationFrameCallbackData(int callbackId)
+{
+    RefPtr<InspectorObject> data = InspectorObject::create();
+    data->setNumber("id", callbackId);
+    return data.release();
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(INSPECTOR)
index 6387fa477deda4923d01b1ebf016c5b9126e5002..ed6080b4fa38e8354fb8cd6fb4dcbd4ed6617ec5 100644 (file)
@@ -79,6 +79,8 @@ namespace WebCore {
 
         static PassRefPtr<InspectorObject> createParseHTMLData(unsigned int length, unsigned int startLine);
 
+        static PassRefPtr<InspectorObject> createAnimationFrameCallbackData(int callbackId);
+
     private:
         TimelineRecordFactory() { }
     };
index 728660ae234ce7503ba99f78ca654b1c97ef3edd..f7c3ee0f3367ccdd0872fca9ac73c1ef64f0793d 100644 (file)
@@ -61,5 +61,9 @@ WebInspector.TimelineAgent.RecordType = {
     ResourceFinish: "ResourceFinish",
 
     FunctionCall: "FunctionCall",
-    GCEvent: "GCEvent"
+    GCEvent: "GCEvent",
+
+    RegisterAnimationFrameCallback: "RegisterAnimationFrameCallback",
+    CancelAnimationFrameCallback: "CancelAnimationFrameCallback",
+    FireAnimationFrameEvent: "FireAnimationFrameEvent"
 };
index d9c0d7b6f663be5a5c2ba673229300243e194bb1..34efd438bcf2d421f5c632fef9de14acf4647687 100644 (file)
@@ -82,6 +82,7 @@ WebInspector.TimelinePanel = function()
     this._sendRequestRecords = {};
     this._scheduledResourceRequests = {};
     this._timerRecords = {};
+    this._registeredAnimationCallbackRecords = {};
 
     this._calculator = new WebInspector.TimelineCalculator();
     this._calculator._showShortEvents = false;
@@ -201,6 +202,9 @@ WebInspector.TimelinePanel.prototype = {
             recordStyles[recordTypes.MarkDOMContent] = { title: WebInspector.UIString("DOMContent event"), category: this.categories.scripting };
             recordStyles[recordTypes.MarkLoad] = { title: WebInspector.UIString("Load event"), category: this.categories.scripting };
             recordStyles[recordTypes.ScheduleResourceRequest] = { title: WebInspector.UIString("Schedule Request"), category: this.categories.loading };
+            recordStyles[recordTypes.RegisterAnimationFrameCallback] = { title: WebInspector.UIString("Register Animation Callback"), category: this.categories.scripting };
+            recordStyles[recordTypes.CancelAnimationFrameCallback] = { title: WebInspector.UIString("Cancel Animation Callback"), category: this.categories.scripting };
+            recordStyles[recordTypes.FireAnimationFrameEvent] = { title: WebInspector.UIString("Animation Frame Event"), category: this.categories.scripting };
             this._recordStylesArray = recordStyles;
         }
         return this._recordStylesArray;
@@ -404,6 +408,12 @@ WebInspector.TimelinePanel.prototype = {
     {
         var connectedToOldRecord = false;
         var recordTypes = WebInspector.TimelineAgent.RecordType;
+
+        if (record.type === recordTypes.RegisterAnimationFrameCallback) {
+            this._registeredAnimationCallbackRecords[record.data.id] = record;
+            return;
+        }
+
         if (record.type === recordTypes.MarkDOMContent || record.type === recordTypes.MarkLoad)
             parentRecord = null; // No bar entry for load events.
         else if (parentRecord === this._rootRecord ||
@@ -425,7 +435,8 @@ WebInspector.TimelinePanel.prototype = {
                 scriptLine: record.data.scriptLine
             }
         };
-        if (record.type === recordTypes.TimerFire && children && children.length) {
+
+        if ((record.type === recordTypes.TimerFire || record.type === recordTypes.FireAnimationFrameEvent) && children && children.length) {
             var childRecord = children[0];
             if (childRecord.type === recordTypes.FunctionCall) {
                 scriptDetails = {
@@ -508,6 +519,7 @@ WebInspector.TimelinePanel.prototype = {
         this._sendRequestRecords = {};
         this._scheduledResourceRequests = {};
         this._timerRecords = {};
+        this._registeredAnimationCallbackRecords = {};
         this._rootRecord = this._createRootRecord();
         this._boundariesAreValid = false;
         this._overviewPane.reset();
@@ -1000,6 +1012,10 @@ WebInspector.TimelinePanel.FormattedRecord = function(record, parentRecord, pane
             this.timeout = timerInstalledRecord.timeout;
             this.singleShot = timerInstalledRecord.singleShot;
         }
+    } else if (record.type === recordTypes.FireAnimationFrameEvent) {
+        var registerCallbackRecord = panel._registeredAnimationCallbackRecords[record.data.id];
+        if (registerCallbackRecord)
+            this.callSiteStackTrace = registerCallbackRecord.stackTrace;
     }
     this._refreshDetails();
 }
@@ -1059,6 +1075,9 @@ WebInspector.TimelinePanel.FormattedRecord.prototype = {
                     contentHelper._appendTextRow(WebInspector.UIString("Repeats"), !this.singleShot);
                 }
                 break;
+            case recordTypes.FireAnimationFrameEvent:
+                contentHelper._appendTextRow(WebInspector.UIString("Callback ID"), this.data.id);
+                break;
             case recordTypes.FunctionCall:
                 contentHelper._appendLinkRow(WebInspector.UIString("Location"), this.scriptName, this.scriptLine);
                 break;
@@ -1119,6 +1138,8 @@ WebInspector.TimelinePanel.FormattedRecord.prototype = {
                 return this.scriptName ? this._linkifyLocation(this.scriptName, this.scriptLine, 0) : this.data.timerId;
             case WebInspector.TimelineAgent.RecordType.FunctionCall:
                 return this.scriptName ? this._linkifyLocation(this.scriptName, this.scriptLine, 0) : null;
+            case WebInspector.TimelineAgent.RecordType.FireAnimationFrameEvent:
+                return this.scriptName ? this._linkifyLocation(this.scriptName, this.scriptLine, 0) : this.data.id;
             case WebInspector.TimelineAgent.RecordType.EventDispatch:
                 return this.data ? this.data.type : null;
             case WebInspector.TimelineAgent.RecordType.Paint:
@@ -1126,6 +1147,9 @@ WebInspector.TimelinePanel.FormattedRecord.prototype = {
             case WebInspector.TimelineAgent.RecordType.TimerInstall:
             case WebInspector.TimelineAgent.RecordType.TimerRemove:
                 return this.stackTrace ? this._linkifyCallFrame(this.stackTrace[0]) : this.data.timerId;
+            case WebInspector.TimelineAgent.RecordType.RegisterAnimationFrameCallback:
+            case WebInspector.TimelineAgent.RecordType.CancelAnimationFrameCallback:
+                return this.stackTrace ? this._linkifyCallFrame(this.stackTrace[0]) : this.data.id;
             case WebInspector.TimelineAgent.RecordType.ParseHTML:
             case WebInspector.TimelineAgent.RecordType.RecalculateStyles:
                 return this.stackTrace ? this._linkifyCallFrame(this.stackTrace[0]) : null;