[chromium] Plumb from GraphicsLayer to the cc thread animation code
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 23 Feb 2012 01:22:22 +0000 (01:22 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 23 Feb 2012 01:22:22 +0000 (01:22 +0000)
https://bugs.webkit.org/show_bug.cgi?id=75874

Patch by Ian Vollick <vollick@chromium.org> on 2012-02-22
Reviewed by James Robinson.

Source/WebCore:

* WebCore.gypi:
* page/Settings.cpp:
(WebCore::Settings::Settings):
* page/Settings.h:
(WebCore::Settings::setThreadedAnimationEnabled):
(WebCore::Settings::threadedAnimationEnabled):
(Settings):
* platform/graphics/chromium/GraphicsLayerChromium.cpp:
(std):
(WebCore::GraphicsLayerChromium::addChild):
(WebCore::GraphicsLayerChromium::addAnimation):
(WebCore):
(WebCore::GraphicsLayerChromium::pauseAnimation):
(WebCore::GraphicsLayerChromium::removeAnimation):
(WebCore::GraphicsLayerChromium::suspendAnimations):
(WebCore::GraphicsLayerChromium::resumeAnimations):
(WebCore::GraphicsLayerChromium::setContentsToMedia):
(WebCore::GraphicsLayerChromium::updateLayerPreserves3D):
(WebCore::GraphicsLayerChromium::mapAnimationNameToId):
* platform/graphics/chromium/GraphicsLayerChromium.h:
(GraphicsLayerChromium):
* platform/graphics/chromium/LayerChromium.cpp:
(WebCore::LayerChromium::LayerChromium):
(WebCore::LayerChromium::addAnimation):
(WebCore):
(WebCore::LayerChromium::pauseAnimation):
(WebCore::LayerChromium::removeAnimation):
(WebCore::LayerChromium::suspendAnimations):
(WebCore::LayerChromium::resumeAnimations):
(WebCore::LayerChromium::setLayerAnimationController):
(WebCore::LayerChromium::pushPropertiesTo):
* platform/graphics/chromium/LayerChromium.h:
(WebCore):
(LayerChromium):
(WebCore::LayerChromium::layerAnimationController):
(WebCore::LayerChromium::numChildren):
* platform/graphics/chromium/cc/CCActiveAnimation.cpp:
(WebCore::CCActiveAnimation::create):
(WebCore):
(WebCore::CCActiveAnimation::CCActiveAnimation):
(WebCore::CCActiveAnimation::~CCActiveAnimation):
(WebCore::CCActiveAnimation::isWaiting):
(WebCore::CCActiveAnimation::isRunningOrHasRun):
(WebCore::CCActiveAnimation::cloneForImplThread):
(WebCore::CCActiveAnimation::synchronizeProperties):
* platform/graphics/chromium/cc/CCActiveAnimation.h:
(CCActiveAnimation):
(WebCore::CCActiveAnimation::AnimationSignature::AnimationSignature):
(AnimationSignature):
(WebCore::CCActiveAnimation::id):
(WebCore::CCActiveAnimation::group):
(WebCore::CCActiveAnimation::signature):
* platform/graphics/chromium/cc/CCAnimationCurve.h:
(CCAnimationCurve):
(CCTransformAnimationCurve):
* platform/graphics/chromium/cc/CCAnimationEvents.h: Copied from Source/WebCore/platform/graphics/chromium/cc/CCAnimationCurve.h.
(WebCore):
(WebCore::CCAnimationStartedEvent::CCAnimationStartedEvent):
(CCAnimationStartedEvent):
* platform/graphics/chromium/cc/CCLayerAnimationController.cpp: Added.
(WebCore):
(WebCore::CCLayerAnimationController::CCLayerAnimationController):
(WebCore::CCLayerAnimationController::~CCLayerAnimationController):
(WebCore::CCLayerAnimationController::create):
(WebCore::CCLayerAnimationController::addAnimation):
(WebCore::CCLayerAnimationController::pauseAnimation):
(WebCore::CCLayerAnimationController::removeAnimation):
(WebCore::CCLayerAnimationController::suspendAnimations):
(WebCore::CCLayerAnimationController::resumeAnimations):
(WebCore::CCLayerAnimationController::synchronizeAnimations):
(WebCore::CCLayerAnimationController::removeCompletedAnimations):
(WebCore::CCLayerAnimationController::pushNewAnimationsToImplThread):
(WebCore::CCLayerAnimationController::removeAnimationsCompletedOnMainThread):
(WebCore::CCLayerAnimationController::pushAnimationProperties):
(WebCore::CCLayerAnimationController::getActiveAnimation):
(WebCore::CCLayerAnimationController::remove):
* platform/graphics/chromium/cc/CCLayerAnimationController.h: Added.
(WebCore):
(CCLayerAnimationController):
(WebCore::CCLayerAnimationController::activeAnimations):
* platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.cpp:
(WebCore::CCLayerAnimationControllerImpl::~CCLayerAnimationControllerImpl):
(WebCore):
(WebCore::CCLayerAnimationControllerImpl::animate):
(WebCore::CCLayerAnimationControllerImpl::add):
(WebCore::CCLayerAnimationControllerImpl::getActiveAnimation):
(WebCore::CCLayerAnimationControllerImpl::startAnimationsWaitingForNextTick):
(WebCore::CCLayerAnimationControllerImpl::startAnimationsWaitingForStartTime):
(WebCore::CCLayerAnimationControllerImpl::startAnimationsWaitingForTargetAvailability):
(WebCore::CCLayerAnimationControllerImpl::purgeFinishedAnimations):
(WebCore::CCLayerAnimationControllerImpl::tickAnimations):
* platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.h:
(CCLayerAnimationControllerImplClient):
(CCLayerAnimationControllerImpl):
* platform/graphics/chromium/cc/CCLayerImpl.cpp:
(WebCore::CCLayerImpl::CCLayerImpl):
* platform/graphics/chromium/cc/CCLayerImpl.h:
(CCLayerImpl):
(WebCore::CCLayerImpl::id):
(WebCore::CCLayerImpl::opacity):
(WebCore::CCLayerImpl::transform):
(WebCore::CCLayerImpl::bounds):
(WebCore::CCLayerImpl::layerAnimationController):
* platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
(WebCore::CCLayerTreeHost::finishCommitOnImplThread):
(WebCore::CCLayerTreeHost::setAnimationEvents):
(WebCore):
(WebCore::CCLayerTreeHost::didBecomeInvisibleOnImplThread):
* platform/graphics/chromium/cc/CCLayerTreeHost.h:
(WebCore::CCSettings::CCSettings):
(CCSettings):
(CCLayerTreeHost):
* platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
(WebCore::CCLayerTreeHostImpl::CCLayerTreeHostImpl):
(WebCore::CCLayerTreeHostImpl::animate):
(WebCore::CCLayerTreeHostImpl::animateLayersRecursive):
(WebCore):
(WebCore::CCLayerTreeHostImpl::animatePageScale):
(WebCore::CCLayerTreeHostImpl::animateLayers):
* platform/graphics/chromium/cc/CCLayerTreeHostImpl.h:
(CCLayerTreeHostImplClient):
(CCLayerTreeHostImpl):
(WebCore::CCLayerTreeHostImpl::needsAnimateLayers):
(WebCore::CCLayerTreeHostImpl::setNeedsAnimateLayers):
* platform/graphics/chromium/cc/CCSingleThreadProxy.cpp:
(WebCore::CCSingleThreadProxy::postAnimationEventsToMainThreadOnImplThread):
(WebCore):
* platform/graphics/chromium/cc/CCSingleThreadProxy.h:
(CCSingleThreadProxy):
(WebCore):
(DebugScopedSetMainThread):
(WebCore::DebugScopedSetMainThread::DebugScopedSetMainThread):
(WebCore::DebugScopedSetMainThread::~DebugScopedSetMainThread):
* platform/graphics/chromium/cc/CCThreadProxy.cpp:
(WebCore::CCThreadProxy::postAnimationEventsToMainThreadOnImplThread):
(WebCore):
(WebCore::CCThreadProxy::setAnimationEvents):
* platform/graphics/chromium/cc/CCThreadProxy.h:
(CCThreadProxy):

Source/WebKit/chromium:

* WebKit.gypi:
* public/WebSettings.h:
* public/platform/WebLayerTreeView.h:
(WebKit::WebLayerTreeView::Settings::Settings):
(Settings):
* src/WebLayerTreeView.cpp:
(WebKit::WebLayerTreeView::Settings::operator CCSettings):
* src/WebSettingsImpl.cpp:
(WebKit::WebSettingsImpl::setThreadedAnimationEnabled):
(WebKit):
* src/WebSettingsImpl.h:
(WebSettingsImpl):
* src/WebViewImpl.cpp:
(WebKit::WebViewImpl::setIsAcceleratedCompositingActive):
* tests/CCActiveAnimationTest.cpp:
(WebCore::createActiveAnimation):
* tests/CCAnimationTestCommon.cpp: Added.
(WebKitTests):
(WebKitTests::FakeFloatAnimationCurve::FakeFloatAnimationCurve):
(WebKitTests::FakeFloatAnimationCurve::~FakeFloatAnimationCurve):
(WebKitTests::FakeFloatAnimationCurve::clone):
(WebKitTests::FakeTransformTransition::FakeTransformTransition):
(WebKitTests::FakeTransformTransition::~FakeTransformTransition):
(WebKitTests::FakeTransformTransition::getValue):
(WebKitTests::FakeTransformTransition::clone):
(WebKitTests::FakeFloatTransition::FakeFloatTransition):
(WebKitTests::FakeFloatTransition::~FakeFloatTransition):
(WebKitTests::FakeFloatTransition::getValue):
(WebKitTests::FakeLayerAnimationControllerImplClient::FakeLayerAnimationControllerImplClient):
(WebKitTests::FakeLayerAnimationControllerImplClient::~FakeLayerAnimationControllerImplClient):
(WebKitTests::FakeFloatTransition::clone):
(WebKitTests::addOpacityTransition):
* tests/CCAnimationTestCommon.h: Added.
(WebCore):
(WebKitTests):
(FakeFloatAnimationCurve):
(WebKitTests::FakeFloatAnimationCurve::duration):
(WebKitTests::FakeFloatAnimationCurve::getValue):
(FakeTransformTransition):
(WebKitTests::FakeTransformTransition::duration):
(FakeFloatTransition):
(WebKitTests::FakeFloatTransition::duration):
(FakeLayerAnimationControllerImplClient):
(WebKitTests::FakeLayerAnimationControllerImplClient::id):
(WebKitTests::FakeLayerAnimationControllerImplClient::opacity):
(WebKitTests::FakeLayerAnimationControllerImplClient::setOpacity):
(WebKitTests::FakeLayerAnimationControllerImplClient::transform):
(WebKitTests::FakeLayerAnimationControllerImplClient::setTransform):
(WebKitTests::FakeLayerAnimationControllerImplClient::bounds):
* tests/CCLayerAnimationControllerImplTest.cpp:
(WebKitTests::createActiveAnimation):
(WebKitTests::TEST):
* tests/CCLayerAnimationControllerTest.cpp: Added.
(WebKitTests):
(WebKitTests::createActiveAnimation):
(WebKitTests::TEST):
* tests/CCLayerTreeHostImplTest.cpp:
(WebKit::CCLayerTreeHostImplTest::postAnimationEventsToMainThreadOnImplThread):
* tests/CCLayerTreeHostTest.cpp:
(WTF::TestHooks::animateLayers):
(MockLayerTreeHostImpl):
(WTF::MockLayerTreeHostImpl::animateLayers):
(WTF::MockLayerTreeHost::create):
(WTF::MockLayerTreeHost::createLayerTreeHostImpl):
(WTF):
(MockLayerAnimationController):
(WTF::MockLayerAnimationController::create):
(WTF::MockLayerAnimationController::addAnimation):
(WTF::MockLayerTreeHostClient::scheduleComposite):
(WTF::CCLayerTreeHostTest::postAddAnimationToMainThread):
(CCLayerTreeHostTest):
(WTF::CCLayerTreeHostTest::dispatchAddAnimation):
(WTF::CCLayerTreeHostTest::doBeginTest):
(CCLayerTreeHostTestAddAnimation):
(WTF::CCLayerTreeHostTestAddAnimation::CCLayerTreeHostTestAddAnimation):
(WTF::CCLayerTreeHostTestAddAnimation::beginTest):
(WTF::CCLayerTreeHostTestAddAnimation::animateLayers):
(WTF::CCLayerTreeHostTestAddAnimation::afterTest):
(WTF::TEST_F):
* tests/TreeSynchronizerTest.cpp:
(FakeLayerAnimationController):
(WebKitTests::FakeLayerAnimationController::create):
(WebKitTests::FakeLayerAnimationController::synchronizedAnimations):
(WebKitTests::FakeLayerAnimationController::FakeLayerAnimationController):
(WebKitTests::FakeLayerAnimationController::synchronizeAnimations):
(WebKitTests):
(WebKitTests::TEST):

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

42 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.gypi
Source/WebCore/page/Settings.cpp
Source/WebCore/page/Settings.h
Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h
Source/WebCore/platform/graphics/chromium/LayerChromium.cpp
Source/WebCore/platform/graphics/chromium/LayerChromium.h
Source/WebCore/platform/graphics/chromium/cc/CCActiveAnimation.cpp
Source/WebCore/platform/graphics/chromium/cc/CCActiveAnimation.h
Source/WebCore/platform/graphics/chromium/cc/CCAnimationCurve.h
Source/WebCore/platform/graphics/chromium/cc/CCAnimationEvents.h [new file with mode: 0644]
Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.h [new file with mode: 0644]
Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.cpp
Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.h
Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp
Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h
Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp
Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h
Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp
Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h
Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp
Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.h
Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp
Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/WebKit.gypi
Source/WebKit/chromium/public/WebSettings.h
Source/WebKit/chromium/public/platform/WebLayerTreeView.h
Source/WebKit/chromium/src/WebLayerTreeView.cpp
Source/WebKit/chromium/src/WebSettingsImpl.cpp
Source/WebKit/chromium/src/WebSettingsImpl.h
Source/WebKit/chromium/src/WebViewImpl.cpp
Source/WebKit/chromium/tests/CCActiveAnimationTest.cpp
Source/WebKit/chromium/tests/CCAnimationTestCommon.cpp [new file with mode: 0644]
Source/WebKit/chromium/tests/CCAnimationTestCommon.h [new file with mode: 0644]
Source/WebKit/chromium/tests/CCLayerAnimationControllerImplTest.cpp
Source/WebKit/chromium/tests/CCLayerAnimationControllerTest.cpp [new file with mode: 0644]
Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp
Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp
Source/WebKit/chromium/tests/TreeSynchronizerTest.cpp

index 26825fb..9597129 100644 (file)
@@ -1,3 +1,150 @@
+2012-02-22  Ian Vollick  <vollick@chromium.org>
+
+        [chromium] Plumb from GraphicsLayer to the cc thread animation code
+        https://bugs.webkit.org/show_bug.cgi?id=75874
+
+        Reviewed by James Robinson.
+
+        * WebCore.gypi:
+        * page/Settings.cpp:
+        (WebCore::Settings::Settings):
+        * page/Settings.h:
+        (WebCore::Settings::setThreadedAnimationEnabled):
+        (WebCore::Settings::threadedAnimationEnabled):
+        (Settings):
+        * platform/graphics/chromium/GraphicsLayerChromium.cpp:
+        (std):
+        (WebCore::GraphicsLayerChromium::addChild):
+        (WebCore::GraphicsLayerChromium::addAnimation):
+        (WebCore):
+        (WebCore::GraphicsLayerChromium::pauseAnimation):
+        (WebCore::GraphicsLayerChromium::removeAnimation):
+        (WebCore::GraphicsLayerChromium::suspendAnimations):
+        (WebCore::GraphicsLayerChromium::resumeAnimations):
+        (WebCore::GraphicsLayerChromium::setContentsToMedia):
+        (WebCore::GraphicsLayerChromium::updateLayerPreserves3D):
+        (WebCore::GraphicsLayerChromium::mapAnimationNameToId):
+        * platform/graphics/chromium/GraphicsLayerChromium.h:
+        (GraphicsLayerChromium):
+        * platform/graphics/chromium/LayerChromium.cpp:
+        (WebCore::LayerChromium::LayerChromium):
+        (WebCore::LayerChromium::addAnimation):
+        (WebCore):
+        (WebCore::LayerChromium::pauseAnimation):
+        (WebCore::LayerChromium::removeAnimation):
+        (WebCore::LayerChromium::suspendAnimations):
+        (WebCore::LayerChromium::resumeAnimations):
+        (WebCore::LayerChromium::setLayerAnimationController):
+        (WebCore::LayerChromium::pushPropertiesTo):
+        * platform/graphics/chromium/LayerChromium.h:
+        (WebCore):
+        (LayerChromium):
+        (WebCore::LayerChromium::layerAnimationController):
+        (WebCore::LayerChromium::numChildren):
+        * platform/graphics/chromium/cc/CCActiveAnimation.cpp:
+        (WebCore::CCActiveAnimation::create):
+        (WebCore):
+        (WebCore::CCActiveAnimation::CCActiveAnimation):
+        (WebCore::CCActiveAnimation::~CCActiveAnimation):
+        (WebCore::CCActiveAnimation::isWaiting):
+        (WebCore::CCActiveAnimation::isRunningOrHasRun):
+        (WebCore::CCActiveAnimation::cloneForImplThread):
+        (WebCore::CCActiveAnimation::synchronizeProperties):
+        * platform/graphics/chromium/cc/CCActiveAnimation.h:
+        (CCActiveAnimation):
+        (WebCore::CCActiveAnimation::AnimationSignature::AnimationSignature):
+        (AnimationSignature):
+        (WebCore::CCActiveAnimation::id):
+        (WebCore::CCActiveAnimation::group):
+        (WebCore::CCActiveAnimation::signature):
+        * platform/graphics/chromium/cc/CCAnimationCurve.h:
+        (CCAnimationCurve):
+        (CCTransformAnimationCurve):
+        * platform/graphics/chromium/cc/CCAnimationEvents.h: Copied from Source/WebCore/platform/graphics/chromium/cc/CCAnimationCurve.h.
+        (WebCore):
+        (WebCore::CCAnimationStartedEvent::CCAnimationStartedEvent):
+        (CCAnimationStartedEvent):
+        * platform/graphics/chromium/cc/CCLayerAnimationController.cpp: Added.
+        (WebCore):
+        (WebCore::CCLayerAnimationController::CCLayerAnimationController):
+        (WebCore::CCLayerAnimationController::~CCLayerAnimationController):
+        (WebCore::CCLayerAnimationController::create):
+        (WebCore::CCLayerAnimationController::addAnimation):
+        (WebCore::CCLayerAnimationController::pauseAnimation):
+        (WebCore::CCLayerAnimationController::removeAnimation):
+        (WebCore::CCLayerAnimationController::suspendAnimations):
+        (WebCore::CCLayerAnimationController::resumeAnimations):
+        (WebCore::CCLayerAnimationController::synchronizeAnimations):
+        (WebCore::CCLayerAnimationController::removeCompletedAnimations):
+        (WebCore::CCLayerAnimationController::pushNewAnimationsToImplThread):
+        (WebCore::CCLayerAnimationController::removeAnimationsCompletedOnMainThread):
+        (WebCore::CCLayerAnimationController::pushAnimationProperties):
+        (WebCore::CCLayerAnimationController::getActiveAnimation):
+        (WebCore::CCLayerAnimationController::remove):
+        * platform/graphics/chromium/cc/CCLayerAnimationController.h: Added.
+        (WebCore):
+        (CCLayerAnimationController):
+        (WebCore::CCLayerAnimationController::activeAnimations):
+        * platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.cpp:
+        (WebCore::CCLayerAnimationControllerImpl::~CCLayerAnimationControllerImpl):
+        (WebCore):
+        (WebCore::CCLayerAnimationControllerImpl::animate):
+        (WebCore::CCLayerAnimationControllerImpl::add):
+        (WebCore::CCLayerAnimationControllerImpl::getActiveAnimation):
+        (WebCore::CCLayerAnimationControllerImpl::startAnimationsWaitingForNextTick):
+        (WebCore::CCLayerAnimationControllerImpl::startAnimationsWaitingForStartTime):
+        (WebCore::CCLayerAnimationControllerImpl::startAnimationsWaitingForTargetAvailability):
+        (WebCore::CCLayerAnimationControllerImpl::purgeFinishedAnimations):
+        (WebCore::CCLayerAnimationControllerImpl::tickAnimations):
+        * platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.h:
+        (CCLayerAnimationControllerImplClient):
+        (CCLayerAnimationControllerImpl):
+        * platform/graphics/chromium/cc/CCLayerImpl.cpp:
+        (WebCore::CCLayerImpl::CCLayerImpl):
+        * platform/graphics/chromium/cc/CCLayerImpl.h:
+        (CCLayerImpl):
+        (WebCore::CCLayerImpl::id):
+        (WebCore::CCLayerImpl::opacity):
+        (WebCore::CCLayerImpl::transform):
+        (WebCore::CCLayerImpl::bounds):
+        (WebCore::CCLayerImpl::layerAnimationController):
+        * platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
+        (WebCore::CCLayerTreeHost::finishCommitOnImplThread):
+        (WebCore::CCLayerTreeHost::setAnimationEvents):
+        (WebCore):
+        (WebCore::CCLayerTreeHost::didBecomeInvisibleOnImplThread):
+        * platform/graphics/chromium/cc/CCLayerTreeHost.h:
+        (WebCore::CCSettings::CCSettings):
+        (CCSettings):
+        (CCLayerTreeHost):
+        * platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
+        (WebCore::CCLayerTreeHostImpl::CCLayerTreeHostImpl):
+        (WebCore::CCLayerTreeHostImpl::animate):
+        (WebCore::CCLayerTreeHostImpl::animateLayersRecursive):
+        (WebCore):
+        (WebCore::CCLayerTreeHostImpl::animatePageScale):
+        (WebCore::CCLayerTreeHostImpl::animateLayers):
+        * platform/graphics/chromium/cc/CCLayerTreeHostImpl.h:
+        (CCLayerTreeHostImplClient):
+        (CCLayerTreeHostImpl):
+        (WebCore::CCLayerTreeHostImpl::needsAnimateLayers):
+        (WebCore::CCLayerTreeHostImpl::setNeedsAnimateLayers):
+        * platform/graphics/chromium/cc/CCSingleThreadProxy.cpp:
+        (WebCore::CCSingleThreadProxy::postAnimationEventsToMainThreadOnImplThread):
+        (WebCore):
+        * platform/graphics/chromium/cc/CCSingleThreadProxy.h:
+        (CCSingleThreadProxy):
+        (WebCore):
+        (DebugScopedSetMainThread):
+        (WebCore::DebugScopedSetMainThread::DebugScopedSetMainThread):
+        (WebCore::DebugScopedSetMainThread::~DebugScopedSetMainThread):
+        * platform/graphics/chromium/cc/CCThreadProxy.cpp:
+        (WebCore::CCThreadProxy::postAnimationEventsToMainThreadOnImplThread):
+        (WebCore):
+        (WebCore::CCThreadProxy::setAnimationEvents):
+        * platform/graphics/chromium/cc/CCThreadProxy.h:
+        (CCThreadProxy):
+
 2012-02-22  Anders Carlsson  <andersca@apple.com>
 
         Subframes with scrollable areas must be added to the non-fast scrollable region
index 2698179..fdc60e4 100644 (file)
             'platform/graphics/chromium/cc/CCActiveAnimation.h',
             'platform/graphics/chromium/cc/CCAnimationCurve.cpp',
             'platform/graphics/chromium/cc/CCAnimationCurve.h',
+            'platform/graphics/chromium/cc/CCAnimationResults.h',
             'platform/graphics/chromium/cc/CCCanvasDrawQuad.cpp',
             'platform/graphics/chromium/cc/CCCanvasDrawQuad.h',
             'platform/graphics/chromium/cc/CCCanvasLayerImpl.cpp',
             'platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp',
             'platform/graphics/chromium/cc/CCHeadsUpDisplay.h',
             'platform/graphics/chromium/cc/CCInputHandler.h',
+            'platform/graphics/chromium/cc/CCLayerAnimationController.h',
+            'platform/graphics/chromium/cc/CCLayerAnimationController.cpp',
             'platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.h',
             'platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.cpp',
             'platform/graphics/chromium/cc/CCLayerImpl.cpp',
index 64f8e05..937d994 100644 (file)
@@ -244,6 +244,7 @@ Settings::Settings(Page* page)
 #if ENABLE(TOUCH_EVENTS)
     , m_touchEventEmulationEnabled(false)
 #endif
+    , m_threadedAnimationEnabled(false)
     , m_loadsImagesAutomaticallyTimer(this, &Settings::loadsImagesAutomaticallyTimerFired)
 {
     // A Frame may not have been created yet, so we initialize the AtomicString 
index f19b4c1..0be7ec0 100644 (file)
@@ -536,6 +536,9 @@ namespace WebCore {
         bool isTouchEventEmulationEnabled() const { return m_touchEventEmulationEnabled; }
 #endif
 
+        void setThreadedAnimationEnabled(bool enabled) { m_threadedAnimationEnabled = enabled; }
+        bool threadedAnimationEnabled() const { return m_threadedAnimationEnabled; }
+
     private:
         Settings(Page*);
 
@@ -686,6 +689,7 @@ namespace WebCore {
 #if ENABLE(TOUCH_EVENTS)
         bool m_touchEventEmulationEnabled : 1;
 #endif
+        bool m_threadedAnimationEnabled : 1;
 
         Timer<Settings> m_loadsImagesAutomaticallyTimer;
         void loadsImagesAutomaticallyTimerFired(Timer<Settings>*);
index 51f2043..cdecf59 100644 (file)
 
 using namespace std;
 
+namespace {
+static int s_nextGroupId = 0;
+}
+
 namespace WebCore {
 
 PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
@@ -124,7 +128,7 @@ bool GraphicsLayerChromium::setChildren(const Vector<GraphicsLayer*>& children)
 void GraphicsLayerChromium::addChild(GraphicsLayer* childLayer)
 {
     GraphicsLayer::addChild(childLayer);
-    if (!m_inSetChildren) 
+    if (!m_inSetChildren)
         updateChildList();
 }
 
@@ -382,6 +386,31 @@ void GraphicsLayerChromium::setContentsToCanvas(PlatformLayer* platformLayer)
         updateChildList();
 }
 
+bool GraphicsLayerChromium::addAnimation(const KeyframeValueList& values, const IntSize& boxSize, const Animation* animation, const String& animationName, double timeOffset)
+{
+    return m_layer->addAnimation(values, boxSize, animation, mapAnimationNameToId(animationName), s_nextGroupId++, timeOffset);
+}
+
+void GraphicsLayerChromium::pauseAnimation(const String& animationName, double timeOffset)
+{
+    m_layer->pauseAnimation(mapAnimationNameToId(animationName), timeOffset);
+}
+
+void GraphicsLayerChromium::removeAnimation(const String& animationName)
+{
+    m_layer->removeAnimation(mapAnimationNameToId(animationName));
+}
+
+void GraphicsLayerChromium::suspendAnimations(double time)
+{
+    m_layer->suspendAnimations(time);
+}
+
+void GraphicsLayerChromium::resumeAnimations()
+{
+    m_layer->resumeAnimations();
+}
+
 void GraphicsLayerChromium::setContentsToMedia(PlatformLayer* layer)
 {
     bool childrenChanged = false;
@@ -396,12 +425,12 @@ void GraphicsLayerChromium::setContentsToMedia(PlatformLayer* layer)
     } else {
         if (m_contentsLayer) {
             childrenChanged = true;
-  
+
             // The old contents layer will be removed via updateChildList.
             m_contentsLayer = 0;
         }
     }
-  
+
     if (childrenChanged)
         updateChildList();
 }
@@ -550,7 +579,7 @@ void GraphicsLayerChromium::updateLayerPreserves3D()
         m_layer->setAnchorPoint(FloatPoint(0.5f, 0.5f));
         TransformationMatrix identity;
         m_layer->setTransform(identity);
-        
+
         // Set the old layer to opacity of 1. Further down we will set the opacity on the transform layer.
         m_layer->setOpacity(1);
 
@@ -689,6 +718,12 @@ void GraphicsLayerChromium::paintContents(GraphicsContext& context, const IntRec
     paintGraphicsLayerContents(context, clip);
 }
 
+int GraphicsLayerChromium::mapAnimationNameToId(const String& animationName)
+{
+    // FIXME: need to maintain a name to id mapping in this class.
+    return 0;
+}
+
 } // namespace WebCore
 
 #endif // USE(ACCELERATED_COMPOSITING)
index dbf15e5..eb3146b 100644 (file)
@@ -95,6 +95,12 @@ public:
     virtual void setContentsToMedia(PlatformLayer*);
     virtual void setContentsToCanvas(PlatformLayer*);
 
+    virtual bool addAnimation(const KeyframeValueList&, const IntSize& boxSize, const Animation*, const String&, double timeOffset);
+    virtual void pauseAnimation(const String& animationName, double timeOffset);
+    virtual void removeAnimation(const String& animationName);
+    virtual void suspendAnimations(double time);
+    virtual void resumeAnimations();
+
     virtual PlatformLayer* platformLayer() const;
 
     virtual void setDebugBackgroundColor(const Color&);
@@ -132,6 +138,8 @@ private:
     void setupContentsLayer(LayerChromium*);
     float contentsScale() const;
 
+    int mapAnimationNameToId(const String& animationName);
+
     String m_nameBase;
 
     RefPtr<ContentLayerChromium> m_layer;
index df2598f..533d19c 100644 (file)
@@ -33,6 +33,7 @@
 #if USE(ACCELERATED_COMPOSITING)
 #include "LayerChromium.h"
 
+#include "cc/CCLayerAnimationController.h"
 #include "cc/CCLayerImpl.h"
 #include "cc/CCLayerTreeHost.h"
 #if USE(SKIA)
@@ -59,6 +60,7 @@ LayerChromium::LayerChromium()
     : m_needsDisplay(false)
     , m_layerId(s_nextLayerId++)
     , m_parent(0)
+    , m_layerAnimationController(CCLayerAnimationController::create())
     , m_scrollable(false)
     , m_anchorPoint(0.5, 0.5)
     , m_backgroundColor(0, 0, 0, 0)
@@ -92,6 +94,47 @@ LayerChromium::~LayerChromium()
     removeAllChildren();
 }
 
+bool LayerChromium::addAnimation(const KeyframeValueList& values, const IntSize& boxSize, const Animation* animation, int animationId, int groupId, double timeOffset)
+{
+    if (!m_layerTreeHost || !m_layerTreeHost->settings().threadedAnimationEnabled)
+        return false;
+
+    bool addedAnimation = m_layerAnimationController->addAnimation(values, boxSize, animation, animationId, groupId, timeOffset);
+    if (addedAnimation)
+        setNeedsCommit();
+    return addedAnimation;
+}
+
+void LayerChromium::pauseAnimation(int animationId, double timeOffset)
+{
+    m_layerAnimationController->pauseAnimation(animationId, timeOffset);
+    setNeedsCommit();
+}
+
+void LayerChromium::removeAnimation(int animationId)
+{
+    m_layerAnimationController->removeAnimation(animationId);
+    setNeedsCommit();
+}
+
+void LayerChromium::suspendAnimations(double time)
+{
+    m_layerAnimationController->suspendAnimations(time);
+    setNeedsCommit();
+}
+
+void LayerChromium::resumeAnimations()
+{
+    m_layerAnimationController->resumeAnimations();
+    setNeedsCommit();
+}
+
+void LayerChromium::setLayerAnimationController(PassOwnPtr<CCLayerAnimationController> layerAnimationController)
+{
+    m_layerAnimationController = layerAnimationController;
+    setNeedsCommit();
+}
+
 void LayerChromium::setIsNonCompositedContent(bool isNonCompositedContent)
 {
     m_isNonCompositedContent = isNonCompositedContent;
@@ -441,6 +484,8 @@ void LayerChromium::pushPropertiesTo(CCLayerImpl* layer)
     if (replicaLayer())
         replicaLayer()->pushPropertiesTo(layer->replicaLayer());
 
+    m_layerAnimationController->synchronizeAnimations(layer->layerAnimationController());
+
     // Reset any state that should be cleared for the next update.
     m_updateRect = FloatRect();
 }
index ff2e7d2..92fb013 100644 (file)
@@ -52,6 +52,7 @@
 
 namespace WebCore {
 
+class CCLayerAnimationController;
 class CCLayerImpl;
 class CCLayerTreeHost;
 class CCTextureUpdater;
@@ -61,7 +62,6 @@ class Region;
 // Base class for composited layers. Special layer types are derived from
 // this class.
 class LayerChromium : public RefCounted<LayerChromium> {
-    friend class LayerTilerChromium;
 public:
     static PassRefPtr<LayerChromium> create();
 
@@ -215,7 +215,21 @@ public:
     void setAlwaysReserveTextures(bool alwaysReserveTextures) { m_alwaysReserveTextures = alwaysReserveTextures; }
     bool alwaysReserveTextures() const { return m_alwaysReserveTextures; }
 
+    bool addAnimation(const KeyframeValueList&, const IntSize& boxSize, const Animation*, int animationId, int groupId, double timeOffset);
+    void pauseAnimation(int animationId, double timeOffset);
+    void removeAnimation(int animationId);
+
+    void suspendAnimations(double time);
+    void resumeAnimations();
+
+    CCLayerAnimationController* layerAnimationController() { return m_layerAnimationController.get(); }
+    void setLayerAnimationController(PassOwnPtr<CCLayerAnimationController>);
+
 protected:
+    friend class CCLayerImpl;
+    friend class LayerTilerChromium;
+    friend class TreeSynchronizer;
+
     LayerChromium();
 
     bool isPaintedAxisAlignedInScreen() const;
@@ -233,8 +247,6 @@ protected:
 
     RefPtr<LayerChromium> m_maskLayer;
 
-    friend class TreeSynchronizer;
-    friend class CCLayerImpl;
     // Constructs a CCLayerImpl of the correct runtime type for this LayerChromium type.
     virtual PassRefPtr<CCLayerImpl> createCCLayerImpl();
     int m_layerId;
@@ -243,10 +255,7 @@ private:
     void setParent(LayerChromium*);
     bool hasAncestor(LayerChromium*) const;
 
-    size_t numChildren() const
-    {
-        return m_children.size();
-    }
+    size_t numChildren() const { return m_children.size(); }
 
     // Returns the index of the child or -1 if not found.
     int indexOfChild(const LayerChromium*);
@@ -259,6 +268,8 @@ private:
 
     RefPtr<CCLayerTreeHost> m_layerTreeHost;
 
+    OwnPtr<CCLayerAnimationController> m_layerAnimationController;
+
     // Layer properties.
     IntSize m_bounds;
     IntRect m_visibleLayerRect;
index 21e6cc7..9ef5fe2 100644 (file)
 
 namespace WebCore {
 
-CCActiveAnimation::CCActiveAnimation(PassOwnPtr<CCAnimationCurve> curve, GroupID group, TargetProperty targetProperty)
+PassOwnPtr<CCActiveAnimation> CCActiveAnimation::create(PassOwnPtr<CCAnimationCurve> curve, int animationId, int groupId, TargetProperty targetProperty)
+{
+    return adoptPtr(new CCActiveAnimation(curve, animationId, groupId, targetProperty));
+}
+
+CCActiveAnimation::CCActiveAnimation(PassOwnPtr<CCAnimationCurve> curve, int animationId, int groupId, TargetProperty targetProperty)
     : m_animationCurve(curve)
-    , m_group(group)
+    , m_id(animationId)
+    , m_group(groupId)
     , m_targetProperty(targetProperty)
     , m_runState(WaitingForTargetAvailability)
     , m_iterations(1)
@@ -44,6 +50,10 @@ CCActiveAnimation::CCActiveAnimation(PassOwnPtr<CCAnimationCurve> curve, GroupID
 {
 }
 
+CCActiveAnimation::~CCActiveAnimation()
+{
+}
+
 void CCActiveAnimation::setRunState(RunState runState, double now)
 {
     if (runState == Running && m_runState == Paused)
@@ -63,6 +73,21 @@ bool CCActiveAnimation::isFinishedAt(double time) const
         && m_iterations * m_animationCurve->duration() <= time - startTime() - m_totalPausedTime;
 }
 
+bool CCActiveAnimation::isWaiting() const
+{
+    return m_runState == WaitingForNextTick
+        || m_runState == WaitingForTargetAvailability
+        || m_runState == WaitingForStartTime;
+}
+
+bool CCActiveAnimation::isRunningOrHasRun() const
+{
+    return m_runState == Running
+        || m_runState == Finished
+        || m_runState == Aborted
+        || m_runState == Paused;
+}
+
 double CCActiveAnimation::trimTimeToCurrentIteration(double now) const
 {
     double trimmed = now;
@@ -95,4 +120,36 @@ double CCActiveAnimation::trimTimeToCurrentIteration(double now) const
     return fmod(trimmed, m_animationCurve->duration());
 }
 
+PassOwnPtr<CCActiveAnimation> CCActiveAnimation::cloneForImplThread() const
+{
+    OwnPtr<CCActiveAnimation> toReturn(adoptPtr(new CCActiveAnimation(m_animationCurve->clone(), m_id, m_group, m_targetProperty)));
+    toReturn->m_runState = m_runState;
+    toReturn->m_iterations = m_iterations;
+    toReturn->m_startTime = m_startTime;
+    toReturn->m_pauseTime = m_pauseTime;
+    toReturn->m_totalPausedTime = m_totalPausedTime;
+    return toReturn.release();
+}
+
+void CCActiveAnimation::synchronizeProperties(CCActiveAnimation* other)
+{
+    // It is possible for the impl thread to initiate a run state change.
+    // This happens when the animation was waiting for a future event to take
+    // place, and the event has happened. In that case, we want 'this' to
+    // assume the impl thread's run state and start time.
+    if (isWaiting() && other->isRunningOrHasRun()) {
+        m_runState = other->m_runState;
+        m_startTime = other->m_startTime;
+    } else {
+        other->m_runState = m_runState;
+        other->m_startTime = m_startTime;
+    }
+
+    // Change in state related to iterations and pause is always initiated from
+    // the main thread, so it is safe to push properties in that direction.
+    other->m_iterations = m_iterations;
+    other->m_pauseTime = m_pauseTime;
+    other->m_totalPausedTime = m_totalPausedTime;
+}
+
 } // namespace WebCore
index c222279..ad9e84e 100644 (file)
 #ifndef CCActiveAnimation_h
 #define CCActiveAnimation_h
 
+#include "cc/CCAnimationCurve.h"
+
+#include <wtf/Noncopyable.h>
 #include <wtf/OwnPtr.h>
 #include <wtf/PassOwnPtr.h>
 
 namespace WebCore {
 
-class CCAnimationCurve;
-
 // A CCActiveAnimation, contains all the state required to play a CCAnimationCurve.
 // Specifically, the affected property, the run state (paused, finished, etc.),
 // loop count, last pause time, and the total time spent paused.
 class CCActiveAnimation {
+    WTF_MAKE_NONCOPYABLE(CCActiveAnimation);
 public:
-    // Animations that must be run together are called 'grouped' and have the same GroupID
-    // Grouped animations are guaranteed to start at the same time and no other animations
-    // may animate any of the group's target properties until all animations in the
-    // group have finished animating. Note: an active animation's group id and target
-    // property uniquely identify that animation.
-    typedef int GroupID;
-
     // Animations begin in one of the 'waiting' states. Animations waiting for the next tick
     // will start the next time the controller animates. Animations waiting for target
     // availibility will run as soon as their target property is free (and all the animations
@@ -68,14 +63,20 @@ public:
         Opacity
     };
 
-    static PassOwnPtr<CCActiveAnimation> create(PassOwnPtr<CCAnimationCurve> curve, GroupID group, TargetProperty targetProperty)
-    {
-        return adoptPtr(new CCActiveAnimation(curve, group, targetProperty));
-    }
+    struct AnimationSignature {
+        AnimationSignature(int groupId, TargetProperty targetProperty)
+            : groupId(groupId)
+            , targetProperty(targetProperty) { }
+        int groupId;
+        TargetProperty targetProperty;
+    };
 
-    virtual ~CCActiveAnimation() { }
+    static PassOwnPtr<CCActiveAnimation> create(PassOwnPtr<CCAnimationCurve>, int animationId, int groupId, TargetProperty);
 
-    GroupID group() const { return m_group; }
+    virtual ~CCActiveAnimation();
+
+    int id() const { return m_id; }
+    int group() const { return m_group; }
     TargetProperty targetProperty() const { return m_targetProperty; }
 
     RunState runState() const { return m_runState; }
@@ -93,6 +94,9 @@ public:
     bool isFinishedAt(double time) const;
     bool isFinished() const { return m_runState == Finished || m_runState == Aborted; }
 
+    bool isWaiting() const;
+    bool isRunningOrHasRun() const;
+
     CCAnimationCurve* animationCurve() { return m_animationCurve.get(); }
     const CCAnimationCurve* animationCurve() const { return m_animationCurve.get(); }
 
@@ -100,11 +104,27 @@ public:
     // of iterations, returns the relative time in the current iteration.
     double trimTimeToCurrentIteration(double now) const;
 
+    AnimationSignature signature() const { return AnimationSignature(m_group, m_targetProperty); }
+
+    PassOwnPtr<CCActiveAnimation> cloneForImplThread() const;
+
+    void synchronizeProperties(CCActiveAnimation*);
+
 private:
-    CCActiveAnimation(PassOwnPtr<CCAnimationCurve>, GroupID, TargetProperty);
+    CCActiveAnimation(PassOwnPtr<CCAnimationCurve>, int animationId, int groupId, TargetProperty);
 
     OwnPtr<CCAnimationCurve> m_animationCurve;
-    GroupID m_group;
+
+    // IDs are not necessarily unique.
+    int m_id;
+
+    // Animations that must be run together are called 'grouped' and have the same group id
+    // Grouped animations are guaranteed to start at the same time and no other animations
+    // may animate any of the group's target properties until all animations in the
+    // group have finished animating. Note: an active animation's group id and target
+    // property uniquely identify that animation.
+    int m_group;
+
     TargetProperty m_targetProperty;
     RunState m_runState;
     int m_iterations;
index de97e38..533abaf 100644 (file)
 #ifndef CCAnimationCurve_h
 #define CCAnimationCurve_h
 
+#include "TransformationMatrix.h"
+
+#include <wtf/PassOwnPtr.h>
+
 namespace WebCore {
 
 class CCFloatAnimationCurve;
@@ -41,6 +45,7 @@ public:
 
     virtual double duration() const = 0;
     virtual Type type() const = 0;
+    virtual PassOwnPtr<CCAnimationCurve> clone() const = 0;
 
     const CCFloatAnimationCurve* toFloatAnimationCurve() const;
     const CCTransformAnimationCurve* toTransformAnimationCurve() const;
@@ -60,7 +65,7 @@ class CCTransformAnimationCurve : public CCAnimationCurve {
 public:
     virtual ~CCTransformAnimationCurve() { }
 
-    virtual TransformOperations getValue(double t) const = 0;
+    virtual TransformationMatrix getValue(double t, const IntSize& layerSize) const = 0;
 
     // Partial CCAnimation implementation.
     virtual Type type() const { return Transform; }
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCAnimationEvents.h b/Source/WebCore/platform/graphics/chromium/cc/CCAnimationEvents.h
new file mode 100644 (file)
index 0000000..b21a79e
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CCAnimationEvents_h
+#define CCAnimationEvents_h
+
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+// Indicates that an animation has started on a particular layer.
+struct CCAnimationStartedEvent {
+    CCAnimationStartedEvent(int layerID, double time)
+        : layerID(layerID)
+        , time(time) { }
+    int layerID;
+    double time;
+};
+
+typedef Vector<CCAnimationStartedEvent> CCAnimationEventsVector;
+
+} // namespace WebCore
+
+#endif // CCAnimationEvents_h
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.cpp
new file mode 100644 (file)
index 0000000..94551d9
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "cc/CCLayerAnimationController.h"
+
+#include "GraphicsLayer.h" // for KeyframeValueList
+#include "cc/CCActiveAnimation.h"
+#include "cc/CCLayerAnimationControllerImpl.h"
+#include <wtf/HashMap.h>
+
+namespace WebCore {
+
+CCLayerAnimationController::CCLayerAnimationController()
+{
+}
+
+CCLayerAnimationController::~CCLayerAnimationController()
+{
+}
+
+PassOwnPtr<CCLayerAnimationController> CCLayerAnimationController::create()
+{
+    return adoptPtr(new CCLayerAnimationController);
+}
+
+bool CCLayerAnimationController::addAnimation(const KeyframeValueList& valueList,
+                                              const IntSize&,
+                                              const Animation* animation,
+                                              int animationId,
+                                              int groupId,
+                                              double timeOffset)
+{
+    return false;
+}
+
+void CCLayerAnimationController::pauseAnimation(int animationId, double timeOffset)
+{
+    for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
+        if (m_activeAnimations[i]->id() == animationId)
+            m_activeAnimations[i]->setRunState(CCActiveAnimation::Paused, timeOffset);
+    }
+}
+
+void CCLayerAnimationController::removeAnimation(int animationId)
+{
+    for (size_t i = 0; i < m_activeAnimations.size();) {
+        if (m_activeAnimations[i]->id() == animationId)
+            m_activeAnimations.remove(i);
+        else
+            i++;
+    }
+}
+
+// According to render layer backing, these are for testing only.
+void CCLayerAnimationController::suspendAnimations(double time)
+{
+}
+
+// Looking at GraphicsLayerCA, this appears to be the analog to suspendAnimations, which is for testing.
+void CCLayerAnimationController::resumeAnimations()
+{
+}
+
+// Ensures that the list of active animations on the main thread and the impl thread
+// are kept in sync.
+void CCLayerAnimationController::synchronizeAnimations(CCLayerAnimationControllerImpl* controllerImpl)
+{
+    removeCompletedAnimations(controllerImpl);
+    pushNewAnimationsToImplThread(controllerImpl);
+    removeAnimationsCompletedOnMainThread(controllerImpl);
+    pushAnimationProperties(controllerImpl);
+}
+
+void CCLayerAnimationController::removeCompletedAnimations(CCLayerAnimationControllerImpl* controllerImpl)
+{
+    // Any animations finished on the impl thread are removed from the main thread's collection.
+    for (size_t i = 0; i < controllerImpl->m_finishedAnimations.size(); ++i)
+        remove(controllerImpl->m_finishedAnimations[i].groupId, controllerImpl->m_finishedAnimations[i].targetProperty);
+    controllerImpl->m_finishedAnimations.clear();
+}
+
+void CCLayerAnimationController::pushNewAnimationsToImplThread(CCLayerAnimationControllerImpl* controllerImpl)
+{
+    // Any new animations owned by the main thread's controller are cloned and adde to the impl thread's controller.
+    for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
+        if (!controllerImpl->getActiveAnimation(m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty()))
+            controllerImpl->add(m_activeAnimations[i]->cloneForImplThread());
+    }
+}
+
+void CCLayerAnimationController::removeAnimationsCompletedOnMainThread(CCLayerAnimationControllerImpl* controllerImpl)
+{
+    // Delete all impl thread animations for which there is no corresponding main thread animation.
+    // Each iteration, controller->m_activeAnimations.size() is decremented or i is incremented
+    // guaranteeing progress towards loop termination.
+    for (size_t i = 0; i < controllerImpl->m_activeAnimations.size();) {
+        CCActiveAnimation* current = getActiveAnimation(controllerImpl->m_activeAnimations[i]->group(), controllerImpl->m_activeAnimations[i]->targetProperty());
+        if (!current)
+            controllerImpl->m_activeAnimations.remove(i);
+        else
+            i++;
+    }
+}
+
+void CCLayerAnimationController::pushAnimationProperties(CCLayerAnimationControllerImpl* controllerImpl)
+{
+    // Delete all impl thread animations for which there is no corresponding main thread animation.
+    // Each iteration, controller->m_activeAnimations.size() is decremented or i is incremented
+    // guaranteeing progress towards loop termination.
+    for (size_t i = 0; i < controllerImpl->m_activeAnimations.size(); ++i) {
+        CCActiveAnimation* currentImpl = controllerImpl->m_activeAnimations[i].get();
+        CCActiveAnimation* current = getActiveAnimation(currentImpl->group(), currentImpl->targetProperty());
+        ASSERT(current);
+        if (current)
+            current->synchronizeProperties(currentImpl);
+    }
+}
+
+CCActiveAnimation* CCLayerAnimationController::getActiveAnimation(int groupId, CCActiveAnimation::TargetProperty targetProperty)
+{
+    for (size_t i = 0; i < m_activeAnimations.size(); ++i)
+        if (m_activeAnimations[i]->group() == groupId && m_activeAnimations[i]->targetProperty() == targetProperty)
+            return m_activeAnimations[i].get();
+    return 0;
+}
+
+void CCLayerAnimationController::remove(int groupId, CCActiveAnimation::TargetProperty targetProperty)
+{
+    for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
+        if (m_activeAnimations[i]->group() == groupId && m_activeAnimations[i]->targetProperty() == targetProperty) {
+            m_activeAnimations.remove(i);
+            return;
+        }
+    }
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.h
new file mode 100644 (file)
index 0000000..6704a60
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CCLayerAnimationController_h
+#define CCLayerAnimationController_h
+
+#include "cc/CCActiveAnimation.h"
+
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class Animation;
+class CCLayerAnimationControllerImpl;
+struct IntSize;
+class KeyframeValueList;
+
+class CCLayerAnimationController {
+    WTF_MAKE_NONCOPYABLE(CCLayerAnimationController);
+public:
+    static PassOwnPtr<CCLayerAnimationController> create();
+
+    virtual ~CCLayerAnimationController();
+
+    // These are virtual for testing.
+    virtual bool addAnimation(const KeyframeValueList&, const IntSize& boxSize, const Animation*, int animationId, int groupId, double timeOffset);
+    virtual void pauseAnimation(int animationId, double timeOffset);
+    virtual void removeAnimation(int animationId);
+    virtual void suspendAnimations(double time);
+    virtual void resumeAnimations();
+
+    // Ensures that the list of active animations on the main thread and the impl thread
+    // are kept in sync. This function does not take ownership of the impl thread controller.
+    virtual void synchronizeAnimations(CCLayerAnimationControllerImpl*);
+
+    // This is for testing purposes only.
+    Vector<OwnPtr<CCActiveAnimation> >& activeAnimations() { return m_activeAnimations; }
+
+protected:
+    CCLayerAnimationController();
+
+private:
+    void removeCompletedAnimations(CCLayerAnimationControllerImpl*);
+    void pushNewAnimationsToImplThread(CCLayerAnimationControllerImpl*);
+    void removeAnimationsCompletedOnMainThread(CCLayerAnimationControllerImpl*);
+    void pushAnimationProperties(CCLayerAnimationControllerImpl*);
+
+    CCActiveAnimation* getActiveAnimation(int groupId, CCActiveAnimation::TargetProperty);
+    void remove(int groupId, CCActiveAnimation::TargetProperty);
+
+    Vector<OwnPtr<CCActiveAnimation> > m_activeAnimations;
+};
+
+} // namespace WebCore
+
+#endif // CCLayerAnimationController_h
index bbca9cb..4f72798 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "cc/CCLayerAnimationControllerImpl.h"
 
+#include "TransformationMatrix.h"
 #include "TransformOperations.h"
 
 namespace WebCore {
@@ -44,28 +45,30 @@ CCLayerAnimationControllerImpl::CCLayerAnimationControllerImpl(CCLayerAnimationC
 {
 }
 
-void CCLayerAnimationControllerImpl::animate(double frameBeginTimeSecs)
+CCLayerAnimationControllerImpl::~CCLayerAnimationControllerImpl()
 {
-    startAnimationsWaitingForNextTick(frameBeginTimeSecs);
-    startAnimationsWaitingForStartTime(frameBeginTimeSecs);
-    startAnimationsWaitingForTargetAvailability(frameBeginTimeSecs);
+}
+
+void CCLayerAnimationControllerImpl::animate(double frameBeginTimeSecs, CCAnimationEventsVector& events)
+{
+    startAnimationsWaitingForNextTick(frameBeginTimeSecs, events);
+    startAnimationsWaitingForStartTime(frameBeginTimeSecs, events);
+    startAnimationsWaitingForTargetAvailability(frameBeginTimeSecs, events);
     resolveConflicts(frameBeginTimeSecs);
     tickAnimations(frameBeginTimeSecs);
     purgeFinishedAnimations();
-    startAnimationsWaitingForTargetAvailability(frameBeginTimeSecs);
+    startAnimationsWaitingForTargetAvailability(frameBeginTimeSecs, events);
 }
 
 void CCLayerAnimationControllerImpl::add(PassOwnPtr<CCActiveAnimation> anim)
 {
     m_activeAnimations.append(anim);
-    if (m_client)
-        m_client->animationControllerImplDidActivate(this);
 }
 
-CCActiveAnimation* CCLayerAnimationControllerImpl::getActiveAnimation(CCActiveAnimation::GroupID group, CCActiveAnimation::TargetProperty property)
+CCActiveAnimation* CCLayerAnimationControllerImpl::getActiveAnimation(int groupId, CCActiveAnimation::TargetProperty property)
 {
     for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
-        if (m_activeAnimations[i]->group() == group && m_activeAnimations[i]->targetProperty() == property)
+        if (m_activeAnimations[i]->group() == groupId && m_activeAnimations[i]->targetProperty() == property)
             return m_activeAnimations[i].get();
     }
     return 0;
@@ -80,25 +83,28 @@ bool CCLayerAnimationControllerImpl::hasActiveAnimation() const
     return false;
 }
 
-void CCLayerAnimationControllerImpl::startAnimationsWaitingForNextTick(double now)
+void CCLayerAnimationControllerImpl::startAnimationsWaitingForNextTick(double now, CCAnimationEventsVector& events)
 {
     for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
         if (m_activeAnimations[i]->runState() == CCActiveAnimation::WaitingForNextTick) {
             m_activeAnimations[i]->setRunState(CCActiveAnimation::Running, now);
             m_activeAnimations[i]->setStartTime(now);
+            events.append(CCAnimationStartedEvent(m_client->id(), now));
         }
     }
 }
 
-void CCLayerAnimationControllerImpl::startAnimationsWaitingForStartTime(double now)
+void CCLayerAnimationControllerImpl::startAnimationsWaitingForStartTime(double now, CCAnimationEventsVector& events)
 {
     for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
-        if (m_activeAnimations[i]->runState() == CCActiveAnimation::WaitingForStartTime && m_activeAnimations[i]->startTime() <= now)
+        if (m_activeAnimations[i]->runState() == CCActiveAnimation::WaitingForStartTime && m_activeAnimations[i]->startTime() <= now) {
             m_activeAnimations[i]->setRunState(CCActiveAnimation::Running, now);
+            events.append(CCAnimationStartedEvent(m_client->id(), now));
+        }
     }
 }
 
-void CCLayerAnimationControllerImpl::startAnimationsWaitingForTargetAvailability(double now)
+void CCLayerAnimationControllerImpl::startAnimationsWaitingForTargetAvailability(double now, CCAnimationEventsVector& events)
 {
     // First collect running properties.
     TargetProperties blockedProperties;
@@ -130,6 +136,7 @@ void CCLayerAnimationControllerImpl::startAnimationsWaitingForTargetAvailability
             if (nullIntersection) {
                 m_activeAnimations[i]->setRunState(CCActiveAnimation::Running, now);
                 m_activeAnimations[i]->setStartTime(now);
+                events.append(CCAnimationStartedEvent(m_client->id(), now));
                 for (size_t j = i + 1; j < m_activeAnimations.size(); ++j) {
                     if (m_activeAnimations[i]->group() == m_activeAnimations[j]->group()) {
                         m_activeAnimations[j]->setRunState(CCActiveAnimation::Running, now);
@@ -178,9 +185,10 @@ void CCLayerAnimationControllerImpl::purgeFinishedAnimations()
                 }
             }
         }
-        if (allAnimsWithSameIdAreFinished)
+        if (allAnimsWithSameIdAreFinished) {
+            m_finishedAnimations.append(m_activeAnimations[i]->signature());
             m_activeAnimations.remove(i);
-        else
+        else
             i++;
     }
 }
@@ -194,14 +202,11 @@ void CCLayerAnimationControllerImpl::tickAnimations(double now)
 
             case CCActiveAnimation::Transform: {
                 const CCTransformAnimationCurve* transformAnimationCurve = m_activeAnimations[i]->animationCurve()->toTransformAnimationCurve();
-                const TransformOperations operations = transformAnimationCurve->getValue(trimmed);
+                const TransformationMatrix matrix = transformAnimationCurve->getValue(trimmed, m_client->bounds());
                 if (m_activeAnimations[i]->isFinishedAt(now))
                     m_activeAnimations[i]->setRunState(CCActiveAnimation::Finished, now);
 
-                // Decide here if absolute or relative. Absolute for now.
-                TransformationMatrix toApply;
-                operations.apply(FloatSize(), toApply);
-                m_client->setTransform(toApply);
+                m_client->setTransform(matrix);
                 break;
             }
 
index 1ad223d..296066d 100644 (file)
 
 #include "cc/CCActiveAnimation.h"
 #include "cc/CCAnimationCurve.h"
+#include "cc/CCAnimationEvents.h"
 
 #include <wtf/HashSet.h>
+#include <wtf/Noncopyable.h>
 #include <wtf/OwnPtr.h>
 #include <wtf/PassOwnPtr.h>
 #include <wtf/Vector.h>
@@ -44,35 +46,41 @@ class CCLayerAnimationControllerImplClient {
 public:
     virtual ~CCLayerAnimationControllerImplClient() { }
 
+    virtual int id() const = 0;
     virtual float opacity() const = 0;
     virtual void setOpacity(float) = 0;
     virtual const TransformationMatrix& transform() const = 0;
     virtual void setTransform(const TransformationMatrix&) = 0;
-    virtual void animationControllerImplDidActivate(CCLayerAnimationControllerImpl*) = 0;
+    virtual const IntSize& bounds() const = 0;
 };
 
 class CCLayerAnimationControllerImpl {
+    WTF_MAKE_NONCOPYABLE(CCLayerAnimationControllerImpl);
 public:
     static PassOwnPtr<CCLayerAnimationControllerImpl> create(CCLayerAnimationControllerImplClient*);
 
-    void animate(double frameBeginTimeSecs);
+    virtual ~CCLayerAnimationControllerImpl();
+
+    void animate(double frameBeginTimeSecs, CCAnimationEventsVector&);
 
     void add(PassOwnPtr<CCActiveAnimation>);
 
     // Returns the active animation in the given group, animating the given property if such an
     // animation exists.
-    CCActiveAnimation* getActiveAnimation(CCActiveAnimation::GroupID, CCActiveAnimation::TargetProperty);
+    CCActiveAnimation* getActiveAnimation(int groupId, CCActiveAnimation::TargetProperty);
 
     // Returns true if there are any animations that are neither finished nor aborted.
     bool hasActiveAnimation() const;
 
 private:
+    friend class CCLayerAnimationController;
+
     // The animator is owned by the layer.
     explicit CCLayerAnimationControllerImpl(CCLayerAnimationControllerImplClient*);
 
-    void startAnimationsWaitingForNextTick(double now);
-    void startAnimationsWaitingForStartTime(double now);
-    void startAnimationsWaitingForTargetAvailability(double now);
+    void startAnimationsWaitingForNextTick(double now, CCAnimationEventsVector&);
+    void startAnimationsWaitingForStartTime(double now, CCAnimationEventsVector&);
+    void startAnimationsWaitingForTargetAvailability(double now, CCAnimationEventsVector&);
     void resolveConflicts(double now);
     void purgeFinishedAnimations();
 
@@ -80,6 +88,7 @@ private:
 
     CCLayerAnimationControllerImplClient* m_client;
     Vector<OwnPtr<CCActiveAnimation> > m_activeAnimations;
+    Vector<CCActiveAnimation::AnimationSignature> m_finishedAnimations;
 };
 
 } // namespace WebCore
index ce54e7e..d4babe2 100644 (file)
@@ -33,6 +33,7 @@
 #include "LayerChromium.h"
 #include "LayerRendererChromium.h"
 #include "cc/CCDebugBorderDrawQuad.h"
+#include "cc/CCLayerAnimationControllerImpl.h"
 #include "cc/CCLayerSorter.h"
 #include "cc/CCSolidColorDrawQuad.h"
 #include <wtf/text/WTFString.h>
@@ -61,6 +62,7 @@ CCLayerImpl::CCLayerImpl(int id)
     , m_drawOpacity(0)
     , m_debugBorderColor(0, 0, 0, 0)
     , m_debugBorderWidth(0)
+    , m_layerAnimationController(CCLayerAnimationControllerImpl::create(this))
 {
     ASSERT(CCProxy::isImplThread());
 }
index 9e6c550..d0d5241 100644 (file)
@@ -32,6 +32,7 @@
 #include "IntRect.h"
 #include "TextStream.h"
 #include "TransformationMatrix.h"
+#include "cc/CCLayerAnimationControllerImpl.h"
 #include "cc/CCRenderPass.h"
 #include "cc/CCRenderSurface.h"
 #include <wtf/OwnPtr.h>
@@ -45,12 +46,21 @@ class CCLayerSorter;
 class LayerChromium;
 class LayerRendererChromium;
 
-class CCLayerImpl : public RefCounted<CCLayerImpl> {
+class CCLayerImpl : public RefCounted<CCLayerImpl>, public CCLayerAnimationControllerImplClient {
 public:
     static PassRefPtr<CCLayerImpl> create(int id)
     {
         return adoptRef(new CCLayerImpl(id));
     }
+
+    // CCLayerAnimationControllerImplClient implementation.
+    virtual int id() const { return m_layerId; }
+    virtual void setOpacity(float);
+    virtual float opacity() const { return m_opacity; }
+    virtual void setTransform(const TransformationMatrix&);
+    virtual const TransformationMatrix& transform() const { return m_transform; }
+    virtual const IntSize& bounds() const { return m_bounds; }
+
     virtual ~CCLayerImpl();
 
     // Tree structure.
@@ -66,8 +76,6 @@ public:
     void setReplicaLayer(PassRefPtr<CCLayerImpl>);
     CCLayerImpl* replicaLayer() const { return m_replicaLayer.get(); }
 
-    int id() const { return m_layerId; }
-
 #ifndef NDEBUG
     int debugID() const { return m_debugID; }
 #endif
@@ -111,9 +119,6 @@ public:
     void setOpaque(bool);
     bool opaque() const { return m_opaque; }
 
-    void setOpacity(float);
-    float opacity() const { return m_opacity; }
-
     void setPosition(const FloatPoint&);
     const FloatPoint& position() const { return m_position; }
 
@@ -129,9 +134,6 @@ public:
     void setSublayerTransform(const TransformationMatrix&);
     const TransformationMatrix& sublayerTransform() const { return m_sublayerTransform; }
 
-    void setTransform(const TransformationMatrix&);
-    const TransformationMatrix& transform() const { return m_transform; }
-
     void setName(const String& name) { m_name = name; }
     const String& name() const { return m_name; }
 
@@ -154,7 +156,6 @@ public:
     CCRenderSurface* targetRenderSurface() const { return m_targetRenderSurface; }
     void setTargetRenderSurface(CCRenderSurface* surface) { m_targetRenderSurface = surface; }
 
-    const IntSize& bounds() const { return m_bounds; }
     void setBounds(const IntSize&);
 
     const IntSize& contentBounds() const { return m_contentBounds; }
@@ -203,6 +204,8 @@ public:
     bool layerPropertyChanged() const { return m_layerPropertyChanged; }
     void resetAllChangeTrackingForSubtree();
 
+    CCLayerAnimationControllerImpl* layerAnimationController() { return m_layerAnimationController.get(); }
+
 protected:
     explicit CCLayerImpl(int);
 
@@ -312,6 +315,9 @@ private:
     // Rect indicating what was repainted/updated during update.
     // Note that plugin layers bypass this and leave it empty.
     FloatRect m_updateRect;
+
+    // Manages animations for this layer.
+    OwnPtr<CCLayerAnimationControllerImpl> m_layerAnimationController;
 };
 
 void sortLayers(Vector<RefPtr<CCLayerImpl> >::iterator first, Vector<RefPtr<CCLayerImpl> >::iterator end, CCLayerSorter*);
index e462e53..ea17e8c 100644 (file)
@@ -171,9 +171,11 @@ void CCLayerTreeHost::finishCommitOnImplThread(CCLayerTreeHostImpl* hostImpl)
     ASSERT(CCProxy::isImplThread());
 
     // Synchronize trees, if one exists at all...
-    if (rootLayer())
+    if (rootLayer()) {
         hostImpl->setRootLayer(TreeSynchronizer::synchronizeTrees(rootLayer(), hostImpl->rootLayer()));
-    else
+        // We may have added an animation during the tree sync. This will cause hostImpl to visit its controllers.
+        hostImpl->setNeedsAnimateLayers();
+    } else
         hostImpl->setRootLayer(0);
 
     hostImpl->setSourceFrameNumber(frameNumber());
@@ -259,6 +261,12 @@ void CCLayerTreeHost::setNeedsRedraw()
         m_client->scheduleComposite();
 }
 
+void CCLayerTreeHost::setAnimationEvents(PassOwnPtr<CCAnimationEventsVector> events)
+{
+    ASSERT(CCThreadProxy::isMainThread());
+    // FIXME: need to walk the tree.
+}
+
 void CCLayerTreeHost::setRootLayer(PassRefPtr<LayerChromium> rootLayer)
 {
     if (m_rootLayer == rootLayer)
@@ -334,9 +342,12 @@ void CCLayerTreeHost::didBecomeInvisibleOnImplThread(CCLayerTreeHostImpl* hostIm
         hostImpl->setRootLayer(0);
         return;
     }
-    if (rootLayer())
+
+    if (rootLayer()) {
         hostImpl->setRootLayer(TreeSynchronizer::synchronizeTrees(rootLayer(), hostImpl->rootLayer()));
-    else
+        // We may have added an animation during the tree sync. This will cause hostImpl to visit its controllers.
+        hostImpl->setNeedsAnimateLayers();
+    } else
         hostImpl->setRootLayer(0);
 }
 
index f5e1134..4ed8da9 100644 (file)
@@ -30,6 +30,7 @@
 #include "LayerChromium.h"
 #include "RateLimiter.h"
 #include "TransformationMatrix.h"
+#include "cc/CCAnimationEvents.h"
 #include "cc/CCLayerTreeHostCommon.h"
 #include "cc/CCProxy.h"
 
@@ -75,6 +76,7 @@ struct CCSettings {
             , refreshRate(0)
             , perTilePainting(false)
             , partialSwapEnabled(false)
+            , threadedAnimationEnabled(false)
             , maxPartialTextureUpdates(std::numeric_limits<size_t>::max()) { }
 
     bool acceleratePainting;
@@ -84,6 +86,7 @@ struct CCSettings {
     double refreshRate;
     bool perTilePainting;
     bool partialSwapEnabled;
+    bool threadedAnimationEnabled;
     size_t maxPartialTextureUpdates;
 };
 
@@ -163,6 +166,8 @@ public:
     virtual void setNeedsCommit();
     void setNeedsRedraw();
 
+    void setAnimationEvents(PassOwnPtr<CCAnimationEventsVector>);
+
     LayerChromium* rootLayer() { return m_rootLayer.get(); }
     const LayerChromium* rootLayer() const { return m_rootLayer.get(); }
     void setRootLayer(PassRefPtr<LayerChromium>);
index 56087d3..ce31951 100644 (file)
@@ -58,6 +58,7 @@ CCLayerTreeHostImpl::CCLayerTreeHostImpl(const CCSettings& settings, CCLayerTree
     , m_sentPageScaleDelta(1)
     , m_minPageScale(0)
     , m_maxPageScale(0)
+    , m_needsAnimateLayers(false)
     , m_pinchGestureActive(false)
 {
     ASSERT(CCProxy::isImplThread());
@@ -98,21 +99,8 @@ GraphicsContext3D* CCLayerTreeHostImpl::context()
 
 void CCLayerTreeHostImpl::animate(double frameBeginTimeMs)
 {
-    if (!m_pageScaleAnimation)
-        return;
-
-    IntSize scrollTotal = toSize(m_scrollLayerImpl->scrollPosition() + m_scrollLayerImpl->scrollDelta());
-
-    setPageScaleDelta(m_pageScaleAnimation->pageScaleAtTime(frameBeginTimeMs) / m_pageScale);
-    IntSize nextScroll = m_pageScaleAnimation->scrollOffsetAtTime(frameBeginTimeMs);
-    nextScroll.scale(1 / m_pageScaleDelta);
-    m_scrollLayerImpl->scrollBy(nextScroll - scrollTotal);
-    m_client->setNeedsRedrawOnImplThread();
-
-    if (m_pageScaleAnimation->isAnimationCompleteAtTime(frameBeginTimeMs)) {
-        m_pageScaleAnimation.clear();
-        m_client->setNeedsCommitOnImplThread();
-    }
+    animatePageScale(frameBeginTimeMs);
+    animateLayers(frameBeginTimeMs);
 }
 
 void CCLayerTreeHostImpl::startPageScaleAnimation(const IntSize& targetPosition, bool anchorPoint, float pageScale, double startTimeMs, double durationMs)
@@ -250,6 +238,34 @@ void CCLayerTreeHostImpl::optimizeRenderPasses(CCRenderPassList& passes)
     }
 }
 
+void CCLayerTreeHostImpl::animateLayersRecursive(CCLayerImpl* current, double frameBeginTimeSecs, CCAnimationEventsVector& events, bool& didAnimate, bool& needsAnimateLayers)
+{
+    bool subtreeNeedsAnimateLayers = false;
+
+    CCLayerAnimationControllerImpl* currentController = current->layerAnimationController();
+
+    bool hadActiveAnimation = currentController->hasActiveAnimation();
+    currentController->animate(frameBeginTimeSecs, events);
+    bool startedAnimation = events.size() > 0;
+
+    // We animated if we either ticked a running animation, or started a new animation.
+    if (hadActiveAnimation || startedAnimation)
+        didAnimate = true;
+
+    // If the current controller still has an active animation, we must continue animating layers.
+    if (currentController->hasActiveAnimation())
+         subtreeNeedsAnimateLayers = true;
+
+    for (size_t i = 0; i < current->children().size(); ++i) {
+        bool childNeedsAnimateLayers = false;
+        animateLayersRecursive(current->children()[i].get(), frameBeginTimeSecs, events, didAnimate, childNeedsAnimateLayers);
+        if (childNeedsAnimateLayers)
+            subtreeNeedsAnimateLayers = true;
+    }
+
+    needsAnimateLayers = subtreeNeedsAnimateLayers;
+}
+
 IntSize CCLayerTreeHostImpl::contentSize() const
 {
     // TODO(aelias): Hardcoding the first child here is weird. Think of
@@ -624,4 +640,42 @@ void CCLayerTreeHostImpl::setFullRootLayerDamage()
     }
 }
 
+void CCLayerTreeHostImpl::animatePageScale(double frameBeginTimeMs)
+{
+    if (!m_pageScaleAnimation)
+        return;
+
+    IntSize scrollTotal = toSize(m_scrollLayerImpl->scrollPosition() + m_scrollLayerImpl->scrollDelta());
+
+    setPageScaleDelta(m_pageScaleAnimation->pageScaleAtTime(frameBeginTimeMs) / m_pageScale);
+    IntSize nextScroll = m_pageScaleAnimation->scrollOffsetAtTime(frameBeginTimeMs);
+    nextScroll.scale(1 / m_pageScaleDelta);
+    m_scrollLayerImpl->scrollBy(nextScroll - scrollTotal);
+    m_client->setNeedsRedrawOnImplThread();
+
+    if (m_pageScaleAnimation->isAnimationCompleteAtTime(frameBeginTimeMs)) {
+        m_pageScaleAnimation.clear();
+        m_client->setNeedsCommitOnImplThread();
+    }
+}
+
+void CCLayerTreeHostImpl::animateLayers(double frameBeginTimeMs)
+{
+    if (!m_settings.threadedAnimationEnabled || !m_needsAnimateLayers || !m_rootLayerImpl)
+        return;
+
+    TRACE_EVENT("CCLayerTreeHostImpl::animateLayers", this, 0);
+
+    OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
+
+    bool didAnimate = false;
+    animateLayersRecursive(m_rootLayerImpl.get(), frameBeginTimeMs / 1000, *events, didAnimate, m_needsAnimateLayers);
+
+    if (!events->isEmpty())
+        m_client->postAnimationEventsToMainThreadOnImplThread(events.release());
+
+    if (didAnimate)
+        m_client->setNeedsRedrawOnImplThread();
 }
+
+} // namespace WebCore
index 0a3cbae..69a8a9a 100644 (file)
 #ifndef CCLayerTreeHostImpl_h
 #define CCLayerTreeHostImpl_h
 
+#include "cc/CCAnimationEvents.h"
 #include "cc/CCInputHandler.h"
 #include "cc/CCLayerSorter.h"
 #include "cc/CCLayerTreeHost.h"
 #include "cc/CCLayerTreeHostCommon.h"
 #include "cc/CCRenderPass.h"
+#include <wtf/PassOwnPtr.h>
 #include <wtf/RefPtr.h>
 
 namespace WebCore {
@@ -48,6 +50,7 @@ public:
     virtual void onSwapBuffersCompleteOnImplThread() = 0;
     virtual void setNeedsRedrawOnImplThread() = 0;
     virtual void setNeedsCommitOnImplThread() = 0;
+    virtual void postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector>) = 0;
 };
 
 // CCLayerTreeHostImpl owns the CCLayerImpl tree as well as associated rendering state
