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--;
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;
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);
}
{
}
-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;
{
}
-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
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);
bool fillsForwards() { return m_fillsForwards; }
int uniqueId() { return m_uniqueId; }
- double beginTime() { return m_beginTime; }
-
protected:
double m_beginTime;
double m_duration;
AndroidOpacityAnimation(const Animation* animation,
KeyframeValueList* operations,
double beginTime);
- AndroidOpacityAnimation(AndroidOpacityAnimation* anim);
- virtual PassRefPtr<AndroidAnimation> copy();
virtual void applyForProgress(LayerAndroid* layer, float progress);
};
KeyframeValueList* operations,
double beginTime);
- AndroidTransformAnimation(AndroidTransformAnimation* anim);
- virtual PassRefPtr<AndroidAnimation> copy();
-
virtual void applyForProgress(LayerAndroid* layer, float progress);
};
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;
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());
}
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...
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)
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();
void removeAnimationsForKeyframes(const String& name);
bool evaluateAnimations();
bool evaluateAnimations(double time);
+ void initAnimations();
bool hasAnimations() const;
void addDirtyArea();
// 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
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;
// 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);
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;
}