2 * Copyright (C) 2009 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "GraphicsLayerAndroid.h"
20 #if USE(ACCELERATED_COMPOSITING)
22 #include "AndroidAnimation.h"
23 #include "Animation.h"
24 #include "FloatRect.h"
25 #include "GraphicsContext.h"
29 #include "PlatformBridge.h"
30 #include "PlatformGraphicsContext.h"
31 #include "RenderLayerBacking.h"
32 #include "RenderView.h"
33 #include "RotateTransformOperation.h"
34 #include "ScaleTransformOperation.h"
36 #include "TransformationMatrix.h"
37 #include "TranslateTransformOperation.h"
39 #include <cutils/log.h>
40 #include <wtf/CurrentTime.h>
41 #include <wtf/text/CString.h>
44 #define LOG(...) android_printLog(ANDROID_LOG_DEBUG, "GraphicsLayer", __VA_ARGS__)
45 #define MLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GraphicsLayer", __VA_ARGS__)
46 #define TLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GraphicsLayer", __VA_ARGS__)
59 static double gPausedDelay;
63 static int gDebugGraphicsLayerAndroidInstances = 0;
64 inline int GraphicsLayerAndroid::instancesCount()
66 return gDebugGraphicsLayerAndroidInstances;
69 static String propertyIdToString(AnimatedPropertyID property)
72 case AnimatedPropertyWebkitTransform:
74 case AnimatedPropertyOpacity:
76 case AnimatedPropertyBackgroundColor:
77 return "backgroundColor";
78 case AnimatedPropertyInvalid:
85 GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayer::compositingCoordinatesOrientation()
87 return CompositingCoordinatesBottomUp;
90 PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
92 return new GraphicsLayerAndroid(client);
95 SkLength convertLength(Length l) {
97 length.type = SkLength::Undefined;
99 if (l.type() == WebCore::Percent) {
100 length.type = SkLength::Percent;
101 length.value = l.percent();
102 } if (l.type() == WebCore::Fixed) {
103 length.type = SkLength::Fixed;
104 length.value = l.value();
109 GraphicsLayerAndroid::GraphicsLayerAndroid(GraphicsLayerClient* client) :
110 GraphicsLayer(client),
111 m_needsSyncChildren(false),
112 m_needsSyncMask(false),
113 m_needsRepaint(false),
114 m_needsDisplay(false),
115 m_needsNotifyClient(false),
116 m_haveContents(false),
120 m_currentTranslateX(0),
121 m_currentTranslateY(0),
122 m_currentPosition(0, 0)
124 m_contentLayer = new LayerAndroid(true);
126 RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_client);
127 RenderLayer* renderLayer = backing->owningLayer();
128 m_contentLayer->setIsRootLayer(renderLayer->isRootLayer());
130 gDebugGraphicsLayerAndroidInstances++;
133 GraphicsLayerAndroid::~GraphicsLayerAndroid()
135 m_contentLayer->unref();
136 gDebugGraphicsLayerAndroidInstances--;
139 void GraphicsLayerAndroid::setName(const String& name)
141 GraphicsLayer::setName(name);
144 NativeLayer GraphicsLayerAndroid::nativeLayer() const
146 LOG("(%x) nativeLayer", this);
150 bool GraphicsLayerAndroid::setChildren(const Vector<GraphicsLayer*>& children)
152 bool childrenChanged = GraphicsLayer::setChildren(children);
153 if (childrenChanged) {
154 m_needsSyncChildren = true;
158 return childrenChanged;
161 void GraphicsLayerAndroid::addChild(GraphicsLayer* childLayer)
164 const char* n = (static_cast<GraphicsLayerAndroid*>(childLayer))->m_name.latin1().data();
165 LOG("(%x) addChild: %x (%s)", this, childLayer, n);
167 GraphicsLayer::addChild(childLayer);
168 m_needsSyncChildren = true;
172 void GraphicsLayerAndroid::addChildAtIndex(GraphicsLayer* childLayer, int index)
174 LOG("(%x) addChild %x AtIndex %d", this, childLayer, index);
175 GraphicsLayer::addChildAtIndex(childLayer, index);
176 m_needsSyncChildren = true;
180 void GraphicsLayerAndroid::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibling)
182 LOG("(%x) addChild %x Below %x", this, childLayer, sibling);
183 GraphicsLayer::addChildBelow(childLayer, sibling);
184 m_needsSyncChildren = true;
188 void GraphicsLayerAndroid::addChildAbove(GraphicsLayer* childLayer, GraphicsLayer* sibling)
190 LOG("(%x) addChild %x Above %x", this, childLayer, sibling);
191 GraphicsLayer::addChildAbove(childLayer, sibling);
192 m_needsSyncChildren = true;
196 bool GraphicsLayerAndroid::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
198 LOG("(%x) replaceChild %x by %x", this, oldChild, newChild);
199 bool ret = GraphicsLayer::replaceChild(oldChild, newChild);
200 m_needsSyncChildren = true;
205 void GraphicsLayerAndroid::removeFromParent()
207 LOG("(%x) removeFromParent()", this);
209 static_cast<GraphicsLayerAndroid*>(m_parent)->needsSyncChildren();
210 GraphicsLayer::removeFromParent();
211 m_needsSyncChildren = true;
215 void GraphicsLayerAndroid::needsSyncChildren()
217 m_needsSyncChildren = true;
221 void GraphicsLayerAndroid::updateFixedPosition()
226 RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_client);
227 RenderLayer* renderLayer = backing->owningLayer();
228 RenderView* view = static_cast<RenderView*>(renderLayer->renderer());
230 // If we are a fixed position layer, just set it
231 if (view->isPositioned() && view->style()->position() == FixedPosition) {
232 // We need to get the passed CSS properties for the element
233 SkLength left, top, right, bottom;
234 left = convertLength(view->style()->left());
235 top = convertLength(view->style()->top());
236 right = convertLength(view->style()->right());
237 bottom = convertLength(view->style()->bottom());
239 // We also need to get the margin...
240 SkLength marginLeft, marginTop, marginRight, marginBottom;
241 marginLeft = convertLength(view->style()->marginLeft());
242 marginTop = convertLength(view->style()->marginTop());
243 marginRight = convertLength(view->style()->marginRight());
244 marginBottom = convertLength(view->style()->marginBottom());
246 // The layer can be bigger than the element we want to draw;
247 // not only that, the layout rect of the element might also be
248 // different from the visible rect of that element (i.e. the element
249 // has a CSS shadow property -- the shadow is "outside" the element).
251 // 1/ get the size of the element (w,h), using the layoutOverflow rect
252 // 2/ pass the current offset of the painting relative to the layer
253 int w = view->rightLayoutOverflow() - view->leftLayoutOverflow();
254 int h = view->bottomLayoutOverflow() - view->topLayoutOverflow();
255 int paintingOffsetX = - offsetFromRenderer().width();
256 int paintingOffsetY = - offsetFromRenderer().height();
259 viewRect.set(paintingOffsetX, paintingOffsetY, paintingOffsetX + w, paintingOffsetY + h);
261 m_contentLayer->setFixedPosition(left, top, right, bottom,
262 marginLeft, marginTop,
263 marginRight, marginBottom,
268 void GraphicsLayerAndroid::setPosition(const FloatPoint& point)
270 m_currentPosition = point;
271 m_needsDisplay = true;
273 LOG("(%x) setPosition(%.2f,%.2f) pos(%.2f, %.2f) anchor(%.2f,%.2f) size(%.2f, %.2f)",
274 this, point.x(), point.y(), m_currentPosition.x(), m_currentPosition.y(),
275 m_anchorPoint.x(), m_anchorPoint.y(), m_size.width(), m_size.height());
277 updateFixedPosition();
281 void GraphicsLayerAndroid::setAnchorPoint(const FloatPoint3D& point)
283 GraphicsLayer::setAnchorPoint(point);
284 m_contentLayer->setAnchorPoint(point.x(), point.y());
288 void GraphicsLayerAndroid::setSize(const FloatSize& size)
290 if ((size.width() != m_size.width())
291 || (size.height() != m_size.height())) {
292 MLOG("(%x) setSize (%.2f,%.2f)", this, size.width(), size.height());
293 GraphicsLayer::setSize(size);
294 m_contentLayer->setSize(size.width(), size.height());
295 updateFixedPosition();
300 void GraphicsLayerAndroid::setTransform(const TransformationMatrix& t)
302 TransformationMatrix::DecomposedType tDecomp;
303 t.decompose(tDecomp);
304 LOG("(%x) setTransform, translate (%.2f, %.2f), mpos(%.2f,%.2f)",
305 this, tDecomp.translateX, tDecomp.translateY,
306 m_position.x(), m_position.y());
308 if ((m_currentTranslateX != tDecomp.translateX)
309 || (m_currentTranslateY != tDecomp.translateY)) {
310 m_currentTranslateX = tDecomp.translateX;
311 m_currentTranslateY = tDecomp.translateY;
312 m_needsDisplay = true;
317 void GraphicsLayerAndroid::setChildrenTransform(const TransformationMatrix& t)
319 if (t == m_childrenTransform)
321 LOG("(%x) setChildrenTransform", this);
323 GraphicsLayer::setChildrenTransform(t);
324 for (unsigned int i = 0; i < m_children.size(); i++) {
325 GraphicsLayer* layer = m_children[i];
326 layer->setTransform(t);
327 if (layer->children().size())
328 layer->setChildrenTransform(t);
333 void GraphicsLayerAndroid::setMaskLayer(GraphicsLayer* layer)
335 if (layer == m_maskLayer)
338 GraphicsLayer::setMaskLayer(layer);
339 m_needsSyncMask = true;
343 void GraphicsLayerAndroid::setMasksToBounds(bool masksToBounds)
345 GraphicsLayer::setMasksToBounds(masksToBounds);
346 m_needsSyncMask = true;
350 void GraphicsLayerAndroid::setDrawsContent(bool drawsContent)
352 GraphicsLayer::setDrawsContent(drawsContent);
354 if (m_drawsContent) {
355 m_haveContents = true;
361 void GraphicsLayerAndroid::setBackgroundColor(const Color& color)
363 LOG("(%x) setBackgroundColor", this);
364 GraphicsLayer::setBackgroundColor(color);
365 SkColor c = SkColorSetARGB(color.alpha(), color.red(), color.green(), color.blue());
366 m_contentLayer->setBackgroundColor(c);
367 m_haveContents = true;
371 void GraphicsLayerAndroid::clearBackgroundColor()
373 LOG("(%x) clearBackgroundColor", this);
374 GraphicsLayer::clearBackgroundColor();
378 void GraphicsLayerAndroid::setContentsOpaque(bool opaque)
380 LOG("(%x) setContentsOpaque (%d)", this, opaque);
381 GraphicsLayer::setContentsOpaque(opaque);
382 m_haveContents = true;
386 void GraphicsLayerAndroid::setOpacity(float opacity)
388 LOG("(%x) setOpacity: %.2f", this, opacity);
389 float clampedOpacity = max(0.0f, min(opacity, 1.0f));
391 if (clampedOpacity == m_opacity)
394 MLOG("(%x) setFinalOpacity: %.2f=>%.2f (%.2f)", this,
395 opacity, clampedOpacity, m_opacity);
396 GraphicsLayer::setOpacity(clampedOpacity);
397 m_contentLayer->setOpacity(clampedOpacity);
401 bool GraphicsLayerAndroid::repaintAll()
403 LOG("(%x) repaintAll", this);
405 for (unsigned int i = 0; i < m_children.size(); i++) {
406 GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_children[i]);
407 if (layer && layer->repaintAll())
410 int nbRects = m_invalidatedRects.size();
412 for (int i = 0; !gPaused && i < nbRects; i++) {
413 FloatRect rect = m_invalidatedRects[i];
418 m_needsRepaint = false;
419 m_invalidatedRects.clear();
424 void GraphicsLayerAndroid::setNeedsDisplay()
426 LOG("(%x) setNeedsDisplay()", this);
427 FloatRect rect(0, 0, m_size.width(), m_size.height());
428 setNeedsDisplayInRect(rect);
431 void GraphicsLayerAndroid::setFrame(Frame* f)
436 void GraphicsLayerAndroid::sendImmediateRepaint()
438 LOG("(%x) sendImmediateRepaint()", this);
439 GraphicsLayerAndroid* rootGraphicsLayer = this;
441 while (rootGraphicsLayer->parent())
442 rootGraphicsLayer = static_cast<GraphicsLayerAndroid*>(rootGraphicsLayer->parent());
444 if (rootGraphicsLayer->m_frame
445 && rootGraphicsLayer->m_frame->view()) {
446 LayerAndroid* rootLayer = new LayerAndroid(true);
447 LayerAndroid* copyLayer = new LayerAndroid(*m_contentLayer);
448 rootLayer->addChild(copyLayer);
450 TLOG("(%x) sendImmediateRepaint, copy the layer, (%.2f,%.2f => %.2f,%.2f)",
451 this, m_contentLayer->getSize().width(), m_contentLayer->getSize().height(),
452 copyLayer->getSize().width(), copyLayer->getSize().height());
453 PlatformBridge::setUIRootLayer(m_frame->view(), rootLayer);
454 PlatformBridge::immediateRepaint(m_frame->view());
458 bool GraphicsLayerAndroid::repaint(const FloatRect& rect)
460 LOG("(%x) repaint(%.2f,%.2f,%.2f,%.2f), gPaused(%d) m_needsRepaint(%d) m_haveContents(%d) ",
461 this, rect.x(), rect.y(), rect.width(), rect.height(),
462 gPaused, m_needsRepaint, m_haveContents);
464 if (!gPaused && m_haveContents && m_needsRepaint && !m_haveImage) {
465 SkAutoPictureRecord arp(m_contentLayer->recordContext(), m_size.width(), m_size.height());
466 SkCanvas* recordingCanvas = arp.getRecordingCanvas();
468 if (!recordingCanvas)
471 if ((rect.width() > 0.5) && (rect.height() > 0.5)) {
472 IntRect r((int)rect.x(), (int)rect.y(),
473 (int)rect.width(), (int)rect.height());
475 PlatformGraphicsContext pgc(recordingCanvas, 0);
476 GraphicsContext gc(&pgc);
478 // with SkPicture, we request the entire layer's content.
481 r.setWidth(m_contentLayer->getWidth());
482 r.setHeight(m_contentLayer->getHeight());
483 paintGraphicsLayerContents(gc, r);
485 TLOG("(%x) repaint(%.2f,%.2f,%.2f,%.2f) on (%.2f,%.2f) contentlayer(%.2f,%.2f,%.2f,%.2f)paintGraphicsLayer called!",
486 this, rect.x(), rect.y(), rect.width(),
487 rect.height(), m_size.width(), m_size.height(),
488 m_contentLayer->getPosition().fX,
489 m_contentLayer->getPosition().fY,
490 m_contentLayer->getSize().width(),
491 m_contentLayer->getSize().height());
498 void GraphicsLayerAndroid::setNeedsDisplayInRect(const FloatRect& rect)
500 for (unsigned int i = 0; i < m_children.size(); i++) {
501 GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_children[i]);
503 FloatRect childrenRect(m_position.x() + m_translateX + rect.x(),
504 m_position.y() + m_translateY + rect.y(),
505 rect.width(), rect.height());
506 layer->setNeedsDisplayInRect(childrenRect);
509 if (!m_haveImage && !drawsContent()) {
510 LOG("(%x) setNeedsDisplay(%.2f,%.2f,%.2f,%.2f) doesn't have content, bypass...",
511 this, rect.x(), rect.y(), rect.width(), rect.height());
515 const size_t maxDirtyRects = 8;
516 for (size_t i = 0; i < m_invalidatedRects.size(); ++i) {
517 if (m_invalidatedRects[i].contains(rect))
522 LOG("(%x) setNeedsDisplayInRect(%d) - (%.2f, %.2f, %.2f, %.2f)", this,
523 m_needsRepaint, rect.x(), rect.y(), rect.width(), rect.height());
526 if (m_invalidatedRects.size() < maxDirtyRects)
527 m_invalidatedRects.append(rect);
529 m_invalidatedRects[0].unite(rect);
531 m_needsRepaint = true;
535 void GraphicsLayerAndroid::pauseDisplay(bool state)
539 gPausedDelay = WTF::currentTime() + 1;
542 bool GraphicsLayerAndroid::addAnimation(const KeyframeValueList& valueList,
543 const IntSize& boxSize,
544 const Animation* anim,
545 const String& keyframesName,
548 if (!anim || anim->isEmptyOrZeroDuration() || valueList.size() != 2)
551 bool createdAnimations = false;
552 if (valueList.property() == AnimatedPropertyWebkitTransform) {
553 createdAnimations = createTransformAnimationsFromKeyframes(valueList,
559 createdAnimations = createAnimationFromKeyframes(valueList,
565 return createdAnimations;
568 bool GraphicsLayerAndroid::createAnimationFromKeyframes(const KeyframeValueList& valueList,
569 const Animation* animation, const String& keyframesName, double beginTime)
571 bool isKeyframe = valueList.size() > 2;
572 TLOG("createAnimationFromKeyframes(%d), name(%s) beginTime(%.2f)",
573 isKeyframe, keyframesName.latin1().data(), beginTime);
574 // TODO: handles keyframe animations correctly
576 switch (valueList.property()) {
577 case AnimatedPropertyInvalid: break;
578 case AnimatedPropertyWebkitTransform: break;
579 case AnimatedPropertyBackgroundColor: break;
580 case AnimatedPropertyOpacity: {
581 MLOG("ANIMATEDPROPERTYOPACITY");
582 const FloatAnimationValue* startVal =
583 static_cast<const FloatAnimationValue*>(valueList.at(0));
584 const FloatAnimationValue* endVal =
585 static_cast<const FloatAnimationValue*>(valueList.at(1));
586 RefPtr<AndroidOpacityAnimation> anim = AndroidOpacityAnimation::create(startVal->value(),
590 if (keyframesName.isEmpty())
591 anim->setName(propertyIdToString(valueList.property()));
593 anim->setName(keyframesName);
595 m_contentLayer->addAnimation(anim.release());
603 void GraphicsLayerAndroid::needsNotifyClient()
605 m_needsNotifyClient = true;
609 bool GraphicsLayerAndroid::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList,
610 const Animation* animation,
611 const String& keyframesName,
613 const IntSize& boxSize)
615 ASSERT(valueList.property() == AnimatedPropertyWebkitTransform);
616 TLOG("createTransformAnimationFromKeyframes, name(%s) beginTime(%.2f)",
617 keyframesName.latin1().data(), beginTime);
619 TransformOperationList functionList;
620 bool listsMatch, hasBigRotation;
621 fetchTransformOperationList(valueList, functionList, listsMatch, hasBigRotation);
623 // If functionLists don't match we do a matrix animation, otherwise we do a component hardware animation.
624 // Also, we can't do component animation unless we have valueFunction, so we need to do matrix animation
625 // if that's not true as well.
627 bool isMatrixAnimation = !listsMatch;
628 size_t numAnimations = isMatrixAnimation ? 1 : functionList.size();
629 bool isKeyframe = valueList.size() > 2;
631 float fromTranslateX = 0;
632 float fromTranslateY = 0;
633 float fromTranslateZ = 0;
634 float toTranslateX = 0;
635 float toTranslateY = 0;
636 float toTranslateZ = 0;
639 float fromScaleX = 1;
640 float fromScaleY = 1;
641 float fromScaleZ = 1;
646 bool doTranslation = false;
647 bool doRotation = false;
648 bool doScaling = false;
650 TLOG("(%x) animateTransform, valueList(%d) functionList(%d) duration(%.2f)", this,
651 valueList.size(), functionList.size(), animation->duration());
653 // FIXME: add support for the translate 3d operations (when
654 // we'll have an OpenGL backend)
656 for (unsigned int i = 0; i < valueList.size(); i++) {
657 const TransformOperations* operation = ((TransformAnimationValue*)valueList.at(i))->value();
658 Vector<RefPtr<TransformOperation> > ops = operation->operations();
659 TLOG("(%x) animateTransform, dealing with the %d operation, with %d ops", this, i, ops.size());
660 for (unsigned int j = 0; j < ops.size(); j++) {
661 TransformOperation* op = ops[j].get();
662 TLOG("(%x) animateTransform, dealing with the %d:%d operation, current op: %d (translate is %d, rotate %d, scale %d)",
663 this, i, j, op->getOperationType(), TransformOperation::TRANSLATE, TransformOperation::ROTATE, TransformOperation::SCALE);
664 if ((op->getOperationType() == TransformOperation::TRANSLATE) ||
665 (op->getOperationType() == TransformOperation::TRANSLATE_3D)) {
666 TranslateTransformOperation* translateOperation = (TranslateTransformOperation*) op;
667 IntSize bounds(m_size.width(), m_size.height());
668 float x = translateOperation->x(bounds);
669 float y = translateOperation->y(bounds);
670 float z = translateOperation->z(bounds);
680 TLOG("(%x) animateTransform, the %d operation is a translation(%.2f,%.2f,%.2f)",
682 doTranslation = true;
683 } else if (op->getOperationType() == TransformOperation::TRANSLATE_X) {
684 TranslateTransformOperation* translateOperation = (TranslateTransformOperation*) op;
685 IntSize bounds(m_size.width(), m_size.height());
686 float x = translateOperation->x(bounds);
691 TLOG("(%x) animateTransform, the %d operation is a translation_x(%.2f)",
693 doTranslation = true;
694 } else if (op->getOperationType() == TransformOperation::TRANSLATE_Y) {
695 TranslateTransformOperation* translateOperation = (TranslateTransformOperation*) op;
696 IntSize bounds(m_size.width(), m_size.height());
697 float y = translateOperation->y(bounds);
702 TLOG("(%x) animateTransform, the %d operation is a translation_y(%.2f)",
704 doTranslation = true;
705 } else if (op->getOperationType() == TransformOperation::TRANSLATE_Z) {
706 TranslateTransformOperation* translateOperation = (TranslateTransformOperation*) op;
707 IntSize bounds(m_size.width(), m_size.height());
708 float z = translateOperation->z(bounds);
713 TLOG("(%x) animateTransform, the %d operation is a translation_z(%.2f)",
715 doTranslation = true;
716 } else if ((op->getOperationType() == TransformOperation::ROTATE)
717 || (op->getOperationType() == TransformOperation::ROTATE_X)
718 || (op->getOperationType() == TransformOperation::ROTATE_Y)) {
719 LOG("(%x) animateTransform, the %d operation is a rotation", this, j);
720 RotateTransformOperation* rotateOperation = (RotateTransformOperation*) op;
721 float angle = rotateOperation->angle();
722 TLOG("(%x) animateTransform, the %d operation is a rotation (%d), of angle %.2f",
723 this, j, op->getOperationType(), angle);
730 } else if (op->getOperationType() == TransformOperation::SCALE_X) {
731 ScaleTransformOperation* scaleOperation = (ScaleTransformOperation*) op;
733 fromScaleX = scaleOperation->x();
735 toScaleX = scaleOperation->x();
737 } else if (op->getOperationType() == TransformOperation::SCALE_Y) {
738 ScaleTransformOperation* scaleOperation = (ScaleTransformOperation*) op;
740 fromScaleY = scaleOperation->y();
742 toScaleY = scaleOperation->y();
744 } else if (op->getOperationType() == TransformOperation::SCALE_Z) {
745 ScaleTransformOperation* scaleOperation = (ScaleTransformOperation*) op;
747 fromScaleZ = scaleOperation->z();
749 toScaleZ = scaleOperation->z();
751 } else if (op->getOperationType() == TransformOperation::SCALE) {
752 ScaleTransformOperation* scaleOperation = (ScaleTransformOperation*) op;
754 fromScaleX = scaleOperation->x();
755 fromScaleY = scaleOperation->y();
756 fromScaleZ = scaleOperation->z();
758 toScaleX = scaleOperation->x();
759 toScaleY = scaleOperation->y();
760 toScaleZ = scaleOperation->z();
764 TLOG("(%x) animateTransform, the %d operation is not a rotation (%d)",
765 this, j, op->getOperationType());
770 RefPtr<AndroidTransformAnimation> anim = AndroidTransformAnimation::create(animation, beginTime);
772 if (keyframesName.isEmpty())
773 anim->setName(propertyIdToString(valueList.property()));
775 anim->setName(keyframesName);
777 anim->setOriginalPosition(m_position);
780 anim->setTranslation(fromTranslateX, fromTranslateY, fromTranslateZ,
781 toTranslateX, toTranslateY, toTranslateZ);
783 anim->setRotation(fromAngle, toAngle);
785 anim->setScale(fromScaleX, fromScaleY, fromScaleZ,
786 toScaleX, toScaleY, toScaleZ);
787 m_contentLayer->addAnimation(anim.release());
793 void GraphicsLayerAndroid::removeAnimationsForProperty(AnimatedPropertyID anID)
795 TLOG("NRO removeAnimationsForProperty(%d)", anID);
796 m_contentLayer->removeAnimation(propertyIdToString(anID));
800 void GraphicsLayerAndroid::removeAnimationsForKeyframes(const String& keyframesName)
802 TLOG("NRO removeAnimationsForKeyframes(%s)", keyframesName.latin1().data());
803 m_contentLayer->removeAnimation(keyframesName);
807 void GraphicsLayerAndroid::pauseAnimation(const String& keyframesName)
809 TLOG("NRO pauseAnimation(%s)", keyframesName.latin1().data());
812 void GraphicsLayerAndroid::suspendAnimations(double time)
814 TLOG("NRO suspendAnimations(%.2f)", time);
817 void GraphicsLayerAndroid::resumeAnimations()
819 TLOG("NRO resumeAnimations()");
822 void GraphicsLayerAndroid::setContentsToImage(Image* image)
824 TLOG("(%x) setContentsToImage", this, image);
826 m_haveContents = true;
828 m_contentLayer->setContentsImage(image->nativeImageForCurrentFrame());
834 PlatformLayer* GraphicsLayerAndroid::platformLayer() const
836 LOG("platformLayer");
837 return (PlatformLayer*) m_contentLayer;
841 void GraphicsLayerAndroid::setDebugBackgroundColor(const Color& color)
845 void GraphicsLayerAndroid::setDebugBorder(const Color& color, float borderWidth)
850 void GraphicsLayerAndroid::setZPosition(float position)
852 LOG("(%x) setZPosition: %.2f", this, position);
853 GraphicsLayer::setZPosition(position);
857 void GraphicsLayerAndroid::askForSync()
860 m_client->notifySyncRequired(this);
863 void GraphicsLayerAndroid::syncChildren()
865 if (m_needsSyncChildren) {
866 m_contentLayer->removeChildren();
867 for (unsigned int i = 0; i < m_children.size(); i++) {
868 m_contentLayer->addChild(
869 (static_cast<GraphicsLayerAndroid*>(m_children[i]))->contentLayer());
871 m_needsSyncChildren = false;
875 void GraphicsLayerAndroid::syncMask()
877 if (m_needsSyncMask) {
879 GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_maskLayer);
880 LayerAndroid* mask = reinterpret_cast<LayerAndroid*>(layer->platformLayer());
881 m_contentLayer->setMaskLayer(mask);
883 m_contentLayer->setMaskLayer(0);
885 m_contentLayer->setMasksToBounds(m_masksToBounds);
886 m_needsSyncMask = false;
890 void GraphicsLayerAndroid::syncPositionState()
892 if (m_needsDisplay) {
893 m_translateX = m_currentTranslateX;
894 m_translateY = m_currentTranslateY;
895 m_position = m_currentPosition;
896 m_contentLayer->setTranslation(m_currentTranslateX, m_currentTranslateY);
897 m_contentLayer->setPosition(m_currentPosition.x(), m_currentPosition.y());
898 m_needsDisplay = false;
902 void GraphicsLayerAndroid::syncCompositingState()
904 for (unsigned int i = 0; i < m_children.size(); i++) {
905 GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_children[i]);
906 layer->syncCompositingState();
913 if (!gPaused || WTF::currentTime() >= gPausedDelay)
917 void GraphicsLayerAndroid::notifyClientAnimationStarted()
919 for (unsigned int i = 0; i < m_children.size(); i++) {
920 GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_children[i]);
921 layer->notifyClientAnimationStarted();
924 if (m_needsNotifyClient) {
926 client()->notifyAnimationStarted(this, WTF::currentTime());
927 m_needsNotifyClient = false;
931 } // namespace WebCore
933 #endif // USE(ACCELERATED_COMPOSITING)