2011-01-26 James Robinson <jamesr@chromium.org>
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 26 Jan 2011 09:18:17 +0000 (09:18 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 26 Jan 2011 09:18:17 +0000 (09:18 +0000)
        Reviewed by Nate Chapin.

        Add a DOMTimeStamp parameter to the requestAnimationFrame callback
        https://bugs.webkit.org/show_bug.cgi?id=53142

        Adds a test for the parameter passed to the requestAnimationFrame callback.

        * fast/animation/request-animation-frame-timestamps-expected.txt: Added.
        * fast/animation/request-animation-frame-timestamps.html: Added.
        * fast/animation/script-tests/request-animation-frame-timestamps.js: Added.
2011-01-26  James Robinson  <jamesr@chromium.org>

        Reviewed by Nate Chapin.

        Add a DOMTimeStamp parameter to the requestAnimationFrame callback
        https://bugs.webkit.org/show_bug.cgi?id=53142

        This adds a DOMTimeStamp parameter to the requestAnimationFrame callback to more
        closely match mozilla's proposal.  This is useful if the page has multiple imperative animations
        and wants to ensure that they all remain synchronized.  If each callback used Date.now() to
        update its animation state, they would potentially be out of sync with each other.  If they use
        the timestamp then all callbacks for the same "frame" will update to the same state.

        Test: fast/animation/request-animation-frame-timestamps.html

        * bindings/scripts/CodeGeneratorV8.pm:
        * bindings/scripts/test/V8/V8TestCallback.cpp:
        (WebCore::V8TestCallback::callbackWithClass2Param):
        * dom/Document.cpp:
        (WebCore::Document::serviceScriptedAnimations):
        * dom/Document.h:
        * dom/RequestAnimationFrameCallback.h:
        * dom/RequestAnimationFrameCallback.idl:
        * page/FrameView.cpp:
        (WebCore::FrameView::serviceScriptedAnimations):
        * page/FrameView.h:
2011-01-26  James Robinson  <jamesr@chromium.org>

        Reviewed by Nate Chapin.

        Add a DOMTimeStamp parameter to the requestAnimationFrame callback
        https://bugs.webkit.org/show_bug.cgi?id=53142

        Provides a timestamp to use for imperative animation callbacks.  In this patch the timestamp is
        just the current time at the start of the callback invocation algorithm.  In the future we
        could enhance this to try to take the compositing delay into effect to try to synchronize
        imperative animations more closely with declarative ones, but this should do for now.

        * src/WebViewImpl.cpp:
        (WebKit::WebViewImpl::animate):

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

15 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/animation/request-animation-frame-timestamps-expected.txt [new file with mode: 0644]
LayoutTests/fast/animation/request-animation-frame-timestamps.html [new file with mode: 0644]
LayoutTests/fast/animation/script-tests/request-animation-frame-timestamps.js [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/bindings/scripts/CodeGeneratorV8.pm
Source/WebCore/bindings/scripts/test/V8/V8TestCallback.cpp
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/dom/RequestAnimationFrameCallback.h
Source/WebCore/dom/RequestAnimationFrameCallback.idl
Source/WebCore/page/FrameView.cpp
Source/WebCore/page/FrameView.h
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/src/WebViewImpl.cpp

index 4594c92..1e62c20 100644 (file)
@@ -1,3 +1,16 @@
+2011-01-26  James Robinson  <jamesr@chromium.org>
+
+        Reviewed by Nate Chapin.
+
+        Add a DOMTimeStamp parameter to the requestAnimationFrame callback
+        https://bugs.webkit.org/show_bug.cgi?id=53142
+
+        Adds a test for the parameter passed to the requestAnimationFrame callback.
+
+        * fast/animation/request-animation-frame-timestamps-expected.txt: Added.
+        * fast/animation/request-animation-frame-timestamps.html: Added.
+        * fast/animation/script-tests/request-animation-frame-timestamps.js: Added.
+
 2011-01-25  Yuzo Fujishima  <yuzo@google.com>
 
         Unreviewed Chromium test expectation change
diff --git a/LayoutTests/fast/animation/request-animation-frame-timestamps-expected.txt b/LayoutTests/fast/animation/request-animation-frame-timestamps-expected.txt
new file mode 100644 (file)
index 0000000..46dd4b0
--- /dev/null
@@ -0,0 +1,13 @@
+Tests the timestamps provided to requestAnimationFrame callbacks
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS firstTimestamp is defined.
+PASS secondTimestamp is defined.
+PASS firstTimestamp is secondTimestamp
+PASS firstTimestamp is defined.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/animation/request-animation-frame-timestamps.html b/LayoutTests/fast/animation/request-animation-frame-timestamps.html
new file mode 100644 (file)
index 0000000..d5e136f
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<link rel="stylesheet" href="../js/resources/js-test-style.css">
+<script src="../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<span id="e"></span>
+<span id="f"></span>
+<script src="script-tests/request-animation-frame-timestamps.js"></script>
+<script src="../js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/animation/script-tests/request-animation-frame-timestamps.js b/LayoutTests/fast/animation/script-tests/request-animation-frame-timestamps.js
new file mode 100644 (file)
index 0000000..241ace0
--- /dev/null
@@ -0,0 +1,29 @@
+description("Tests the timestamps provided to requestAnimationFrame callbacks");
+
+function busyWait(millis) {
+    var start = Date.now();
+    while (Date.now()-start < millis) {}
+}
+
+var e = document.getElementById("e");
+var firstTimestamp = undefined;
+
+window.webkitRequestAnimationFrame(function(timestamp) {
+    firstTimestamp = timestamp;
+    shouldBeDefined("firstTimestamp");
+    busyWait(10);
+}, e);
+
+var secondTimestamp = undefined;
+window.webkitRequestAnimationFrame(function(timestamp) {
+    secondTimestamp = timestamp;
+    shouldBeDefined("secondTimestamp");
+    shouldBe("firstTimestamp", "secondTimestamp");
+}, e);
+
+if (window.layoutTestController)
+    layoutTestController.display();
+
+shouldBeDefined("firstTimestamp");
+
+var successfullyParsed = true;
index ca40e8c..43e6c70 100644 (file)
@@ -1,3 +1,30 @@
+2011-01-26  James Robinson  <jamesr@chromium.org>
+
+        Reviewed by Nate Chapin.
+
+        Add a DOMTimeStamp parameter to the requestAnimationFrame callback
+        https://bugs.webkit.org/show_bug.cgi?id=53142
+
+        This adds a DOMTimeStamp parameter to the requestAnimationFrame callback to more
+        closely match mozilla's proposal.  This is useful if the page has multiple imperative animations
+        and wants to ensure that they all remain synchronized.  If each callback used Date.now() to
+        update its animation state, they would potentially be out of sync with each other.  If they use
+        the timestamp then all callbacks for the same "frame" will update to the same state.
+
+        Test: fast/animation/request-animation-frame-timestamps.html
+
+        * bindings/scripts/CodeGeneratorV8.pm:
+        * bindings/scripts/test/V8/V8TestCallback.cpp:
+        (WebCore::V8TestCallback::callbackWithClass2Param):
+        * dom/Document.cpp:
+        (WebCore::Document::serviceScriptedAnimations):
+        * dom/Document.h:
+        * dom/RequestAnimationFrameCallback.h:
+        * dom/RequestAnimationFrameCallback.idl:
+        * page/FrameView.cpp:
+        (WebCore::FrameView::serviceScriptedAnimations):
+        * page/FrameView.h:
+
 2011-01-25  Yuzo Fujishima  <yuzo@google.com>
 
         Unreviewed attempt to fix compilation error for Chromium Clang.
index f418eb5..c18ef10 100644 (file)
@@ -2393,7 +2393,7 @@ END
             @args = ();
             foreach my $param (@params) {
                 my $paramName = $param->name;
-                push(@implContent, "    v8::Handle<v8::Value> ${paramName}Handle = toV8(${paramName});\n");
+                push(@implContent, "    v8::Handle<v8::Value> ${paramName}Handle = " . NativeToJSValue($param, $paramName) . ";\n");
                 push(@implContent, "    if (${paramName}Handle.IsEmpty()) {\n");
                 push(@implContent, "        CRASH();\n");
                 push(@implContent, "        return true;\n");
@@ -3089,76 +3089,81 @@ sub IsDOMNodeType
 }
 
 
-sub ReturnNativeToJSValue
+sub NativeToJSValue
 {
     my $signature = shift;
     my $value = shift;
     my $indent = shift;
     my $type = GetTypeFromSignature($signature);
 
-    return "return v8Boolean($value)" if $type eq "boolean";
-    return "return v8::Handle<v8::Value>()" if $type eq "void";     # equivalent to v8::Undefined()
+    return "v8Boolean($value)" if $type eq "boolean";
+    return "v8::Handle<v8::Value>()" if $type eq "void";     # equivalent to v8::Undefined()
 
     # HTML5 says that unsigned reflected attributes should be in the range
     # [0, 2^31). When a value isn't in this range, a default value (or 0)
     # should be returned instead.
     if ($signature->extendedAttributes->{"Reflect"} and ($type eq "unsigned long" or $type eq "unsigned short")) {
         $value =~ s/getUnsignedIntegralAttribute/getIntegralAttribute/g;
-        return "return v8::Integer::NewFromUnsigned(std::max(0, " . $value . "))";
+        return "v8::Integer::NewFromUnsigned(std::max(0, " . $value . "))";
     }
 
     # For all the types where we use 'int' as the representation type,
     # we use Integer::New which has a fast Smi conversion check.
     my $nativeType = GetNativeType($type);
-    return "return v8::Integer::New($value)" if $nativeType eq "int";
-    return "return v8::Integer::NewFromUnsigned($value)" if $nativeType eq "unsigned";
+    return "v8::Integer::New($value)" if $nativeType eq "int";
+    return "v8::Integer::NewFromUnsigned($value)" if $nativeType eq "unsigned";
 
-    return "return v8DateOrNull($value)" if $type eq "Date";
+    return "v8DateOrNull($value)" if $type eq "Date";
     # long long and unsigned long long are not representable in ECMAScript.
-    return "return v8::Number::New(static_cast<double>($value))" if $type eq "long long" or $type eq "unsigned long long" or $type eq "DOMTimeStamp";
-    return "return v8::Number::New($value)" if $codeGenerator->IsPrimitiveType($type) or $type eq "SVGPaintType";
-    return "return $value.v8Value()" if $nativeType eq "ScriptValue";
+    return "v8::Number::New(static_cast<double>($value))" if $type eq "long long" or $type eq "unsigned long long" or $type eq "DOMTimeStamp";
+    return "v8::Number::New($value)" if $codeGenerator->IsPrimitiveType($type) or $type eq "SVGPaintType";
+    return "$value.v8Value()" if $nativeType eq "ScriptValue";
 
     if ($codeGenerator->IsStringType($type)) {
         my $conv = $signature->extendedAttributes->{"ConvertNullStringTo"};
         if (defined $conv) {
-            return "return v8StringOrNull($value)" if $conv eq "Null";
-            return "return v8StringOrUndefined($value)" if $conv eq "Undefined";
-            return "return v8StringOrFalse($value)" if $conv eq "False";
+            return "v8StringOrNull($value)" if $conv eq "Null";
+            return "v8StringOrUndefined($value)" if $conv eq "Undefined";
+            return "v8StringOrFalse($value)" if $conv eq "False";
 
             die "Unknown value for ConvertNullStringTo extended attribute";
         }
         $conv = $signature->extendedAttributes->{"ConvertScriptString"};
-        return "return v8StringOrNull($value)" if $conv;
-        return "return v8String($value)";
+        return "v8StringOrNull($value)" if $conv;
+        return "v8String($value)";
     }
 
     AddIncludesForType($type);
 
     # special case for non-DOM node interfaces
     if (IsDOMNodeType($type)) {
-        return "return toV8(${value}" . ($signature->extendedAttributes->{"ReturnsNew"} ? ", true)" : ")");
+        return "toV8(${value}" . ($signature->extendedAttributes->{"ReturnsNew"} ? ", true)" : ")");
     }
 
     if ($type eq "EventTarget") {
-        return "return V8DOMWrapper::convertEventTargetToV8Object($value)";
+        return "V8DOMWrapper::convertEventTargetToV8Object($value)";
     }
 
     if ($type eq "EventListener") {
         $implIncludes{"V8AbstractEventListener.h"} = 1;
-        return "return ${value} ? v8::Handle<v8::Value>(static_cast<V8AbstractEventListener*>(${value})->getListenerObject(imp->scriptExecutionContext())) : v8::Handle<v8::Value>(v8::Null())";
+        return "${value} ? v8::Handle<v8::Value>(static_cast<V8AbstractEventListener*>(${value})->getListenerObject(imp->scriptExecutionContext())) : v8::Handle<v8::Value>(v8::Null())";
     }
 
     if ($type eq "SerializedScriptValue") {
         $implIncludes{"$type.h"} = 1;
-        return "return $value->deserialize()";
+        return "$value->deserialize()";
     }
 
     $implIncludes{"wtf/RefCounted.h"} = 1;
     $implIncludes{"wtf/RefPtr.h"} = 1;
     $implIncludes{"wtf/GetPtr.h"} = 1;
 
-    return "return toV8($value)";
+    return "toV8($value)";
+}
+
+sub ReturnNativeToJSValue
+{
+    return "return " . NativeToJSValue(@_);
 }
 
 # Internal helper
index 36a5ca2..057302d 100644 (file)
@@ -29,6 +29,9 @@
 #include "V8CustomVoidCallback.h"
 #include "V8DOMString.h"
 #include "V8Proxy.h"
+#include <wtf/GetPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
 
 #include <wtf/Assertions.h>
 
@@ -113,7 +116,7 @@ bool V8TestCallback::callbackWithClass2Param(Class2* class2Param, const String&
         CRASH();
         return true;
     }
-    v8::Handle<v8::Value> strArgHandle = toV8(strArg);
+    v8::Handle<v8::Value> strArgHandle = v8String(strArg);
     if (strArgHandle.IsEmpty()) {
         CRASH();
         return true;
index 53c715c..7bbd0e0 100644 (file)
@@ -4986,7 +4986,7 @@ void Document::webkitCancelRequestAnimationFrame(int id)
     }
 }
 
-void Document::serviceScriptedAnimations()
+void Document::serviceScriptedAnimations(DOMTimeStamp time)
 {
     if (!m_requestAnimationFrameCallbacks)
         return;
@@ -5014,7 +5014,7 @@ void Document::serviceScriptedAnimations()
             RequestAnimationFrameCallback* callback = callbacks[i].get();
             if (!callback->m_firedOrCancelled && (!callback->m_element || callback->m_element->renderer())) {
                 callback->m_firedOrCancelled = true;
-                callback->handleEvent();
+                callback->handleEvent(time);
                 firedCallback = true;
                 callbacks.remove(i);
                 break;
index f6bcdc9..f3d8e77 100644 (file)
@@ -32,6 +32,7 @@
 #include "CollectionType.h"
 #include "Color.h"
 #include "ContainerNode.h"
+#include "DOMTimeStamp.h"
 #include "DocumentTiming.h"
 #include "QualifiedName.h"
 #include "ScriptExecutionContext.h"
@@ -1078,7 +1079,7 @@ public:
 #if ENABLE(REQUEST_ANIMATION_FRAME)
     int webkitRequestAnimationFrame(PassRefPtr<RequestAnimationFrameCallback>, Element*);
     void webkitCancelRequestAnimationFrame(int id);
-    void serviceScriptedAnimations();
+    void serviceScriptedAnimations(DOMTimeStamp);
 #endif
 
     bool mayCauseFlashOfUnstyledContent() const;
index 819e495..3edeb9e 100644 (file)
@@ -40,7 +40,7 @@ namespace WebCore {
 class RequestAnimationFrameCallback : public RefCounted<RequestAnimationFrameCallback> {
 public:
     virtual ~RequestAnimationFrameCallback() { }
-    virtual bool handleEvent() = 0;
+    virtual bool handleEvent(DOMTimeStamp) = 0;
 
     RefPtr<Element> m_element;
     int m_id;
index 8d232e5..1905193 100644 (file)
@@ -32,6 +32,6 @@ module core {
     interface [
         Callback=FunctionOnly,Conditional=REQUEST_ANIMATION_FRAME
     ] RequestAnimationFrameCallback{
-        boolean handleEvent();
+        boolean handleEvent(in DOMTimeStamp time);
     };
 }
index 2a66698..e44ed18 100644 (file)
@@ -1651,10 +1651,10 @@ void FrameView::unscheduleRelayout()
 }
 
 #if ENABLE(REQUEST_ANIMATION_FRAME)
-void FrameView::serviceScriptedAnimations()
+void FrameView::serviceScriptedAnimations(DOMTimeStamp time)
 {
     for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext())
-        frame->document()->serviceScriptedAnimations();
+        frame->document()->serviceScriptedAnimations(time);
 }
 #endif
 
index 8491f5c..8586f77 100644 (file)
@@ -101,7 +101,7 @@ public:
     bool needsFullRepaint() const { return m_doFullRepaint; }
 
 #if ENABLE(REQUEST_ANIMATION_FRAME)
-    void serviceScriptedAnimations();
+    void serviceScriptedAnimations(DOMTimeStamp);
 #endif
 
 #if USE(ACCELERATED_COMPOSITING)
index bc91e67..406fdb6 100644 (file)
@@ -1,3 +1,18 @@
+2011-01-26  James Robinson  <jamesr@chromium.org>
+
+        Reviewed by Nate Chapin.
+
+        Add a DOMTimeStamp parameter to the requestAnimationFrame callback
+        https://bugs.webkit.org/show_bug.cgi?id=53142
+
+        Provides a timestamp to use for imperative animation callbacks.  In this patch the timestamp is
+        just the current time at the start of the callback invocation algorithm.  In the future we
+        could enhance this to try to take the compositing delay into effect to try to synchronize
+        imperative animations more closely with declarative ones, but this should do for now.
+
+        * src/WebViewImpl.cpp:
+        (WebKit::WebViewImpl::animate):
+
 2011-01-25  Kent Tamura  <tkent@chromium.org>
 
         Unreviewed trivial change.
index 798e5ff..16cbb67 100644 (file)
 #include "WebVector.h"
 #include "WebViewClient.h"
 #include <wtf/ByteArray.h>
+#include <wtf/CurrentTime.h>
 #include <wtf/RefPtr.h>
 
 #if PLATFORM(CG)
@@ -979,7 +980,7 @@ void WebViewImpl::animate()
     if (webframe) {
         FrameView* view = webframe->frameView();
         if (view)
-            view->serviceScriptedAnimations();
+            view->serviceScriptedAnimations(convertSecondsToDOMTimeStamp(currentTime()));
     }
 #endif
 }