summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp')
-rw-r--r--WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp852
1 files changed, 852 insertions, 0 deletions
diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
new file mode 100644
index 0000000..7637be9
--- /dev/null
+++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -0,0 +1,852 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "config.h"
+#include "GraphicsLayerAndroid.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "AndroidAnimation.h"
+#include "Animation.h"
+#include "CString.h"
+#include "FloatRect.h"
+#include "GraphicsContext.h"
+#include "Image.h"
+#include "PlatformBridge.h"
+#include "PlatformGraphicsContext.h"
+#include "RenderLayerBacking.h"
+#include "RenderView.h"
+#include "RotateTransformOperation.h"
+#include "ScaleTransformOperation.h"
+#include "SkCanvas.h"
+#include "TransformationMatrix.h"
+#include "TranslateTransformOperation.h"
+
+#include <cutils/log.h>
+#include <wtf/CurrentTime.h>
+
+#undef LOG
+#define LOG(...) android_printLog(ANDROID_LOG_DEBUG, "GraphicsLayer", __VA_ARGS__)
+#define MLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GraphicsLayer", __VA_ARGS__)
+#define TLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GraphicsLayer", __VA_ARGS__)
+
+#undef LOG
+#define LOG(...)
+#undef MLOG
+#define MLOG(...)
+#undef TLOG
+#define TLOG(...)
+#undef LAYER_DEBUG
+
+using namespace std;
+
+static bool gPaused;
+static double gPausedDelay;
+
+namespace WebCore {
+
+static int gDebugGraphicsLayerAndroidInstances = 0;
+inline int GraphicsLayerAndroid::instancesCount()
+{
+ return gDebugGraphicsLayerAndroidInstances;
+}
+
+static String propertyIdToString(AnimatedPropertyID property)
+{
+ switch (property) {
+ case AnimatedPropertyWebkitTransform:
+ return "transform";
+ case AnimatedPropertyOpacity:
+ return "opacity";
+ case AnimatedPropertyBackgroundColor:
+ return "backgroundColor";
+ case AnimatedPropertyInvalid:
+ ASSERT_NOT_REACHED();
+ }
+ ASSERT_NOT_REACHED();
+ return "";
+}
+
+GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayer::compositingCoordinatesOrientation()
+{
+ return CompositingCoordinatesBottomUp;
+}
+
+PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
+{
+ return new GraphicsLayerAndroid(client);
+}
+
+GraphicsLayerAndroid::GraphicsLayerAndroid(GraphicsLayerClient* client) :
+ GraphicsLayer(client),
+ m_needsSyncChildren(false),
+ m_needsSyncMask(false),
+ m_needsRepaint(false),
+ m_needsDisplay(false),
+ m_haveContents(false),
+ m_haveImage(false),
+ m_translateX(0),
+ m_translateY(0),
+ m_currentTranslateX(0),
+ m_currentTranslateY(0),
+ m_currentPosition(0, 0)
+{
+ m_contentLayer = new LayerAndroid(true);
+ if (client) {
+ RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(client);
+ RenderLayer* renderLayer = backing->owningLayer();
+ m_contentLayer->setIsRootLayer(renderLayer->isRootLayer());
+ RenderView* view = static_cast<RenderView*>(renderLayer->renderer());
+ if (view->isPositioned() && view->style()->position() == FixedPosition) {
+ FloatPoint position(view->style()->left().value(),
+ view->style()->right().value());
+ m_contentLayer->setFixedPosition(position);
+ }
+ }
+ gDebugGraphicsLayerAndroidInstances++;
+}
+
+GraphicsLayerAndroid::~GraphicsLayerAndroid()
+{
+ if (!parent() && m_frame && m_frame->view())
+ PlatformBridge::setRootLayer(m_frame->view(), 0);
+
+ gDebugGraphicsLayerAndroidInstances--;
+}
+
+void GraphicsLayerAndroid::setName(const String& name)
+{
+ GraphicsLayer::setName(name);
+}
+
+NativeLayer GraphicsLayerAndroid::nativeLayer() const
+{
+ LOG("(%x) nativeLayer", this);
+ return 0;
+}
+
+bool GraphicsLayerAndroid::setChildren(const Vector<GraphicsLayer*>& children)
+{
+ bool childrenChanged = GraphicsLayer::setChildren(children);
+ if (childrenChanged) {
+ m_needsSyncChildren = true;
+ askForSync();
+ }
+
+ return childrenChanged;
+}
+
+void GraphicsLayerAndroid::addChild(GraphicsLayer* childLayer)
+{
+#ifndef NDEBUG
+ const char* n = (static_cast<GraphicsLayerAndroid*>(childLayer))->m_name.latin1().data();
+ LOG("(%x) addChild: %x (%s)", this, childLayer, n);
+#endif
+ GraphicsLayer::addChild(childLayer);
+ m_needsSyncChildren = true;
+ askForSync();
+}
+
+void GraphicsLayerAndroid::addChildAtIndex(GraphicsLayer* childLayer, int index)
+{
+ LOG("(%x) addChild %x AtIndex %d", this, childLayer, index);
+ GraphicsLayer::addChildAtIndex(childLayer, index);
+ m_needsSyncChildren = true;
+ askForSync();
+}
+
+void GraphicsLayerAndroid::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibling)
+{
+ LOG("(%x) addChild %x Below %x", this, childLayer, sibling);
+ GraphicsLayer::addChildBelow(childLayer, sibling);
+ m_needsSyncChildren = true;
+ askForSync();
+}
+
+void GraphicsLayerAndroid::addChildAbove(GraphicsLayer* childLayer, GraphicsLayer* sibling)
+{
+ LOG("(%x) addChild %x Above %x", this, childLayer, sibling);
+ GraphicsLayer::addChildAbove(childLayer, sibling);
+ m_needsSyncChildren = true;
+ askForSync();
+}
+
+bool GraphicsLayerAndroid::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
+{
+ LOG("(%x) replaceChild %x by %x", this, oldChild, newChild);
+ bool ret = GraphicsLayer::replaceChild(oldChild, newChild);
+ m_needsSyncChildren = true;
+ askForSync();
+ return ret;
+}
+
+void GraphicsLayerAndroid::removeFromParent()
+{
+ LOG("(%x) removeFromParent()", this);
+ if (m_parent)
+ static_cast<GraphicsLayerAndroid*>(m_parent)->needsSyncChildren();
+ GraphicsLayer::removeFromParent();
+ m_needsSyncChildren = true;
+ askForSync();
+}
+
+void GraphicsLayerAndroid::needsSyncChildren()
+{
+ m_needsSyncChildren = true;
+ askForSync();
+}
+
+void GraphicsLayerAndroid::setPosition(const FloatPoint& point)
+{
+ m_currentPosition = point;
+ m_needsDisplay = true;
+#ifdef LAYER_DEBUG_2
+ LOG("(%x) setPosition(%.2f,%.2f) pos(%.2f, %.2f) anchor(%.2f,%.2f) size(%.2f, %.2f)",
+ this, point.x(), point.y(), m_currentPosition.x(), m_currentPosition.y(),
+ m_anchorPoint.x(), m_anchorPoint.y(), m_size.width(), m_size.height());
+#endif
+ askForSync();
+}
+
+void GraphicsLayerAndroid::setAnchorPoint(const FloatPoint3D& point)
+{
+ GraphicsLayer::setAnchorPoint(point);
+ m_contentLayer->setAnchorPoint(point);
+ askForSync();
+}
+
+void GraphicsLayerAndroid::setSize(const FloatSize& size)
+{
+ if ((size.width() != m_size.width())
+ || (size.height() != m_size.height())) {
+ MLOG("(%x) setSize (%.2f,%.2f)", this, size.width(), size.height());
+ GraphicsLayer::setSize(size);
+ m_contentLayer->setSize(size);
+ askForSync();
+ }
+}
+
+void GraphicsLayerAndroid::setTransform(const TransformationMatrix& t)
+{
+ TransformationMatrix::DecomposedType tDecomp;
+ t.decompose(tDecomp);
+ LOG("(%x) setTransform, translate (%.2f, %.2f), mpos(%.2f,%.2f)",
+ this, tDecomp.translateX, tDecomp.translateY,
+ m_position.x(), m_position.y());
+
+ if ((m_currentTranslateX != tDecomp.translateX)
+ || (m_currentTranslateY != tDecomp.translateY)) {
+ m_currentTranslateX = tDecomp.translateX;
+ m_currentTranslateY = tDecomp.translateY;
+ m_needsDisplay = true;
+ askForSync();
+ }
+}
+
+void GraphicsLayerAndroid::setChildrenTransform(const TransformationMatrix& t)
+{
+ if (t == m_childrenTransform)
+ return;
+ LOG("(%x) setChildrenTransform", this);
+
+ GraphicsLayer::setChildrenTransform(t);
+ for (unsigned int i = 0; i < m_children.size(); i++) {
+ GraphicsLayer* layer = m_children[i];
+ layer->setTransform(t);
+ if (layer->children().size())
+ layer->setChildrenTransform(t);
+ }
+ askForSync();
+}
+
+void GraphicsLayerAndroid::setMaskLayer(GraphicsLayer* layer)
+{
+ if (layer == m_maskLayer)
+ return;
+
+ GraphicsLayer::setMaskLayer(layer);
+ m_needsSyncMask = true;
+ askForSync();
+}
+
+void GraphicsLayerAndroid::setMasksToBounds(bool masksToBounds)
+{
+ GraphicsLayer::setMasksToBounds(masksToBounds);
+ m_needsSyncMask = true;
+ askForSync();
+}
+
+void GraphicsLayerAndroid::setDrawsContent(bool drawsContent)
+{
+ GraphicsLayer::setDrawsContent(drawsContent);
+ m_contentLayer->setDrawsContent(m_drawsContent);
+
+ if (m_drawsContent) {
+ m_haveContents = true;
+ m_contentLayer->setHaveContents(true);
+ setNeedsDisplay();
+ }
+ askForSync();
+}
+
+void GraphicsLayerAndroid::setBackgroundColor(const Color& color)
+{
+ LOG("(%x) setBackgroundColor", this);
+ GraphicsLayer::setBackgroundColor(color);
+ m_contentLayer->setBackgroundColor(color);
+ m_haveContents = true;
+ askForSync();
+}
+
+void GraphicsLayerAndroid::clearBackgroundColor()
+{
+ LOG("(%x) clearBackgroundColor", this);
+ GraphicsLayer::clearBackgroundColor();
+ askForSync();
+}
+
+void GraphicsLayerAndroid::setContentsOpaque(bool opaque)
+{
+ LOG("(%x) setContentsOpaque (%d)", this, opaque);
+ GraphicsLayer::setContentsOpaque(opaque);
+ m_haveContents = true;
+ m_contentLayer->setHaveContents(true);
+ m_contentLayer->setDrawsContent(true);
+ askForSync();
+}
+
+void GraphicsLayerAndroid::setOpacity(float opacity)
+{
+ LOG("(%x) setOpacity: %.2f", this, opacity);
+ float clampedOpacity = max(0.0f, min(opacity, 1.0f));
+
+ if (clampedOpacity == m_opacity)
+ return;
+
+ MLOG("(%x) setFinalOpacity: %.2f=>%.2f (%.2f)", this,
+ opacity, clampedOpacity, m_opacity);
+ GraphicsLayer::setOpacity(clampedOpacity);
+ askForSync();
+}
+
+bool GraphicsLayerAndroid::repaintAll()
+{
+ LOG("(%x) repaintAll", this);
+ bool ret = false;
+ for (unsigned int i = 0; i < m_children.size(); i++) {
+ GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_children[i]);
+ if (layer && layer->repaintAll())
+ ret = true;
+ }
+ int nbRects = m_invalidatedRects.size();
+
+ for (int i = 0; !gPaused && i < nbRects; i++) {
+ FloatRect rect = m_invalidatedRects[i];
+ if (repaint(rect))
+ ret = true;
+ }
+ if (!gPaused) {
+ m_needsRepaint = false;
+ m_invalidatedRects.clear();
+ }
+ return ret;
+}
+
+void GraphicsLayerAndroid::setNeedsDisplay()
+{
+ LOG("(%x) setNeedsDisplay()", this);
+ FloatRect rect(0, 0, m_size.width(), m_size.height());
+ setNeedsDisplayInRect(rect);
+}
+
+void GraphicsLayerAndroid::setFrame(Frame* f)
+{
+ m_frame = f;
+}
+
+void GraphicsLayerAndroid::sendImmediateRepaint()
+{
+ LOG("(%x) sendImmediateRepaint()", this);
+ GraphicsLayerAndroid* rootGraphicsLayer = this;
+
+ while (rootGraphicsLayer->parent())
+ rootGraphicsLayer = static_cast<GraphicsLayerAndroid*>(rootGraphicsLayer->parent());
+
+ if (rootGraphicsLayer->m_frame
+ && rootGraphicsLayer->m_frame->view()) {
+ LayerAndroid* copyLayer = new LayerAndroid(m_contentLayer.get());
+ TLOG("(%x) sendImmediateRepaint, copy the layer, (%.2f,%.2f => %.2f,%.2f)",
+ this, m_contentLayer->size().width(), m_contentLayer->size().height(),
+ copyLayer->size().width(), copyLayer->size().height());
+ PlatformBridge::setRootLayer(m_frame->view(), (int)copyLayer);
+ PlatformBridge::immediateRepaint(m_frame->view());
+ }
+}
+
+bool GraphicsLayerAndroid::repaint(const FloatRect& rect)
+{
+ LOG("(%x) repaint(%.2f,%.2f,%.2f,%.2f), gPaused(%d) m_needsRepaint(%d) m_haveContents(%d) ",
+ this, rect.x(), rect.y(), rect.width(), rect.height(),
+ gPaused, m_needsRepaint, m_haveContents);
+
+ m_contentLayer->setDrawsContent(true);
+
+ if (!gPaused && m_haveContents && m_needsRepaint) {
+ SkAutoPictureRecord arp(m_contentLayer->recordContext(), m_size.width(), m_size.height());
+ SkCanvas* recordingCanvas = arp.getRecordingCanvas();
+
+ if (!recordingCanvas)
+ return false;
+
+ if ((rect.width() > 0.5) && (rect.height() > 0.5)) {
+ IntRect r((int)rect.x(), (int)rect.y(),
+ (int)rect.width(), (int)rect.height());
+
+ PlatformGraphicsContext pgc(recordingCanvas, 0);
+ GraphicsContext gc(&pgc);
+
+ // with SkPicture, we request the entire layer's content.
+ r.setX(0);
+ r.setY(0);
+ r.setWidth(m_contentLayer->size().width());
+ r.setHeight(m_contentLayer->size().height());
+ paintGraphicsLayerContents(gc, r);
+
+ TLOG("(%x) repaint(%.2f,%.2f,%.2f,%.2f) on (%.2f,%.2f) contentlayer(%.2f,%.2f,%.2f,%.2f)paintGraphicsLayer called!",
+ this, rect.x(), rect.y(), rect.width(),
+ rect.height(), m_size.width(), m_size.height(),
+ m_contentLayer->position().x(),
+ m_contentLayer->position().y(),
+ m_contentLayer->size().width(),
+ m_contentLayer->size().height());
+ }
+ return true;
+ }
+ return false;
+}
+
+void GraphicsLayerAndroid::setNeedsDisplayInRect(const FloatRect& rect)
+{
+ for (unsigned int i = 0; i < m_children.size(); i++) {
+ GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_children[i]);
+ if (layer) {
+ FloatRect childrenRect(m_position.x() + m_translateX + rect.x(),
+ m_position.y() + m_translateY + rect.y(),
+ rect.width(), rect.height());
+ layer->setNeedsDisplayInRect(childrenRect);
+ }
+ }
+ if (!m_haveImage && !drawsContent()) {
+ LOG("(%x) setNeedsDisplay(%.2f,%.2f,%.2f,%.2f) doesn't have content, bypass...",
+ this, rect.x(), rect.y(), rect.width(), rect.height());
+ return;
+ }
+
+ const size_t maxDirtyRects = 8;
+ for (size_t i = 0; i < m_invalidatedRects.size(); ++i) {
+ if (m_invalidatedRects[i].contains(rect))
+ return;
+ }
+
+#ifdef LAYER_DEBUG
+ LOG("(%x) setNeedsDisplayInRect(%d) - (%.2f, %.2f, %.2f, %.2f)", this,
+ m_needsRepaint, rect.x(), rect.y(), rect.width(), rect.height());
+#endif
+
+ if (m_invalidatedRects.size() < maxDirtyRects)
+ m_invalidatedRects.append(rect);
+ else
+ m_invalidatedRects[0].unite(rect);
+
+ m_needsRepaint = true;
+ askForSync();
+}
+
+void GraphicsLayerAndroid::pauseDisplay(bool state)
+{
+ gPaused = state;
+ if (gPaused)
+ gPausedDelay = WTF::currentTime() + 1;
+}
+
+bool GraphicsLayerAndroid::addAnimation(const KeyframeValueList& valueList,
+ const IntSize& boxSize,
+ const Animation* anim,
+ const String& keyframesName,
+ double beginTime)
+{
+ if (!anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2)
+ return false;
+
+ bool createdAnimations = false;
+ if (valueList.property() == AnimatedPropertyWebkitTransform) {
+ createdAnimations = createTransformAnimationsFromKeyframes(valueList,
+ anim,
+ keyframesName,
+ beginTime,
+ boxSize);
+ } else {
+ createdAnimations = createAnimationFromKeyframes(valueList,
+ anim,
+ keyframesName,
+ beginTime);
+ }
+ askForSync();
+ return createdAnimations;
+}
+
+bool GraphicsLayerAndroid::createAnimationFromKeyframes(const KeyframeValueList& valueList,
+ const Animation* animation, const String& keyframesName, double beginTime)
+{
+ bool isKeyframe = valueList.size() > 2;
+ TLOG("createAnimationFromKeyframes(%d), name(%s) beginTime(%.2f)",
+ isKeyframe, keyframesName.latin1().data(), beginTime);
+ // TODO: handles keyframe animations correctly
+
+ switch (valueList.property()) {
+ case AnimatedPropertyInvalid: break;
+ case AnimatedPropertyWebkitTransform: break;
+ case AnimatedPropertyBackgroundColor: break;
+ case AnimatedPropertyOpacity: {
+ MLOG("ANIMATEDPROPERTYOPACITY");
+ const FloatAnimationValue* startVal =
+ static_cast<const FloatAnimationValue*>(valueList.at(0));
+ const FloatAnimationValue* endVal =
+ static_cast<const FloatAnimationValue*>(valueList.at(1));
+ RefPtr<AndroidOpacityAnimation> anim = AndroidOpacityAnimation::create(m_contentLayer.get(),
+ startVal->value(),
+ endVal->value(),
+ animation,
+ beginTime);
+ if (keyframesName.isEmpty())
+ anim->setName(propertyIdToString(valueList.property()));
+ else
+ anim->setName(keyframesName);
+
+ m_contentLayer->addAnimation(anim.release());
+ AndroidAnimationTimer* timer = new AndroidAnimationTimer(this, WTF::currentTime());
+ timer->startOneShot(0);
+ return true;
+ } break;
+ }
+ return false;
+}
+
+bool GraphicsLayerAndroid::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList,
+ const Animation* animation,
+ const String& keyframesName,
+ double beginTime,
+ const IntSize& boxSize)
+{
+ ASSERT(valueList.property() == AnimatedPropertyWebkitTransform);
+ TLOG("createTransformAnimationFromKeyframes, name(%s) beginTime(%.2f)",
+ keyframesName.latin1().data(), beginTime);
+
+ TransformOperationList functionList;
+ bool listsMatch, hasBigRotation;
+ fetchTransformOperationList(valueList, functionList, listsMatch, hasBigRotation);
+
+ // If functionLists don't match we do a matrix animation, otherwise we do a component hardware animation.
+ // Also, we can't do component animation unless we have valueFunction, so we need to do matrix animation
+ // if that's not true as well.
+
+ bool isMatrixAnimation = !listsMatch;
+ size_t numAnimations = isMatrixAnimation ? 1 : functionList.size();
+ bool isKeyframe = valueList.size() > 2;
+
+ float fromTranslateX = 0;
+ float fromTranslateY = 0;
+ float fromTranslateZ = 0;
+ float toTranslateX = 0;
+ float toTranslateY = 0;
+ float toTranslateZ = 0;
+ float fromAngle = 0;
+ float toAngle = 0;
+ float fromScaleX = 1;
+ float fromScaleY = 1;
+ float fromScaleZ = 1;
+ float toScaleX = 1;
+ float toScaleY = 1;
+ float toScaleZ = 1;
+
+ bool doTranslation = false;
+ bool doRotation = false;
+ bool doScaling = false;
+
+ TLOG("(%x) animateTransform, valueList(%d) functionList(%d) duration(%.2f)", this,
+ valueList.size(), functionList.size(), animation->duration());
+
+ for (unsigned int i = 0; i < valueList.size(); i++) {
+ const TransformOperations* operation = ((TransformAnimationValue*)valueList.at(i))->value();
+ Vector<RefPtr<TransformOperation> > ops = operation->operations();
+ TLOG("(%x) animateTransform, dealing with the %d operation, with %d ops", this, i, ops.size());
+ for (unsigned int j = 0; j < ops.size(); j++) {
+ TransformOperation* op = ops[j].get();
+ TLOG("(%x) animateTransform, dealing with the %d:%d operation, current op: %d (translate is %d, rotate %d, scale %d)",
+ this, i, j, op->getOperationType(), TransformOperation::TRANSLATE, TransformOperation::ROTATE, TransformOperation::SCALE);
+ if (op->getOperationType() == TransformOperation::TRANSLATE) {
+ TranslateTransformOperation* translateOperation = (TranslateTransformOperation*) op;
+ IntSize bounds(m_size.width(), m_size.height());
+ float x = translateOperation->x(bounds);
+ float y = translateOperation->y(bounds);
+ float z = translateOperation->z(bounds);
+ if (!i) {
+ fromTranslateX = x;
+ fromTranslateY = y;
+ fromTranslateZ = z;
+ } else {
+ toTranslateX = x;
+ toTranslateY = y;
+ toTranslateZ = z;
+ }
+ TLOG("(%x) animateTransform, the %d operation is a translation(%.2f,%.2f,%.2f)",
+ this, j, x, y, z);
+ doTranslation = true;
+ } else if (op->getOperationType() == TransformOperation::TRANSLATE_X) {
+ TranslateTransformOperation* translateOperation = (TranslateTransformOperation*) op;
+ IntSize bounds(m_size.width(), m_size.height());
+ float x = translateOperation->x(bounds);
+ if (!i)
+ fromTranslateX = x;
+ else
+ toTranslateX = x;
+ TLOG("(%x) animateTransform, the %d operation is a translation_x(%.2f)",
+ this, j, x);
+ doTranslation = true;
+ } else if (op->getOperationType() == TransformOperation::TRANSLATE_Y) {
+ TranslateTransformOperation* translateOperation = (TranslateTransformOperation*) op;
+ IntSize bounds(m_size.width(), m_size.height());
+ float y = translateOperation->y(bounds);
+ if (!i)
+ fromTranslateY = y;
+ else
+ toTranslateY = y;
+ TLOG("(%x) animateTransform, the %d operation is a translation_y(%.2f)",
+ this, j, y);
+ doTranslation = true;
+ } else if ((op->getOperationType() == TransformOperation::ROTATE)
+ || (op->getOperationType() == TransformOperation::ROTATE_X)
+ || (op->getOperationType() == TransformOperation::ROTATE_Y)) {
+ LOG("(%x) animateTransform, the %d operation is a rotation", this, j);
+ RotateTransformOperation* rotateOperation = (RotateTransformOperation*) op;
+ float angle = rotateOperation->angle();
+ TLOG("(%x) animateTransform, the %d operation is a rotation (%d), of angle %.2f",
+ this, j, op->getOperationType(), angle);
+
+ if (!i)
+ fromAngle = angle;
+ else
+ toAngle = angle;
+ doRotation = true;
+ } else if (op->getOperationType() == TransformOperation::SCALE_X) {
+ ScaleTransformOperation* scaleOperation = (ScaleTransformOperation*) op;
+ if (!i)
+ fromScaleX = scaleOperation->x();
+ else
+ toScaleX = scaleOperation->x();
+ doScaling = true;
+ } else if (op->getOperationType() == TransformOperation::SCALE_Y) {
+ ScaleTransformOperation* scaleOperation = (ScaleTransformOperation*) op;
+ if (!i)
+ fromScaleY = scaleOperation->y();
+ else
+ toScaleY = scaleOperation->y();
+ doScaling = true;
+ } else if (op->getOperationType() == TransformOperation::SCALE_Z) {
+ ScaleTransformOperation* scaleOperation = (ScaleTransformOperation*) op;
+ if (!i)
+ fromScaleZ = scaleOperation->z();
+ else
+ toScaleZ = scaleOperation->z();
+ doScaling = true;
+ } else if (op->getOperationType() == TransformOperation::SCALE) {
+ ScaleTransformOperation* scaleOperation = (ScaleTransformOperation*) op;
+ if (!i) {
+ fromScaleX = scaleOperation->x();
+ fromScaleY = scaleOperation->y();
+ fromScaleZ = scaleOperation->z();
+ } else {
+ toScaleX = scaleOperation->x();
+ toScaleY = scaleOperation->y();
+ toScaleZ = scaleOperation->z();
+ }
+ doScaling = true;
+ } else {
+ TLOG("(%x) animateTransform, the %d operation is not a rotation (%d)",
+ this, j, op->getOperationType());
+ }
+ }
+ }
+
+ RefPtr<AndroidTransformAnimation> anim = AndroidTransformAnimation::create(m_contentLayer.get(),
+ animation, beginTime);
+
+ if (keyframesName.isEmpty())
+ anim->setName(propertyIdToString(valueList.property()));
+ else
+ anim->setName(keyframesName);
+
+ anim->setOriginalPosition(m_position);
+
+ if (doTranslation)
+ anim->setTranslation(fromTranslateX, fromTranslateY, fromTranslateZ,
+ toTranslateX, toTranslateY, toTranslateZ);
+ if (doRotation)
+ anim->setRotation(fromAngle, toAngle);
+ if (doScaling)
+ anim->setScale(fromScaleX, fromScaleY, fromScaleZ,
+ toScaleX, toScaleY, toScaleZ);
+ m_contentLayer->addAnimation(anim.release());
+
+ AndroidAnimationTimer* timer = new AndroidAnimationTimer(this, WTF::currentTime());
+ timer->startOneShot(0);
+ return true;
+}
+
+void GraphicsLayerAndroid::removeAnimationsForProperty(AnimatedPropertyID anID)
+{
+ TLOG("NRO removeAnimationsForProperty(%d)", anID);
+ m_contentLayer->removeAnimation(propertyIdToString(anID));
+ askForSync();
+}
+
+void GraphicsLayerAndroid::removeAnimationsForKeyframes(const String& keyframesName)
+{
+ TLOG("NRO removeAnimationsForKeyframes(%s)", keyframesName.latin1().data());
+ m_contentLayer->removeAnimation(keyframesName);
+ askForSync();
+}
+
+void GraphicsLayerAndroid::pauseAnimation(const String& keyframesName)
+{
+ TLOG("NRO pauseAnimation(%s)", keyframesName.latin1().data());
+}
+
+void GraphicsLayerAndroid::suspendAnimations(double time)
+{
+ TLOG("NRO suspendAnimations(%.2f)", time);
+}
+
+void GraphicsLayerAndroid::resumeAnimations()
+{
+ TLOG("NRO resumeAnimations()");
+}
+
+void GraphicsLayerAndroid::setContentsToImage(Image* image)
+{
+ TLOG("(%x) setContentsToImage", this, image);
+ if (image) {
+ m_haveContents = true;
+ m_contentLayer->setHaveContents(true);
+ m_contentLayer->setDrawsContent(true);
+ m_contentLayer->setHaveImage(true);
+ if (!m_haveImage) {
+ m_haveImage = true;
+ setNeedsDisplay();
+ askForSync();
+ }
+ } else
+ m_contentLayer->setHaveImage(false);
+}
+
+PlatformLayer* GraphicsLayerAndroid::platformLayer() const
+{
+ LOG("platformLayer");
+ return (PlatformLayer*) m_contentLayer.get();
+}
+
+#ifndef NDEBUG
+void GraphicsLayerAndroid::setDebugBackgroundColor(const Color& color)
+{
+}
+
+void GraphicsLayerAndroid::setDebugBorder(const Color& color, float borderWidth)
+{
+}
+#endif
+
+void GraphicsLayerAndroid::setZPosition(float position)
+{
+ LOG("(%x) setZPosition: %.2f", this, position);
+ GraphicsLayer::setZPosition(position);
+ askForSync();
+}
+
+void GraphicsLayerAndroid::askForSync()
+{
+ if (m_client)
+ m_client->notifySyncRequired(this);
+}
+
+void GraphicsLayerAndroid::syncChildren()
+{
+ if (m_needsSyncChildren) {
+ m_contentLayer->removeAllChildren();
+ for (unsigned int i = 0; i < m_children.size(); i++) {
+ m_contentLayer->addChildren(
+ (static_cast<GraphicsLayerAndroid*>(m_children[i]))->contentLayer());
+ }
+ m_needsSyncChildren = false;
+ }
+}
+
+void GraphicsLayerAndroid::syncMask()
+{
+ if (m_needsSyncMask) {
+ if (m_maskLayer) {
+ GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_maskLayer);
+ LayerAndroid* mask = reinterpret_cast<LayerAndroid*>(layer->platformLayer());
+ m_contentLayer->setMaskLayer(mask);
+ } else
+ m_contentLayer->setMaskLayer(0);
+
+ m_contentLayer->setMasksToBounds(m_masksToBounds);
+ m_needsSyncMask = false;
+ }
+}
+
+void GraphicsLayerAndroid::syncPositionState()
+{
+ if (m_needsDisplay) {
+ m_translateX = m_currentTranslateX;
+ m_translateY = m_currentTranslateY;
+ m_position = m_currentPosition;
+ FloatPoint translation(m_currentTranslateX, m_currentTranslateY);
+ m_contentLayer->setTranslation(translation);
+ m_contentLayer->setPosition(m_currentPosition);
+ m_needsDisplay = false;
+ }
+}
+
+void GraphicsLayerAndroid::syncCompositingState()
+{
+ for (unsigned int i = 0; i < m_children.size(); i++) {
+ GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_children[i]);
+ layer->syncCompositingState();
+ }
+
+ syncChildren();
+ syncMask();
+ syncPositionState();
+
+ if (!gPaused || WTF::currentTime() >= gPausedDelay)
+ repaintAll();
+}
+
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)