@@ -68,7 +71,7 @@ public:
     virtual void pinchGestureEnd();
     virtual void startPageScaleAnimation(const IntSize& targetPosition, bool anchorPoint, float pageScale, double startTimeMs, double durationMs);
 
-    // Virtual for testing
+    // Virtual for testing.
     virtual void beginCommit();
     virtual void commitComplete();
     virtual void animate(double frameDisplayTimeMs);
@@ -119,8 +122,17 @@ public:
 
     void startPageScaleAnimation(const IntSize& tragetPosition, bool useAnchor, float scale, double durationSec);
 
+    bool needsAnimateLayers() const { return m_needsAnimateLayers; }
+    void setNeedsAnimateLayers() { m_needsAnimateLayers = true; }
+
 protected:
     CCLayerTreeHostImpl(const CCSettings&, CCLayerTreeHostImplClient*);
+
+    void animatePageScale(double frameBeginTimeMs);
+
+    // Virtual for testing.
+    virtual void animateLayers(double frameBeginTimeMs);
+
     CCLayerTreeHostImplClient* m_client;
     int m_sourceFrameNumber;
     int m_frameNumber;
@@ -139,6 +151,7 @@ private:
     void trackDamageForAllSurfaces(CCLayerImpl* rootDrawLayer, const CCLayerList& renderSurfaceLayerList);
     void calculateRenderPasses(CCRenderPassList&, CCLayerList& renderSurfaceLayerList);
     void optimizeRenderPasses(CCRenderPassList&);
