From c6151a04881a67d08d91237891fbc7cb82927219 Mon Sep 17 00:00:00 2001 From: John Reck Date: Fri, 2 Dec 2011 19:12:05 -0800 Subject: Don't deep copy animations, prepare animations on both trees Bug: 5699085 Previously, animations were copied along with layer trees from the webkit to UI thread. This changes that to instead use a single object per animation with refcounting so that animations are kept consistent. Additionally, animations are now run on both the painting and drawing trees in the tree manager so that animated content clipped correctly during a tree swap. Change-Id: I79f0c0e47b717f9fdddf303eb7ec29efc4950aaf --- .../platform/graphics/android/AndroidAnimation.cpp | 42 +--------------- .../platform/graphics/android/AndroidAnimation.h | 11 +--- .../platform/graphics/android/LayerAndroid.cpp | 58 +++++----------------- .../platform/graphics/android/LayerAndroid.h | 1 + .../platform/graphics/android/TreeManager.cpp | 16 ++++-- Source/WebKit/android/nav/WebView.cpp | 7 +-- 6 files changed, 33 insertions(+), 102 deletions(-) (limited to 'Source') diff --git a/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp b/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp index 245d2f1..6b22359 100644 --- a/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp +++ b/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp @@ -79,23 +79,6 @@ AndroidAnimation::AndroidAnimation(AnimatedPropertyID type, gDebugAndroidAnimationInstances++; } -AndroidAnimation::AndroidAnimation(AndroidAnimation* anim) - : m_beginTime(anim->m_beginTime) - , m_duration(anim->m_duration) - , m_fillsBackwards(anim->m_fillsBackwards) - , m_fillsForwards(anim->m_fillsForwards) - , m_iterationCount(anim->m_iterationCount) - , m_direction(anim->m_direction) - , m_timingFunction(anim->m_timingFunction) - , m_name(anim->name()) - , m_type(anim->m_type) - , m_operations(anim->m_operations) - , m_uniqueId(anim->m_uniqueId) - , m_hasFinished(anim->m_hasFinished) -{ - gDebugAndroidAnimationInstances++; -} - AndroidAnimation::~AndroidAnimation() { gDebugAndroidAnimationInstances--; @@ -109,8 +92,7 @@ void AndroidAnimation::suggestBeginTime(double time) double AndroidAnimation::elapsedTime(double time) { - suggestBeginTime(time); - double elapsedTime = time - m_beginTime; + double elapsedTime = (m_beginTime < 0.000001) ? 0 : time - m_beginTime; if (m_duration <= 0) m_duration = 0.000001; @@ -201,7 +183,7 @@ bool AndroidAnimation::evaluate(LayerAndroid* layer, double time) if (progress < 0) { // The animation hasn't started yet - if (m_fillsBackwards) { + if (m_fillsBackwards || m_beginTime <= 0.000001) { // in this case we want to apply the initial keyframe to the layer applyForProgress(layer, 0); } @@ -239,16 +221,6 @@ AndroidOpacityAnimation::AndroidOpacityAnimation(const Animation* animation, { } -AndroidOpacityAnimation::AndroidOpacityAnimation(AndroidOpacityAnimation* anim) - : AndroidAnimation(anim) -{ -} - -PassRefPtr AndroidOpacityAnimation::copy() -{ - return adoptRef(new AndroidOpacityAnimation(this)); -} - void AndroidAnimation::pickValues(double progress, int* start, int* end) { float distance = -1; @@ -312,16 +284,6 @@ AndroidTransformAnimation::AndroidTransformAnimation(const Animation* animation, { } -AndroidTransformAnimation::AndroidTransformAnimation(AndroidTransformAnimation* anim) - : AndroidAnimation(anim) -{ -} - -PassRefPtr AndroidTransformAnimation::copy() -{ - return adoptRef(new AndroidTransformAnimation(this)); -} - void AndroidTransformAnimation::applyForProgress(LayerAndroid* layer, float progress) { // First, we need to get the from and to values diff --git a/Source/WebCore/platform/graphics/android/AndroidAnimation.h b/Source/WebCore/platform/graphics/android/AndroidAnimation.h index 52cef4e..dca769f 100644 --- a/Source/WebCore/platform/graphics/android/AndroidAnimation.h +++ b/Source/WebCore/platform/graphics/android/AndroidAnimation.h @@ -33,16 +33,14 @@ namespace WebCore { class TimingFunction; -class AndroidAnimation : public RefCounted { +class AndroidAnimation : public ThreadSafeRefCounted { public: AndroidAnimation(AnimatedPropertyID type, const Animation* animation, KeyframeValueList* operations, double beginTime); - AndroidAnimation(AndroidAnimation* anim); virtual ~AndroidAnimation(); - virtual PassRefPtr copy() = 0; void suggestBeginTime(double time); double elapsedTime(double time); void pickValues(double progress, int* start, int* end); @@ -59,8 +57,6 @@ public: bool fillsForwards() { return m_fillsForwards; } int uniqueId() { return m_uniqueId; } - double beginTime() { return m_beginTime; } - protected: double m_beginTime; double m_duration; @@ -84,8 +80,6 @@ public: AndroidOpacityAnimation(const Animation* animation, KeyframeValueList* operations, double beginTime); - AndroidOpacityAnimation(AndroidOpacityAnimation* anim); - virtual PassRefPtr copy(); virtual void applyForProgress(LayerAndroid* layer, float progress); }; @@ -100,9 +94,6 @@ public: KeyframeValueList* operations, double beginTime); - AndroidTransformAnimation(AndroidTransformAnimation* anim); - virtual PassRefPtr copy(); - virtual void applyForProgress(LayerAndroid* layer, float progress); }; diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp index 0557847..962bcdf 100644 --- a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -215,8 +215,7 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer), KeyframesMap::const_iterator end = layer.m_animations.end(); for (KeyframesMap::const_iterator it = layer.m_animations.begin(); it != end; ++it) { - pair key((it->second)->name(), (it->second)->type()); - m_animations.add(key, (it->second)->copy()); + m_animations.add(it->first, it->second); } m_hasText = layer.m_hasText; @@ -325,6 +324,17 @@ bool LayerAndroid::evaluateAnimations(double time) return hasRunningAnimations || m_hasRunningAnimations; } +void LayerAndroid::initAnimations() { + // tell auto-initializing animations to start now + for (int i = 0; i < countChildren(); i++) + getChild(i)->initAnimations(); + + KeyframesMap::const_iterator localBegin = m_animations.begin(); + KeyframesMap::const_iterator localEnd = m_animations.end(); + for (KeyframesMap::const_iterator localIt = localBegin; localIt != localEnd; ++localIt) + (localIt->second)->suggestBeginTime(WTF::currentTime()); +} + void LayerAndroid::addDirtyArea() { IntSize layerSize(getSize().width(), getSize().height()); @@ -369,7 +379,7 @@ void LayerAndroid::removeAnimationsForKeyframes(const String& name) } for (unsigned int i = 0; i < toDelete.size(); i++) - m_animations.remove(toDelete[i]); + m_animations.remove(toDelete[i]); } // We only use the bounding rect of the layer as mask... @@ -877,12 +887,6 @@ void LayerAndroid::setIsDrawing(bool isDrawing) m_texture->setDrawingLayer(isDrawing ? this : 0); m_texture->clearPaintingLayer(); } - - // tell auto-initializing animations to start now - KeyframesMap::const_iterator localBegin = m_animations.begin(); - KeyframesMap::const_iterator localEnd = m_animations.end(); - for (KeyframesMap::const_iterator localIt = localBegin; localIt != localEnd; ++localIt) - (localIt->second)->suggestBeginTime(WTF::currentTime()); } void LayerAndroid::setIsPainting(Layer* drawingTree) @@ -898,45 +902,9 @@ void LayerAndroid::setIsPainting(Layer* drawingTree) if (drawingTree) drawingLayer = static_cast(drawingTree)->findById(uniqueId()); - copyAnimationStartTimes(drawingLayer); obtainTextureForPainting(drawingLayer); } -void LayerAndroid::copyAnimationStartTimesRecursive(LayerAndroid* oldTree) -{ - // used for copying UI-side animation start times in software rendering mode - if (!oldTree) - return; - - for (int i = 0; i < countChildren(); i++) - this->getChild(i)->copyAnimationStartTimesRecursive(oldTree); - - LayerAndroid* layer = oldTree->findById(uniqueId()); - if (layer) - copyAnimationStartTimes(layer); -} - -void LayerAndroid::copyAnimationStartTimes(LayerAndroid* oldLayer) -{ - if (!oldLayer) - return; - - // copy animation start times, if applicable - KeyframesMap::const_iterator localBegin = m_animations.begin(); - KeyframesMap::const_iterator localEnd = m_animations.end(); - for (KeyframesMap::const_iterator localIt = localBegin; localIt != localEnd; ++localIt) { - KeyframesMap::const_iterator oldBegin = oldLayer->m_animations.begin(); - KeyframesMap::const_iterator oldEnd = oldLayer->m_animations.end(); - for (KeyframesMap::const_iterator oldIt = oldBegin; oldIt != oldEnd; ++oldIt) { - if ((localIt->second)->uniqueId() == (oldIt->second)->uniqueId()) { - // animations are identical, try to copy start time of the old - // one, which will have been initialized some time in the past - (localIt->second)->suggestBeginTime((oldIt->second)->beginTime()); - } - } - } -} - void LayerAndroid::mergeInvalsInto(Layer* replacementTree) { int count = this->countChildren(); diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.h b/Source/WebCore/platform/graphics/android/LayerAndroid.h index 5c13899..c1f1bc9 100644 --- a/Source/WebCore/platform/graphics/android/LayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/LayerAndroid.h @@ -214,6 +214,7 @@ public: void removeAnimationsForKeyframes(const String& name); bool evaluateAnimations(); bool evaluateAnimations(double time); + void initAnimations(); bool hasAnimations() const; void addDirtyArea(); diff --git a/Source/WebCore/platform/graphics/android/TreeManager.cpp b/Source/WebCore/platform/graphics/android/TreeManager.cpp index 71e5f6b..b7eaacf 100644 --- a/Source/WebCore/platform/graphics/android/TreeManager.cpp +++ b/Source/WebCore/platform/graphics/android/TreeManager.cpp @@ -88,6 +88,8 @@ void TreeManager::swap() // painting tree becomes the drawing tree XLOG("drawing tree %p", m_paintingTree); m_paintingTree->setIsDrawing(true); + if (m_paintingTree->countChildren()) + static_cast(m_paintingTree->getChild(0))->initAnimations(); if (m_queuedTree) { // start painting with the queued tree @@ -206,14 +208,20 @@ bool TreeManager::drawGL(double currentTime, IntRect& viewRect, bool ret = false; bool didTreeSwap = false; if (m_paintingTree) { - ret |= m_paintingTree->prepare(currentTime, viewRect, - visibleRect, scale); - LayerAndroid* laTree = 0; + XLOG("preparing painting tree %p", m_paintingTree); + LayerAndroid* laTree = 0; if (m_paintingTree->countChildren()) { laTree = static_cast(m_paintingTree->getChild(0)); - laTree->computeTexturesAmount(texturesResultPtr); + ret |= laTree->evaluateAnimations(currentTime); } + + ret |= m_paintingTree->prepare(currentTime, viewRect, + visibleRect, scale); + + if (laTree) + laTree->computeTexturesAmount(texturesResultPtr); + if (/*!m_fastSwapMode && */ m_paintingTree->isReady()) { XLOG("have painting tree %p ready, swapping!", m_paintingTree); didTreeSwap = true; diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp index fa25c46..d3b9591 100644 --- a/Source/WebKit/android/nav/WebView.cpp +++ b/Source/WebKit/android/nav/WebView.cpp @@ -1468,8 +1468,6 @@ void setBaseLayer(BaseLayerAndroid* layer, SkRegion& inval, bool showVisualIndic // TODO: the below tree copies are only necessary in software rendering LayerAndroid* newCompositeRoot = static_cast(layer->getChild(0)); copyScrollPositionRecursive(compositeRoot(), newCompositeRoot); - if (newCompositeRoot) - newCompositeRoot->copyAnimationStartTimesRecursive(compositeRoot()); } #endif SkSafeUnref(m_baseLayer); @@ -1915,10 +1913,13 @@ static void nativeUpdateDrawGLFunction(JNIEnv *env, jobject obj, jobject jrect, static bool nativeEvaluateLayersAnimations(JNIEnv *env, jobject obj, jint nativeView) { + // only call in software rendering, initialize and evaluate animations #if USE(ACCELERATED_COMPOSITING) LayerAndroid* root = ((WebView*)nativeView)->compositeRoot(); - if (root) + if (root) { + root->initAnimations(); return root->evaluateAnimations(); + } #endif return false; } -- cgit v1.1