Home | History | Annotate | Download | only in ca
      1 /*
      2  * Copyright (C) 2010 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 
     28 #if USE(ACCELERATED_COMPOSITING)
     29 
     30 #include "GraphicsLayerCA.h"
     31 
     32 #include "Animation.h"
     33 #include "FloatConversion.h"
     34 #include "FloatRect.h"
     35 #include "PlatformCALayer.h"
     36 #include "PlatformString.h"
     37 #include "RotateTransformOperation.h"
     38 #include "ScaleTransformOperation.h"
     39 #include "SystemTime.h"
     40 #include "TranslateTransformOperation.h"
     41 #include <QuartzCore/CATransform3D.h>
     42 #include <limits.h>
     43 #include <wtf/CurrentTime.h>
     44 #include <wtf/text/StringConcatenate.h>
     45 
     46 using namespace std;
     47 
     48 #define HAVE_MODERN_QUARTZCORE (!defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD))
     49 
     50 namespace WebCore {
     51 
     52 // The threshold width or height above which a tiled layer will be used. This should be
     53 // large enough to avoid tiled layers for most GraphicsLayers, but less than the OpenGL
     54 // texture size limit on all supported hardware.
     55 static const int cMaxPixelDimension = 2000;
     56 
     57 // If we send a duration of 0 to CA, then it will use the default duration
     58 // of 250ms. So send a very small value instead.
     59 static const float cAnimationAlmostZeroDuration = 1e-3f;
     60 
     61 // CACurrentMediaTime() is a time since boot. These methods convert between that and
     62 // WebCore time, which is system time (UTC).
     63 static CFTimeInterval currentTimeToMediaTime(double t)
     64 {
     65     return CACurrentMediaTime() + t - WTF::currentTime();
     66 }
     67 
     68 static bool isTransformTypeTransformationMatrix(TransformOperation::OperationType transformType)
     69 {
     70     switch (transformType) {
     71     case TransformOperation::SKEW_X:
     72     case TransformOperation::SKEW_Y:
     73     case TransformOperation::SKEW:
     74     case TransformOperation::MATRIX:
     75     case TransformOperation::ROTATE_3D:
     76     case TransformOperation::MATRIX_3D:
     77     case TransformOperation::PERSPECTIVE:
     78     case TransformOperation::IDENTITY:
     79     case TransformOperation::NONE:
     80         return true;
     81     default:
     82         return false;
     83     }
     84 }
     85 
     86 static bool isTransformTypeFloatPoint3D(TransformOperation::OperationType transformType)
     87 {
     88     switch (transformType) {
     89     case TransformOperation::SCALE:
     90     case TransformOperation::SCALE_3D:
     91     case TransformOperation::TRANSLATE:
     92     case TransformOperation::TRANSLATE_3D:
     93         return true;
     94     default:
     95         return false;
     96     }
     97 }
     98 
     99 static bool isTransformTypeNumber(TransformOperation::OperationType transformType)
    100 {
    101     return !isTransformTypeTransformationMatrix(transformType) && !isTransformTypeFloatPoint3D(transformType);
    102 }
    103 
    104 static void getTransformFunctionValue(const TransformOperation* transformOp, TransformOperation::OperationType transformType, const IntSize& size, float& value)
    105 {
    106     switch (transformType) {
    107     case TransformOperation::ROTATE:
    108     case TransformOperation::ROTATE_X:
    109     case TransformOperation::ROTATE_Y:
    110         value = transformOp ? narrowPrecisionToFloat(deg2rad(static_cast<const RotateTransformOperation*>(transformOp)->angle())) : 0;
    111         break;
    112     case TransformOperation::SCALE_X:
    113         value = transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->x()) : 1;
    114         break;
    115     case TransformOperation::SCALE_Y:
    116         value = transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->y()) : 1;
    117         break;
    118     case TransformOperation::SCALE_Z:
    119         value = transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->z()) : 1;
    120         break;
    121     case TransformOperation::TRANSLATE_X:
    122         value = transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->x(size)) : 0;
    123         break;
    124     case TransformOperation::TRANSLATE_Y:
    125         value = transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->y(size)) : 0;
    126         break;
    127     case TransformOperation::TRANSLATE_Z:
    128         value = transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->z(size)) : 0;
    129         break;
    130     default:
    131         break;
    132     }
    133 }
    134 
    135 static void getTransformFunctionValue(const TransformOperation* transformOp, TransformOperation::OperationType transformType, const IntSize& size, FloatPoint3D& value)
    136 {
    137     switch (transformType) {
    138     case TransformOperation::SCALE:
    139     case TransformOperation::SCALE_3D:
    140         value.setX(transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->x()) : 1);
    141         value.setY(transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->y()) : 1);
    142         value.setZ(transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->z()) : 1);
    143         break;
    144     case TransformOperation::TRANSLATE:
    145     case TransformOperation::TRANSLATE_3D:
    146         value.setX(transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->x(size)) : 0);
    147         value.setY(transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->y(size)) : 0);
    148         value.setZ(transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->z(size)) : 0);
    149         break;
    150     default:
    151         break;
    152     }
    153 }
    154 
    155 static void getTransformFunctionValue(const TransformOperation* transformOp, TransformOperation::OperationType transformType, const IntSize& size, TransformationMatrix& value)
    156 {
    157     switch (transformType) {
    158     case TransformOperation::SKEW_X:
    159     case TransformOperation::SKEW_Y:
    160     case TransformOperation::SKEW:
    161     case TransformOperation::MATRIX:
    162     case TransformOperation::ROTATE_3D:
    163     case TransformOperation::MATRIX_3D:
    164     case TransformOperation::PERSPECTIVE:
    165     case TransformOperation::IDENTITY:
    166     case TransformOperation::NONE:
    167         if (transformOp)
    168             transformOp->apply(value, size);
    169         else
    170             value.makeIdentity();
    171         break;
    172     default:
    173         break;
    174     }
    175 }
    176 
    177 #if HAVE_MODERN_QUARTZCORE
    178 static PlatformCAAnimation::ValueFunctionType getValueFunctionNameForTransformOperation(TransformOperation::OperationType transformType)
    179 {
    180     // Use literal strings to avoid link-time dependency on those symbols.
    181     switch (transformType) {
    182     case TransformOperation::ROTATE_X:
    183         return PlatformCAAnimation::RotateX;
    184     case TransformOperation::ROTATE_Y:
    185         return PlatformCAAnimation::RotateY;
    186     case TransformOperation::ROTATE:
    187         return PlatformCAAnimation::RotateZ;
    188     case TransformOperation::SCALE_X:
    189         return PlatformCAAnimation::ScaleX;
    190     case TransformOperation::SCALE_Y:
    191         return PlatformCAAnimation::ScaleY;
    192     case TransformOperation::SCALE_Z:
    193         return PlatformCAAnimation::ScaleZ;
    194     case TransformOperation::TRANSLATE_X:
    195         return PlatformCAAnimation::TranslateX;
    196     case TransformOperation::TRANSLATE_Y:
    197         return PlatformCAAnimation::TranslateY;
    198     case TransformOperation::TRANSLATE_Z:
    199         return PlatformCAAnimation::TranslateZ;
    200     case TransformOperation::SCALE:
    201     case TransformOperation::SCALE_3D:
    202         return PlatformCAAnimation::Scale;
    203     case TransformOperation::TRANSLATE:
    204     case TransformOperation::TRANSLATE_3D:
    205         return PlatformCAAnimation::Translate;
    206     default:
    207         return PlatformCAAnimation::NoValueFunction;
    208     }
    209 }
    210 #endif
    211 
    212 static String propertyIdToString(AnimatedPropertyID property)
    213 {
    214     switch (property) {
    215     case AnimatedPropertyWebkitTransform:
    216         return "transform";
    217     case AnimatedPropertyOpacity:
    218         return "opacity";
    219     case AnimatedPropertyBackgroundColor:
    220         return "backgroundColor";
    221     case AnimatedPropertyInvalid:
    222         ASSERT_NOT_REACHED();
    223     }
    224     ASSERT_NOT_REACHED();
    225     return "";
    226 }
    227 
    228 static String animationIdentifier(const String& animationName, AnimatedPropertyID property, int index)
    229 {
    230     return makeString(animationName, '_', String::number(property), '_', String::number(index));
    231 }
    232 
    233 static bool animationHasStepsTimingFunction(const KeyframeValueList& valueList, const Animation* anim)
    234 {
    235     if (anim->timingFunction()->isStepsTimingFunction())
    236         return true;
    237 
    238     for (unsigned i = 0; i < valueList.size(); ++i) {
    239         const TimingFunction* timingFunction = valueList.at(i)->timingFunction();
    240         if (timingFunction && timingFunction->isStepsTimingFunction())
    241             return true;
    242     }
    243 
    244     return false;
    245 }
    246 
    247 PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
    248 {
    249     return new GraphicsLayerCA(client);
    250 }
    251 
    252 GraphicsLayerCA::GraphicsLayerCA(GraphicsLayerClient* client)
    253     : GraphicsLayer(client)
    254     , m_contentsLayerPurpose(NoContentsLayer)
    255     , m_contentsLayerHasBackgroundColor(false)
    256     , m_uncommittedChanges(NoChange)
    257     , m_contentsScale(1)
    258     , m_allowTiledLayer(true)
    259 {
    260     m_layer = PlatformCALayer::create(PlatformCALayer::LayerTypeWebLayer, this);
    261 
    262 #if !HAVE_MODERN_QUARTZCORE
    263     setContentsOrientation(defaultContentsOrientation());
    264 #endif
    265 
    266     updateDebugIndicators();
    267 }
    268 
    269 GraphicsLayerCA::~GraphicsLayerCA()
    270 {
    271     // We release our references to the PlatformCALayers here, but do not actively unparent them,
    272     // since that will cause a commit and break our batched commit model. The layers will
    273     // get released when the rootmost modified GraphicsLayerCA rebuilds its child layers.
    274 
    275     // Clean up the layer.
    276     if (m_layer)
    277         m_layer->setOwner(0);
    278 
    279     if (m_contentsLayer)
    280         m_contentsLayer->setOwner(0);
    281 
    282     if (m_structuralLayer)
    283         m_structuralLayer->setOwner(0);
    284 
    285     removeCloneLayers();
    286 }
    287 
    288 void GraphicsLayerCA::setName(const String& name)
    289 {
    290     String longName = String::format("CALayer(%p) GraphicsLayer(%p) ", m_layer.get(), this) + name;
    291     GraphicsLayer::setName(longName);
    292     noteLayerPropertyChanged(NameChanged);
    293 }
    294 
    295 PlatformLayer* GraphicsLayerCA::platformLayer() const
    296 {
    297     return primaryLayer()->platformLayer();
    298 }
    299 
    300 bool GraphicsLayerCA::setChildren(const Vector<GraphicsLayer*>& children)
    301 {
    302     bool childrenChanged = GraphicsLayer::setChildren(children);
    303     if (childrenChanged)
    304         noteSublayersChanged();
    305 
    306     return childrenChanged;
    307 }
    308 
    309 void GraphicsLayerCA::addChild(GraphicsLayer* childLayer)
    310 {
    311     GraphicsLayer::addChild(childLayer);
    312     noteSublayersChanged();
    313 }
    314 
    315 void GraphicsLayerCA::addChildAtIndex(GraphicsLayer* childLayer, int index)
    316 {
    317     GraphicsLayer::addChildAtIndex(childLayer, index);
    318     noteSublayersChanged();
    319 }
    320 
    321 void GraphicsLayerCA::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibling)
    322 {
    323     GraphicsLayer::addChildBelow(childLayer, sibling);
    324     noteSublayersChanged();
    325 }
    326 
    327 void GraphicsLayerCA::addChildAbove(GraphicsLayer* childLayer, GraphicsLayer* sibling)
    328 {
    329     GraphicsLayer::addChildAbove(childLayer, sibling);
    330     noteSublayersChanged();
    331 }
    332 
    333 bool GraphicsLayerCA::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
    334 {
    335     if (GraphicsLayer::replaceChild(oldChild, newChild)) {
    336         noteSublayersChanged();
    337         return true;
    338     }
    339     return false;
    340 }
    341 
    342 void GraphicsLayerCA::removeFromParent()
    343 {
    344     if (m_parent)
    345         static_cast<GraphicsLayerCA*>(m_parent)->noteSublayersChanged();
    346     GraphicsLayer::removeFromParent();
    347 }
    348 
    349 void GraphicsLayerCA::setMaskLayer(GraphicsLayer* layer)
    350 {
    351     if (layer == m_maskLayer)
    352         return;
    353 
    354     GraphicsLayer::setMaskLayer(layer);
    355     noteLayerPropertyChanged(MaskLayerChanged);
    356 
    357     propagateLayerChangeToReplicas();
    358 
    359     if (m_replicatedLayer)
    360         static_cast<GraphicsLayerCA*>(m_replicatedLayer)->propagateLayerChangeToReplicas();
    361 }
    362 
    363 void GraphicsLayerCA::setReplicatedLayer(GraphicsLayer* layer)
    364 {
    365     if (layer == m_replicatedLayer)
    366         return;
    367 
    368     GraphicsLayer::setReplicatedLayer(layer);
    369     noteLayerPropertyChanged(ReplicatedLayerChanged);
    370 }
    371 
    372 void GraphicsLayerCA::setReplicatedByLayer(GraphicsLayer* layer)
    373 {
    374     if (layer == m_replicaLayer)
    375         return;
    376 
    377     GraphicsLayer::setReplicatedByLayer(layer);
    378     noteSublayersChanged();
    379     noteLayerPropertyChanged(ReplicatedLayerChanged);
    380 }
    381 
    382 void GraphicsLayerCA::setPosition(const FloatPoint& point)
    383 {
    384     if (point == m_position)
    385         return;
    386 
    387     GraphicsLayer::setPosition(point);
    388     noteLayerPropertyChanged(PositionChanged);
    389 }
    390 
    391 void GraphicsLayerCA::setAnchorPoint(const FloatPoint3D& point)
    392 {
    393     if (point == m_anchorPoint)
    394         return;
    395 
    396     GraphicsLayer::setAnchorPoint(point);
    397     noteLayerPropertyChanged(AnchorPointChanged);
    398 }
    399 
    400 void GraphicsLayerCA::setSize(const FloatSize& size)
    401 {
    402     if (size == m_size)
    403         return;
    404 
    405     GraphicsLayer::setSize(size);
    406     noteLayerPropertyChanged(SizeChanged);
    407 }
    408 
    409 void GraphicsLayerCA::setTransform(const TransformationMatrix& t)
    410 {
    411     if (t == m_transform)
    412         return;
    413 
    414     GraphicsLayer::setTransform(t);
    415     noteLayerPropertyChanged(TransformChanged);
    416 }
    417 
    418 void GraphicsLayerCA::setChildrenTransform(const TransformationMatrix& t)
    419 {
    420     if (t == m_childrenTransform)
    421         return;
    422 
    423     GraphicsLayer::setChildrenTransform(t);
    424     noteLayerPropertyChanged(ChildrenTransformChanged);
    425 }
    426 
    427 void GraphicsLayerCA::moveOrCopyLayerAnimation(MoveOrCopy operation, const String& animationIdentifier, PlatformCALayer *fromLayer, PlatformCALayer *toLayer)
    428 {
    429     RefPtr<PlatformCAAnimation> anim = fromLayer->animationForKey(animationIdentifier);
    430     if (!anim)
    431         return;
    432 
    433     switch (operation) {
    434     case Move:
    435         fromLayer->removeAnimationForKey(animationIdentifier);
    436         toLayer->addAnimationForKey(animationIdentifier, anim.get());
    437         break;
    438 
    439     case Copy:
    440         toLayer->addAnimationForKey(animationIdentifier, anim.get());
    441         break;
    442     }
    443 }
    444 
    445 void GraphicsLayerCA::moveOrCopyAnimationsForProperty(MoveOrCopy operation, AnimatedPropertyID property, PlatformCALayer *fromLayer, PlatformCALayer *toLayer)
    446 {
    447     // Look for running animations affecting this property.
    448     AnimationsMap::const_iterator end = m_runningAnimations.end();
    449     for (AnimationsMap::const_iterator it = m_runningAnimations.begin(); it != end; ++it) {
    450         const Vector<LayerPropertyAnimation>& propertyAnimations = it->second;
    451         size_t numAnimations = propertyAnimations.size();
    452         for (size_t i = 0; i < numAnimations; ++i) {
    453             const LayerPropertyAnimation& currAnimation = propertyAnimations[i];
    454             if (currAnimation.m_property == property)
    455                 moveOrCopyLayerAnimation(operation, animationIdentifier(currAnimation.m_name, currAnimation.m_property, currAnimation.m_index), fromLayer, toLayer);
    456         }
    457     }
    458 }
    459 
    460 void GraphicsLayerCA::setPreserves3D(bool preserves3D)
    461 {
    462     if (preserves3D == m_preserves3D)
    463         return;
    464 
    465     GraphicsLayer::setPreserves3D(preserves3D);
    466     noteLayerPropertyChanged(Preserves3DChanged);
    467 }
    468 
    469 void GraphicsLayerCA::setMasksToBounds(bool masksToBounds)
    470 {
    471     if (masksToBounds == m_masksToBounds)
    472         return;
    473 
    474     GraphicsLayer::setMasksToBounds(masksToBounds);
    475     noteLayerPropertyChanged(MasksToBoundsChanged);
    476 }
    477 
    478 void GraphicsLayerCA::setDrawsContent(bool drawsContent)
    479 {
    480     if (drawsContent == m_drawsContent)
    481         return;
    482 
    483     GraphicsLayer::setDrawsContent(drawsContent);
    484     noteLayerPropertyChanged(DrawsContentChanged);
    485 }
    486 
    487 void GraphicsLayerCA::setAcceleratesDrawing(bool acceleratesDrawing)
    488 {
    489     if (acceleratesDrawing == m_acceleratesDrawing)
    490         return;
    491 
    492     GraphicsLayer::setAcceleratesDrawing(acceleratesDrawing);
    493     noteLayerPropertyChanged(AcceleratesDrawingChanged);
    494 }
    495 
    496 void GraphicsLayerCA::setAllowTiledLayer(bool allowTiledLayer)
    497 {
    498     if (allowTiledLayer == m_allowTiledLayer)
    499         return;
    500 
    501     m_allowTiledLayer = allowTiledLayer;
    502 
    503     // Handling this as a SizeChanged will cause use to switch in or out of tiled layer as needed
    504     noteLayerPropertyChanged(SizeChanged);
    505 }
    506 
    507 void GraphicsLayerCA::setBackgroundColor(const Color& color)
    508 {
    509     if (m_backgroundColorSet && m_backgroundColor == color)
    510         return;
    511 
    512     GraphicsLayer::setBackgroundColor(color);
    513 
    514     m_contentsLayerHasBackgroundColor = true;
    515     noteLayerPropertyChanged(BackgroundColorChanged);
    516 }
    517 
    518 void GraphicsLayerCA::clearBackgroundColor()
    519 {
    520     if (!m_backgroundColorSet)
    521         return;
    522 
    523     GraphicsLayer::clearBackgroundColor();
    524     m_contentsLayerHasBackgroundColor = false;
    525     noteLayerPropertyChanged(BackgroundColorChanged);
    526 }
    527 
    528 void GraphicsLayerCA::setContentsOpaque(bool opaque)
    529 {
    530     if (m_contentsOpaque == opaque)
    531         return;
    532 
    533     GraphicsLayer::setContentsOpaque(opaque);
    534     noteLayerPropertyChanged(ContentsOpaqueChanged);
    535 }
    536 
    537 void GraphicsLayerCA::setBackfaceVisibility(bool visible)
    538 {
    539     if (m_backfaceVisibility == visible)
    540         return;
    541 
    542     GraphicsLayer::setBackfaceVisibility(visible);
    543     noteLayerPropertyChanged(BackfaceVisibilityChanged);
    544 }
    545 
    546 void GraphicsLayerCA::setOpacity(float opacity)
    547 {
    548     float clampedOpacity = max(0.0f, min(opacity, 1.0f));
    549 
    550     if (clampedOpacity == m_opacity)
    551         return;
    552 
    553     GraphicsLayer::setOpacity(clampedOpacity);
    554     noteLayerPropertyChanged(OpacityChanged);
    555 }
    556 
    557 void GraphicsLayerCA::setNeedsDisplay()
    558 {
    559     FloatRect hugeRect(-numeric_limits<float>::max() / 2, -numeric_limits<float>::max() / 2,
    560                        numeric_limits<float>::max(), numeric_limits<float>::max());
    561 
    562     setNeedsDisplayInRect(hugeRect);
    563 }
    564 
    565 void GraphicsLayerCA::setNeedsDisplayInRect(const FloatRect& r)
    566 {
    567     if (!drawsContent())
    568         return;
    569 
    570     FloatRect rect(r);
    571     FloatRect layerBounds(FloatPoint(), m_size);
    572     rect.intersect(layerBounds);
    573     if (rect.isEmpty())
    574         return;
    575 
    576     const size_t maxDirtyRects = 32;
    577 
    578     for (size_t i = 0; i < m_dirtyRects.size(); ++i) {
    579         if (m_dirtyRects[i].contains(rect))
    580             return;
    581     }
    582 
    583     if (m_dirtyRects.size() < maxDirtyRects)
    584         m_dirtyRects.append(rect);
    585     else
    586         m_dirtyRects[0].unite(rect);
    587 
    588     noteLayerPropertyChanged(DirtyRectsChanged);
    589 }
    590 
    591 void GraphicsLayerCA::setContentsNeedsDisplay()
    592 {
    593     noteLayerPropertyChanged(ContentsNeedsDisplay);
    594 }
    595 
    596 void GraphicsLayerCA::setContentsRect(const IntRect& rect)
    597 {
    598     if (rect == m_contentsRect)
    599         return;
    600 
    601     GraphicsLayer::setContentsRect(rect);
    602     noteLayerPropertyChanged(ContentsRectChanged);
    603 }
    604 
    605 bool GraphicsLayerCA::addAnimation(const KeyframeValueList& valueList, const IntSize& boxSize, const Animation* anim, const String& animationName, double timeOffset)
    606 {
    607     ASSERT(!animationName.isEmpty());
    608 
    609     if (!anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2)
    610         return false;
    611 
    612 #if !HAVE_MODERN_QUARTZCORE
    613     // Older versions of QuartzCore do not handle opacity in transform layers properly, so we will
    614     // always do software animation in that case.
    615     if (valueList.property() == AnimatedPropertyOpacity)
    616         return false;
    617 #endif
    618 
    619     // CoreAnimation does not handle the steps() timing function. Fall back
    620     // to software animation in that case.
    621     if (animationHasStepsTimingFunction(valueList, anim))
    622         return false;
    623 
    624     bool createdAnimations = false;
    625     if (valueList.property() == AnimatedPropertyWebkitTransform)
    626         createdAnimations = createTransformAnimationsFromKeyframes(valueList, anim, animationName, timeOffset, boxSize);
    627     else
    628         createdAnimations = createAnimationFromKeyframes(valueList, anim, animationName, timeOffset);
    629 
    630     if (createdAnimations)
    631         noteLayerPropertyChanged(AnimationChanged);
    632 
    633     return createdAnimations;
    634 }
    635 
    636 void GraphicsLayerCA::pauseAnimation(const String& animationName, double timeOffset)
    637 {
    638     if (!animationIsRunning(animationName))
    639         return;
    640 
    641     AnimationsToProcessMap::iterator it = m_animationsToProcess.find(animationName);
    642     if (it != m_animationsToProcess.end()) {
    643         AnimationProcessingAction& processingInfo = it->second;
    644         // If an animation is scheduled to be removed, don't change the remove to a pause.
    645         if (processingInfo.action != Remove)
    646             processingInfo.action = Pause;
    647     } else
    648         m_animationsToProcess.add(animationName, AnimationProcessingAction(Pause, timeOffset));
    649 
    650     noteLayerPropertyChanged(AnimationChanged);
    651 }
    652 
    653 void GraphicsLayerCA::removeAnimation(const String& animationName)
    654 {
    655     if (!animationIsRunning(animationName))
    656         return;
    657 
    658     m_animationsToProcess.add(animationName, AnimationProcessingAction(Remove));
    659     noteLayerPropertyChanged(AnimationChanged);
    660 }
    661 
    662 void GraphicsLayerCA::platformCALayerAnimationStarted(CFTimeInterval startTime)
    663 {
    664     if (m_client)
    665         m_client->notifyAnimationStarted(this, startTime);
    666 }
    667 
    668 void GraphicsLayerCA::setContentsToImage(Image* image)
    669 {
    670     if (image) {
    671         CGImageRef newImage = image->nativeImageForCurrentFrame();
    672         if (!newImage)
    673             return;
    674 
    675         // Check to see if the image changed; we have to do this because the call to
    676         // CGImageCreateCopyWithColorSpace() below can create a new image every time.
    677         if (m_uncorrectedContentsImage && m_uncorrectedContentsImage.get() == newImage)
    678             return;
    679 
    680         m_uncorrectedContentsImage = newImage;
    681         m_pendingContentsImage = newImage;
    682 
    683 #if !PLATFORM(WIN)
    684         CGColorSpaceRef colorSpace = CGImageGetColorSpace(m_pendingContentsImage.get());
    685 
    686         static CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
    687         if (colorSpace && CFEqual(colorSpace, deviceRGB)) {
    688             // CoreGraphics renders images tagged with DeviceRGB using the color space of the main display. When we hand such
    689             // images to CA we need to tag them similarly so CA rendering matches CG rendering.
    690             static CGColorSpaceRef genericRGB = CGDisplayCopyColorSpace(kCGDirectMainDisplay);
    691             m_pendingContentsImage.adoptCF(CGImageCreateCopyWithColorSpace(m_pendingContentsImage.get(), genericRGB));
    692         }
    693 #endif
    694         m_contentsLayerPurpose = ContentsLayerForImage;
    695         if (!m_contentsLayer)
    696             noteSublayersChanged();
    697     } else {
    698         m_uncorrectedContentsImage = 0;
    699         m_pendingContentsImage = 0;
    700         m_contentsLayerPurpose = NoContentsLayer;
    701         if (m_contentsLayer)
    702             noteSublayersChanged();
    703     }
    704 
    705     noteLayerPropertyChanged(ContentsImageChanged);
    706 }
    707 
    708 void GraphicsLayerCA::setContentsToMedia(PlatformLayer* mediaLayer)
    709 {
    710     if (m_contentsLayer && mediaLayer == m_contentsLayer->platformLayer())
    711         return;
    712 
    713     // FIXME: The passed in layer might be a raw layer or an externally created
    714     // PlatformCALayer. To determine this we attempt to get the
    715     // PlatformCALayer pointer. If this returns a null pointer we assume it's
    716     // raw. This test might be invalid if the raw layer is, for instance, the
    717     // PlatformCALayer is using a user data pointer in the raw layer, and
    718     // the creator of the raw layer is using it for some other purpose.
    719     // For now we don't support such a case.
    720     PlatformCALayer* platformCALayer = PlatformCALayer::platformCALayer(mediaLayer);
    721     m_contentsLayer = mediaLayer ? (platformCALayer ? platformCALayer : PlatformCALayer::create(mediaLayer, this)) : 0;
    722     m_contentsLayerPurpose = mediaLayer ? ContentsLayerForMedia : NoContentsLayer;
    723 
    724     noteSublayersChanged();
    725     noteLayerPropertyChanged(ContentsMediaLayerChanged);
    726 }
    727 
    728 void GraphicsLayerCA::setContentsToCanvas(PlatformLayer* canvasLayer)
    729 {
    730     if (m_contentsLayer && canvasLayer == m_contentsLayer->platformLayer())
    731         return;
    732 
    733     // Create the PlatformCALayer to wrap the incoming layer
    734     m_contentsLayer = canvasLayer ? PlatformCALayer::create(canvasLayer, this) : 0;
    735 
    736     m_contentsLayerPurpose = canvasLayer ? ContentsLayerForCanvas : NoContentsLayer;
    737 
    738     noteSublayersChanged();
    739     noteLayerPropertyChanged(ContentsCanvasLayerChanged);
    740 }
    741 
    742 void GraphicsLayerCA::layerDidDisplay(PlatformLayer* layer)
    743 {
    744     PlatformCALayer* currentLayer = PlatformCALayer::platformCALayer(layer);
    745     PlatformCALayer* sourceLayer;
    746     LayerMap* layerCloneMap;
    747 
    748     if (currentLayer == m_layer) {
    749         sourceLayer = m_layer.get();
    750         layerCloneMap = m_layerClones.get();
    751     } else if (currentLayer == m_contentsLayer) {
    752         sourceLayer = m_contentsLayer.get();
    753         layerCloneMap = m_contentsLayerClones.get();
    754     } else
    755         return;
    756 
    757     if (layerCloneMap) {
    758         LayerMap::const_iterator end = layerCloneMap->end();
    759         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
    760             PlatformCALayer* currClone = it->second.get();
    761             if (!currClone)
    762                 continue;
    763 
    764             if (currClone->contents() != sourceLayer->contents())
    765                 currClone->setContents(sourceLayer->contents());
    766             else
    767                 currClone->setContentsChanged();
    768         }
    769     }
    770 }
    771 
    772 void GraphicsLayerCA::syncCompositingState()
    773 {
    774     recursiveCommitChanges();
    775 }
    776 
    777 void GraphicsLayerCA::syncCompositingStateForThisLayerOnly()
    778 {
    779     commitLayerChangesBeforeSublayers();
    780     commitLayerChangesAfterSublayers();
    781 }
    782 
    783 void GraphicsLayerCA::recursiveCommitChanges()
    784 {
    785     commitLayerChangesBeforeSublayers();
    786 
    787     if (m_maskLayer)
    788         static_cast<GraphicsLayerCA*>(m_maskLayer)->commitLayerChangesBeforeSublayers();
    789 
    790     const Vector<GraphicsLayer*>& childLayers = children();
    791     size_t numChildren = childLayers.size();
    792     for (size_t i = 0; i < numChildren; ++i) {
    793         GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
    794         curChild->recursiveCommitChanges();
    795     }
    796 
    797     if (m_replicaLayer)
    798         static_cast<GraphicsLayerCA*>(m_replicaLayer)->recursiveCommitChanges();
    799 
    800     if (m_maskLayer)
    801         static_cast<GraphicsLayerCA*>(m_maskLayer)->commitLayerChangesAfterSublayers();
    802 
    803     commitLayerChangesAfterSublayers();
    804 }
    805 
    806 void GraphicsLayerCA::commitLayerChangesBeforeSublayers()
    807 {
    808     if (!m_uncommittedChanges)
    809         return;
    810 
    811     // Need to handle Preserves3DChanged first, because it affects which layers subsequent properties are applied to
    812     if (m_uncommittedChanges & (Preserves3DChanged | ReplicatedLayerChanged))
    813         updateStructuralLayer();
    814 
    815     if (m_uncommittedChanges & NameChanged)
    816         updateLayerNames();
    817 
    818     if (m_uncommittedChanges & ContentsImageChanged) // Needs to happen before ChildrenChanged
    819         updateContentsImage();
    820 
    821     if (m_uncommittedChanges & ContentsMediaLayerChanged) // Needs to happen before ChildrenChanged
    822         updateContentsMediaLayer();
    823 
    824     if (m_uncommittedChanges & ContentsCanvasLayerChanged) // Needs to happen before ChildrenChanged
    825         updateContentsCanvasLayer();
    826 
    827     if (m_uncommittedChanges & BackgroundColorChanged) // Needs to happen before ChildrenChanged, and after updating image or video
    828         updateLayerBackgroundColor();
    829 
    830     if (m_uncommittedChanges & ChildrenChanged)
    831         updateSublayerList();
    832 
    833     if (m_uncommittedChanges & PositionChanged)
    834         updateLayerPosition();
    835 
    836     if (m_uncommittedChanges & AnchorPointChanged)
    837         updateAnchorPoint();
    838 
    839     if (m_uncommittedChanges & SizeChanged)
    840         updateLayerSize();
    841 
    842     if (m_uncommittedChanges & TransformChanged)
    843         updateTransform();
    844 
    845     if (m_uncommittedChanges & ChildrenTransformChanged)
    846         updateChildrenTransform();
    847 
    848     if (m_uncommittedChanges & MasksToBoundsChanged)
    849         updateMasksToBounds();
    850 
    851     if (m_uncommittedChanges & DrawsContentChanged)
    852         updateLayerDrawsContent();
    853 
    854     if (m_uncommittedChanges & ContentsOpaqueChanged)
    855         updateContentsOpaque();
    856 
    857     if (m_uncommittedChanges & BackfaceVisibilityChanged)
    858         updateBackfaceVisibility();
    859 
    860     if (m_uncommittedChanges & OpacityChanged)
    861         updateOpacityOnLayer();
    862 
    863     if (m_uncommittedChanges & AnimationChanged)
    864         updateLayerAnimations();
    865 
    866     if (m_uncommittedChanges & DirtyRectsChanged)
    867         repaintLayerDirtyRects();
    868 
    869     if (m_uncommittedChanges & ContentsRectChanged)
    870         updateContentsRect();
    871 
    872     if (m_uncommittedChanges & MaskLayerChanged)
    873         updateMaskLayer();
    874 
    875     if (m_uncommittedChanges & ContentsNeedsDisplay)
    876         updateContentsNeedsDisplay();
    877 
    878     if (m_uncommittedChanges & AcceleratesDrawingChanged)
    879         updateAcceleratesDrawing();
    880 
    881     if (m_uncommittedChanges & ContentsScaleChanged)
    882         updateContentsScale();
    883 }
    884 
    885 void GraphicsLayerCA::commitLayerChangesAfterSublayers()
    886 {
    887     if (!m_uncommittedChanges)
    888         return;
    889 
    890     if (m_uncommittedChanges & ReplicatedLayerChanged)
    891         updateReplicatedLayers();
    892 
    893     m_uncommittedChanges = NoChange;
    894 }
    895 
    896 void GraphicsLayerCA::updateLayerNames()
    897 {
    898     switch (structuralLayerPurpose()) {
    899     case StructuralLayerForPreserves3D:
    900         m_structuralLayer->setName("Transform layer " + name());
    901         break;
    902     case StructuralLayerForReplicaFlattening:
    903         m_structuralLayer->setName("Replica flattening layer " + name());
    904         break;
    905     case NoStructuralLayer:
    906         break;
    907     }
    908     m_layer->setName(name());
    909 }
    910 
    911 void GraphicsLayerCA::updateSublayerList()
    912 {
    913     PlatformCALayerList newSublayers;
    914     const Vector<GraphicsLayer*>& childLayers = children();
    915 
    916     if (m_structuralLayer || m_contentsLayer || childLayers.size() > 0) {
    917         if (m_structuralLayer) {
    918             // Add the replica layer first.
    919             if (m_replicaLayer)
    920                 newSublayers.append(static_cast<GraphicsLayerCA*>(m_replicaLayer)->primaryLayer());
    921             // Add the primary layer. Even if we have negative z-order children, the primary layer always comes behind.
    922             newSublayers.append(m_layer);
    923         } else if (m_contentsLayer) {
    924             // FIXME: add the contents layer in the correct order with negative z-order children.
    925             // This does not cause visible rendering issues because currently contents layers are only used
    926             // for replaced elements that don't have children.
    927             newSublayers.append(m_contentsLayer);
    928         }
    929 
    930         size_t numChildren = childLayers.size();
    931         for (size_t i = 0; i < numChildren; ++i) {
    932             GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
    933             PlatformCALayer* childLayer = curChild->layerForSuperlayer();
    934             newSublayers.append(childLayer);
    935         }
    936 
    937         for (size_t i = 0; i < newSublayers.size(); --i)
    938             newSublayers[i]->removeFromSuperlayer();
    939     }
    940 
    941     if (m_structuralLayer) {
    942         m_structuralLayer->setSublayers(newSublayers);
    943 
    944         if (m_contentsLayer) {
    945             // If we have a transform layer, then the contents layer is parented in the
    946             // primary layer (which is itself a child of the transform layer).
    947             m_layer->removeAllSublayers();
    948             m_layer->appendSublayer(m_contentsLayer.get());
    949         }
    950     } else
    951         m_layer->setSublayers(newSublayers);
    952 }
    953 
    954 void GraphicsLayerCA::updateLayerPosition()
    955 {
    956     FloatSize usedSize = m_usingTiledLayer ? constrainedSize() : m_size;
    957 
    958     // Position is offset on the layer by the layer anchor point.
    959     FloatPoint posPoint(m_position.x() + m_anchorPoint.x() * usedSize.width(),
    960                           m_position.y() + m_anchorPoint.y() * usedSize.height());
    961 
    962     primaryLayer()->setPosition(posPoint);
    963 
    964     if (LayerMap* layerCloneMap = primaryLayerClones()) {
    965         LayerMap::const_iterator end = layerCloneMap->end();
    966         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
    967             FloatPoint clonePosition = posPoint;
    968             if (m_replicaLayer && isReplicatedRootClone(it->first)) {
    969                 // Maintain the special-case position for the root of a clone subtree,
    970                 // which we set up in replicatedLayerRoot().
    971                 clonePosition = positionForCloneRootLayer();
    972             }
    973             it->second->setPosition(clonePosition);
    974         }
    975     }
    976 }
    977 
    978 void GraphicsLayerCA::updateLayerSize()
    979 {
    980     FloatRect rect(0, 0, m_size.width(), m_size.height());
    981     if (m_structuralLayer) {
    982         m_structuralLayer->setBounds(rect);
    983 
    984         if (LayerMap* layerCloneMap = m_structuralLayerClones.get()) {
    985             LayerMap::const_iterator end = layerCloneMap->end();
    986             for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
    987                 it->second->setBounds(rect);
    988         }
    989 
    990         // The anchor of the contents layer is always at 0.5, 0.5, so the position is center-relative.
    991         CGPoint centerPoint = CGPointMake(m_size.width() / 2.0f, m_size.height() / 2.0f);
    992         m_layer->setPosition(centerPoint);
    993 
    994         if (LayerMap* layerCloneMap = m_layerClones.get()) {
    995             LayerMap::const_iterator end = layerCloneMap->end();
    996             for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
    997                 it->second->setPosition(centerPoint);
    998         }
    999     }
   1000 
   1001     bool needTiledLayer = requiresTiledLayer(m_size);
   1002     if (needTiledLayer != m_usingTiledLayer)
   1003         swapFromOrToTiledLayer(needTiledLayer);
   1004 
   1005     if (m_usingTiledLayer) {
   1006         FloatSize sizeToUse = constrainedSize();
   1007         rect = CGRectMake(0, 0, sizeToUse.width(), sizeToUse.height());
   1008     }
   1009 
   1010     m_layer->setBounds(rect);
   1011     if (LayerMap* layerCloneMap = m_layerClones.get()) {
   1012         LayerMap::const_iterator end = layerCloneMap->end();
   1013         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
   1014             it->second->setBounds(rect);
   1015     }
   1016 
   1017     // Contents transform may depend on height.
   1018     updateContentsTransform();
   1019 
   1020     // Note that we don't resize m_contentsLayer. It's up the caller to do that.
   1021 
   1022     // if we've changed the bounds, we need to recalculate the position
   1023     // of the layer, taking anchor point into account.
   1024     updateLayerPosition();
   1025 }
   1026 
   1027 void GraphicsLayerCA::updateAnchorPoint()
   1028 {
   1029     primaryLayer()->setAnchorPoint(m_anchorPoint);
   1030 
   1031     if (LayerMap* layerCloneMap = primaryLayerClones()) {
   1032         LayerMap::const_iterator end = layerCloneMap->end();
   1033         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
   1034             PlatformCALayer* currLayer = it->second.get();
   1035             currLayer->setAnchorPoint(m_anchorPoint);
   1036         }
   1037     }
   1038 
   1039     updateLayerPosition();
   1040 }
   1041 
   1042 void GraphicsLayerCA::updateTransform()
   1043 {
   1044     primaryLayer()->setTransform(m_transform);
   1045 
   1046     if (LayerMap* layerCloneMap = primaryLayerClones()) {
   1047         LayerMap::const_iterator end = layerCloneMap->end();
   1048         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
   1049             PlatformCALayer* currLayer = it->second.get();
   1050             if (m_replicaLayer && isReplicatedRootClone(it->first)) {
   1051                 // Maintain the special-case transform for the root of a clone subtree,
   1052                 // which we set up in replicatedLayerRoot().
   1053                 currLayer->setTransform(TransformationMatrix());
   1054             } else
   1055                 currLayer->setTransform(m_transform);
   1056         }
   1057     }
   1058 }
   1059 
   1060 void GraphicsLayerCA::updateChildrenTransform()
   1061 {
   1062     primaryLayer()->setSublayerTransform(m_childrenTransform);
   1063 
   1064     if (LayerMap* layerCloneMap = primaryLayerClones()) {
   1065         LayerMap::const_iterator end = layerCloneMap->end();
   1066         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
   1067             it->second->setSublayerTransform(m_childrenTransform);
   1068     }
   1069 }
   1070 
   1071 void GraphicsLayerCA::updateMasksToBounds()
   1072 {
   1073     m_layer->setMasksToBounds(m_masksToBounds);
   1074 
   1075     if (LayerMap* layerCloneMap = m_layerClones.get()) {
   1076         LayerMap::const_iterator end = layerCloneMap->end();
   1077         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
   1078             it->second->setMasksToBounds(m_masksToBounds);
   1079     }
   1080 
   1081     updateDebugIndicators();
   1082 }
   1083 
   1084 void GraphicsLayerCA::updateContentsOpaque()
   1085 {
   1086     m_layer.get()->setOpaque(m_contentsOpaque);
   1087 
   1088     if (LayerMap* layerCloneMap = m_layerClones.get()) {
   1089         LayerMap::const_iterator end = layerCloneMap->end();
   1090         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
   1091             it->second->setOpaque(m_contentsOpaque);
   1092     }
   1093 }
   1094 
   1095 void GraphicsLayerCA::updateBackfaceVisibility()
   1096 {
   1097     if (m_structuralLayer && structuralLayerPurpose() == StructuralLayerForReplicaFlattening) {
   1098         m_structuralLayer->setDoubleSided(m_backfaceVisibility);
   1099 
   1100         if (LayerMap* layerCloneMap = m_structuralLayerClones.get()) {
   1101             LayerMap::const_iterator end = layerCloneMap->end();
   1102             for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
   1103                 it->second->setDoubleSided(m_backfaceVisibility);
   1104         }
   1105     }
   1106 
   1107     m_layer->setDoubleSided(m_backfaceVisibility);
   1108 
   1109     if (LayerMap* layerCloneMap = m_layerClones.get()) {
   1110         LayerMap::const_iterator end = layerCloneMap->end();
   1111         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
   1112             it->second->setDoubleSided(m_backfaceVisibility);
   1113     }
   1114 }
   1115 
   1116 void GraphicsLayerCA::updateStructuralLayer()
   1117 {
   1118     ensureStructuralLayer(structuralLayerPurpose());
   1119 }
   1120 
   1121 void GraphicsLayerCA::ensureStructuralLayer(StructuralLayerPurpose purpose)
   1122 {
   1123     if (purpose == NoStructuralLayer) {
   1124         if (m_structuralLayer) {
   1125             // Replace the transformLayer in the parent with this layer.
   1126             m_layer->removeFromSuperlayer();
   1127 
   1128             // If m_layer doesn't have a parent, it means it's the root layer and
   1129             // is likely hosted by something that is not expecting to be changed
   1130             ASSERT(m_structuralLayer->superlayer());
   1131             m_structuralLayer->superlayer()->replaceSublayer(m_structuralLayer.get(), m_layer.get());
   1132 
   1133             moveOrCopyAnimationsForProperty(Move, AnimatedPropertyWebkitTransform, m_structuralLayer.get(), m_layer.get());
   1134             moveOrCopyAnimationsForProperty(Move, AnimatedPropertyOpacity, m_structuralLayer.get(), m_layer.get());
   1135 
   1136             // Release the structural layer.
   1137             m_structuralLayer = 0;
   1138 
   1139             // Update the properties of m_layer now that we no longer have a structural layer.
   1140             updateLayerPosition();
   1141             updateLayerSize();
   1142             updateAnchorPoint();
   1143             updateTransform();
   1144             updateChildrenTransform();
   1145 
   1146             updateSublayerList();
   1147             updateOpacityOnLayer();
   1148         }
   1149         return;
   1150     }
   1151 
   1152     bool structuralLayerChanged = false;
   1153 
   1154     if (purpose == StructuralLayerForPreserves3D) {
   1155         if (m_structuralLayer && m_structuralLayer->layerType() != PlatformCALayer::LayerTypeTransformLayer)
   1156             m_structuralLayer = 0;
   1157 
   1158         if (!m_structuralLayer) {
   1159             m_structuralLayer = PlatformCALayer::create(PlatformCALayer::LayerTypeTransformLayer, this);
   1160             structuralLayerChanged = true;
   1161         }
   1162     } else {
   1163         if (m_structuralLayer && m_structuralLayer->layerType() != PlatformCALayer::LayerTypeLayer)
   1164             m_structuralLayer = 0;
   1165 
   1166         if (!m_structuralLayer) {
   1167             m_structuralLayer = PlatformCALayer::create(PlatformCALayer::LayerTypeLayer, this);
   1168             structuralLayerChanged = true;
   1169         }
   1170     }
   1171 
   1172     if (!structuralLayerChanged)
   1173         return;
   1174 
   1175     updateLayerNames();
   1176 
   1177     // Update the properties of the structural layer.
   1178     updateLayerPosition();
   1179     updateLayerSize();
   1180     updateAnchorPoint();
   1181     updateTransform();
   1182     updateChildrenTransform();
   1183     updateBackfaceVisibility();
   1184 
   1185     // Set properties of m_layer to their default values, since these are expressed on on the structural layer.
   1186     FloatPoint point(m_size.width() / 2.0f, m_size.height() / 2.0f);
   1187     FloatPoint3D anchorPoint(0.5f, 0.5f, 0);
   1188     m_layer->setPosition(point);
   1189     m_layer->setAnchorPoint(anchorPoint);
   1190     m_layer->setTransform(TransformationMatrix());
   1191     m_layer->setOpacity(1);
   1192     if (m_layerClones) {
   1193         LayerMap::const_iterator end = m_layerClones->end();
   1194         for (LayerMap::const_iterator it = m_layerClones->begin(); it != end; ++it) {
   1195             PlatformCALayer* currLayer = it->second.get();
   1196             currLayer->setPosition(point);
   1197             currLayer->setAnchorPoint(anchorPoint);
   1198             currLayer->setTransform(TransformationMatrix());
   1199             currLayer->setOpacity(1);
   1200         }
   1201     }
   1202 
   1203     // Move this layer to be a child of the transform layer.
   1204     // If m_layer doesn't have a parent, it means it's the root layer and
   1205     // is likely hosted by something that is not expecting to be changed
   1206     ASSERT(m_layer->superlayer());
   1207     m_layer->superlayer()->replaceSublayer(m_layer.get(), m_structuralLayer.get());
   1208     m_structuralLayer->appendSublayer(m_layer.get());
   1209 
   1210     moveOrCopyAnimationsForProperty(Move, AnimatedPropertyWebkitTransform, m_layer.get(), m_structuralLayer.get());
   1211     moveOrCopyAnimationsForProperty(Move, AnimatedPropertyOpacity, m_layer.get(), m_structuralLayer.get());
   1212 
   1213     updateSublayerList();
   1214     updateOpacityOnLayer();
   1215 }
   1216 
   1217 GraphicsLayerCA::StructuralLayerPurpose GraphicsLayerCA::structuralLayerPurpose() const
   1218 {
   1219     if (preserves3D())
   1220         return StructuralLayerForPreserves3D;
   1221 
   1222     if (isReplicated())
   1223         return StructuralLayerForReplicaFlattening;
   1224 
   1225     return NoStructuralLayer;
   1226 }
   1227 
   1228 void GraphicsLayerCA::updateLayerDrawsContent()
   1229 {
   1230     bool needTiledLayer = requiresTiledLayer(m_size);
   1231     if (needTiledLayer != m_usingTiledLayer)
   1232         swapFromOrToTiledLayer(needTiledLayer);
   1233 
   1234     if (m_drawsContent)
   1235         m_layer->setNeedsDisplay();
   1236     else
   1237         m_layer->setContents(0);
   1238 
   1239     updateDebugIndicators();
   1240 }
   1241 
   1242 void GraphicsLayerCA::updateAcceleratesDrawing()
   1243 {
   1244     m_layer->setAcceleratesDrawing(m_acceleratesDrawing);
   1245 }
   1246 
   1247 void GraphicsLayerCA::updateLayerBackgroundColor()
   1248 {
   1249     if (!m_contentsLayer)
   1250         return;
   1251 
   1252     // We never create the contents layer just for background color yet.
   1253     if (m_backgroundColorSet)
   1254         m_contentsLayer->setBackgroundColor(m_backgroundColor);
   1255     else
   1256         m_contentsLayer->setBackgroundColor(Color::transparent);
   1257 }
   1258 
   1259 void GraphicsLayerCA::updateContentsImage()
   1260 {
   1261     if (m_pendingContentsImage) {
   1262         if (!m_contentsLayer.get()) {
   1263             m_contentsLayer = PlatformCALayer::create(PlatformCALayer::LayerTypeLayer, this);
   1264 #ifndef NDEBUG
   1265             m_contentsLayer->setName("Image Layer");
   1266 #endif
   1267             setupContentsLayer(m_contentsLayer.get());
   1268             // m_contentsLayer will be parented by updateSublayerList
   1269         }
   1270 
   1271         // FIXME: maybe only do trilinear if the image is being scaled down,
   1272         // but then what if the layer size changes?
   1273 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
   1274         m_contentsLayer->setMinificationFilter(PlatformCALayer::Trilinear);
   1275 #endif
   1276         m_contentsLayer->setContents(m_pendingContentsImage.get());
   1277         m_pendingContentsImage = 0;
   1278 
   1279         if (m_contentsLayerClones) {
   1280             LayerMap::const_iterator end = m_contentsLayerClones->end();
   1281             for (LayerMap::const_iterator it = m_contentsLayerClones->begin(); it != end; ++it)
   1282                 it->second->setContents(m_contentsLayer->contents());
   1283         }
   1284 
   1285         updateContentsRect();
   1286     } else {
   1287         // No image.
   1288         // m_contentsLayer will be removed via updateSublayerList.
   1289         m_contentsLayer = 0;
   1290     }
   1291 }
   1292 
   1293 void GraphicsLayerCA::updateContentsMediaLayer()
   1294 {
   1295     // Video layer was set as m_contentsLayer, and will get parented in updateSublayerList().
   1296     if (m_contentsLayer) {
   1297         setupContentsLayer(m_contentsLayer.get());
   1298         updateContentsRect();
   1299     }
   1300 }
   1301 
   1302 void GraphicsLayerCA::updateContentsCanvasLayer()
   1303 {
   1304     // CanvasLayer was set as m_contentsLayer, and will get parented in updateSublayerList().
   1305     if (m_contentsLayer) {
   1306         setupContentsLayer(m_contentsLayer.get());
   1307         m_contentsLayer->setNeedsDisplay();
   1308         updateContentsRect();
   1309     }
   1310 }
   1311 
   1312 void GraphicsLayerCA::updateContentsRect()
   1313 {
   1314     if (!m_contentsLayer)
   1315         return;
   1316 
   1317     FloatPoint point(m_contentsRect.x(), m_contentsRect.y());
   1318     FloatRect rect(0, 0, m_contentsRect.width(), m_contentsRect.height());
   1319 
   1320     m_contentsLayer->setPosition(point);
   1321     m_contentsLayer->setBounds(rect);
   1322 
   1323     if (m_contentsLayerClones) {
   1324         LayerMap::const_iterator end = m_contentsLayerClones->end();
   1325         for (LayerMap::const_iterator it = m_contentsLayerClones->begin(); it != end; ++it) {
   1326             it->second->setPosition(point);
   1327             it->second->setBounds(rect);
   1328         }
   1329     }
   1330 }
   1331 
   1332 void GraphicsLayerCA::updateMaskLayer()
   1333 {
   1334     PlatformCALayer* maskCALayer = m_maskLayer ? static_cast<GraphicsLayerCA*>(m_maskLayer)->primaryLayer() : 0;
   1335     m_layer->setMask(maskCALayer);
   1336 
   1337     LayerMap* maskLayerCloneMap = m_maskLayer ? static_cast<GraphicsLayerCA*>(m_maskLayer)->primaryLayerClones() : 0;
   1338 
   1339     if (LayerMap* layerCloneMap = m_layerClones.get()) {
   1340         LayerMap::const_iterator end = layerCloneMap->end();
   1341         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
   1342             PlatformCALayer* maskClone = maskLayerCloneMap ? maskLayerCloneMap->get(it->first).get() : 0;
   1343             it->second->setMask(maskClone);
   1344         }
   1345     }
   1346 }
   1347 
   1348 void GraphicsLayerCA::updateReplicatedLayers()
   1349 {
   1350     // Clone the descendants of the replicated layer, and parent under us.
   1351     ReplicaState replicaState(ReplicaState::ReplicaBranch);
   1352 
   1353     RefPtr<PlatformCALayer>replicaRoot = replicatedLayerRoot(replicaState);
   1354     if (!replicaRoot)
   1355         return;
   1356 
   1357     if (m_structuralLayer)
   1358         m_structuralLayer->insertSublayer(replicaRoot.get(), 0);
   1359     else
   1360         m_layer->insertSublayer(replicaRoot.get(), 0);
   1361 }
   1362 
   1363 // For now, this assumes that layers only ever have one replica, so replicaIndices contains only 0 and 1.
   1364 GraphicsLayerCA::CloneID GraphicsLayerCA::ReplicaState::cloneID() const
   1365 {
   1366     size_t depth = m_replicaBranches.size();
   1367 
   1368     const size_t bitsPerUChar = sizeof(UChar) * 8;
   1369     size_t vectorSize = (depth + bitsPerUChar - 1) / bitsPerUChar;
   1370 
   1371     Vector<UChar> result(vectorSize);
   1372     result.fill(0);
   1373 
   1374     // Create a string from the bit sequence which we can use to identify the clone.
   1375     // Note that the string may contain embedded nulls, but that's OK.
   1376     for (size_t i = 0; i < depth; ++i) {
   1377         UChar& currChar = result[i / bitsPerUChar];
   1378         currChar = (currChar << 1) | m_replicaBranches[i];
   1379     }
   1380 
   1381     return String::adopt(result);
   1382 }
   1383 
   1384 PassRefPtr<PlatformCALayer> GraphicsLayerCA::replicatedLayerRoot(ReplicaState& replicaState)
   1385 {
   1386     // Limit replica nesting, to avoid 2^N explosion of replica layers.
   1387     if (!m_replicatedLayer || replicaState.replicaDepth() == ReplicaState::maxReplicaDepth)
   1388         return 0;
   1389 
   1390     GraphicsLayerCA* replicatedLayer = static_cast<GraphicsLayerCA*>(m_replicatedLayer);
   1391 
   1392     RefPtr<PlatformCALayer> clonedLayerRoot = replicatedLayer->fetchCloneLayers(this, replicaState, RootCloneLevel);
   1393     FloatPoint cloneRootPosition = replicatedLayer->positionForCloneRootLayer();
   1394 
   1395     // Replica root has no offset or transform
   1396     clonedLayerRoot->setPosition(cloneRootPosition);
   1397     clonedLayerRoot->setTransform(TransformationMatrix());
   1398 
   1399     return clonedLayerRoot;
   1400 }
   1401 
   1402 void GraphicsLayerCA::updateLayerAnimations()
   1403 {
   1404     if (m_animationsToProcess.size()) {
   1405         AnimationsToProcessMap::const_iterator end = m_animationsToProcess.end();
   1406         for (AnimationsToProcessMap::const_iterator it = m_animationsToProcess.begin(); it != end; ++it) {
   1407             const String& currAnimationName = it->first;
   1408             AnimationsMap::iterator animationIt = m_runningAnimations.find(currAnimationName);
   1409             if (animationIt == m_runningAnimations.end())
   1410                 continue;
   1411 
   1412             const AnimationProcessingAction& processingInfo = it->second;
   1413             const Vector<LayerPropertyAnimation>& animations = animationIt->second;
   1414             for (size_t i = 0; i < animations.size(); ++i) {
   1415                 const LayerPropertyAnimation& currAnimation = animations[i];
   1416                 switch (processingInfo.action) {
   1417                 case Remove:
   1418                     removeCAAnimationFromLayer(currAnimation.m_property, currAnimationName, currAnimation.m_index);
   1419                     break;
   1420                 case Pause:
   1421                     pauseCAAnimationOnLayer(currAnimation.m_property, currAnimationName, currAnimation.m_index, processingInfo.timeOffset);
   1422                     break;
   1423                 }
   1424             }
   1425 
   1426             if (processingInfo.action == Remove)
   1427                 m_runningAnimations.remove(currAnimationName);
   1428         }
   1429 
   1430         m_animationsToProcess.clear();
   1431     }
   1432 
   1433     size_t numAnimations;
   1434     if ((numAnimations = m_uncomittedAnimations.size())) {
   1435         for (size_t i = 0; i < numAnimations; ++i) {
   1436             const LayerPropertyAnimation& pendingAnimation = m_uncomittedAnimations[i];
   1437             setAnimationOnLayer(pendingAnimation.m_animation.get(), pendingAnimation.m_property, pendingAnimation.m_name, pendingAnimation.m_index, pendingAnimation.m_timeOffset);
   1438 
   1439             AnimationsMap::iterator it = m_runningAnimations.find(pendingAnimation.m_name);
   1440             if (it == m_runningAnimations.end()) {
   1441                 Vector<LayerPropertyAnimation> animations;
   1442                 animations.append(pendingAnimation);
   1443                 m_runningAnimations.add(pendingAnimation.m_name, animations);
   1444             } else {
   1445                 Vector<LayerPropertyAnimation>& animations = it->second;
   1446                 animations.append(pendingAnimation);
   1447             }
   1448         }
   1449 
   1450         m_uncomittedAnimations.clear();
   1451     }
   1452 }
   1453 
   1454 void GraphicsLayerCA::setAnimationOnLayer(PlatformCAAnimation* caAnim, AnimatedPropertyID property, const String& animationName, int index, double timeOffset)
   1455 {
   1456     PlatformCALayer* layer = animatedLayer(property);
   1457 
   1458     if (timeOffset)
   1459         caAnim->setBeginTime(CACurrentMediaTime() - timeOffset);
   1460 
   1461     String animationID = animationIdentifier(animationName, property, index);
   1462 
   1463     layer->removeAnimationForKey(animationID);
   1464     layer->addAnimationForKey(animationID, caAnim);
   1465 
   1466     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
   1467         LayerMap::const_iterator end = layerCloneMap->end();
   1468         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
   1469             // Skip immediate replicas, since they move with the original.
   1470             if (m_replicaLayer && isReplicatedRootClone(it->first))
   1471                 continue;
   1472 
   1473             it->second->removeAnimationForKey(animationID);
   1474             it->second->addAnimationForKey(animationID, caAnim);
   1475         }
   1476     }
   1477 }
   1478 
   1479 // Workaround for <rdar://problem/7311367>
   1480 static void bug7311367Workaround(PlatformCALayer* transformLayer, const TransformationMatrix& transform)
   1481 {
   1482     if (!transformLayer)
   1483         return;
   1484 
   1485     TransformationMatrix caTransform = transform;
   1486     caTransform.setM41(caTransform.m41() + 1);
   1487     transformLayer->setTransform(caTransform);
   1488 
   1489     caTransform.setM41(caTransform.m41() - 1);
   1490     transformLayer->setTransform(caTransform);
   1491 }
   1492 
   1493 bool GraphicsLayerCA::removeCAAnimationFromLayer(AnimatedPropertyID property, const String& animationName, int index)
   1494 {
   1495     PlatformCALayer* layer = animatedLayer(property);
   1496 
   1497     String animationID = animationIdentifier(animationName, property, index);
   1498 
   1499     if (!layer->animationForKey(animationID))
   1500         return false;
   1501 
   1502     layer->removeAnimationForKey(animationID);
   1503     bug7311367Workaround(m_structuralLayer.get(), m_transform);
   1504 
   1505     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
   1506         LayerMap::const_iterator end = layerCloneMap->end();
   1507         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
   1508             // Skip immediate replicas, since they move with the original.
   1509             if (m_replicaLayer && isReplicatedRootClone(it->first))
   1510                 continue;
   1511 
   1512             it->second ->removeAnimationForKey(animationID);
   1513         }
   1514     }
   1515     return true;
   1516 }
   1517 
   1518 void GraphicsLayerCA::pauseCAAnimationOnLayer(AnimatedPropertyID property, const String& animationName, int index, double timeOffset)
   1519 {
   1520     PlatformCALayer* layer = animatedLayer(property);
   1521 
   1522     String animationID = animationIdentifier(animationName, property, index);
   1523 
   1524     RefPtr<PlatformCAAnimation> curAnim = layer->animationForKey(animationID);
   1525     if (!curAnim)
   1526         return;
   1527 
   1528     // Animations on the layer are immutable, so we have to clone and modify.
   1529     RefPtr<PlatformCAAnimation> newAnim = curAnim->copy();
   1530 
   1531     newAnim->setSpeed(0);
   1532     newAnim->setTimeOffset(timeOffset);
   1533 
   1534     layer->addAnimationForKey(animationID, newAnim.get()); // This will replace the running animation.
   1535 
   1536     // Pause the animations on the clones too.
   1537     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
   1538         LayerMap::const_iterator end = layerCloneMap->end();
   1539         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
   1540             // Skip immediate replicas, since they move with the original.
   1541             if (m_replicaLayer && isReplicatedRootClone(it->first))
   1542                 continue;
   1543             it->second->addAnimationForKey(animationID, newAnim.get());
   1544         }
   1545     }
   1546 }
   1547 
   1548 void GraphicsLayerCA::repaintLayerDirtyRects()
   1549 {
   1550     if (!m_dirtyRects.size())
   1551         return;
   1552 
   1553     for (size_t i = 0; i < m_dirtyRects.size(); ++i)
   1554         m_layer->setNeedsDisplay(&(m_dirtyRects[i]));
   1555 
   1556     m_dirtyRects.clear();
   1557 }
   1558 
   1559 void GraphicsLayerCA::updateContentsNeedsDisplay()
   1560 {
   1561     if (m_contentsLayer)
   1562         m_contentsLayer->setNeedsDisplay();
   1563 }
   1564 
   1565 bool GraphicsLayerCA::createAnimationFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset)
   1566 {
   1567     ASSERT(valueList.property() != AnimatedPropertyWebkitTransform);
   1568 
   1569     bool isKeyframe = valueList.size() > 2;
   1570     bool valuesOK;
   1571 
   1572     bool additive = false;
   1573     int animationIndex = 0;
   1574 
   1575     RefPtr<PlatformCAAnimation> caAnimation;
   1576 
   1577     if (isKeyframe) {
   1578         caAnimation = createKeyframeAnimation(animation, valueList.property(), additive);
   1579         valuesOK = setAnimationKeyframes(valueList, animation, caAnimation.get());
   1580     } else {
   1581         caAnimation = createBasicAnimation(animation, valueList.property(), additive);
   1582         valuesOK = setAnimationEndpoints(valueList, animation, caAnimation.get());
   1583     }
   1584 
   1585     if (!valuesOK)
   1586         return false;
   1587 
   1588     m_uncomittedAnimations.append(LayerPropertyAnimation(caAnimation, animationName, valueList.property(), animationIndex, timeOffset));
   1589 
   1590     return true;
   1591 }
   1592 
   1593 bool GraphicsLayerCA::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset, const IntSize& boxSize)
   1594 {
   1595     ASSERT(valueList.property() == AnimatedPropertyWebkitTransform);
   1596 
   1597     TransformOperationList functionList;
   1598     bool listsMatch, hasBigRotation;
   1599     fetchTransformOperationList(valueList, functionList, listsMatch, hasBigRotation);
   1600 
   1601     // We need to fall back to software animation if we don't have setValueFunction:, and
   1602     // we would need to animate each incoming transform function separately. This is the
   1603     // case if we have a rotation >= 180 or we have more than one transform function.
   1604     if ((hasBigRotation || functionList.size() > 1) && !PlatformCAAnimation::supportsValueFunction())
   1605         return false;
   1606 
   1607     bool validMatrices = true;
   1608 
   1609     // If functionLists don't match we do a matrix animation, otherwise we do a component hardware animation.
   1610     // Also, we can't do component animation unless we have valueFunction, so we need to do matrix animation
   1611     // if that's not true as well.
   1612     bool isMatrixAnimation = !listsMatch || !PlatformCAAnimation::supportsValueFunction();
   1613 
   1614     size_t numAnimations = isMatrixAnimation ? 1 : functionList.size();
   1615     bool isKeyframe = valueList.size() > 2;
   1616 
   1617     // Iterate through the transform functions, sending an animation for each one.
   1618     for (size_t animationIndex = 0; animationIndex < numAnimations; ++animationIndex) {
   1619         TransformOperation::OperationType transformOp = isMatrixAnimation ? TransformOperation::MATRIX_3D : functionList[animationIndex];
   1620         RefPtr<PlatformCAAnimation> caAnimation;
   1621 
   1622 #if defined(BUILDING_ON_LEOPARD) || defined(BUILDING_ON_SNOW_LEOPARD) || PLATFORM(WIN)
   1623         // CA applies animations in reverse order (<rdar://problem/7095638>) so we need the last one we add (per property)
   1624         // to be non-additive.
   1625         // FIXME: This fix has not been added to QuartzCore on Windows yet (<rdar://problem/9112233>) so we expect the
   1626         // reversed animation behavior
   1627         bool additive = animationIndex < (numAnimations - 1);
   1628 #else
   1629         bool additive = animationIndex > 0;
   1630 #endif
   1631         if (isKeyframe) {
   1632             caAnimation = createKeyframeAnimation(animation, valueList.property(), additive);
   1633             validMatrices = setTransformAnimationKeyframes(valueList, animation, caAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize);
   1634         } else {
   1635             caAnimation = createBasicAnimation(animation, valueList.property(), additive);
   1636             validMatrices = setTransformAnimationEndpoints(valueList, animation, caAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize);
   1637         }
   1638 
   1639         if (!validMatrices)
   1640             break;
   1641 
   1642         m_uncomittedAnimations.append(LayerPropertyAnimation(caAnimation, animationName, valueList.property(), animationIndex, timeOffset));
   1643     }
   1644 
   1645     return validMatrices;
   1646 }
   1647 
   1648 PassRefPtr<PlatformCAAnimation> GraphicsLayerCA::createBasicAnimation(const Animation* anim, AnimatedPropertyID property, bool additive)
   1649 {
   1650     RefPtr<PlatformCAAnimation> basicAnim = PlatformCAAnimation::create(PlatformCAAnimation::Basic, propertyIdToString(property));
   1651     setupAnimation(basicAnim.get(), anim, additive);
   1652     return basicAnim;
   1653 }
   1654 
   1655 PassRefPtr<PlatformCAAnimation>GraphicsLayerCA::createKeyframeAnimation(const Animation* anim, AnimatedPropertyID property, bool additive)
   1656 {
   1657     RefPtr<PlatformCAAnimation> keyframeAnim = PlatformCAAnimation::create(PlatformCAAnimation::Keyframe, propertyIdToString(property));
   1658     setupAnimation(keyframeAnim.get(), anim, additive);
   1659     return keyframeAnim;
   1660 }
   1661 
   1662 void GraphicsLayerCA::setupAnimation(PlatformCAAnimation* propertyAnim, const Animation* anim, bool additive)
   1663 {
   1664     double duration = anim->duration();
   1665     if (duration <= 0)
   1666         duration = cAnimationAlmostZeroDuration;
   1667 
   1668     float repeatCount = anim->iterationCount();
   1669     if (repeatCount == Animation::IterationCountInfinite)
   1670         repeatCount = numeric_limits<float>::max();
   1671     else if (anim->direction() == Animation::AnimationDirectionAlternate)
   1672         repeatCount /= 2;
   1673 
   1674     PlatformCAAnimation::FillModeType fillMode = PlatformCAAnimation::NoFillMode;
   1675     switch (anim->fillMode()) {
   1676     case AnimationFillModeNone:
   1677         fillMode = PlatformCAAnimation::Forwards; // Use "forwards" rather than "removed" because the style system will remove the animation when it is finished. This avoids a flash.
   1678         break;
   1679     case AnimationFillModeBackwards:
   1680         fillMode = PlatformCAAnimation::Both; // Use "both" rather than "backwards" because the style system will remove the animation when it is finished. This avoids a flash.
   1681         break;
   1682     case AnimationFillModeForwards:
   1683         fillMode = PlatformCAAnimation::Forwards;
   1684         break;
   1685     case AnimationFillModeBoth:
   1686         fillMode = PlatformCAAnimation::Both;
   1687         break;
   1688     }
   1689 
   1690     propertyAnim->setDuration(duration);
   1691     propertyAnim->setRepeatCount(repeatCount);
   1692     propertyAnim->setAutoreverses(anim->direction());
   1693     propertyAnim->setRemovedOnCompletion(false);
   1694     propertyAnim->setAdditive(additive);
   1695     propertyAnim->setFillMode(fillMode);
   1696 }
   1697 
   1698 const TimingFunction* GraphicsLayerCA::timingFunctionForAnimationValue(const AnimationValue* animValue, const Animation* anim)
   1699 {
   1700     if (animValue->timingFunction())
   1701         return animValue->timingFunction();
   1702     if (anim->isTimingFunctionSet())
   1703         return anim->timingFunction().get();
   1704 
   1705     return CubicBezierTimingFunction::defaultTimingFunction();
   1706 }
   1707 
   1708 bool GraphicsLayerCA::setAnimationEndpoints(const KeyframeValueList& valueList, const Animation* anim, PlatformCAAnimation* basicAnim)
   1709 {
   1710     switch (valueList.property()) {
   1711     case AnimatedPropertyOpacity: {
   1712         basicAnim->setFromValue(static_cast<const FloatAnimationValue*>(valueList.at(0))->value());
   1713         basicAnim->setToValue(static_cast<const FloatAnimationValue*>(valueList.at(1))->value());
   1714         break;
   1715     }
   1716     default:
   1717         ASSERT_NOT_REACHED(); // we don't animate color yet
   1718         break;
   1719     }
   1720 
   1721     // This codepath is used for 2-keyframe animations, so we still need to look in the start
   1722     // for a timing function.
   1723     const TimingFunction* timingFunction = timingFunctionForAnimationValue(valueList.at(0), anim);
   1724     if (timingFunction)
   1725         basicAnim->setTimingFunction(timingFunction);
   1726 
   1727     return true;
   1728 }
   1729 
   1730 bool GraphicsLayerCA::setAnimationKeyframes(const KeyframeValueList& valueList, const Animation* anim, PlatformCAAnimation* keyframeAnim)
   1731 {
   1732     Vector<float> keyTimes;
   1733     Vector<float> values;
   1734     Vector<const TimingFunction*> timingFunctions;
   1735 
   1736     for (unsigned i = 0; i < valueList.size(); ++i) {
   1737         const AnimationValue* curValue = valueList.at(i);
   1738         keyTimes.append(curValue->keyTime());
   1739 
   1740         switch (valueList.property()) {
   1741         case AnimatedPropertyOpacity: {
   1742             const FloatAnimationValue* floatValue = static_cast<const FloatAnimationValue*>(curValue);
   1743             values.append(floatValue->value());
   1744             break;
   1745         }
   1746         default:
   1747             ASSERT_NOT_REACHED(); // we don't animate color yet
   1748             break;
   1749         }
   1750 
   1751         timingFunctions.append(timingFunctionForAnimationValue(curValue, anim));
   1752     }
   1753 
   1754     // We toss the last tfArray value because it has to one shorter than the others.
   1755     timingFunctions.removeLast();
   1756 
   1757     keyframeAnim->setKeyTimes(keyTimes);
   1758     keyframeAnim->setValues(values);
   1759     keyframeAnim->setTimingFunctions(timingFunctions);
   1760 
   1761     return true;
   1762 }
   1763 
   1764 bool GraphicsLayerCA::setTransformAnimationEndpoints(const KeyframeValueList& valueList, const Animation* anim, PlatformCAAnimation* basicAnim, int functionIndex, TransformOperation::OperationType transformOpType, bool isMatrixAnimation, const IntSize& boxSize)
   1765 {
   1766     ASSERT(valueList.size() == 2);
   1767     const TransformAnimationValue* startValue = static_cast<const TransformAnimationValue*>(valueList.at(0));
   1768     const TransformAnimationValue* endValue = static_cast<const TransformAnimationValue*>(valueList.at(1));
   1769 
   1770     if (isMatrixAnimation) {
   1771         TransformationMatrix fromTransform, toTransform;
   1772         startValue->value()->apply(boxSize, fromTransform);
   1773         endValue->value()->apply(boxSize, toTransform);
   1774 
   1775         // If any matrix is singular, CA won't animate it correctly. So fall back to software animation
   1776         if (!fromTransform.isInvertible() || !toTransform.isInvertible())
   1777             return false;
   1778 
   1779         basicAnim->setFromValue(fromTransform);
   1780         basicAnim->setToValue(toTransform);
   1781     } else {
   1782         if (isTransformTypeNumber(transformOpType)) {
   1783             float fromValue;
   1784             getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue);
   1785             basicAnim->setFromValue(fromValue);
   1786 
   1787             float toValue;
   1788             getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue);
   1789             basicAnim->setToValue(toValue);
   1790         } else if (isTransformTypeFloatPoint3D(transformOpType)) {
   1791             FloatPoint3D fromValue;
   1792             getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue);
   1793             basicAnim->setFromValue(fromValue);
   1794 
   1795             FloatPoint3D toValue;
   1796             getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue);
   1797             basicAnim->setToValue(toValue);
   1798         } else {
   1799             TransformationMatrix fromValue;
   1800             getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue);
   1801             basicAnim->setFromValue(fromValue);
   1802 
   1803             TransformationMatrix toValue;
   1804             getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue);
   1805             basicAnim->setToValue(toValue);
   1806         }
   1807     }
   1808 
   1809     // This codepath is used for 2-keyframe animations, so we still need to look in the start
   1810     // for a timing function.
   1811     const TimingFunction* timingFunction = timingFunctionForAnimationValue(valueList.at(0), anim);
   1812     basicAnim->setTimingFunction(timingFunction);
   1813 
   1814 #if HAVE_MODERN_QUARTZCORE
   1815     PlatformCAAnimation::ValueFunctionType valueFunction = getValueFunctionNameForTransformOperation(transformOpType);
   1816     if (valueFunction != PlatformCAAnimation::NoValueFunction)
   1817         basicAnim->setValueFunction(valueFunction);
   1818 #endif
   1819 
   1820     return true;
   1821 }
   1822 
   1823 bool GraphicsLayerCA::setTransformAnimationKeyframes(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* keyframeAnim, int functionIndex, TransformOperation::OperationType transformOpType, bool isMatrixAnimation, const IntSize& boxSize)
   1824 {
   1825     Vector<float> keyTimes;
   1826     Vector<float> floatValues;
   1827     Vector<FloatPoint3D> floatPoint3DValues;
   1828     Vector<TransformationMatrix> transformationMatrixValues;
   1829     Vector<const TimingFunction*> timingFunctions;
   1830 
   1831     for (unsigned i = 0; i < valueList.size(); ++i) {
   1832         const TransformAnimationValue* curValue = static_cast<const TransformAnimationValue*>(valueList.at(i));
   1833         keyTimes.append(curValue->keyTime());
   1834 
   1835         if (isMatrixAnimation) {
   1836             TransformationMatrix transform;
   1837             curValue->value()->apply(boxSize, transform);
   1838 
   1839             // If any matrix is singular, CA won't animate it correctly. So fall back to software animation
   1840             if (!transform.isInvertible())
   1841                 return false;
   1842 
   1843             transformationMatrixValues.append(transform);
   1844         } else {
   1845             const TransformOperation* transformOp = curValue->value()->at(functionIndex);
   1846             if (isTransformTypeNumber(transformOpType)) {
   1847                 float value;
   1848                 getTransformFunctionValue(transformOp, transformOpType, boxSize, value);
   1849                 floatValues.append(value);
   1850             } else if (isTransformTypeFloatPoint3D(transformOpType)) {
   1851                 FloatPoint3D value;
   1852                 getTransformFunctionValue(transformOp, transformOpType, boxSize, value);
   1853                 floatPoint3DValues.append(value);
   1854             } else {
   1855                 TransformationMatrix value;
   1856                 getTransformFunctionValue(transformOp, transformOpType, boxSize, value);
   1857                 transformationMatrixValues.append(value);
   1858             }
   1859         }
   1860 
   1861         const TimingFunction* timingFunction = timingFunctionForAnimationValue(curValue, animation);
   1862         timingFunctions.append(timingFunction);
   1863     }
   1864 
   1865     // We toss the last tfArray value because it has to one shorter than the others.
   1866     timingFunctions.removeLast();
   1867 
   1868     keyframeAnim->setKeyTimes(keyTimes);
   1869 
   1870     if (isTransformTypeNumber(transformOpType))
   1871         keyframeAnim->setValues(floatValues);
   1872     else if (isTransformTypeFloatPoint3D(transformOpType))
   1873         keyframeAnim->setValues(floatPoint3DValues);
   1874     else
   1875         keyframeAnim->setValues(transformationMatrixValues);
   1876 
   1877     keyframeAnim->setTimingFunctions(timingFunctions);
   1878 
   1879 #if HAVE_MODERN_QUARTZCORE
   1880     PlatformCAAnimation::ValueFunctionType valueFunction = getValueFunctionNameForTransformOperation(transformOpType);
   1881     if (valueFunction != PlatformCAAnimation::NoValueFunction)
   1882         keyframeAnim->setValueFunction(valueFunction);
   1883 #endif
   1884     return true;
   1885 }
   1886 
   1887 void GraphicsLayerCA::suspendAnimations(double time)
   1888 {
   1889     double t = currentTimeToMediaTime(time ? time : currentTime());
   1890     primaryLayer()->setSpeed(0);
   1891     primaryLayer()->setTimeOffset(t);
   1892 
   1893     // Suspend the animations on the clones too.
   1894     if (LayerMap* layerCloneMap = primaryLayerClones()) {
   1895         LayerMap::const_iterator end = layerCloneMap->end();
   1896         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
   1897             it->second->setSpeed(0);
   1898             it->second->setTimeOffset(t);
   1899         }
   1900     }
   1901 }
   1902 
   1903 void GraphicsLayerCA::resumeAnimations()
   1904 {
   1905     primaryLayer()->setSpeed(1);
   1906     primaryLayer()->setTimeOffset(0);
   1907 
   1908     // Resume the animations on the clones too.
   1909     if (LayerMap* layerCloneMap = primaryLayerClones()) {
   1910         LayerMap::const_iterator end = layerCloneMap->end();
   1911         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
   1912             it->second->setSpeed(1);
   1913             it->second->setTimeOffset(0);
   1914         }
   1915     }
   1916 }
   1917 
   1918 PlatformCALayer* GraphicsLayerCA::hostLayerForSublayers() const
   1919 {
   1920     return m_structuralLayer.get() ? m_structuralLayer.get() : m_layer.get();
   1921 }
   1922 
   1923 PlatformCALayer* GraphicsLayerCA::layerForSuperlayer() const
   1924 {
   1925     return m_structuralLayer ? m_structuralLayer.get() : m_layer.get();
   1926 }
   1927 
   1928 PlatformCALayer* GraphicsLayerCA::animatedLayer(AnimatedPropertyID property) const
   1929 {
   1930     return (property == AnimatedPropertyBackgroundColor) ? m_contentsLayer.get() : primaryLayer();
   1931 }
   1932 
   1933 GraphicsLayerCA::LayerMap* GraphicsLayerCA::animatedLayerClones(AnimatedPropertyID property) const
   1934 {
   1935     return (property == AnimatedPropertyBackgroundColor) ? m_contentsLayerClones.get() : primaryLayerClones();
   1936 }
   1937 
   1938 void GraphicsLayerCA::setContentsScale(float scale)
   1939 {
   1940     float newScale = clampedContentsScaleForScale(scale);
   1941     if (newScale == m_contentsScale)
   1942         return;
   1943 
   1944     m_contentsScale = newScale;
   1945     noteLayerPropertyChanged(ContentsScaleChanged);
   1946 }
   1947 
   1948 float GraphicsLayerCA::clampedContentsScaleForScale(float scale) const
   1949 {
   1950     // Define some limits as a sanity check for the incoming scale value
   1951     // those too small to see.
   1952     const float maxScale = 5.0f;
   1953     const float minScale = 0.01f;
   1954 
   1955     // Avoid very slight scale changes that would be doing extra work for no benefit
   1956     const float maxAllowableDelta = 0.05f;
   1957 
   1958     // Clamp
   1959     float result = max(minScale, min(scale, maxScale));
   1960 
   1961     // If it hasn't changed much, don't do any work
   1962     return ((fabs(result - m_contentsScale) / m_contentsScale) < maxAllowableDelta) ? m_contentsScale : result;
   1963 }
   1964 
   1965 void GraphicsLayerCA::updateContentsScale()
   1966 {
   1967     bool needTiledLayer = requiresTiledLayer(m_size);
   1968     if (needTiledLayer != m_usingTiledLayer)
   1969         swapFromOrToTiledLayer(needTiledLayer);
   1970 
   1971     m_layer->setContentsScale(m_contentsScale);
   1972     if (drawsContent())
   1973         m_layer->setNeedsDisplay();
   1974 }
   1975 
   1976 void GraphicsLayerCA::setDebugBackgroundColor(const Color& color)
   1977 {
   1978     if (color.isValid())
   1979         m_layer->setBackgroundColor(color);
   1980     else
   1981         m_layer->setBackgroundColor(Color::transparent);
   1982 }
   1983 
   1984 void GraphicsLayerCA::setDebugBorder(const Color& color, float borderWidth)
   1985 {
   1986     if (color.isValid()) {
   1987         m_layer->setBorderColor(color);
   1988         m_layer->setBorderWidth(borderWidth);
   1989     } else {
   1990         m_layer->setBorderColor(Color::transparent);
   1991         m_layer->setBorderWidth(0);
   1992     }
   1993 }
   1994 
   1995 FloatSize GraphicsLayerCA::constrainedSize() const
   1996 {
   1997     float tileColumns = ceilf(m_size.width() / kTiledLayerTileSize);
   1998     float tileRows = ceilf(m_size.height() / kTiledLayerTileSize);
   1999     double numTiles = tileColumns * tileRows;
   2000 
   2001     FloatSize constrainedSize = m_size;
   2002     const unsigned cMaxTileCount = 512;
   2003     while (numTiles > cMaxTileCount) {
   2004         // Constrain the wider dimension.
   2005         if (constrainedSize.width() >= constrainedSize.height()) {
   2006             tileColumns = max(floorf(cMaxTileCount / tileRows), 1.0f);
   2007             constrainedSize.setWidth(tileColumns * kTiledLayerTileSize);
   2008         } else {
   2009             tileRows = max(floorf(cMaxTileCount / tileColumns), 1.0f);
   2010             constrainedSize.setHeight(tileRows * kTiledLayerTileSize);
   2011         }
   2012         numTiles = tileColumns * tileRows;
   2013     }
   2014 
   2015     return constrainedSize;
   2016 }
   2017 
   2018 bool GraphicsLayerCA::requiresTiledLayer(const FloatSize& size) const
   2019 {
   2020     if (!m_drawsContent || !m_allowTiledLayer)
   2021         return false;
   2022 
   2023     // FIXME: catch zero-size height or width here (or earlier)?
   2024     return size.width() > cMaxPixelDimension || size.height() > cMaxPixelDimension;
   2025 }
   2026 
   2027 void GraphicsLayerCA::swapFromOrToTiledLayer(bool useTiledLayer)
   2028 {
   2029     ASSERT(useTiledLayer != m_usingTiledLayer);
   2030     RefPtr<PlatformCALayer> oldLayer = m_layer;
   2031 
   2032     m_layer = PlatformCALayer::create(useTiledLayer ? PlatformCALayer::LayerTypeWebTiledLayer : PlatformCALayer::LayerTypeWebLayer, this);
   2033     m_layer->setContentsScale(m_contentsScale);
   2034 
   2035     m_usingTiledLayer = useTiledLayer;
   2036 
   2037     if (useTiledLayer) {
   2038 #if !HAVE_MODERN_QUARTZCORE
   2039         // Tiled layer has issues with flipped coordinates.
   2040         setContentsOrientation(CompositingCoordinatesTopDown);
   2041 #endif
   2042     } else {
   2043 #if !HAVE_MODERN_QUARTZCORE
   2044         setContentsOrientation(GraphicsLayerCA::defaultContentsOrientation());
   2045 #endif
   2046     }
   2047 
   2048     m_layer->adoptSublayers(oldLayer.get());
   2049 
   2050     // If m_layer doesn't have a parent, it means it's the root layer and
   2051     // is likely hosted by something that is not expecting to be changed
   2052     ASSERT(oldLayer->superlayer());
   2053     oldLayer->superlayer()->replaceSublayer(oldLayer.get(), m_layer.get());
   2054 
   2055     updateContentsTransform();
   2056 
   2057     updateLayerPosition();
   2058     updateLayerSize();
   2059     updateAnchorPoint();
   2060     updateTransform();
   2061     updateChildrenTransform();
   2062     updateMasksToBounds();
   2063     updateContentsOpaque();
   2064     updateBackfaceVisibility();
   2065     updateLayerBackgroundColor();
   2066 
   2067     updateOpacityOnLayer();
   2068 
   2069 #ifndef NDEBUG
   2070     String name = String::format("CALayer(%p) GraphicsLayer(%p) ", m_layer.get(), this) + m_name;
   2071     m_layer->setName(name);
   2072 #endif
   2073 
   2074     // move over animations
   2075     moveOrCopyAnimationsForProperty(Move, AnimatedPropertyWebkitTransform, oldLayer.get(), m_layer.get());
   2076     moveOrCopyAnimationsForProperty(Move, AnimatedPropertyOpacity, oldLayer.get(), m_layer.get());
   2077     moveOrCopyAnimationsForProperty(Move, AnimatedPropertyBackgroundColor, oldLayer.get(), m_layer.get());
   2078 
   2079     // need to tell new layer to draw itself
   2080     setNeedsDisplay();
   2081 
   2082     updateDebugIndicators();
   2083 }
   2084 
   2085 GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayerCA::defaultContentsOrientation() const
   2086 {
   2087 #if !HAVE_MODERN_QUARTZCORE
   2088     // Older QuartzCore does not support -geometryFlipped, so we manually flip the root
   2089     // layer geometry, and then flip the contents of each layer back so that the CTM for CG
   2090     // is unflipped, allowing it to do the correct font auto-hinting.
   2091     return CompositingCoordinatesBottomUp;
   2092 #else
   2093     return CompositingCoordinatesTopDown;
   2094 #endif
   2095 }
   2096 
   2097 void GraphicsLayerCA::updateContentsTransform()
   2098 {
   2099 #if !HAVE_MODERN_QUARTZCORE
   2100     if (contentsOrientation() == CompositingCoordinatesBottomUp) {
   2101         CGAffineTransform contentsTransform = CGAffineTransformMakeScale(1, -1);
   2102         contentsTransform = CGAffineTransformTranslate(contentsTransform, 0, -m_layer->bounds().size().height());
   2103         m_layer->setContentsTransform(TransformationMatrix(contentsTransform));
   2104     }
   2105 #endif
   2106 }
   2107 
   2108 void GraphicsLayerCA::setupContentsLayer(PlatformCALayer* contentsLayer)
   2109 {
   2110     // Turn off implicit animations on the inner layer.
   2111     contentsLayer->setMasksToBounds(true);
   2112 
   2113     if (defaultContentsOrientation() == CompositingCoordinatesBottomUp) {
   2114         TransformationMatrix flipper(
   2115             1.0f, 0.0f, 0.0f, 0.0f,
   2116             0.0f, -1.0f, 0.0f, 0.0f,
   2117             0.0f, 0.0f, 1.0f, 0.0f,
   2118             0.0f, 0.0f, 0.0f, 1.0f);
   2119         contentsLayer->setTransform(flipper);
   2120         contentsLayer->setAnchorPoint(FloatPoint3D(0, 1, 0));
   2121     } else
   2122         contentsLayer->setAnchorPoint(FloatPoint3D());
   2123 
   2124     if (showDebugBorders()) {
   2125         contentsLayer->setBorderColor(Color(0, 0, 128, 180));
   2126         contentsLayer->setBorderWidth(1.0f);
   2127     }
   2128 }
   2129 
   2130 PassRefPtr<PlatformCALayer> GraphicsLayerCA::findOrMakeClone(CloneID cloneID, PlatformCALayer *sourceLayer, LayerMap* clones, CloneLevel cloneLevel)
   2131 {
   2132     if (!sourceLayer)
   2133         return 0;
   2134 
   2135     RefPtr<PlatformCALayer> resultLayer;
   2136 
   2137     // Add with a dummy value to get an iterator for the insertion position, and a boolean that tells
   2138     // us whether there's an item there. This technique avoids two hash lookups.
   2139     RefPtr<PlatformCALayer> dummy;
   2140     pair<LayerMap::iterator, bool> addResult = clones->add(cloneID, dummy);
   2141     if (!addResult.second) {
   2142         // Value was not added, so it exists already.
   2143         resultLayer = addResult.first->second.get();
   2144     } else {
   2145         resultLayer = cloneLayer(sourceLayer, cloneLevel);
   2146 #ifndef NDEBUG
   2147         resultLayer->setName(String::format("Clone %d of layer %p", cloneID[0U], sourceLayer));
   2148 #endif
   2149         addResult.first->second = resultLayer;
   2150     }
   2151 
   2152     return resultLayer;
   2153 }
   2154 
   2155 void GraphicsLayerCA::ensureCloneLayers(CloneID cloneID, RefPtr<PlatformCALayer>& primaryLayer, RefPtr<PlatformCALayer>& structuralLayer, RefPtr<PlatformCALayer>& contentsLayer, CloneLevel cloneLevel)
   2156 {
   2157     structuralLayer = 0;
   2158     contentsLayer = 0;
   2159 
   2160     if (!m_layerClones)
   2161         m_layerClones = new LayerMap;
   2162 
   2163     if (!m_structuralLayerClones && m_structuralLayer)
   2164         m_structuralLayerClones = new LayerMap;
   2165 
   2166     if (!m_contentsLayerClones && m_contentsLayer)
   2167         m_contentsLayerClones = new LayerMap;
   2168 
   2169     primaryLayer = findOrMakeClone(cloneID, m_layer.get(), m_layerClones.get(), cloneLevel);
   2170     structuralLayer = findOrMakeClone(cloneID, m_structuralLayer.get(), m_structuralLayerClones.get(), cloneLevel);
   2171     contentsLayer = findOrMakeClone(cloneID, m_contentsLayer.get(), m_contentsLayerClones.get(), cloneLevel);
   2172 }
   2173 
   2174 void GraphicsLayerCA::removeCloneLayers()
   2175 {
   2176     m_layerClones = 0;
   2177     m_structuralLayerClones = 0;
   2178     m_contentsLayerClones = 0;
   2179 }
   2180 
   2181 FloatPoint GraphicsLayerCA::positionForCloneRootLayer() const
   2182 {
   2183     // This can get called during a sync when we've just removed the m_replicaLayer.
   2184     if (!m_replicaLayer)
   2185         return FloatPoint();
   2186 
   2187     FloatPoint replicaPosition = m_replicaLayer->replicatedLayerPosition();
   2188     return FloatPoint(replicaPosition.x() + m_anchorPoint.x() * m_size.width(),
   2189                       replicaPosition.y() + m_anchorPoint.y() * m_size.height());
   2190 }
   2191 
   2192 void GraphicsLayerCA::propagateLayerChangeToReplicas()
   2193 {
   2194     for (GraphicsLayer* currLayer = this; currLayer; currLayer = currLayer->parent()) {
   2195         GraphicsLayerCA* currLayerCA = static_cast<GraphicsLayerCA*>(currLayer);
   2196         if (!currLayerCA->hasCloneLayers())
   2197             break;
   2198 
   2199         if (currLayerCA->replicaLayer())
   2200             static_cast<GraphicsLayerCA*>(currLayerCA->replicaLayer())->noteLayerPropertyChanged(ReplicatedLayerChanged);
   2201     }
   2202 }
   2203 
   2204 PassRefPtr<PlatformCALayer> GraphicsLayerCA::fetchCloneLayers(GraphicsLayer* replicaRoot, ReplicaState& replicaState, CloneLevel cloneLevel)
   2205 {
   2206     RefPtr<PlatformCALayer> primaryLayer;
   2207     RefPtr<PlatformCALayer> structuralLayer;
   2208     RefPtr<PlatformCALayer> contentsLayer;
   2209     ensureCloneLayers(replicaState.cloneID(), primaryLayer, structuralLayer, contentsLayer, cloneLevel);
   2210 
   2211     if (m_maskLayer) {
   2212         RefPtr<PlatformCALayer> maskClone = static_cast<GraphicsLayerCA*>(m_maskLayer)->fetchCloneLayers(replicaRoot, replicaState, IntermediateCloneLevel);
   2213         primaryLayer->setMask(maskClone.get());
   2214     }
   2215 
   2216     if (m_replicatedLayer) {
   2217         // We are a replica being asked for clones of our layers.
   2218         RefPtr<PlatformCALayer> replicaRoot = replicatedLayerRoot(replicaState);
   2219         if (!replicaRoot)
   2220             return 0;
   2221 
   2222         if (structuralLayer) {
   2223             structuralLayer->insertSublayer(replicaRoot.get(), 0);
   2224             return structuralLayer;
   2225         }
   2226 
   2227         primaryLayer->insertSublayer(replicaRoot.get(), 0);
   2228         return primaryLayer;
   2229     }
   2230 
   2231     const Vector<GraphicsLayer*>& childLayers = children();
   2232     Vector<RefPtr<PlatformCALayer> > clonalSublayers;
   2233 
   2234     RefPtr<PlatformCALayer> replicaLayer;
   2235 
   2236     if (m_replicaLayer && m_replicaLayer != replicaRoot) {
   2237         // We have nested replicas. Ask the replica layer for a clone of its contents.
   2238         replicaState.setBranchType(ReplicaState::ReplicaBranch);
   2239         replicaLayer = static_cast<GraphicsLayerCA*>(m_replicaLayer)->fetchCloneLayers(replicaRoot, replicaState, RootCloneLevel);
   2240         replicaState.setBranchType(ReplicaState::ChildBranch);
   2241     }
   2242 
   2243     if (replicaLayer || structuralLayer || contentsLayer || childLayers.size() > 0) {
   2244         if (structuralLayer) {
   2245             // Replicas render behind the actual layer content.
   2246             if (replicaLayer)
   2247                 clonalSublayers.append(replicaLayer);
   2248 
   2249             // Add the primary layer next. Even if we have negative z-order children, the primary layer always comes behind.
   2250             clonalSublayers.append(primaryLayer);
   2251         } else if (contentsLayer) {
   2252             // FIXME: add the contents layer in the correct order with negative z-order children.
   2253             // This does not cause visible rendering issues because currently contents layers are only used
   2254             // for replaced elements that don't have children.
   2255             clonalSublayers.append(contentsLayer);
   2256         }
   2257 
   2258         replicaState.push(ReplicaState::ChildBranch);
   2259 
   2260         size_t numChildren = childLayers.size();
   2261         for (size_t i = 0; i < numChildren; ++i) {
   2262             GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
   2263 
   2264             RefPtr<PlatformCALayer> childLayer = curChild->fetchCloneLayers(replicaRoot, replicaState, IntermediateCloneLevel);
   2265             if (childLayer)
   2266                 clonalSublayers.append(childLayer);
   2267         }
   2268 
   2269         replicaState.pop();
   2270 
   2271         for (size_t i = 0; i < clonalSublayers.size(); ++i)
   2272             clonalSublayers[i]->removeFromSuperlayer();
   2273     }
   2274 
   2275     RefPtr<PlatformCALayer> result;
   2276     if (structuralLayer) {
   2277         structuralLayer->setSublayers(clonalSublayers);
   2278 
   2279         if (contentsLayer) {
   2280             // If we have a transform layer, then the contents layer is parented in the
   2281             // primary layer (which is itself a child of the transform layer).
   2282             primaryLayer->removeAllSublayers();
   2283             primaryLayer->appendSublayer(contentsLayer.get());
   2284         }
   2285 
   2286         result = structuralLayer;
   2287     } else {
   2288         primaryLayer->setSublayers(clonalSublayers);
   2289         result = primaryLayer;
   2290     }
   2291 
   2292     return result;
   2293 }
   2294 
   2295 PassRefPtr<PlatformCALayer> GraphicsLayerCA::cloneLayer(PlatformCALayer *layer, CloneLevel cloneLevel)
   2296 {
   2297     PlatformCALayer::LayerType layerType = (layer->layerType() == PlatformCALayer::LayerTypeTransformLayer) ?
   2298                                                 PlatformCALayer::LayerTypeTransformLayer : PlatformCALayer::LayerTypeLayer;
   2299     RefPtr<PlatformCALayer> newLayer = PlatformCALayer::create(layerType, this);
   2300 
   2301     newLayer->setPosition(layer->position());
   2302     newLayer->setBounds(layer->bounds());
   2303     newLayer->setAnchorPoint(layer->anchorPoint());
   2304     newLayer->setTransform(layer->transform());
   2305     newLayer->setSublayerTransform(layer->sublayerTransform());
   2306     newLayer->setContents(layer->contents());
   2307     newLayer->setMasksToBounds(layer->masksToBounds());
   2308     newLayer->setDoubleSided(layer->isDoubleSided());
   2309     newLayer->setOpaque(layer->isOpaque());
   2310     newLayer->setBackgroundColor(layer->backgroundColor());
   2311     newLayer->setContentsScale(layer->contentsScale());
   2312 
   2313     if (cloneLevel == IntermediateCloneLevel) {
   2314         newLayer->setOpacity(layer->opacity());
   2315         moveOrCopyAnimationsForProperty(Copy, AnimatedPropertyWebkitTransform, layer, newLayer.get());
   2316         moveOrCopyAnimationsForProperty(Copy, AnimatedPropertyOpacity, layer, newLayer.get());
   2317     }
   2318 
   2319     if (showDebugBorders()) {
   2320         newLayer->setBorderColor(Color(255, 122, 251));
   2321         newLayer->setBorderWidth(2);
   2322     }
   2323 
   2324     return newLayer;
   2325 }
   2326 
   2327 void GraphicsLayerCA::setOpacityInternal(float accumulatedOpacity)
   2328 {
   2329     LayerMap* layerCloneMap = 0;
   2330 
   2331     if (preserves3D()) {
   2332         m_layer->setOpacity(accumulatedOpacity);
   2333         layerCloneMap = m_layerClones.get();
   2334     } else {
   2335         primaryLayer()->setOpacity(accumulatedOpacity);
   2336         layerCloneMap = primaryLayerClones();
   2337     }
   2338 
   2339     if (layerCloneMap) {
   2340         LayerMap::const_iterator end = layerCloneMap->end();
   2341         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
   2342             if (m_replicaLayer && isReplicatedRootClone(it->first))
   2343                 continue;
   2344             it->second->setOpacity(m_opacity);
   2345         }
   2346     }
   2347 }
   2348 
   2349 void GraphicsLayerCA::updateOpacityOnLayer()
   2350 {
   2351 #if !HAVE_MODERN_QUARTZCORE
   2352     // Distribute opacity either to our own layer or to our children. We pass in the
   2353     // contribution from our parent(s).
   2354     distributeOpacity(parent() ? parent()->accumulatedOpacity() : 1);
   2355 #else
   2356     primaryLayer()->setOpacity(m_opacity);
   2357 
   2358     if (LayerMap* layerCloneMap = primaryLayerClones()) {
   2359         LayerMap::const_iterator end = layerCloneMap->end();
   2360         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
   2361             if (m_replicaLayer && isReplicatedRootClone(it->first))
   2362                 continue;
   2363 
   2364             it->second->setOpacity(m_opacity);
   2365         }
   2366 
   2367     }
   2368 #endif
   2369 }
   2370 
   2371 void GraphicsLayerCA::noteSublayersChanged()
   2372 {
   2373     noteLayerPropertyChanged(ChildrenChanged);
   2374     propagateLayerChangeToReplicas();
   2375 }
   2376 
   2377 void GraphicsLayerCA::noteLayerPropertyChanged(LayerChangeFlags flags)
   2378 {
   2379     if (!m_uncommittedChanges && m_client)
   2380         m_client->notifySyncRequired(this);
   2381 
   2382     m_uncommittedChanges |= flags;
   2383 }
   2384 
   2385 } // namespace WebCore
   2386 
   2387 #endif // USE(ACCELERATED_COMPOSITING)
   2388