+    void animateLayersRecursive(CCLayerImpl*, double frameBeginTimeSecs, CCAnimationEventsVector&, bool& didAnimate, bool& needsAnimateLayers);
     IntSize contentSize() const;
 
     OwnPtr<LayerRendererChromium> m_layerRenderer;
@@ -154,6 +167,8 @@ private:
     float m_sentPageScaleDelta;
     float m_minPageScale, m_maxPageScale;
 
+    // If this is true, it is necessary to traverse the layer tree ticking the animators.
+    bool m_needsAnimateLayers;
     bool m_pinchGestureActive;
     IntPoint m_previousPinchAnchor;
 
index 17a6959..ea8c40f 100644 (file)
@@ -233,6 +233,13 @@ void CCSingleThreadProxy::stop()
     m_layerTreeHost = 0;
 }
 
+void CCSingleThreadProxy::postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector> events)
+{
+    ASSERT(CCProxy::isImplThread());
+    DebugScopedSetMainThread main;
+    m_layerTreeHost->setAnimationEvents(events);
+}
+
 // Called by the legacy scheduling path (e.g. where render_widget does the scheduling)
 void CCSingleThreadProxy::compositeImmediately()
 {
index adda9f1..71b5e99 100644 (file)
@@ -25,6 +25,7 @@
 #ifndef CCSingleThreadProxy_h
 #define CCSingleThreadProxy_h
 
+#include "cc/CCAnimationEvents.h"
 #include "cc/CCCompletionEvent.h"
 #include "cc/CCLayerTreeHostImpl.h"
 #include "cc/CCProxy.h"
@@ -63,6 +64,7 @@ public:
     virtual void onSwapBuffersCompleteOnImplThread() { ASSERT_NOT_REACHED(); }
     virtual void setNeedsRedrawOnImplThread() { m_layerTreeHost->setNeedsCommit(); }
     virtual void setNeedsCommitOnImplThread() { m_layerTreeHost->setNeedsCommit(); }
+    virtual void postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector>);
 
     // Called by the legacy path where RenderWidget does the scheduling.
     void compositeImmediately();
