Home | History | Annotate | Download | only in android
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      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
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     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.
     15  */
     16 
     17 #include "config.h"
     18 #include "GraphicsLayerAndroid.h"
     19 
     20 #if USE(ACCELERATED_COMPOSITING)
     21 
     22 #include "AndroidAnimation.h"
     23 #include "Animation.h"
     24 #include "CString.h"
     25 #include "FloatRect.h"
     26 #include "GraphicsContext.h"
     27 #include "Image.h"
     28 #include "Length.h"
     29 #include "SkLayer.h"
     30 #include "PlatformBridge.h"
     31 #include "PlatformGraphicsContext.h"
     32 #include "RenderLayerBacking.h"
     33 #include "RenderView.h"
     34 #include "RotateTransformOperation.h"
     35 #include "ScaleTransformOperation.h"
     36 #include "SkCanvas.h"
     37 #include "TransformationMatrix.h"
     38 #include "TranslateTransformOperation.h"
     39 
     40 #include <cutils/log.h>
     41 #include <wtf/CurrentTime.h>
     42 
     43 #undef LOG
     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__)
     47 
     48 #undef LOG
     49 #define LOG(...)
     50 #undef MLOG
     51 #define MLOG(...)
     52 #undef TLOG
     53 #define TLOG(...)
     54 #undef LAYER_DEBUG
     55 
     56 using namespace std;
     57 
     58 static bool gPaused;
     59 static double gPausedDelay;
     60 
     61 namespace WebCore {
     62 
     63 static int gDebugGraphicsLayerAndroidInstances = 0;
     64 inline int GraphicsLayerAndroid::instancesCount()
     65 {
     66     return gDebugGraphicsLayerAndroidInstances;
     67 }
     68 
     69 static String propertyIdToString(AnimatedPropertyID property)
     70 {
     71     switch (property) {
     72     case AnimatedPropertyWebkitTransform:
     73         return "transform";
     74     case AnimatedPropertyOpacity:
     75         return "opacity";
     76     case AnimatedPropertyBackgroundColor:
     77         return "backgroundColor";
     78     case AnimatedPropertyInvalid:
     79         ASSERT_NOT_REACHED();
     80     }
     81     ASSERT_NOT_REACHED();
     82     return "";
     83 }
     84 
     85 GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayer::compositingCoordinatesOrientation()
     86 {
     87     return CompositingCoordinatesBottomUp;
     88 }
     89 
     90 PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
     91 {
     92     return new GraphicsLayerAndroid(client);
     93 }
     94 
     95 SkLength convertLength(Length l) {
     96   SkLength length;
     97   length.type = SkLength::Undefined;
     98   length.value = 0;
     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();
    105   }
    106   return length;
    107 }
    108 
    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),
    117     m_haveImage(false),
    118     m_translateX(0),
    119     m_translateY(0),
    120     m_currentTranslateX(0),
    121     m_currentTranslateY(0),
    122     m_currentPosition(0, 0)
    123 {
    124     m_contentLayer = new LayerAndroid(true);
    125     if (m_client) {
    126         RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_client);
    127         RenderLayer* renderLayer = backing->owningLayer();
    128         m_contentLayer->setIsRootLayer(renderLayer->isRootLayer());
    129     }
    130     gDebugGraphicsLayerAndroidInstances++;
    131 }
    132 
    133 GraphicsLayerAndroid::~GraphicsLayerAndroid()
    134 {
    135     m_contentLayer->unref();
    136     gDebugGraphicsLayerAndroidInstances--;
    137 }
    138 
    139 void GraphicsLayerAndroid::setName(const String& name)
    140 {
    141     GraphicsLayer::setName(name);
    142 }
    143 
    144 NativeLayer GraphicsLayerAndroid::nativeLayer() const
    145 {
    146     LOG("(%x) nativeLayer", this);
    147     return 0;
    148 }
    149 
    150 bool GraphicsLayerAndroid::setChildren(const Vector<GraphicsLayer*>& children)
    151 {
    152     bool childrenChanged = GraphicsLayer::setChildren(children);
    153     if (childrenChanged) {
    154         m_needsSyncChildren = true;
    155         askForSync();
    156     }
    157 
    158     return childrenChanged;
    159 }
    160 
    161 void GraphicsLayerAndroid::addChild(GraphicsLayer* childLayer)
    162 {
    163 #ifndef NDEBUG
    164     const char* n = (static_cast<GraphicsLayerAndroid*>(childLayer))->m_name.latin1().data();
    165     LOG("(%x) addChild: %x (%s)", this, childLayer, n);
    166 #endif
    167     GraphicsLayer::addChild(childLayer);
    168     m_needsSyncChildren = true;
    169     askForSync();
    170 }
    171 
    172 void GraphicsLayerAndroid::addChildAtIndex(GraphicsLayer* childLayer, int index)
    173 {
    174     LOG("(%x) addChild %x AtIndex %d", this, childLayer, index);
    175     GraphicsLayer::addChildAtIndex(childLayer, index);
    176     m_needsSyncChildren = true;
    177     askForSync();
    178 }
    179 
    180 void GraphicsLayerAndroid::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibling)
    181 {
    182     LOG("(%x) addChild %x Below %x", this, childLayer, sibling);
    183     GraphicsLayer::addChildBelow(childLayer, sibling);
    184     m_needsSyncChildren = true;
    185     askForSync();
    186 }
    187 
    188 void GraphicsLayerAndroid::addChildAbove(GraphicsLayer* childLayer, GraphicsLayer* sibling)
    189 {
    190     LOG("(%x) addChild %x Above %x", this, childLayer, sibling);
    191     GraphicsLayer::addChildAbove(childLayer, sibling);
    192     m_needsSyncChildren = true;
    193     askForSync();
    194 }
    195 
    196 bool GraphicsLayerAndroid::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
    197 {
    198     LOG("(%x) replaceChild %x by %x", this, oldChild, newChild);
    199     bool ret = GraphicsLayer::replaceChild(oldChild, newChild);
    200     m_needsSyncChildren = true;
    201     askForSync();
    202     return ret;
    203 }
    204 
    205 void GraphicsLayerAndroid::removeFromParent()
    206 {
    207     LOG("(%x) removeFromParent()", this);
    208     if (m_parent)
    209         static_cast<GraphicsLayerAndroid*>(m_parent)->needsSyncChildren();
    210     GraphicsLayer::removeFromParent();
    211     m_needsSyncChildren = true;
    212     askForSync();
    213 }
    214 
    215 void GraphicsLayerAndroid::needsSyncChildren()
    216 {
    217     m_needsSyncChildren = true;
    218     askForSync();
    219 }
    220 
    221 void GraphicsLayerAndroid::updateFixedPosition()
    222 {
    223     if (!m_client)
    224         return;
    225 
    226     RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_client);
    227     RenderLayer* renderLayer = backing->owningLayer();
    228     RenderView* view = static_cast<RenderView*>(renderLayer->renderer());
    229 
    230     // If we are a fixed position layer, just set it
    231     if (view->isPositioned() && view->style()->position() == FixedPosition) {
    232         SkLength left, top, right, bottom;
    233         left = convertLength(view->style()->left());
    234         top = convertLength(view->style()->top());
    235         right = convertLength(view->style()->right());
    236         bottom = convertLength(view->style()->bottom());
    237         // We need to pass the size of the element to compute the final fixed
    238         // position -- we can't use the layer's size as it could possibly differs.
    239         // We also have to use the visible overflow and not just the size,
    240         // as some child elements could be overflowing.
    241         int w = view->rightVisibleOverflow() - view->leftVisibleOverflow();
    242         int h = view->bottomVisibleOverflow() - view->topVisibleOverflow();
    243 
    244         SkLength marginLeft, marginTop, marginRight, marginBottom;
    245         marginLeft = convertLength(view->style()->marginLeft());
    246         marginTop = convertLength(view->style()->marginTop());
    247         marginRight = convertLength(view->style()->marginRight());
    248         marginBottom = convertLength(view->style()->marginBottom());
    249 
    250         m_contentLayer->setFixedPosition(left, top, right, bottom,
    251                                          marginLeft, marginTop,
    252                                          marginRight, marginBottom,
    253                                          offsetFromRenderer().width(),
    254                                          offsetFromRenderer().height(),
    255                                          w, h);
    256     }
    257 }
    258 
    259 void GraphicsLayerAndroid::setPosition(const FloatPoint& point)
    260 {
    261     m_currentPosition = point;
    262     m_needsDisplay = true;
    263 #ifdef LAYER_DEBUG_2
    264     LOG("(%x) setPosition(%.2f,%.2f) pos(%.2f, %.2f) anchor(%.2f,%.2f) size(%.2f, %.2f)",
    265         this, point.x(), point.y(), m_currentPosition.x(), m_currentPosition.y(),
    266         m_anchorPoint.x(), m_anchorPoint.y(), m_size.width(), m_size.height());
    267 #endif
    268     updateFixedPosition();
    269     askForSync();
    270 }
    271 
    272 void GraphicsLayerAndroid::setAnchorPoint(const FloatPoint3D& point)
    273 {
    274     GraphicsLayer::setAnchorPoint(point);
    275     m_contentLayer->setAnchorPoint(point.x(), point.y());
    276     askForSync();
    277 }
    278 
    279 void GraphicsLayerAndroid::setSize(const FloatSize& size)
    280 {
    281     if ((size.width() != m_size.width())
    282           || (size.height() != m_size.height())) {
    283         MLOG("(%x) setSize (%.2f,%.2f)", this, size.width(), size.height());
    284         GraphicsLayer::setSize(size);
    285         m_contentLayer->setSize(size.width(), size.height());
    286         askForSync();
    287     }
    288 }
    289 
    290 void GraphicsLayerAndroid::setTransform(const TransformationMatrix& t)
    291 {
    292     TransformationMatrix::DecomposedType tDecomp;
    293     t.decompose(tDecomp);
    294     LOG("(%x) setTransform, translate (%.2f, %.2f), mpos(%.2f,%.2f)",
    295         this, tDecomp.translateX, tDecomp.translateY,
    296         m_position.x(), m_position.y());
    297 
    298     if ((m_currentTranslateX != tDecomp.translateX)
    299           || (m_currentTranslateY != tDecomp.translateY)) {
    300         m_currentTranslateX = tDecomp.translateX;
    301         m_currentTranslateY = tDecomp.translateY;
    302         m_needsDisplay = true;
    303         askForSync();
    304     }
    305 }
    306 
    307 void GraphicsLayerAndroid::setChildrenTransform(const TransformationMatrix& t)
    308 {
    309     if (t == m_childrenTransform)
    310        return;
    311     LOG("(%x) setChildrenTransform", this);
    312 
    313     GraphicsLayer::setChildrenTransform(t);
    314     for (unsigned int i = 0; i < m_children.size(); i++) {
    315         GraphicsLayer* layer = m_children[i];
    316         layer->setTransform(t);
    317         if (layer->children().size())
    318             layer->setChildrenTransform(t);
    319     }
    320     askForSync();
    321 }
    322 
    323 void GraphicsLayerAndroid::setMaskLayer(GraphicsLayer* layer)
    324 {
    325     if (layer == m_maskLayer)
    326       return;
    327 
    328     GraphicsLayer::setMaskLayer(layer);
    329     m_needsSyncMask = true;
    330     askForSync();
    331 }
    332 
    333 void GraphicsLayerAndroid::setMasksToBounds(bool masksToBounds)
    334 {
    335     GraphicsLayer::setMasksToBounds(masksToBounds);
    336     m_needsSyncMask = true;
    337     askForSync();
    338 }
    339 
    340 void GraphicsLayerAndroid::setDrawsContent(bool drawsContent)
    341 {
    342     GraphicsLayer::setDrawsContent(drawsContent);
    343 
    344     if (m_drawsContent) {
    345         m_haveContents = true;
    346         setNeedsDisplay();
    347     }
    348     askForSync();
    349 }
    350 
    351 void GraphicsLayerAndroid::setBackgroundColor(const Color& color)
    352 {
    353     LOG("(%x) setBackgroundColor", this);
    354     GraphicsLayer::setBackgroundColor(color);
    355     SkColor c = SkColorSetARGB(color.alpha(), color.red(), color.green(), color.blue());
    356     m_contentLayer->setBackgroundColor(c);
    357     m_haveContents = true;
    358     askForSync();
    359 }
    360 
    361 void GraphicsLayerAndroid::clearBackgroundColor()
    362 {
    363     LOG("(%x) clearBackgroundColor", this);
    364     GraphicsLayer::clearBackgroundColor();
    365     askForSync();
    366 }
    367 
    368 void GraphicsLayerAndroid::setContentsOpaque(bool opaque)
    369 {
    370     LOG("(%x) setContentsOpaque (%d)", this, opaque);
    371     GraphicsLayer::setContentsOpaque(opaque);
    372     m_haveContents = true;
    373     askForSync();
    374 }
    375 
    376 void GraphicsLayerAndroid::setOpacity(float opacity)
    377 {
    378     LOG("(%x) setOpacity: %.2f", this, opacity);
    379     float clampedOpacity = max(0.0f, min(opacity, 1.0f));
    380 
    381     if (clampedOpacity == m_opacity)
    382         return;
    383 
    384     MLOG("(%x) setFinalOpacity: %.2f=>%.2f (%.2f)", this,
    385         opacity, clampedOpacity, m_opacity);
    386     GraphicsLayer::setOpacity(clampedOpacity);
    387     m_contentLayer->setOpacity(clampedOpacity);
    388     askForSync();
    389 }
    390 
    391 bool GraphicsLayerAndroid::repaintAll()
    392 {
    393      LOG("(%x) repaintAll", this);
    394      bool ret = false;
    395      for (unsigned int i = 0; i < m_children.size(); i++) {
    396          GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_children[i]);
    397          if (layer && layer->repaintAll())
    398              ret = true;
    399      }
    400      int nbRects = m_invalidatedRects.size();
    401 
    402      for (int i = 0; !gPaused && i < nbRects; i++) {
    403          FloatRect rect = m_invalidatedRects[i];
    404          if (repaint(rect))
    405              ret = true;
    406      }
    407      if (!gPaused) {
    408          m_needsRepaint = false;
    409          m_invalidatedRects.clear();
    410      }
    411      return ret;
    412 }
    413 
    414 void GraphicsLayerAndroid::setNeedsDisplay()
    415 {
    416     LOG("(%x) setNeedsDisplay()", this);
    417     FloatRect rect(0, 0, m_size.width(), m_size.height());
    418     setNeedsDisplayInRect(rect);
    419 }
    420 
    421 void GraphicsLayerAndroid::setFrame(Frame* f)
    422 {
    423     m_frame = f;
    424 }
    425 
    426 void GraphicsLayerAndroid::sendImmediateRepaint()
    427 {
    428     LOG("(%x) sendImmediateRepaint()", this);
    429     GraphicsLayerAndroid* rootGraphicsLayer = this;
    430 
    431     while (rootGraphicsLayer->parent())
    432         rootGraphicsLayer = static_cast<GraphicsLayerAndroid*>(rootGraphicsLayer->parent());
    433 
    434     if (rootGraphicsLayer->m_frame
    435         && rootGraphicsLayer->m_frame->view()) {
    436         LayerAndroid* rootLayer = new LayerAndroid(true);
    437         LayerAndroid* copyLayer = new LayerAndroid(*m_contentLayer);
    438         rootLayer->addChild(copyLayer);
    439         copyLayer->unref();
    440         TLOG("(%x) sendImmediateRepaint, copy the layer, (%.2f,%.2f => %.2f,%.2f)",
    441             this, m_contentLayer->getSize().width(), m_contentLayer->getSize().height(),
    442             copyLayer->getSize().width(), copyLayer->getSize().height());
    443         PlatformBridge::setUIRootLayer(m_frame->view(), rootLayer);
    444         PlatformBridge::immediateRepaint(m_frame->view());
    445     }
    446 }
    447 
    448 bool GraphicsLayerAndroid::repaint(const FloatRect& rect)
    449 {
    450     LOG("(%x) repaint(%.2f,%.2f,%.2f,%.2f), gPaused(%d) m_needsRepaint(%d) m_haveContents(%d) ",
    451         this, rect.x(), rect.y(), rect.width(), rect.height(),
    452         gPaused, m_needsRepaint, m_haveContents);
    453 
    454     if (!gPaused && m_haveContents && m_needsRepaint) {
    455         SkAutoPictureRecord arp(m_contentLayer->recordContext(), m_size.width(), m_size.height());
    456         SkCanvas* recordingCanvas = arp.getRecordingCanvas();
    457 
    458         if (!recordingCanvas)
    459             return false;
    460 
    461         if ((rect.width() > 0.5) && (rect.height() > 0.5)) {
    462             IntRect r((int)rect.x(), (int)rect.y(),
    463                   (int)rect.width(), (int)rect.height());
    464 
    465             PlatformGraphicsContext pgc(recordingCanvas, 0);
    466             GraphicsContext gc(&pgc);
    467 
    468             // with SkPicture, we request the entire layer's content.
    469             r.setX(0);
    470             r.setY(0);
    471             r.setWidth(m_contentLayer->getWidth());
    472             r.setHeight(m_contentLayer->getHeight());
    473             paintGraphicsLayerContents(gc, r);
    474 
    475             TLOG("(%x) repaint(%.2f,%.2f,%.2f,%.2f) on (%.2f,%.2f) contentlayer(%.2f,%.2f,%.2f,%.2f)paintGraphicsLayer called!",
    476                 this, rect.x(), rect.y(), rect.width(),
    477                 rect.height(), m_size.width(), m_size.height(),
    478                 m_contentLayer->getPosition().fX,
    479                 m_contentLayer->getPosition().fY,
    480                 m_contentLayer->getSize().width(),
    481                 m_contentLayer->getSize().height());
    482         }
    483         return true;
    484     }
    485     return false;
    486 }
    487 
    488 void GraphicsLayerAndroid::setNeedsDisplayInRect(const FloatRect& rect)
    489 {
    490     for (unsigned int i = 0; i < m_children.size(); i++) {
    491         GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_children[i]);
    492         if (layer) {
    493             FloatRect childrenRect(m_position.x() + m_translateX + rect.x(),
    494                                    m_position.y() + m_translateY + rect.y(),
    495                                    rect.width(), rect.height());
    496             layer->setNeedsDisplayInRect(childrenRect);
    497         }
    498     }
    499     if (!m_haveImage && !drawsContent()) {
    500         LOG("(%x) setNeedsDisplay(%.2f,%.2f,%.2f,%.2f) doesn't have content, bypass...",
    501             this, rect.x(), rect.y(), rect.width(), rect.height());
    502         return;
    503     }
    504 
    505     const size_t maxDirtyRects = 8;
    506     for (size_t i = 0; i < m_invalidatedRects.size(); ++i) {
    507         if (m_invalidatedRects[i].contains(rect))
    508             return;
    509     }
    510 
    511 #ifdef LAYER_DEBUG
    512     LOG("(%x) setNeedsDisplayInRect(%d) - (%.2f, %.2f, %.2f, %.2f)", this,
    513         m_needsRepaint, rect.x(), rect.y(), rect.width(), rect.height());
    514 #endif
    515 
    516     if (m_invalidatedRects.size() < maxDirtyRects)
    517         m_invalidatedRects.append(rect);
    518     else
    519         m_invalidatedRects[0].unite(rect);
    520 
    521     m_needsRepaint = true;
    522     askForSync();
    523 }
    524 
    525 void GraphicsLayerAndroid::pauseDisplay(bool state)
    526 {
    527     gPaused = state;
    528     if (gPaused)
    529         gPausedDelay = WTF::currentTime() + 1;
    530 }
    531 
    532 bool GraphicsLayerAndroid::addAnimation(const KeyframeValueList& valueList,
    533                                         const IntSize& boxSize,
    534                                         const Animation* anim,
    535                                         const String& keyframesName,
    536                                         double beginTime)
    537 {
    538     if (!anim || anim->isEmptyOrZeroDuration() || valueList.size() != 2)
    539     return false;
    540 
    541     bool createdAnimations = false;
    542     if (valueList.property() == AnimatedPropertyWebkitTransform) {
    543         createdAnimations = createTransformAnimationsFromKeyframes(valueList,
    544                                                                    anim,
    545                                                                    keyframesName,
    546                                                                    beginTime,
    547                                                                    boxSize);
    548     } else {
    549         createdAnimations = createAnimationFromKeyframes(valueList,
    550                                                          anim,
    551                                                          keyframesName,
    552                                                          beginTime);
    553     }
    554     askForSync();
    555     return createdAnimations;
    556 }
    557 
    558 bool GraphicsLayerAndroid::createAnimationFromKeyframes(const KeyframeValueList& valueList,
    559      const Animation* animation, const String& keyframesName, double beginTime)
    560 {
    561     bool isKeyframe = valueList.size() > 2;
    562     TLOG("createAnimationFromKeyframes(%d), name(%s) beginTime(%.2f)",
    563         isKeyframe, keyframesName.latin1().data(), beginTime);
    564     // TODO: handles keyframe animations correctly
    565 
    566     switch (valueList.property()) {
    567     case AnimatedPropertyInvalid: break;
    568     case AnimatedPropertyWebkitTransform: break;
    569     case AnimatedPropertyBackgroundColor: break;
    570     case AnimatedPropertyOpacity: {
    571         MLOG("ANIMATEDPROPERTYOPACITY");
    572         const FloatAnimationValue* startVal =
    573             static_cast<const FloatAnimationValue*>(valueList.at(0));
    574         const FloatAnimationValue* endVal =
    575             static_cast<const FloatAnimationValue*>(valueList.at(1));
    576         RefPtr<AndroidOpacityAnimation> anim = AndroidOpacityAnimation::create(startVal->value(),
    577                                                                                endVal->value(),
    578                                                                                animation,
    579                                                                                beginTime);
    580         if (keyframesName.isEmpty())
    581             anim->setName(propertyIdToString(valueList.property()));
    582         else
    583             anim->setName(keyframesName);
    584 
    585         m_contentLayer->addAnimation(anim.release());
    586         needsNotifyClient();
    587         return true;
    588     } break;
    589     }
    590     return false;
    591 }
    592 
    593 void GraphicsLayerAndroid::needsNotifyClient()
    594 {
    595     m_needsNotifyClient = true;
    596     askForSync();
    597 }
    598 
    599 bool GraphicsLayerAndroid::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList,
    600                                                                   const Animation* animation,
    601                                                                   const String& keyframesName,
    602                                                                   double beginTime,
    603                                                                   const IntSize& boxSize)
    604 {
    605     ASSERT(valueList.property() == AnimatedPropertyWebkitTransform);
    606     TLOG("createTransformAnimationFromKeyframes, name(%s) beginTime(%.2f)",
    607         keyframesName.latin1().data(), beginTime);
    608 
    609     TransformOperationList functionList;
    610     bool listsMatch, hasBigRotation;
    611     fetchTransformOperationList(valueList, functionList, listsMatch, hasBigRotation);
    612 
    613     // If functionLists don't match we do a matrix animation, otherwise we do a component hardware animation.
    614     // Also, we can't do component animation unless we have valueFunction, so we need to do matrix animation
    615     // if that's not true as well.
    616 
    617     bool isMatrixAnimation = !listsMatch;
    618     size_t numAnimations = isMatrixAnimation ? 1 : functionList.size();
    619     bool isKeyframe = valueList.size() > 2;
    620 
    621     float fromTranslateX = 0;
    622     float fromTranslateY = 0;
    623     float fromTranslateZ = 0;
    624     float toTranslateX   = 0;
    625     float toTranslateY   = 0;
    626     float toTranslateZ   = 0;
    627     float fromAngle      = 0;
    628     float toAngle        = 0;
    629     float fromScaleX     = 1;
    630     float fromScaleY     = 1;
    631     float fromScaleZ     = 1;
    632     float toScaleX       = 1;
    633     float toScaleY       = 1;
    634     float toScaleZ       = 1;
    635 
    636     bool doTranslation = false;
    637     bool doRotation = false;
    638     bool doScaling = false;
    639 
    640     TLOG("(%x) animateTransform, valueList(%d) functionList(%d) duration(%.2f)", this,
    641         valueList.size(), functionList.size(), animation->duration());
    642 
    643     // FIXME: add support for the translate 3d operations (when
    644     // we'll have an OpenGL backend)
    645 
    646     for (unsigned int i = 0; i < valueList.size(); i++) {
    647         const TransformOperations* operation = ((TransformAnimationValue*)valueList.at(i))->value();
    648         Vector<RefPtr<TransformOperation> > ops = operation->operations();
    649         TLOG("(%x) animateTransform, dealing with the %d operation, with %d ops", this, i, ops.size());
    650         for (unsigned int j = 0; j < ops.size(); j++) {
    651             TransformOperation* op = ops[j].get();
    652             TLOG("(%x) animateTransform, dealing with the %d:%d operation, current op: %d (translate is %d, rotate %d, scale %d)",
    653                 this, i, j, op->getOperationType(), TransformOperation::TRANSLATE, TransformOperation::ROTATE, TransformOperation::SCALE);
    654             if ((op->getOperationType() == TransformOperation::TRANSLATE) ||
    655                 (op->getOperationType() == TransformOperation::TRANSLATE_3D)) {
    656                 TranslateTransformOperation* translateOperation = (TranslateTransformOperation*) op;
    657                 IntSize bounds(m_size.width(), m_size.height());
    658                 float x = translateOperation->x(bounds);
    659                 float y = translateOperation->y(bounds);
    660                 float z = translateOperation->z(bounds);
    661                 if (!i) {
    662                     fromTranslateX = x;
    663                     fromTranslateY = y;
    664                     fromTranslateZ = z;
    665                 } else {
    666                     toTranslateX = x;
    667                     toTranslateY = y;
    668                     toTranslateZ = z;
    669                 }
    670                 TLOG("(%x) animateTransform, the %d operation is a translation(%.2f,%.2f,%.2f)",
    671                     this, j, x, y, z);
    672                 doTranslation = true;
    673             } else if (op->getOperationType() == TransformOperation::TRANSLATE_X) {
    674                 TranslateTransformOperation* translateOperation = (TranslateTransformOperation*) op;
    675                 IntSize bounds(m_size.width(), m_size.height());
    676                 float x = translateOperation->x(bounds);
    677                 if (!i)
    678                     fromTranslateX = x;
    679                 else
    680                     toTranslateX = x;
    681                 TLOG("(%x) animateTransform, the %d operation is a translation_x(%.2f)",
    682                     this, j, x);
    683                 doTranslation = true;
    684             } else if (op->getOperationType() == TransformOperation::TRANSLATE_Y) {
    685                 TranslateTransformOperation* translateOperation = (TranslateTransformOperation*) op;
    686                 IntSize bounds(m_size.width(), m_size.height());
    687                 float y = translateOperation->y(bounds);
    688                 if (!i)
    689                     fromTranslateY = y;
    690                 else
    691                     toTranslateY = y;
    692                 TLOG("(%x) animateTransform, the %d operation is a translation_y(%.2f)",
    693                     this, j, y);
    694                 doTranslation = true;
    695             } else if (op->getOperationType() == TransformOperation::TRANSLATE_Z) {
    696                 TranslateTransformOperation* translateOperation = (TranslateTransformOperation*) op;
    697                 IntSize bounds(m_size.width(), m_size.height());
    698                 float z = translateOperation->z(bounds);
    699                 if (!i)
    700                     fromTranslateZ = z;
    701                 else
    702                     toTranslateZ = z;
    703                 TLOG("(%x) animateTransform, the %d operation is a translation_z(%.2f)",
    704                     this, j, z);
    705                 doTranslation = true;
    706             } else if ((op->getOperationType() == TransformOperation::ROTATE)
    707                           || (op->getOperationType() == TransformOperation::ROTATE_X)
    708                           || (op->getOperationType() == TransformOperation::ROTATE_Y)) {
    709                 LOG("(%x) animateTransform, the %d operation is a rotation", this, j);
    710                 RotateTransformOperation* rotateOperation = (RotateTransformOperation*) op;
    711                 float angle = rotateOperation->angle();
    712                 TLOG("(%x) animateTransform, the %d operation is a rotation (%d), of angle %.2f",
    713                     this, j, op->getOperationType(), angle);
    714 
    715                 if (!i)
    716                     fromAngle = angle;
    717                 else
    718                     toAngle = angle;
    719                 doRotation = true;
    720             } else if (op->getOperationType() == TransformOperation::SCALE_X) {
    721                 ScaleTransformOperation* scaleOperation = (ScaleTransformOperation*) op;
    722                 if (!i)
    723                     fromScaleX = scaleOperation->x();
    724                 else
    725                     toScaleX = scaleOperation->x();
    726                 doScaling = true;
    727             } else if (op->getOperationType() == TransformOperation::SCALE_Y) {
    728                 ScaleTransformOperation* scaleOperation = (ScaleTransformOperation*) op;
    729                 if (!i)
    730                     fromScaleY = scaleOperation->y();
    731                 else
    732                     toScaleY = scaleOperation->y();
    733                 doScaling = true;
    734             } else if (op->getOperationType() == TransformOperation::SCALE_Z) {
    735                 ScaleTransformOperation* scaleOperation = (ScaleTransformOperation*) op;
    736                 if (!i)
    737                     fromScaleZ = scaleOperation->z();
    738                 else
    739                     toScaleZ = scaleOperation->z();
    740                 doScaling = true;
    741             } else if (op->getOperationType() == TransformOperation::SCALE) {
    742                 ScaleTransformOperation* scaleOperation = (ScaleTransformOperation*) op;
    743                 if (!i) {
    744                     fromScaleX = scaleOperation->x();
    745                     fromScaleY = scaleOperation->y();
    746                     fromScaleZ = scaleOperation->z();
    747                 } else {
    748                     toScaleX = scaleOperation->x();
    749                     toScaleY = scaleOperation->y();
    750                     toScaleZ = scaleOperation->z();
    751                 }
    752                 doScaling = true;
    753             } else {
    754                 TLOG("(%x) animateTransform, the %d operation is not a rotation (%d)",
    755                     this, j, op->getOperationType());
    756             }
    757         }
    758     }
    759 
    760     RefPtr<AndroidTransformAnimation> anim = AndroidTransformAnimation::create(animation, beginTime);
    761 
    762     if (keyframesName.isEmpty())
    763         anim->setName(propertyIdToString(valueList.property()));
    764     else
    765         anim->setName(keyframesName);
    766 
    767     anim->setOriginalPosition(m_position);
    768 
    769     if (doTranslation)
    770         anim->setTranslation(fromTranslateX, fromTranslateY, fromTranslateZ,
    771                          toTranslateX, toTranslateY, toTranslateZ);
    772     if (doRotation)
    773         anim->setRotation(fromAngle, toAngle);
    774     if (doScaling)
    775         anim->setScale(fromScaleX, fromScaleY, fromScaleZ,
    776                        toScaleX, toScaleY, toScaleZ);
    777     m_contentLayer->addAnimation(anim.release());
    778 
    779     needsNotifyClient();
    780     return true;
    781 }
    782 
    783 void GraphicsLayerAndroid::removeAnimationsForProperty(AnimatedPropertyID anID)
    784 {
    785     TLOG("NRO removeAnimationsForProperty(%d)", anID);
    786     m_contentLayer->removeAnimation(propertyIdToString(anID));
    787     askForSync();
    788 }
    789 
    790 void GraphicsLayerAndroid::removeAnimationsForKeyframes(const String& keyframesName)
    791 {
    792     TLOG("NRO removeAnimationsForKeyframes(%s)", keyframesName.latin1().data());
    793     m_contentLayer->removeAnimation(keyframesName);
    794     askForSync();
    795 }
    796 
    797 void GraphicsLayerAndroid::pauseAnimation(const String& keyframesName)
    798 {
    799     TLOG("NRO pauseAnimation(%s)", keyframesName.latin1().data());
    800 }
    801 
    802 void GraphicsLayerAndroid::suspendAnimations(double time)
    803 {
    804     TLOG("NRO suspendAnimations(%.2f)", time);
    805 }
    806 
    807 void GraphicsLayerAndroid::resumeAnimations()
    808 {
    809     TLOG("NRO resumeAnimations()");
    810 }
    811 
    812 void GraphicsLayerAndroid::setContentsToImage(Image* image)
    813 {
    814     TLOG("(%x) setContentsToImage", this, image);
    815     if (image) {
    816         m_haveContents = true;
    817         if (!m_haveImage) {
    818             m_haveImage = true;
    819             setNeedsDisplay();
    820             askForSync();
    821         }
    822     }
    823 }
    824 
    825 PlatformLayer* GraphicsLayerAndroid::platformLayer() const
    826 {
    827     LOG("platformLayer");
    828     return (PlatformLayer*) m_contentLayer;
    829 }
    830 
    831 #ifndef NDEBUG
    832 void GraphicsLayerAndroid::setDebugBackgroundColor(const Color& color)
    833 {
    834 }
    835 
    836 void GraphicsLayerAndroid::setDebugBorder(const Color& color, float borderWidth)
    837 {
    838 }
    839 #endif
    840 
    841 void GraphicsLayerAndroid::setZPosition(float position)
    842 {
    843     LOG("(%x) setZPosition: %.2f", this, position);
    844     GraphicsLayer::setZPosition(position);
    845     askForSync();
    846 }
    847 
    848 void GraphicsLayerAndroid::askForSync()
    849 {
    850     if (m_client)
    851         m_client->notifySyncRequired(this);
    852 }
    853 
    854 void GraphicsLayerAndroid::syncChildren()
    855 {
    856     if (m_needsSyncChildren) {
    857         m_contentLayer->removeChildren();
    858         for (unsigned int i = 0; i < m_children.size(); i++) {
    859             m_contentLayer->addChild(
    860                 (static_cast<GraphicsLayerAndroid*>(m_children[i]))->contentLayer());
    861         }
    862         m_needsSyncChildren = false;
    863     }
    864 }
    865 
    866 void GraphicsLayerAndroid::syncMask()
    867 {
    868     if (m_needsSyncMask) {
    869         if (m_maskLayer) {
    870             GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_maskLayer);
    871             LayerAndroid* mask = reinterpret_cast<LayerAndroid*>(layer->platformLayer());
    872             m_contentLayer->setMaskLayer(mask);
    873         } else
    874             m_contentLayer->setMaskLayer(0);
    875 
    876         m_contentLayer->setMasksToBounds(m_masksToBounds);
    877         m_needsSyncMask = false;
    878     }
    879 }
    880 
    881 void GraphicsLayerAndroid::syncPositionState()
    882 {
    883      if (m_needsDisplay) {
    884          m_translateX = m_currentTranslateX;
    885          m_translateY = m_currentTranslateY;
    886          m_position = m_currentPosition;
    887          m_contentLayer->setTranslation(m_currentTranslateX, m_currentTranslateY);
    888          m_contentLayer->setPosition(m_currentPosition.x(), m_currentPosition.y());
    889          m_needsDisplay = false;
    890      }
    891 }
    892 
    893 void GraphicsLayerAndroid::syncCompositingState()
    894 {
    895     for (unsigned int i = 0; i < m_children.size(); i++) {
    896         GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_children[i]);
    897         layer->syncCompositingState();
    898     }
    899 
    900     syncChildren();
    901     syncMask();
    902     syncPositionState();
    903 
    904     if (!gPaused || WTF::currentTime() >= gPausedDelay)
    905         repaintAll();
    906 }
    907 
    908 void GraphicsLayerAndroid::notifyClientAnimationStarted()
    909 {
    910     for (unsigned int i = 0; i < m_children.size(); i++) {
    911         GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_children[i]);
    912         layer->notifyClientAnimationStarted();
    913     }
    914 
    915     if (m_needsNotifyClient) {
    916         if (client())
    917             client()->notifyAnimationStarted(this, WTF::currentTime());
    918         m_needsNotifyClient = false;
    919     }
    920 }
    921 
    922 } // namespace WebCore
    923 
    924 #endif // USE(ACCELERATED_COMPOSITING)
    925