summaryrefslogtreecommitdiffstats
path: root/Source/WebCore
diff options
context:
space:
mode:
authorChris Craik <ccraik@google.com>2011-11-30 10:50:43 -0800
committerAndroid Git Automerger <android-git-automerger@android.com>2011-11-30 10:50:43 -0800
commited5d84ae70b5ff966ed7a934d5658f6648088d30 (patch)
treeccdbc1b22881ea9f7347cf29e24598faeaa6403d /Source/WebCore
parentc75d89bc16f0cf638347ee3348f782b8309d8be3 (diff)
parent807ee5ec662a7864dee505040ade9a9b3eab143c (diff)
downloadexternal_webkit-ed5d84ae70b5ff966ed7a934d5658f6648088d30.zip
external_webkit-ed5d84ae70b5ff966ed7a934d5658f6648088d30.tar.gz
external_webkit-ed5d84ae70b5ff966ed7a934d5658f6648088d30.tar.bz2
am 807ee5ec: Merge "synchronize animation starts with webkit" into ics-mr1
* commit '807ee5ec662a7864dee505040ade9a9b3eab143c': synchronize animation starts with webkit
Diffstat (limited to 'Source/WebCore')
-rw-r--r--Source/WebCore/platform/graphics/android/AndroidAnimation.cpp32
-rw-r--r--Source/WebCore/platform/graphics/android/AndroidAnimation.h6
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.cpp8
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.h3
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp8
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.cpp46
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.h3
-rw-r--r--Source/WebCore/platform/graphics/android/TreeManager.cpp46
-rw-r--r--Source/WebCore/platform/graphics/android/TreeManager.h6
-rw-r--r--Source/WebCore/rendering/RenderLayerCompositor.cpp5
10 files changed, 106 insertions, 57 deletions
diff --git a/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp b/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp
index 5601269..245d2f1 100644
--- a/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp
+++ b/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp
@@ -49,6 +49,8 @@
namespace WebCore {
+static int gUniqueId;
+
static long gDebugAndroidAnimationInstances;
long AndroidAnimation::instancesCount()
@@ -69,12 +71,11 @@ AndroidAnimation::AndroidAnimation(AnimatedPropertyID type,
, m_timingFunction(animation->timingFunction())
, m_type(type)
, m_operations(operations)
+ , m_uniqueId(++gUniqueId)
+ , m_hasFinished(false)
{
ASSERT(m_timingFunction);
- if (!static_cast<int>(beginTime)) // time not set
- m_beginTime = WTF::currentTime();
-
gDebugAndroidAnimationInstances++;
}
@@ -89,6 +90,8 @@ AndroidAnimation::AndroidAnimation(AndroidAnimation* anim)
, 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++;
}
@@ -98,20 +101,24 @@ AndroidAnimation::~AndroidAnimation()
gDebugAndroidAnimationInstances--;
}
-double AndroidAnimation::elapsedTime(double time)
+void AndroidAnimation::suggestBeginTime(double time)
{
- if (m_beginTime <= 0.000001) // overflow or not correctly set
+ if (m_beginTime <= 0.000001) // overflow or not yet set
m_beginTime = time;
+}
- m_elapsedTime = time - m_beginTime;
+double AndroidAnimation::elapsedTime(double time)
+{
+ suggestBeginTime(time);
+ double elapsedTime = time - m_beginTime;
if (m_duration <= 0)
m_duration = 0.000001;
- if (m_elapsedTime < 0) // animation not yet started.
+ if (elapsedTime < 0) // animation not yet started.
return 0;
- return m_elapsedTime;
+ return elapsedTime;
}
bool AndroidAnimation::checkIterationsAndProgress(double time, float* finalProgress)
@@ -127,6 +134,13 @@ bool AndroidAnimation::checkIterationsAndProgress(double time, float* finalProgr
// If not infinite, return false if we are done
if (m_iterationCount > 0 && progress > dur) {
*finalProgress = 1.0;
+ if (!m_hasFinished) {
+ // first time past duration, continue with progress 1.0 so the
+ // element's final position lines up with it's last keyframe
+ m_hasFinished = true;
+ return true;
+ }
+
return false;
}
@@ -195,7 +209,7 @@ bool AndroidAnimation::evaluate(LayerAndroid* layer, double time)
return true;
}
- if (progress >= 1) {
+ if (progress > 1) {
if (!m_fillsForwards)
return false;
progress = 1;
diff --git a/Source/WebCore/platform/graphics/android/AndroidAnimation.h b/Source/WebCore/platform/graphics/android/AndroidAnimation.h
index 16a63e8..52cef4e 100644
--- a/Source/WebCore/platform/graphics/android/AndroidAnimation.h
+++ b/Source/WebCore/platform/graphics/android/AndroidAnimation.h
@@ -43,6 +43,7 @@ public:
virtual ~AndroidAnimation();
virtual PassRefPtr<AndroidAnimation> copy() = 0;
+ void suggestBeginTime(double time);
double elapsedTime(double time);
void pickValues(double progress, int* start, int* end);
bool checkIterationsAndProgress(double time, float* finalProgress);
@@ -56,11 +57,12 @@ public:
AnimatedPropertyID type() { return m_type; }
bool fillsBackwards() { return m_fillsBackwards; }
bool fillsForwards() { return m_fillsForwards; }
+ int uniqueId() { return m_uniqueId; }
+ double beginTime() { return m_beginTime; }
protected:
double m_beginTime;
- double m_elapsedTime;
double m_duration;
bool m_fillsBackwards;
bool m_fillsForwards;
@@ -70,6 +72,8 @@ protected:
String m_name;
AnimatedPropertyID m_type;
KeyframeValueList* m_operations;
+ int m_uniqueId;
+ bool m_hasFinished;
};
class AndroidOpacityAnimation : public AndroidAnimation {
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
index 1087640..4820120 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
@@ -84,9 +84,9 @@ GLWebViewState::GLWebViewState()
, m_goingLeft(false)
, m_expandedTileBoundsX(0)
, m_expandedTileBoundsY(0)
+ , m_highEndGfx(false)
, m_scale(1)
, m_layersRenderingMode(kAllTextures)
- , m_highEndGfx(false)
{
m_viewport.setEmpty();
m_futureViewportTileBounds.setEmpty();
@@ -436,7 +436,8 @@ void GLWebViewState::fullInval()
bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
IntRect& webViewRect, int titleBarHeight,
- IntRect& clip, float scale, bool* buffersSwappedPtr)
+ IntRect& clip, float scale,
+ bool* treesSwappedPtr, bool* newTreeHasAnimPtr)
{
m_scale = scale;
TilesManager::instance()->getProfiler()->nextFrame(viewport.fLeft,
@@ -495,7 +496,8 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
bool fastSwap = isScrolling() || m_layersRenderingMode == kSingleSurfaceRendering;
ret |= m_treeManager.drawGL(currentTime, rect, viewport,
scale, fastSwap,
- buffersSwappedPtr, &nbTexturesNeeded);
+ treesSwappedPtr, newTreeHasAnimPtr,
+ &nbTexturesNeeded);
if (!ret)
resetFrameworkInval();
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.h b/Source/WebCore/platform/graphics/android/GLWebViewState.h
index 2a6c8df..cffd28f 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.h
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.h
@@ -214,7 +214,8 @@ public:
bool drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
IntRect& webViewRect, int titleBarHeight,
- IntRect& clip, float scale, bool* buffersSwappedPtr);
+ IntRect& clip, float scale,
+ bool* treesSwappedPtr, bool* newTreeHasAnimPtr);
#ifdef MEASURES_PERF
void dumpMeasures();
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
index 387c3e0..44c9a2d 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -331,6 +331,9 @@ void GraphicsLayerAndroid::setSize(const FloatSize& size)
void GraphicsLayerAndroid::setBackfaceVisibility(bool b)
{
+ if (b == m_backfaceVisibility)
+ return;
+
GraphicsLayer::setBackfaceVisibility(b);
m_contentLayer->setBackfaceVisibility(b);
askForSync();
@@ -397,7 +400,7 @@ void GraphicsLayerAndroid::setDrawsContent(bool drawsContent)
void GraphicsLayerAndroid::setBackgroundColor(const Color& color)
{
- if (color == m_backgroundColor)
+ if (color == m_backgroundColor && m_backgroundColorSet)
return;
LOG("(%x) setBackgroundColor", this);
GraphicsLayer::setBackgroundColor(color);
@@ -409,6 +412,9 @@ void GraphicsLayerAndroid::setBackgroundColor(const Color& color)
void GraphicsLayerAndroid::clearBackgroundColor()
{
+ if (!m_backgroundColorSet)
+ return;
+
LOG("(%x) clearBackgroundColor", this);
GraphicsLayer::clearBackgroundColor();
askForSync();
diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
index 859973a..86991d5 100644
--- a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
@@ -879,6 +879,12 @@ 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)
@@ -889,7 +895,34 @@ void LayerAndroid::setIsPainting(Layer* drawingTree)
for (int i = 0; i < count; i++)
this->getChild(i)->setIsPainting(drawingTree);
- obtainTextureForPainting(static_cast<LayerAndroid*>(drawingTree));
+
+ LayerAndroid* drawingLayer = 0;
+ if (drawingTree)
+ drawingLayer = static_cast<LayerAndroid*>(drawingTree)->findById(uniqueId());
+
+ copyAnimationStartTimes(drawingLayer);
+ obtainTextureForPainting(drawingLayer);
+}
+
+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)
@@ -960,7 +993,7 @@ bool LayerAndroid::updateWithLayer(LayerAndroid* layer)
return false;
}
-void LayerAndroid::obtainTextureForPainting(LayerAndroid* drawingTree)
+void LayerAndroid::obtainTextureForPainting(LayerAndroid* drawingLayer)
{
if (!needsTexture())
return;
@@ -976,12 +1009,9 @@ void LayerAndroid::obtainTextureForPainting(LayerAndroid* drawingTree)
m_texture = 0;
}
} else {
- if (drawingTree) {
- LayerAndroid* drawingLayer = drawingTree->findById(uniqueId());
- if (drawingLayer) {
- // if a previous tree had the same layer, paint with that painted surface
- m_texture = drawingLayer->m_texture;
- }
+ if (drawingLayer) {
+ // if a previous tree had the same layer, paint with that painted surface
+ m_texture = drawingLayer->m_texture;
}
if (!m_texture)
diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.h b/Source/WebCore/platform/graphics/android/LayerAndroid.h
index ae9dc88..8b82b27 100644
--- a/Source/WebCore/platform/graphics/android/LayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/LayerAndroid.h
@@ -290,7 +290,7 @@ public:
friend void android::cleanupImageRefs(LayerAndroid* layer);
PaintedSurface* texture() { return m_texture; }
- void obtainTextureForPainting(LayerAndroid* drawingTree);
+ void obtainTextureForPainting(LayerAndroid* drawingLayer);
// Update layers using another tree. Only works for basic properties
// such as the position, the transform. Return true if anything more
@@ -323,6 +323,7 @@ private:
friend class CachedLayer::Debug; // debugging access only
#endif
+ void copyAnimationStartTimes(LayerAndroid* oldLayer);
void findInner(FindState&) const;
bool prepareContext(bool force = false);
void clipInner(SkTDArray<SkRect>* region, const SkRect& local) const;
diff --git a/Source/WebCore/platform/graphics/android/TreeManager.cpp b/Source/WebCore/platform/graphics/android/TreeManager.cpp
index 5fd3b7c..fe55df8 100644
--- a/Source/WebCore/platform/graphics/android/TreeManager.cpp
+++ b/Source/WebCore/platform/graphics/android/TreeManager.cpp
@@ -132,6 +132,10 @@ void TreeManager::clearTrees()
// or start painting it if we aren't
void TreeManager::updateWithTree(Layer* newTree, bool brandNew)
{
+ XLOG("updateWithTree - %p, has children %d, has animations %d",
+ newTree, newTree && newTree->countChildren(),
+ newTree && newTree->countChildren()
+ ? static_cast<LayerAndroid*>(newTree->getChild(0))->hasAnimations() : 0);
// can't have a queued tree unless have a painting tree too
ASSERT(m_paintingTree || !m_queuedTree);
@@ -143,10 +147,6 @@ void TreeManager::updateWithTree(Layer* newTree, bool brandNew)
if (!newTree || brandNew) {
clearTrees();
if (brandNew) {
- m_animationOffset = 0;
- m_isAnimating = false;
- m_lastFrameTime = WTF::currentTime();
-
m_paintingTree = newTree;
m_paintingTree->setIsPainting(m_drawingTree);
}
@@ -159,6 +159,11 @@ void TreeManager::updateWithTree(Layer* newTree, bool brandNew)
// have a queued tree, copy over invals so the regions are
// eventually repainted
m_queuedTree->mergeInvalsInto(newTree);
+
+ XLOG("DISCARDING tree - %p, has children %d, has animations %d",
+ newTree, newTree && newTree->countChildren(),
+ newTree && newTree->countChildren()
+ ? static_cast<LayerAndroid*>(newTree->getChild(0))->hasAnimations() : 0);
}
SkSafeUnref(m_queuedTree);
m_queuedTree = newTree;
@@ -172,7 +177,7 @@ void TreeManager::updateWithTree(Layer* newTree, bool brandNew)
bool TreeManager::drawGL(double currentTime, IntRect& viewRect,
SkRect& visibleRect, float scale,
- bool enterFastSwapMode, bool* buffersSwappedPtr,
+ bool enterFastSwapMode, bool* treesSwappedPtr, bool* newTreeHasAnimPtr,
TexturesResult* texturesResultPtr)
{
m_fastSwapMode |= enterFastSwapMode;
@@ -185,17 +190,20 @@ bool TreeManager::drawGL(double currentTime, IntRect& viewRect,
if (m_paintingTree) {
ret |= m_paintingTree->prepare(currentTime, viewRect,
visibleRect, scale);
+ LayerAndroid* laTree = 0;
if (m_paintingTree->countChildren()) {
- LayerAndroid* laTree = static_cast<LayerAndroid*>(m_paintingTree->getChild(0));
+ laTree = static_cast<LayerAndroid*>(m_paintingTree->getChild(0));
laTree->computeTexturesAmount(texturesResultPtr);
}
if (/*!m_fastSwapMode && */ m_paintingTree->isReady()) {
XLOG("have painting tree %p ready, swapping!", m_paintingTree);
didTreeSwap = true;
swap();
- if (buffersSwappedPtr)
- *buffersSwappedPtr = true;
+ if (treesSwappedPtr)
+ *treesSwappedPtr = true;
+ if (laTree && newTreeHasAnimPtr)
+ *newTreeHasAnimPtr = laTree->hasAnimations();
}
} else if (m_drawingTree) {
XLOG("preparing drawing tree %p", m_drawingTree);
@@ -207,17 +215,11 @@ bool TreeManager::drawGL(double currentTime, IntRect& viewRect,
}
}
- if (!m_isAnimating) {
- m_animationOffset += currentTime - m_lastFrameTime;
-#ifdef ANIM_DEBUG
- XLOGC("adding to %f", m_animationOffset);
-#endif
- }
if (m_drawingTree) {
bool drawingReady = didTreeSwap || m_drawingTree->isReady();
- if (drawingReady || m_fastSwapMode)
+ if (didTreeSwap || m_fastSwapMode || (drawingReady && !m_paintingTree))
m_drawingTree->swapTiles();
if (drawingReady) {
@@ -229,18 +231,8 @@ bool TreeManager::drawGL(double currentTime, IntRect& viewRect,
}
if (m_drawingTree->countChildren()) {
-#ifdef ANIM_DEBUG
- XLOGC("drawing tree %p with animation time offset of %f, locked %d",
- m_drawingTree, m_animationOffset, m_isAnimating);
-#endif
LayerAndroid* laTree = static_cast<LayerAndroid*>(m_drawingTree->getChild(0));
- m_isAnimating = laTree->evaluateAnimations(currentTime - m_animationOffset);
- if (!m_isAnimating)
- m_animationOffset = 0;
- ret |= m_isAnimating;
- } else if (!m_paintingTree) {
- m_animationOffset = 0;
- m_isAnimating = false;
+ ret |= laTree->evaluateAnimations(currentTime);
}
XLOG("drawing tree %p", m_drawingTree);
ret |= m_drawingTree->drawGL(viewRect, visibleRect, scale);
@@ -250,8 +242,6 @@ bool TreeManager::drawGL(double currentTime, IntRect& viewRect,
m_paintingTree->state()->drawBackground(defaultBackground);
}
- m_lastFrameTime = currentTime;
-
if (m_paintingTree) {
XLOG("still have painting tree %p", m_paintingTree);
return true;
diff --git a/Source/WebCore/platform/graphics/android/TreeManager.h b/Source/WebCore/platform/graphics/android/TreeManager.h
index 09b1bd9..d2e10c8 100644
--- a/Source/WebCore/platform/graphics/android/TreeManager.h
+++ b/Source/WebCore/platform/graphics/android/TreeManager.h
@@ -48,7 +48,7 @@ public:
bool drawGL(double currentTime, IntRect& viewRect,
SkRect& visibleRect, float scale,
- bool enterFastSwapMode, bool* buffersSwappedPtr,
+ bool enterFastSwapMode, bool* treesSwappedPtr, bool* newTreeHasAnimPtr,
TexturesResult* texturesResultPtr);
void drawCanvas(SkCanvas* canvas, bool drawLayers);
@@ -70,10 +70,6 @@ private:
Layer* m_queuedTree;
bool m_fastSwapMode;
-
- double m_animationOffset;
- double m_lastFrameTime;
- bool m_isAnimating;
};
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp
index 85c57a6..06fa0f6 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp
@@ -1578,7 +1578,12 @@ bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* render
return false;
if (AnimationController* animController = renderer->animation()) {
+#if PLATFORM(ANDROID)
+ // android renders an opacity animation much faster if it's composited
+ return (animController->isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity))
+#else
return (animController->isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity) && inCompositingMode())
+#endif
|| animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitTransform);
}
return false;