@@ -111,6 +113,24 @@ public:
     }
 };
 
+// For use in the single-threaded case. In debug builds, it pretends that the
+// code is running on the main thread to satisfy assertion checks.
+class DebugScopedSetMainThread {
+public:
+    DebugScopedSetMainThread()
+    {
+#if !ASSERT_DISABLED
+        CCProxy::setCurrentThreadIsImplThread(false);
+#endif
+    }
+    ~DebugScopedSetMainThread()
+    {
+#if !ASSERT_DISABLED
+        CCProxy::setCurrentThreadIsImplThread(true);
+#endif
+    }
+};
+
 } // namespace WebCore
 
 #endif
index 3ea72e2..75ef136 100644 (file)
@@ -259,6 +259,13 @@ void CCThreadProxy::setNeedsCommitOnImplThread()
     m_schedulerOnImplThread->setNeedsCommit();
 }
 
+void CCThreadProxy::postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector> events)
+{
+    ASSERT(isImplThread());
+    TRACE_EVENT("CCThreadProxy::postAnimationEventsToMainThreadOnImplThread", this, 0);
+    m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::setAnimationEvents, events));
+}
+
 void CCThreadProxy::setNeedsRedraw()
 {
     ASSERT(isMainThread());
@@ -562,6 +569,14 @@ void CCThreadProxy::didCompleteSwapBuffers()
     m_layerTreeHost->didCompleteSwapBuffers();
 }
 
