summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Reck <jreck@google.com>2011-12-02 19:12:05 -0800
committerChris Craik <ccraik@google.com>2011-12-05 17:01:13 -0800
commitc6151a04881a67d08d91237891fbc7cb82927219 (patch)
tree5a68a6baf72fe12d82f3a3d44e4e8eab87c87ff3
parent3fb3b3e0e16ce89f589b71ba2cc5942f42f0ac27 (diff)
downloadexternal_webkit-c6151a04881a67d08d91237891fbc7cb82927219.zip
external_webkit-c6151a04881a67d08d91237891fbc7cb82927219.tar.gz
external_webkit-c6151a04881a67d08d91237891fbc7cb82927219.tar.bz2
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
-rw-r--r--Source/WebCore/platform/graphics/android/AndroidAnimation.cpp42
-rw-r--r--Source/WebCore/platform/graphics/android/AndroidAnimation.h11
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.cpp58
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.h1
-rw-r--r--Source/WebCore/platform/graphics/android/TreeManager.cpp16
-rw-r--r--Source/WebKit/android/nav/WebView.cpp7
6 files changed, 33 insertions, 102 deletions
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<AndroidAnimation> 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<AndroidAnimation> 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<AndroidAnimation> {
+class AndroidAnimation : public ThreadSafeRefCounted<AndroidAnimation> {
public:
AndroidAnimation(AnimatedPropertyID type,
const Animation* animation,
KeyframeValueList* operations,
double beginTime);
- AndroidAnimation(AndroidAnimation* anim);
virtual ~AndroidAnimation();
- virtual PassRefPtr<AndroidAnimation> 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<AndroidAnimation> copy();
virtual void applyForProgress(LayerAndroid* layer, float progress);
};
@@ -100,9 +94,6 @@ public:
KeyframeValueList* operations,
double beginTime);
- AndroidTransformAnimation(AndroidTransformAnimation* anim);
- virtual PassRefPtr<AndroidAnimation> 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<String, int> 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<LayerAndroid*>(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<LayerAndroid*>(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<LayerAndroid*>(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<LayerAndroid*>(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;
}