diff options
Diffstat (limited to 'WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp')
-rw-r--r-- | WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp | 852 |
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) |