+void CCThreadProxy::setAnimationEvents(PassOwnPtr<CCAnimationEventsVector> events)
+{
+    ASSERT(isMainThread());
+    if (!m_layerTreeHost)
+        return;
+    m_layerTreeHost->setAnimationEvents(events);
+}
+
 void CCThreadProxy::initializeImplOnImplThread(CCCompletionEvent* completion)
 {
     TRACE_EVENT("CCThreadProxy::initializeImplOnImplThread", this, 0);
index 23c29f4..330ef51 100644 (file)
@@ -25,6 +25,7 @@
 #ifndef CCThreadProxy_h
 #define CCThreadProxy_h
 
+#include "cc/CCAnimationEvents.h"
 #include "cc/CCCompletionEvent.h"
 #include "cc/CCLayerTreeHostImpl.h"
 #include "cc/CCProxy.h"
@@ -70,6 +71,7 @@ public:
     virtual void onSwapBuffersCompleteOnImplThread();
     virtual void setNeedsRedrawOnImplThread();
     virtual void setNeedsCommitOnImplThread();
+    virtual void postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector>);
 
     // CCSchedulerClient implementation
     virtual bool canDraw();
@@ -86,6 +88,7 @@ private:
     void beginFrameAndCommit(int sequenceNumber, double frameBeginTime, PassOwnPtr<CCScrollAndScaleSet>);
     void didCommitAndDrawFrame();
     void didCompleteSwapBuffers();
+    void setAnimationEvents(PassOwnPtr<CCAnimationEventsVector>);
 
     // Called on impl thread
     struct ReadbackRequest {
index 7df88a3..de32e0e 100644 (file)
@@ -1,3 +1,98 @@
+2012-02-22  Ian Vollick  <vollick@chromium.org>
+
+        [chromium] Plumb from GraphicsLayer to the cc thread animation code
+        https://bugs.webkit.org/show_bug.cgi?id=75874
+
+        Reviewed by James Robinson.
+
+        * WebKit.gypi:
+        * public/WebSettings.h:
+        * public/platform/WebLayerTreeView.h:
+        (WebKit::WebLayerTreeView::Settings::Settings):
+        (Settings):
+        * src/WebLayerTreeView.cpp:
+        (WebKit::WebLayerTreeView::Settings::operator CCSettings):
+        * src/WebSettingsImpl.cpp:
+        (WebKit::WebSettingsImpl::setThreadedAnimationEnabled):
+        (WebKit):
+        * src/WebSettingsImpl.h:
+        (WebSettingsImpl):
+        * src/WebViewImpl.cpp:
+        (WebKit::WebViewImpl::setIsAcceleratedCompositingActive):
+        * tests/CCActiveAnimationTest.cpp:
+        (WebCore::createActiveAnimation):
+        * tests/CCAnimationTestCommon.cpp: Added.
+        (WebKitTests):
+        (WebKitTests::FakeFloatAnimationCurve::FakeFloatAnimationCurve):
+        (WebKitTests::FakeFloatAnimationCurve::~FakeFloatAnimationCurve):
+        (WebKitTests::FakeFloatAnimationCurve::clone):
+        (WebKitTests::FakeTransformTransition::FakeTransformTransition):
+        (WebKitTests::FakeTransformTransition::~FakeTransformTransition):
+        (WebKitTests::FakeTransformTransition::getValue):
+        (WebKitTests::FakeTransformTransition::clone):
+        (WebKitTests::FakeFloatTransition::FakeFloatTransition):
+        (WebKitTests::FakeFloatTransition::~FakeFloatTransition):
+        (WebKitTests::FakeFloatTransition::getValue):
+        (WebKitTests::FakeLayerAnimationControllerImplClient::FakeLayerAnimationControllerImplClient):
+        (WebKitTests::FakeLayerAnimationControllerImplClient::~FakeLayerAnimationControllerImplClient):
+        (WebKitTests::FakeFloatTransition::clone):
+        (WebKitTests::addOpacityTransition):
+        * tests/CCAnimationTestCommon.h: Added.
+        (WebCore):
+        (WebKitTests):
+        (FakeFloatAnimationCurve):
+        (WebKitTests::FakeFloatAnimationCurve::duration):
+        (WebKitTests::FakeFloatAnimationCurve::getValue):
+        (FakeTransformTransition):
+        (WebKitTests::FakeTransformTransition::duration):
+        (FakeFloatTransition):
+        (WebKitTests::FakeFloatTransition::duration):
+        (FakeLayerAnimationControllerImplClient):
+        (WebKitTests::FakeLayerAnimationControllerImplClient::id):
+        (WebKitTests::FakeLayerAnimationControllerImplClient::opacity):
+        (WebKitTests::FakeLayerAnimationControllerImplClient::setOpacity):
+        (WebKitTests::FakeLayerAnimationControllerImplClient::transform):
+        (WebKitTests::FakeLayerAnimationControllerImplClient::setTransform):
+        (WebKitTests::FakeLayerAnimationControllerImplClient::bounds):
+        * tests/CCLayerAnimationControllerImplTest.cpp:
+        (WebKitTests::createActiveAnimation):
+        (WebKitTests::TEST):
+        * tests/CCLayerAnimationControllerTest.cpp: Added.
+        (WebKitTests):
+        (WebKitTests::createActiveAnimation):
+        (WebKitTests::TEST):
+        * tests/CCLayerTreeHostImplTest.cpp:
+        (WebKit::CCLayerTreeHostImplTest::postAnimationEventsToMainThreadOnImplThread):
+        * tests/CCLayerTreeHostTest.cpp:
+        (WTF::TestHooks::animateLayers):
+        (MockLayerTreeHostImpl):
+        (WTF::MockLayerTreeHostImpl::animateLayers):
+        (WTF::MockLayerTreeHost::create):
+        (WTF::MockLayerTreeHost::createLayerTreeHostImpl):
+        (WTF):
+        (MockLayerAnimationController):
+        (WTF::MockLayerAnimationController::create):
+        (WTF::MockLayerAnimationController::addAnimation):
+        (WTF::MockLayerTreeHostClient::scheduleComposite):
+        (WTF::CCLayerTreeHostTest::postAddAnimationToMainThread):
+        (CCLayerTreeHostTest):
+        (WTF::CCLayerTreeHostTest::dispatchAddAnimation):
+        (WTF::CCLayerTreeHostTest::doBeginTest):
+        (CCLayerTreeHostTestAddAnimation):
+        (WTF::CCLayerTreeHostTestAddAnimation::CCLayerTreeHostTestAddAnimation):
+        (WTF::CCLayerTreeHostTestAddAnimation::beginTest):
+        (WTF::CCLayerTreeHostTestAddAnimation::animateLayers):
+        (WTF::CCLayerTreeHostTestAddAnimation::afterTest):
+        (WTF::TEST_F):
+        * tests/TreeSynchronizerTest.cpp:
+        (FakeLayerAnimationController):
+        (WebKitTests::FakeLayerAnimationController::create):
+        (WebKitTests::FakeLayerAnimationController::synchronizedAnimations):
+        (WebKitTests::FakeLayerAnimationController::FakeLayerAnimationController):
+        (WebKitTests::FakeLayerAnimationController::synchronizeAnimations):
+        (WebKitTests):
+        (WebKitTests::TEST):
+
 2012-02-21  Ryosuke Niwa  <rniwa@webkit.org>
 
         Remove the remaining uses of CSSStyleDeclaration in Editor
index 9aa5d2c..a422401 100644 (file)
             'tests/AssociatedURLLoaderTest.cpp',
             'tests/Canvas2DLayerChromiumTest.cpp',
             'tests/CCActiveAnimationTest.cpp',
+            'tests/CCAnimationTestCommon.cpp',
+            'tests/CCAnimationTestCommon.h',
             'tests/CCDamageTrackerTest.cpp',
             'tests/CCDelayBasedTimeSourceTest.cpp',
             'tests/CCFrameRateControllerTest.cpp',
             'tests/CCLayerAnimationControllerImplTest.cpp',
+            'tests/CCLayerAnimationControllerTest.cpp',
             'tests/CCLayerImplTest.cpp',
             'tests/CCLayerIteratorTest.cpp',
             'tests/CCLayerQuadTest.cpp',
index 976e76b..7f1bbb0 100644 (file)
@@ -142,6 +142,7 @@ public:
     virtual void setAcceleratedPaintingEnabled(bool) = 0;
     virtual void setPerTilePaintingEnabled(bool) = 0;
     virtual void setPartialSwapEnabled(bool) = 0;
+    virtual void setThreadedAnimationEnabled(bool) = 0;
 
 protected:
     ~WebSettings() { }
index 1ad4689..17a876a 100644 (file)
@@ -50,7 +50,8 @@ public:
             , showPlatformLayerTree(false)
             , refreshRate(0)
             , perTilePainting(false)
-            , partialSwapEnabled(false) { }
+            , partialSwapEnabled(false)
+            , threadedAnimationEnabled(false) { }
 
         bool acceleratePainting;
         bool compositeOffscreen;
@@ -59,6 +60,7 @@ public:
         double refreshRate;
         bool perTilePainting;
         bool partialSwapEnabled;
+        bool threadedAnimationEnabled;
 #if WEBKIT_IMPLEMENTATION
         operator WebCore::CCSettings() const;
 #endif
index ca03514..d2c0f0c 100644 (file)
@@ -45,6 +45,7 @@ WebLayerTreeView::Settings::operator CCSettings() const
     settings.refreshRate = refreshRate;
     settings.perTilePainting = perTilePainting;
     settings.partialSwapEnabled = partialSwapEnabled;
+    settings.threadedAnimationEnabled = threadedAnimationEnabled;
 
     // FIXME: showFPSCounter / showPlatformLayerTree / maxPartialTextureUpdates aren't supported currently.
     return settings;
index a8b67f8..485a5b0 100644 (file)
@@ -543,4 +543,9 @@ void WebSettingsImpl::setPartialSwapEnabled(bool enabled)
     m_settings->setPartialSwapEnabled(enabled);
 }
 
+void WebSettingsImpl::setThreadedAnimationEnabled(bool enabled)
+{
+    m_settings->setThreadedAnimationEnabled(enabled);
+}
+
 } // namespace WebKit
index bb611c7..51d9323 100644 (file)
@@ -137,6 +137,7 @@ public:
     virtual void setAcceleratedPaintingEnabled(bool);
     virtual void setPerTilePaintingEnabled(bool);
     virtual void setPartialSwapEnabled(bool);
+    virtual void setThreadedAnimationEnabled(bool);
 
 private:
     WebCore::Settings* m_settings;
index e3af8eb..34da0de 100644 (file)
@@ -3168,6 +3168,7 @@ void WebViewImpl::setIsAcceleratedCompositingActive(bool active)
 
         ccSettings.perTilePainting = page()->settings()->perTileDrawingEnabled();
         ccSettings.partialSwapEnabled = page()->settings()->partialSwapEnabled();
+        ccSettings.threadedAnimationEnabled = page()->settings()->threadedAnimationEnabled();
 
         m_nonCompositedContentHost = NonCompositedContentHost::create(WebViewImplContentPainter::create(this));
         m_nonCompositedContentHost->setShowDebugBorders(page()->settings()->showDebugBorders());
index 3e93d95..e14ef9b 100644 (file)
 #include "config.h"
 
 #include "cc/CCActiveAnimation.h"
-
-#include "cc/CCAnimationCurve.h"
+#include "CCAnimationTestCommon.h"
 
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 #include <wtf/Vector.h>
 
-namespace WebCore {
+using namespace WebKitTests;
+using namespace WebCore;
 
-class FakeFloatAnimation : public CCFloatAnimationCurve {
-public:
-    virtual double duration() const { return 1; }
-    virtual float getValue(double now) const { return 0; }
-};
+namespace {
 
 PassOwnPtr<CCActiveAnimation> createActiveAnimation(int iterations)
 {
-    OwnPtr<CCActiveAnimation> toReturn(CCActiveAnimation::create(adoptPtr(new FakeFloatAnimation), 1, CCActiveAnimation::Opacity));
+    OwnPtr<CCActiveAnimation> toReturn(CCActiveAnimation::create(adoptPtr(new FakeFloatAnimationCurve), 0, 1, CCActiveAnimation::Opacity));
     toReturn->setIterations(iterations);
     return toReturn.release();
 }
@@ -164,4 +160,4 @@ TEST(CCActiveAnimationTest, IsFinished)
     EXPECT_TRUE(anim->isFinished());
 }
 
-} // namespace WebCore
+} // namespace
diff --git a/Source/WebKit/chromium/tests/CCAnimationTestCommon.cpp b/Source/WebKit/chromium/tests/CCAnimationTestCommon.cpp
new file mode 100644 (file)
index 0000000..0e06157
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "CCAnimationTestCommon.h"
+
+#include "GraphicsLayer.h"
+#include "LayerChromium.h"
+
+using namespace WebCore;
+
+namespace WebKitTests {
+
+FakeFloatAnimationCurve::FakeFloatAnimationCurve()
+{
+}
+
+FakeFloatAnimationCurve::~FakeFloatAnimationCurve()
+{
+}
+
+PassOwnPtr<WebCore::CCAnimationCurve> FakeFloatAnimationCurve::clone() const
+{
+    return adoptPtr(new FakeFloatAnimationCurve);
+}
+
+FakeTransformTransition::FakeTransformTransition(double duration)
+    : m_duration(duration)
+{
+}
+
+FakeTransformTransition::~FakeTransformTransition()
+{
+}
+
+WebCore::TransformationMatrix FakeTransformTransition::getValue(double time, const WebCore::IntSize& size) const
+{
+    return WebCore::TransformationMatrix();
+}
+
+PassOwnPtr<WebCore::CCAnimationCurve> FakeTransformTransition::clone() const
+{
+    return adoptPtr(new FakeTransformTransition(*this));
+}
+
+
+FakeFloatTransition::FakeFloatTransition(double duration, float from, float to)
+    : m_duration(duration)
+    , m_from(from)
+    , m_to(to)
+{
+}
+
+FakeFloatTransition::~FakeFloatTransition()
+{
+}
+
+float FakeFloatTransition::getValue(double time) const
+{
+    time /= m_duration;
+    if (time >= 1)
+        time = 1;
+    return (1 - time) * m_from + time * m_to;
+}
+
+FakeLayerAnimationControllerImplClient::FakeLayerAnimationControllerImplClient()
+    : m_opacity(0)
+{
+}
+
+FakeLayerAnimationControllerImplClient::~FakeLayerAnimationControllerImplClient()
+{
+}
+
+PassOwnPtr<WebCore::CCAnimationCurve> FakeFloatTransition::clone() const
+{
+    return adoptPtr(new FakeFloatTransition(*this));
+}
+
+void addOpacityTransition(WebCore::LayerChromium& layer, double duration, float startOpacity, float endOpacity)
+{
+    WebCore::KeyframeValueList values(AnimatedPropertyOpacity);
+    if (duration > 0)
+        values.insert(new FloatAnimationValue(0, startOpacity));
+    values.insert(new FloatAnimationValue(duration, endOpacity));
+
+    RefPtr<Animation> animation = Animation::create();
+    animation->setDuration(1);
+
+    IntSize boxSize;
+
+    layer.addAnimation(values, boxSize, animation.get(), 0, 0, 0);
+}
+
+} // namespace WebKitTests
diff --git a/Source/WebKit/chromium/tests/CCAnimationTestCommon.h b/Source/WebKit/chromium/tests/CCAnimationTestCommon.h
new file mode 100644 (file)
index 0000000..9f964e4
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CCAnimationTestCommon_h
+#define CCAnimationTestCommon_h
+
+#include "cc/CCAnimationCurve.h"
+#include "cc/CCLayerAnimationControllerImpl.h"
+
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+class LayerChromium;
+}
+
+namespace WebKitTests {
+
+class FakeFloatAnimationCurve : public WebCore::CCFloatAnimationCurve {
+public:
+    FakeFloatAnimationCurve();
+    virtual ~FakeFloatAnimationCurve();
+
+    virtual double duration() const { return 1; }
+    virtual float getValue(double now) const { return 0; }
+    virtual PassOwnPtr<WebCore::CCAnimationCurve> clone() const;
+};
+
+class FakeTransformTransition : public WebCore::CCTransformAnimationCurve {
+public:
+    FakeTransformTransition(double duration);
+    virtual ~FakeTransformTransition();
+
+    virtual double duration() const { return m_duration; }
+    virtual WebCore::TransformationMatrix getValue(double time, const WebCore::IntSize&) const;
+
+    virtual PassOwnPtr<WebCore::CCAnimationCurve> clone() const;
+
+private:
+    double m_duration;
+};
+
+class FakeFloatTransition : public WebCore::CCFloatAnimationCurve {
+public:
+    FakeFloatTransition(double duration, float from, float to);
+    virtual ~FakeFloatTransition();
+
+    virtual double duration() const { return m_duration; }
+    virtual float getValue(double time) const;
+
+    virtual PassOwnPtr<WebCore::CCAnimationCurve> clone() const;
+
+private:
+    double m_duration;
+    float m_from;
+    float m_to;
+};
+
+class FakeLayerAnimationControllerImplClient : public WebCore::CCLayerAnimationControllerImplClient {
+public:
+    FakeLayerAnimationControllerImplClient();
+    virtual ~FakeLayerAnimationControllerImplClient();
+
+    virtual int id() const { return 0; }
+    virtual float opacity() const { return m_opacity; }
+    virtual void setOpacity(float opacity) { m_opacity = opacity; }
+    virtual const WebCore::TransformationMatrix& transform() const { return m_transform; }
+    virtual void setTransform(const WebCore::TransformationMatrix& transform) { m_transform = transform; }
+    virtual const WebCore::IntSize& bounds() const { return m_bounds; }
+
+private:
+    float m_opacity;
+    WebCore::TransformationMatrix m_transform;
+    WebCore::IntSize m_bounds;
+};
+
+void addOpacityTransition(WebCore::LayerChromium&, double duration, float startOpacity, float endOpacity);
+
+} // namespace WebKitTests
+
+#endif // CCAnimationTesctCommon_h
index 3d50d06..e1aeccc 100644 (file)
 
 #include "config.h"
 
+#include "CCAnimationTestCommon.h"
 #include "cc/CCLayerAnimationControllerImpl.h"
-
-#include "TransformOperations.h"
 #include "cc/CCAnimationCurve.h"
-
+#include "cc/CCAnimationEvents.h"
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 #include <wtf/Vector.h>
 
 using namespace WebCore;
+using namespace WebKitTests;
 
 namespace {
 
-class FakeControllerClient : public CCLayerAnimationControllerImplClient {
-public:
-    FakeControllerClient() : m_opacity(0) { }
-    virtual ~FakeControllerClient() { }
-
-    virtual float opacity() const { return m_opacity; }
-    virtual void setOpacity(float opacity) { m_opacity = opacity; }
-    virtual const TransformationMatrix& transform() const { return m_transform; }
-    virtual void setTransform(const TransformationMatrix& transform) { m_transform = transform; }
-    virtual void animationControllerImplDidActivate(CCLayerAnimationControllerImpl* controller)
-    {
-        m_activeControllers.append(controller);
-    }
-
-    Vector<CCLayerAnimationControllerImpl*>& activeControllers() { return m_activeControllers; }
-
-private:
-    float m_opacity;
-    TransformationMatrix m_transform;
-    Vector<CCLayerAnimationControllerImpl*> m_activeControllers;
-};
-
-class FakeTransformTransition : public CCTransformAnimationCurve {
-public:
-    FakeTransformTransition(double duration) : m_duration(duration) { }
-    virtual double duration() const { return m_duration; }
-    virtual TransformOperations getValue(double time) const
-    {
-        return TransformOperations();
-    }
-
-private:
-    double m_duration;
-};
-
-class FakeFloatTransition : public CCFloatAnimationCurve {
-public:
-    FakeFloatTransition(double duration, float from, float to)
-        : m_duration(duration)
-        , m_from(from)
-        , m_to(to)
-    {
-    }
-
-    virtual double duration() const { return m_duration; }
-    virtual float getValue(double time) const
-    {
-        time /= m_duration;
-        if (time >= 1)
-            time = 1;
-        return (1 - time) * m_from + time * m_to;
-    }
-
-private:
-    double m_duration;
-    float m_from;
-    float m_to;
-};
+PassOwnPtr<CCActiveAnimation> createActiveAnimation(PassOwnPtr<CCAnimationCurve> curve, int id, CCActiveAnimation::TargetProperty property)
+{
+    return CCActiveAnimation::create(curve, 0, id, property);
+}
 
 // Tests that transitioning opacity from 0 to 1 works as expected.
 TEST(CCLayerAnimationControllerImplTest, TrivialTransition)
 {
-    FakeControllerClient dummy;
+    OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
+    FakeLayerAnimationControllerImplClient dummy;
     OwnPtr<CCLayerAnimationControllerImpl> controller(
         CCLayerAnimationControllerImpl::create(&dummy));
 
-    OwnPtr<CCActiveAnimation> toAdd(CCActiveAnimation::create(adoptPtr(new FakeFloatTransition(1, 0, 1)), 1, CCActiveAnimation::Opacity));
+    OwnPtr<CCActiveAnimation> toAdd(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 0, 1)), 1, CCActiveAnimation::Opacity));
 
     controller->add(toAdd.release());
-    controller->animate(0);
+    controller->animate(0, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0, dummy.opacity());
-    controller->animate(1);
+    controller->animate(1, *events);
     EXPECT_EQ(1, dummy.opacity());
     EXPECT_FALSE(controller->hasActiveAnimation());
 }
@@ -117,20 +64,21 @@ TEST(CCLayerAnimationControllerImplTest, TrivialTransition)
 // Tests that two queued animations affecting the same property run in sequence.
 TEST(CCLayerAnimationControllerImplTest, TrivialQueuing)
 {
-    FakeControllerClient dummy;
+    OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
+    FakeLayerAnimationControllerImplClient dummy;
     OwnPtr<CCLayerAnimationControllerImpl> controller(
         CCLayerAnimationControllerImpl::create(&dummy));
 
-    controller->add(CCActiveAnimation::create(adoptPtr(new FakeFloatTransition(1, 0, 1)), 1, CCActiveAnimation::Opacity));
-    controller->add(CCActiveAnimation::create(adoptPtr(new FakeFloatTransition(1, 1, 0.5f)), 2, CCActiveAnimation::Opacity));
+    controller->add(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 0, 1)), 1, CCActiveAnimation::Opacity));
+    controller->add(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 1, 0.5f)), 2, CCActiveAnimation::Opacity));
 
-    controller->animate(0);
+    controller->animate(0, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0, dummy.opacity());
-    controller->animate(1);
+    controller->animate(1, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(1, dummy.opacity());
-    controller->animate(2);
+    controller->animate(2, *events);
     EXPECT_EQ(0.5f, dummy.opacity());
     EXPECT_FALSE(controller->hasActiveAnimation());
 }
@@ -138,22 +86,23 @@ TEST(CCLayerAnimationControllerImplTest, TrivialQueuing)
 // Tests interrupting a transition with another transition.
 TEST(CCLayerAnimationControllerImplTest, Interrupt)
 {
-    FakeControllerClient dummy;
+    OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
+    FakeLayerAnimationControllerImplClient dummy;
     OwnPtr<CCLayerAnimationControllerImpl> controller(
         CCLayerAnimationControllerImpl::create(&dummy));
-    controller->add(CCActiveAnimation::create(adoptPtr(new FakeFloatTransition(1, 0, 1)), 1, CCActiveAnimation::Opacity));
-    controller->animate(0);
+    controller->add(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 0, 1)), 1, CCActiveAnimation::Opacity));
+    controller->animate(0, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0, dummy.opacity());
 
-    OwnPtr<CCActiveAnimation> toAdd(CCActiveAnimation::create(adoptPtr(new FakeFloatTransition(1, 1, 0.5f)), 2, CCActiveAnimation::Opacity));
+    OwnPtr<CCActiveAnimation> toAdd(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 1, 0.5f)), 2, CCActiveAnimation::Opacity));
     toAdd->setRunState(CCActiveAnimation::WaitingForNextTick, 0);
     controller->add(toAdd.release());
 
-    controller->animate(0.5); // second anim starts NOW.
+    controller->animate(0.5, *events); // second anim starts NOW.
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(1, dummy.opacity());
-    controller->animate(1.5);
+    controller->animate(1.5, *events);
     EXPECT_EQ(0.5f, dummy.opacity());
     EXPECT_FALSE(controller->hasActiveAnimation());
 }
@@ -161,23 +110,24 @@ TEST(CCLayerAnimationControllerImplTest, Interrupt)
 // Tests scheduling two animations to run together when only one property is free.
 TEST(CCLayerAnimationControllerImplTest, ScheduleTogetherWhenAPropertyIsBlocked)
 {
-    FakeControllerClient dummy;
+    OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
+    FakeLayerAnimationControllerImplClient dummy;
     OwnPtr<CCLayerAnimationControllerImpl> controller(
         CCLayerAnimationControllerImpl::create(&dummy));
 
-    controller->add(CCActiveAnimation::create(adoptPtr(new FakeTransformTransition(1)), 1, CCActiveAnimation::Transform));
-    controller->add(CCActiveAnimation::create(adoptPtr(new FakeTransformTransition(1)), 2, CCActiveAnimation::Transform));
-    controller->add(CCActiveAnimation::create(adoptPtr(new FakeFloatTransition(1, 0, 1)), 2, CCActiveAnimation::Opacity));
+    controller->add(createActiveAnimation(adoptPtr(new FakeTransformTransition(1)), 1, CCActiveAnimation::Transform));
+    controller->add(createActiveAnimation(adoptPtr(new FakeTransformTransition(1)), 2, CCActiveAnimation::Transform));
+    controller->add(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 0, 1)), 2, CCActiveAnimation::Opacity));
 
-    controller->animate(0);
+    controller->animate(0, *events);
     EXPECT_EQ(0, dummy.opacity());
     EXPECT_TRUE(controller->hasActiveAnimation());
-    controller->animate(1);
+    controller->animate(1, *events);
     // Should not have started the float transition yet.
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0, dummy.opacity());
     // The the float animation should have started at time 1 and should be done.
-    controller->animate(2);
+    controller->animate(2, *events);
     EXPECT_EQ(1, dummy.opacity());
     EXPECT_FALSE(controller->hasActiveAnimation());
 }
@@ -187,29 +137,30 @@ TEST(CCLayerAnimationControllerImplTest, ScheduleTogetherWhenAPropertyIsBlocked)
 // for both to finish).
 TEST(CCLayerAnimationControllerImplTest, ScheduleTogetherWithAnAnimWaiting)
 {
-    FakeControllerClient dummy;
+    OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
+    FakeLayerAnimationControllerImplClient dummy;
     OwnPtr<CCLayerAnimationControllerImpl> controller(
         CCLayerAnimationControllerImpl::create(&dummy));
 
-    controller->add(CCActiveAnimation::create(adoptPtr(new FakeTransformTransition(2)), 1, CCActiveAnimation::Transform));
-    controller->add(CCActiveAnimation::create(adoptPtr(new FakeFloatTransition(1, 0, 1)), 1, CCActiveAnimation::Opacity));
-    controller->add(CCActiveAnimation::create(adoptPtr(new FakeFloatTransition(1, 1, 0.5f)), 2, CCActiveAnimation::Opacity));
+    controller->add(createActiveAnimation(adoptPtr(new FakeTransformTransition(2)), 1, CCActiveAnimation::Transform));
+    controller->add(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 0, 1)), 1, CCActiveAnimation::Opacity));
+    controller->add(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 1, 0.5f)), 2, CCActiveAnimation::Opacity));
 
     // Anims with id 1 should both start now.
-    controller->animate(0);
+    controller->animate(0, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0, dummy.opacity());
     // The opacity animation should have finished at time 1, but the group
     // of animations with id 1 don't finish until time 2 because of the length
     // of the transform animation.
-    controller->animate(2);
+    controller->animate(2, *events);
     // Should not have started the float transition yet.
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(1, dummy.opacity());
 
     // The the second opacity animation should start at time 2 and should be
     // done by time 3
-    controller->animate(3);
+    controller->animate(3, *events);
     EXPECT_EQ(0.5f, dummy.opacity());
     EXPECT_FALSE(controller->hasActiveAnimation());
 }
@@ -217,22 +168,23 @@ TEST(CCLayerAnimationControllerImplTest, ScheduleTogetherWithAnAnimWaiting)
 // Tests scheduling an animation to start in the future.
 TEST(CCLayerAnimationControllerImplTest, ScheduleAnimation)
 {
-    FakeControllerClient dummy;
+    OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
+    FakeLayerAnimationControllerImplClient dummy;
     OwnPtr<CCLayerAnimationControllerImpl> controller(
         CCLayerAnimationControllerImpl::create(&dummy));
 
-    OwnPtr<CCActiveAnimation> toAdd(CCActiveAnimation::create(adoptPtr(new FakeFloatTransition(1, 0, 1)), 1, CCActiveAnimation::Opacity));
+    OwnPtr<CCActiveAnimation> toAdd(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 0, 1)), 1, CCActiveAnimation::Opacity));
     toAdd->setRunState(CCActiveAnimation::WaitingForStartTime, 0);
     toAdd->setStartTime(1);
     controller->add(toAdd.release());
 
-    controller->animate(0);
+    controller->animate(0, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0, dummy.opacity());
-    controller->animate(1);
+    controller->animate(1, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0, dummy.opacity());
-    controller->animate(2);
+    controller->animate(2, *events);
     EXPECT_EQ(1, dummy.opacity());
     EXPECT_FALSE(controller->hasActiveAnimation());
 }
@@ -240,28 +192,29 @@ TEST(CCLayerAnimationControllerImplTest, ScheduleAnimation)
 // Tests scheduling an animation to start in the future that's interrupting a running animation.
 TEST(CCLayerAnimationControllerImplTest, ScheduledAnimationInterruptsRunningAnimation)
 {
-    FakeControllerClient dummy;
+    OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
+    FakeLayerAnimationControllerImplClient dummy;
     OwnPtr<CCLayerAnimationControllerImpl> controller(
         CCLayerAnimationControllerImpl::create(&dummy));
 
-    controller->add(CCActiveAnimation::create(adoptPtr(new FakeFloatTransition(2, 0, 1)), 1, CCActiveAnimation::Opacity));
+    controller->add(createActiveAnimation(adoptPtr(new FakeFloatTransition(2, 0, 1)), 1, CCActiveAnimation::Opacity));
 
-    OwnPtr<CCActiveAnimation> toAdd(CCActiveAnimation::create(adoptPtr(new FakeFloatTransition(1, 0.5f, 0)), 2, CCActiveAnimation::Opacity));
+    OwnPtr<CCActiveAnimation> toAdd(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 0.5f, 0)), 2, CCActiveAnimation::Opacity));
     toAdd->setRunState(CCActiveAnimation::WaitingForStartTime, 0);
     toAdd->setStartTime(1);
     controller->add(toAdd.release());
 
     // First 2s opacity transition should start immediately.
-    controller->animate(0);
+    controller->animate(0, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0, dummy.opacity());
-    controller->animate(0.5);
+    controller->animate(0.5, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0.25f, dummy.opacity());
-    controller->animate(1);
+    controller->animate(1, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0.5f, dummy.opacity());
-    controller->animate(2);
+    controller->animate(2, *events);
     EXPECT_EQ(0, dummy.opacity());
     EXPECT_FALSE(controller->hasActiveAnimation());
 }
@@ -270,34 +223,35 @@ TEST(CCLayerAnimationControllerImplTest, ScheduledAnimationInterruptsRunningAnim
 // and there is yet another animation queued to start later.
 TEST(CCLayerAnimationControllerImplTest, ScheduledAnimationInterruptsRunningAnimationWithAnimInQueue)
 {
-    FakeControllerClient dummy;
+    OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
+    FakeLayerAnimationControllerImplClient dummy;
     OwnPtr<CCLayerAnimationControllerImpl> controller(
         CCLayerAnimationControllerImpl::create(&dummy));
 
-    controller->add(CCActiveAnimation::create(adoptPtr(new FakeFloatTransition(2, 0, 1)), 1, CCActiveAnimation::Opacity));
+    controller->add(createActiveAnimation(adoptPtr(new FakeFloatTransition(2, 0, 1)), 1, CCActiveAnimation::Opacity));
 
-    OwnPtr<CCActiveAnimation> toAdd(CCActiveAnimation::create(adoptPtr(new FakeFloatTransition(2, 0.5f, 0)), 2, CCActiveAnimation::Opacity));
+    OwnPtr<CCActiveAnimation> toAdd(createActiveAnimation(adoptPtr(new FakeFloatTransition(2, 0.5f, 0)), 2, CCActiveAnimation::Opacity));
     toAdd->setRunState(CCActiveAnimation::WaitingForStartTime, 0);
     toAdd->setStartTime(1);
     controller->add(toAdd.release());
 
-    controller->add(CCActiveAnimation::create(adoptPtr(new FakeFloatTransition(1, 0, 0.75f)), 3, CCActiveAnimation::Opacity));
+    controller->add(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 0, 0.75f)), 3, CCActiveAnimation::Opacity));
 
     // First 2s opacity transition should start immediately.
-    controller->animate(0);
+    controller->animate(0, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0, dummy.opacity());
-    controller->animate(0.5);
+    controller->animate(0.5, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0.25f, dummy.opacity());
     EXPECT_TRUE(controller->hasActiveAnimation());
-    controller->animate(1);
+    controller->animate(1, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0.5f, dummy.opacity());
-    controller->animate(3);
+    controller->animate(3, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0, dummy.opacity());
-    controller->animate(4);
+    controller->animate(4, *events);
     EXPECT_EQ(0.75f, dummy.opacity());
     EXPECT_FALSE(controller->hasActiveAnimation());
 }
@@ -305,64 +259,66 @@ TEST(CCLayerAnimationControllerImplTest, ScheduledAnimationInterruptsRunningAnim
 // Test that a looping animation loops and for the correct number of iterations.
 TEST(CCLayerAnimationControllerImplTest, TrivialLooping)
 {
-    FakeControllerClient dummy;
+    OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
+    FakeLayerAnimationControllerImplClient dummy;
     OwnPtr<CCLayerAnimationControllerImpl> controller(
         CCLayerAnimationControllerImpl::create(&dummy));
 
-    OwnPtr<CCActiveAnimation> toAdd(CCActiveAnimation::create(adoptPtr(new FakeFloatTransition(1, 0, 1)), 1, CCActiveAnimation::Opacity));
+    OwnPtr<CCActiveAnimation> toAdd(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 0, 1)), 1, CCActiveAnimation::Opacity));
     toAdd->setIterations(3);
     controller->add(toAdd.release());
 
-    controller->animate(0);
+    controller->animate(0, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0, dummy.opacity());
-    controller->animate(1.25);
+    controller->animate(1.25, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0.25f, dummy.opacity());
-    controller->animate(1.75);
+    controller->animate(1.75, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0.75f, dummy.opacity());
-    controller->animate(2.25);
+    controller->animate(2.25, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0.25f, dummy.opacity());
-    controller->animate(2.75);
+    controller->animate(2.75, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0.75f, dummy.opacity());
-    controller->animate(3);
+    controller->animate(3, *events);
     EXPECT_FALSE(controller->hasActiveAnimation());
     EXPECT_EQ(1, dummy.opacity());
 
     // Just be extra sure.
-    controller->animate(4);
+    controller->animate(4, *events);
     EXPECT_EQ(1, dummy.opacity());
 }
 
 // Test that an infinitely looping animation does indeed go until aborted.
 TEST(CCLayerAnimationControllerImplTest, InfiniteLooping)
 {
-    FakeControllerClient dummy;
+    OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
+    FakeLayerAnimationControllerImplClient dummy;
     OwnPtr<CCLayerAnimationControllerImpl> controller(
         CCLayerAnimationControllerImpl::create(&dummy));
 
     const int id = 1;
-    OwnPtr<CCActiveAnimation> toAdd(CCActiveAnimation::create(adoptPtr(new FakeFloatTransition(1, 0, 1)), id, CCActiveAnimation::Opacity));
+    OwnPtr<CCActiveAnimation> toAdd(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 0, 1)), id, CCActiveAnimation::Opacity));
     toAdd->setIterations(-1);
     controller->add(toAdd.release());
 
-    controller->animate(0);
+    controller->animate(0, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0, dummy.opacity());
-    controller->animate(1.25);
+    controller->animate(1.25, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0.25f, dummy.opacity());
-    controller->animate(1.75);
+    controller->animate(1.75, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0.75f, dummy.opacity());
 
-    controller->animate(1073741824.25);
+    controller->animate(1073741824.25, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0.25f, dummy.opacity());
-    controller->animate(1073741824.75);
+    controller->animate(1073741824.75, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0.75f, dummy.opacity());
 
@@ -375,80 +331,66 @@ TEST(CCLayerAnimationControllerImplTest, InfiniteLooping)
 // Test that pausing and resuming work as expected.
 TEST(CCLayerAnimationControllerImplTest, PauseResume)
 {
-    FakeControllerClient dummy;
+    OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
+    FakeLayerAnimationControllerImplClient dummy;
     OwnPtr<CCLayerAnimationControllerImpl> controller(
         CCLayerAnimationControllerImpl::create(&dummy));
 
     const int id = 1;
-    controller->add(CCActiveAnimation::create(adoptPtr(new FakeFloatTransition(1, 0, 1)), id, CCActiveAnimation::Opacity));
+    controller->add(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 0, 1)), id, CCActiveAnimation::Opacity));
 
-    controller->animate(0);
+    controller->animate(0, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0, dummy.opacity());
-    controller->animate(0.5);
+    controller->animate(0.5, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0.5f, dummy.opacity());
 
     EXPECT_TRUE(controller->getActiveAnimation(id, CCActiveAnimation::Opacity));
     controller->getActiveAnimation(id, CCActiveAnimation::Opacity)->setRunState(CCActiveAnimation::Paused, 0.5f);
 
-    controller->animate(1024);
+    controller->animate(1024, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0.5f, dummy.opacity());
 
     EXPECT_TRUE(controller->getActiveAnimation(id, CCActiveAnimation::Opacity));
     controller->getActiveAnimation(id, CCActiveAnimation::Opacity)->setRunState(CCActiveAnimation::Running, 1024);
 
-    controller->animate(1024.25);
+    controller->animate(1024.25, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0.75f, dummy.opacity());
-    controller->animate(1024.5);
+    controller->animate(1024.5, *events);
     EXPECT_FALSE(controller->hasActiveAnimation());
     EXPECT_EQ(1, dummy.opacity());
 }
 
 TEST(CCLayerAnimationControllerImplTest, AbortAGroupedAnimation)
 {
-    FakeControllerClient dummy;
+    OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
+    FakeLayerAnimationControllerImplClient dummy;
     OwnPtr<CCLayerAnimationControllerImpl> controller(
         CCLayerAnimationControllerImpl::create(&dummy));
 
     const int id = 1;
-    controller->add(CCActiveAnimation::create(adoptPtr(new FakeTransformTransition(1)), id, CCActiveAnimation::Transform));
-    controller->add(CCActiveAnimation::create(adoptPtr(new FakeFloatTransition(2, 0, 1)), id, CCActiveAnimation::Opacity));
-    controller->add(CCActiveAnimation::create(adoptPtr(new FakeFloatTransition(1, 1, 0.75f)), 2, CCActiveAnimation::Opacity));
+    controller->add(createActiveAnimation(adoptPtr(new FakeTransformTransition(1)), id, CCActiveAnimation::Transform));
+    controller->add(createActiveAnimation(adoptPtr(new FakeFloatTransition(2, 0, 1)), id, CCActiveAnimation::Opacity));
+    controller->add(createActiveAnimation(adoptPtr(new FakeFloatTransition(1, 1, 0.75f)), 2, CCActiveAnimation::Opacity));
 
-    controller->animate(0);
+    controller->animate(0, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0, dummy.opacity());
-    controller->animate(1);
+    controller->animate(1, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(0.5f, dummy.opacity());
 
     EXPECT_TRUE(controller->getActiveAnimation(id, CCActiveAnimation::Opacity));
     controller->getActiveAnimation(id, CCActiveAnimation::Opacity)->setRunState(CCActiveAnimation::Aborted, 1);
-    controller->animate(1);
+    controller->animate(1, *events);
     EXPECT_TRUE(controller->hasActiveAnimation());
     EXPECT_EQ(1, dummy.opacity());
-    controller->animate(2);
+    controller->animate(2, *events);
     EXPECT_TRUE(!controller->hasActiveAnimation());
     EXPECT_EQ(0.75f, dummy.opacity());
 }
 
-// Tests that adding an animation to the controller calls the appropriate callback on the controller client
-// (in this case, adding the controller to the list of active controller).
-TEST(CCLayerAnimationControllerImplTest, DidActivate)
-{
-    FakeControllerClient dummy;
-    OwnPtr<CCLayerAnimationControllerImpl> controller(
-        CCLayerAnimationControllerImpl::create(&dummy));
-
-    EXPECT_EQ(size_t(0), dummy.activeControllers().size());
-
-    controller->add(CCActiveAnimation::create(adoptPtr(new FakeFloatTransition(1, 0, 1)), 1, CCActiveAnimation::Opacity));
-
-    EXPECT_EQ(size_t(1), dummy.activeControllers().size());
-    EXPECT_EQ(controller.get(), dummy.activeControllers()[0]);
-}
-
 } // namespace
diff --git a/Source/WebKit/chromium/tests/CCLayerAnimationControllerTest.cpp b/Source/WebKit/chromium/tests/CCLayerAnimationControllerTest.cpp
new file mode 100644 (file)
index 0000000..6ecc1ff
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "cc/CCLayerAnimationController.h"
+
+#include "CCAnimationTestCommon.h"
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <wtf/Vector.h>
+
+using namespace WebCore;
+using namespace WebKitTests;
+
+namespace {
+
+PassOwnPtr<CCActiveAnimation> createActiveAnimation(PassOwnPtr<CCAnimationCurve> curve, int id, CCActiveAnimation::TargetProperty property)
+{
+    return CCActiveAnimation::create(curve, 0, id, property);
+}
+
+TEST(CCLayerAnimationControllerTest, syncNewAnimation)
+{
+    FakeLayerAnimationControllerImplClient dummy;
+    OwnPtr<CCLayerAnimationControllerImpl> controllerImpl(
+        CCLayerAnimationControllerImpl::create(&dummy));
+    OwnPtr<CCLayerAnimationController> controller(
+        CCLayerAnimationController::create());
+
+    EXPECT_FALSE(controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity));
+
+    controller->activeAnimations().append(CCActiveAnimation::create(adoptPtr(new FakeFloatAnimationCurve()), 0, 0, CCActiveAnimation::Opacity));
+
+    controller->synchronizeAnimations(controllerImpl.get());
+
+    EXPECT_TRUE(controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity));
+    EXPECT_EQ(CCActiveAnimation::WaitingForTargetAvailability, controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity)->runState());
+}
+
+TEST(CCLayerAnimationControllerTest, syncAnimationProperties)
+{
+    FakeLayerAnimationControllerImplClient dummy;
+    OwnPtr<CCLayerAnimationControllerImpl> controllerImpl(
+        CCLayerAnimationControllerImpl::create(&dummy));
+    OwnPtr<CCLayerAnimationController> controller(
+        CCLayerAnimationController::create());
+
+    EXPECT_FALSE(controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity));
+
+    controller->activeAnimations().append(CCActiveAnimation::create(adoptPtr(new FakeFloatAnimationCurve()), 0, 0, CCActiveAnimation::Opacity));
+
+    controller->synchronizeAnimations(controllerImpl.get());
+
+    EXPECT_TRUE(controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity));
+    EXPECT_EQ(CCActiveAnimation::WaitingForTargetAvailability, controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity)->runState());
+
+    // Push an animation property change to the impl thread (should not cause an animation to be added).
+    controller->pauseAnimation(0, 0);
+    controller->synchronizeAnimations(controllerImpl.get());
+
+    EXPECT_TRUE(controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity));
+    EXPECT_EQ(CCActiveAnimation::Paused, controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity)->runState());
+}
+
+TEST(CCLayerAnimationControllerTest, syncAbortedAnimation)
+{
+    FakeLayerAnimationControllerImplClient dummy;
+    OwnPtr<CCLayerAnimationControllerImpl> controllerImpl(
+        CCLayerAnimationControllerImpl::create(&dummy));
+    OwnPtr<CCLayerAnimationController> controller(
+        CCLayerAnimationController::create());
+
+    EXPECT_FALSE(controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity));
+
+    controller->activeAnimations().append(CCActiveAnimation::create(adoptPtr(new FakeFloatAnimationCurve()), 0, 0, CCActiveAnimation::Opacity));
+
+    controller->synchronizeAnimations(controllerImpl.get());
+
+    EXPECT_TRUE(controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity));
+    EXPECT_EQ(CCActiveAnimation::WaitingForTargetAvailability, controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity)->runState());
+
+    controller->removeAnimation(0);
+
+    // Abort an animation from the main thread.
+    controller->synchronizeAnimations(controllerImpl.get());
+
+    EXPECT_FALSE(controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity));
+}
+
+TEST(CCLayerAnimationControllerTest, syncCompletedAnimation)
+{
+    FakeLayerAnimationControllerImplClient dummy;
+    OwnPtr<CCLayerAnimationControllerImpl> controllerImpl(
+        CCLayerAnimationControllerImpl::create(&dummy));
+    OwnPtr<CCLayerAnimationController> controller(
+        CCLayerAnimationController::create());
+
+    EXPECT_FALSE(controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity));
+
+    controller->activeAnimations().append(CCActiveAnimation::create(adoptPtr(new FakeFloatAnimationCurve()), 0, 0, CCActiveAnimation::Opacity));
+
+    controller->synchronizeAnimations(controllerImpl.get());
+
+    EXPECT_TRUE(controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity));
+    EXPECT_EQ(CCActiveAnimation::WaitingForTargetAvailability, controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity)->runState());
+
+    // Step through the animation until it is finished. At the next sync, the main thread's animation should be cleared.
+    OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
+    controllerImpl->animate(0, *events);
+    controllerImpl->animate(2, *events);
+
+    EXPECT_FALSE(controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity));
+    EXPECT_EQ(size_t(1), controller->activeAnimations().size());
+
+    controller->synchronizeAnimations(controllerImpl.get());
+
+    EXPECT_EQ(size_t(0), controller->activeAnimations().size());
+}
+
+} // namespace
index 3aa6a17..5b7f502 100644 (file)
@@ -52,6 +52,7 @@ public:
     virtual void onSwapBuffersCompleteOnImplThread() { }
     virtual void setNeedsRedrawOnImplThread() { m_didRequestRedraw = true; }
     virtual void setNeedsCommitOnImplThread() { m_didRequestCommit = true; }
+    virtual void postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector>) { }
 
     static void expectClearedScrollDeltasRecursive(CCLayerImpl* layer)
     {
index 16371a1..8260989 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "cc/CCLayerTreeHost.h"
 
+#include "CCAnimationTestCommon.h"
 #include "CompositorFakeWebGraphicsContext3D.h"
 #include "ContentLayerChromium.h"
 #include "FilterOperations.h"
@@ -35,6 +36,8 @@
 #include "TextureManager.h"
 #include "WebCompositor.h"
 #include "WebKit.h"
+#include "cc/CCActiveAnimation.h"
+#include "cc/CCLayerAnimationController.h"
 #include "cc/CCLayerImpl.h"
 #include "cc/CCLayerTreeHostImpl.h"
 #include "cc/CCScopedThreadProxy.h"
@@ -50,6 +53,7 @@
 
 using namespace WebCore;
 using namespace WebKit;
+using namespace WebKitTests;
 using namespace WTF;
 
 namespace {
@@ -60,6 +64,7 @@ public:
     virtual void beginCommitOnCCThread(CCLayerTreeHostImpl*) { }
     virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*) { }
     virtual void drawLayersOnCCThread(CCLayerTreeHostImpl*) { }
+    virtual void animateLayers(CCLayerTreeHostImpl*) { }
     virtual void applyScrollAndScale(const IntSize&, float) { }
     virtual void updateAnimations(double frameBeginTime) { }
     virtual void layout() { }
@@ -91,6 +96,13 @@ public:
         m_testHooks->drawLayersOnCCThread(this);
     }
 
+protected:
+    virtual void animateLayers(double frameBeginTimeMs)
+    {
+        CCLayerTreeHostImpl::animateLayers(frameBeginTimeMs);
+        m_testHooks->animateLayers(this);
+    }
+
 private:
     MockLayerTreeHostImpl(TestHooks* testHooks, const CCSettings& settings, CCLayerTreeHostImplClient* client)
         : CCLayerTreeHostImpl(settings, client)
@@ -106,7 +118,11 @@ class MockLayerTreeHost : public CCLayerTreeHost {
 public:
     static PassRefPtr<MockLayerTreeHost> create(TestHooks* testHooks, CCLayerTreeHostClient* client, PassRefPtr<LayerChromium> rootLayer, const CCSettings& settings)
     {
-        RefPtr<MockLayerTreeHost> layerTreeHost = adoptRef(new MockLayerTreeHost(testHooks, client, settings));
+        // For these tests, we will enable threaded animations.
+        CCSettings settingsCopy = settings;
+        settingsCopy.threadedAnimationEnabled = true;
+
+        RefPtr<MockLayerTreeHost> layerTreeHost = adoptRef(new MockLayerTreeHost(testHooks, client, settingsCopy));
         bool success = layerTreeHost->initialize();
         EXPECT_TRUE(success);
         layerTreeHost->setRootLayer(rootLayer);
@@ -119,7 +135,10 @@ public:
 
     virtual PassOwnPtr<CCLayerTreeHostImpl> createLayerTreeHostImpl(CCLayerTreeHostImplClient* client)
     {
-        return MockLayerTreeHostImpl::create(m_testHooks, settings(), client);
+        // For these tests, we will enable threaded animations.
+        CCSettings settings;
+        settings.threadedAnimationEnabled = true;
+        return MockLayerTreeHostImpl::create(m_testHooks, settings, client);
     }
 
 private:
@@ -132,6 +151,25 @@ private:
     TestHooks* m_testHooks;
 };
 
+// Adapts CCLayerAnimationController for test. Adds a dummy implementation of addAnimation that inserts a float animation.
+// FIXME: once CCLayerAnimationController::addAnimation is implemented, that function should be called directly and this
+// class can be removed.
+class MockLayerAnimationController : public CCLayerAnimationController {
+public:
+    static PassOwnPtr<MockLayerAnimationController> create()
+    {
+        return adoptPtr(new MockLayerAnimationController);
+    }
+
+private:
+    virtual bool addAnimation(const KeyframeValueList&, const IntSize& boxSize, const Animation*, int animationId, int groupId, double timeOffset)
+    {
+        double duration = 0;
+        activeAnimations().append(CCActiveAnimation::create(adoptPtr(new FakeFloatTransition(duration, 1, 0)), animationId, groupId, CCActiveAnimation::Opacity));
+        return true;
+    }
+};
+
 class CompositorFakeWebGraphicsContext3DWithTextureTracking : public CompositorFakeWebGraphicsContext3D {
 public:
     static PassOwnPtr<CompositorFakeWebGraphicsContext3DWithTextureTracking> create(Attributes attrs)
@@ -226,7 +264,9 @@ public:
     {
     }
 
-    virtual void scheduleComposite() { }
+    virtual void scheduleComposite()
+    {
+    }
 
 private:
     explicit MockLayerTreeHostClient(TestHooks* testHooks) : m_testHooks(testHooks) { }
@@ -256,6 +296,11 @@ public:
         callOnMainThread(CCLayerTreeHostTest::dispatchSetNeedsAnimate, this);
     }
 
+    void postAddAnimationToMainThread()
+    {
+        callOnMainThread(CCLayerTreeHostTest::dispatchAddAnimation, this);
+    }
+
     void postSetNeedsCommitToMainThread()
     {
         callOnMainThread(CCLayerTreeHostTest::dispatchSetNeedsCommit, this);
@@ -271,7 +316,6 @@ public:
         callOnMainThread(CCLayerTreeHostTest::dispatchSetNeedsAnimateAndCommit, this);
     }
 
-
     void postSetVisibleToMainThread(bool visible)
     {
         callOnMainThread(visible ? CCLayerTreeHostTest::dispatchSetVisible : CCLayerTreeHostTest::dispatchSetInvisible, this);
@@ -314,6 +358,15 @@ protected:
           test->m_layerTreeHost->setNeedsAnimate();
     }
 
+    static void dispatchAddAnimation(void* self)
+    {
+      ASSERT(isMainThread());
+      CCLayerTreeHostTest* test = static_cast<CCLayerTreeHostTest*>(self);
+      ASSERT(test);
+      if (test->m_layerTreeHost && test->m_layerTreeHost->rootLayer())
+          test->m_layerTreeHost->rootLayer()->addAnimation(KeyframeValueList(AnimatedPropertyOpacity), IntSize(), 0, 0, 0, 0.0);
+    }
+
     static void dispatchSetNeedsAnimateAndCommit(void* self)
     {
       ASSERT(isMainThread());
@@ -464,6 +517,7 @@ void CCLayerTreeHostTest::doBeginTest()
     m_layerTreeHost = MockLayerTreeHost::create(this, m_client.get(), rootLayer, m_settings);
     ASSERT_TRUE(m_layerTreeHost);
     rootLayer->setLayerTreeHost(m_layerTreeHost.get());
+    rootLayer->setLayerAnimationController(MockLayerAnimationController::create());
 
     m_beginning = true;
     beginTest();
@@ -790,6 +844,47 @@ TEST_F(CCLayerTreeHostTestSetNeedsAnimateInsideAnimationCallback, runMultiThread
     runTestThreaded();
 }
 
+// Add a layer animation and confirm that CCLayerTreeHostImpl::animateLayers does get
+// called and continues to get called.
+class CCLayerTreeHostTestAddAnimation : public CCLayerTreeHostTestThreadOnly {
+public:
+    CCLayerTreeHostTestAddAnimation()
+        : m_numAnimates(0)
+        , m_layerTreeHostImpl(0)
+    {
+    }
+
+    virtual void beginTest()
+    {
+        postAddAnimationToMainThread();
+    }
+
+    virtual void animateLayers(CCLayerTreeHostImpl* layerTreeHostImpl)
+    {
+        if (!m_numAnimates) {
+            // The animation had zero duration so layerTreeHostImpl should no
+            // longer need to animate its layers.
+            EXPECT_FALSE(layerTreeHostImpl->needsAnimateLayers());
+            m_numAnimates++;
+            return;
+        }
+        endTest();
+    }
+
+    virtual void afterTest()
+    {
+    }
+
+private:
+    int m_numAnimates;
+    CCLayerTreeHostImpl* m_layerTreeHostImpl;
+};
+
+TEST_F(CCLayerTreeHostTestAddAnimation, runMultiThread)
+{
+    runTestThreaded();
+}
+
 class CCLayerTreeHostTestScrollSimple : public CCLayerTreeHostTestThreadOnly {
 public:
     CCLayerTreeHostTestScrollSimple()
index 1557a7d..4724b4a 100644 (file)
 
 #include "TreeSynchronizer.h"
 
+#include "CCAnimationTestCommon.h"
 #include "LayerChromium.h"
+#include "cc/CCLayerAnimationController.h"
 #include "cc/CCLayerImpl.h"
 #include "cc/CCProxy.h"
 #include "cc/CCSingleThreadProxy.h"
 #include <gtest/gtest.h>
 
 using namespace WebCore;
+using namespace WebKitTests;
 
 namespace {
 
@@ -91,6 +94,30 @@ private:
     Vector<int>* m_ccLayerDestructionList;
 };
 
+class FakeLayerAnimationController : public CCLayerAnimationController {
+public:
+    static PassOwnPtr<FakeLayerAnimationController> create()
+    {
+        return adoptPtr(new FakeLayerAnimationController);
+    }
+
+    bool synchronizedAnimations() const { return m_synchronizedAnimations; }
+
+private:
+    FakeLayerAnimationController()
+        : m_synchronizedAnimations(false)
+    {
+    }
+
+    virtual void synchronizeAnimations(CCLayerAnimationControllerImpl* controllerImpl)
+    {
+        CCLayerAnimationController::synchronizeAnimations(controllerImpl);
+        m_synchronizedAnimations = true;
+    }
+
+    bool m_synchronizedAnimations;
+};
+
 void expectTreesAreIdentical(LayerChromium* layer, CCLayerImpl* ccLayer)
 {
     ASSERT_TRUE(layer);
@@ -307,5 +334,19 @@ TEST(TreeSynchronizerTest, syncMaskReplicaAndReplicaMaskLayers)
     expectTreesAreIdentical(layerTreeRoot.get(), ccLayerTreeRoot.get());
 }
 
+TEST(TreeSynchronizerTest, synchronizeAnimations)
+{
+    DebugScopedSetImplThread impl;
+    RefPtr<LayerChromium> layerTreeRoot = LayerChromium::create();
+
+    layerTreeRoot->setLayerAnimationController(FakeLayerAnimationController::create());
+
+    EXPECT_FALSE(static_cast<FakeLayerAnimationController*>(layerTreeRoot->layerAnimationController())->synchronizedAnimations());
+
+    RefPtr<CCLayerImpl> ccLayerTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), 0);
+    ccLayerTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), ccLayerTreeRoot.get());
+
+    EXPECT_TRUE(static_cast<FakeLayerAnimationController*>(layerTreeRoot->layerAnimationController())->synchronizedAnimations());
+}
 
 } // namespace