Rubber-banding should not affect the visibleRect of the TileCache
[WebKit-https.git] / Source / WebCore / platform / graphics / ca / GraphicsLayerCA.cpp
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 "GraphicsLayerFactory.h"
36 #include "PlatformCALayer.h"
37 #include "RotateTransformOperation.h"
38 #include "ScaleTransformOperation.h"
39 #include "SystemTime.h"
40 #include "TextStream.h"
41 #include "TiledBacking.h"
42 #include "TransformState.h"
43 #include "TranslateTransformOperation.h"
44 #include <QuartzCore/CATransform3D.h>
45 #include <limits.h>
46 #include <wtf/CurrentTime.h>
47 #include <wtf/text/WTFString.h>
48
49 #if PLATFORM(MAC)
50 #include "WebCoreSystemInterface.h"
51 #endif
52
53 using namespace std;
54
55 namespace WebCore {
56
57 // The threshold width or height above which a tiled layer will be used. This should be
58 // large enough to avoid tiled layers for most GraphicsLayers, but less than the OpenGL
59 // texture size limit on all supported hardware.
60 static const int cMaxPixelDimension = 2000;
61
62 // If we send a duration of 0 to CA, then it will use the default duration
63 // of 250ms. So send a very small value instead.
64 static const float cAnimationAlmostZeroDuration = 1e-3f;
65
66 static bool isTransformTypeTransformationMatrix(TransformOperation::OperationType transformType)
67 {
68     switch (transformType) {
69     case TransformOperation::SKEW_X:
70     case TransformOperation::SKEW_Y:
71     case TransformOperation::SKEW:
72     case TransformOperation::MATRIX:
73     case TransformOperation::ROTATE_3D:
74     case TransformOperation::MATRIX_3D:
75     case TransformOperation::PERSPECTIVE:
76     case TransformOperation::IDENTITY:
77     case TransformOperation::NONE:
78         return true;
79     default:
80         return false;
81     }
82 }
83
84 static bool isTransformTypeFloatPoint3D(TransformOperation::OperationType transformType)
85 {
86     switch (transformType) {
87     case TransformOperation::SCALE:
88     case TransformOperation::SCALE_3D:
89     case TransformOperation::TRANSLATE:
90     case TransformOperation::TRANSLATE_3D:
91         return true;
92     default:
93         return false;
94     }
95 }
96
97 static bool isTransformTypeNumber(TransformOperation::OperationType transformType)
98 {
99     return !isTransformTypeTransformationMatrix(transformType) && !isTransformTypeFloatPoint3D(transformType);
100 }
101
102 static void getTransformFunctionValue(const TransformOperation* transformOp, TransformOperation::OperationType transformType, const IntSize& size, float& value)
103 {
104     switch (transformType) {
105     case TransformOperation::ROTATE:
106     case TransformOperation::ROTATE_X:
107     case TransformOperation::ROTATE_Y:
108         value = transformOp ? narrowPrecisionToFloat(deg2rad(static_cast<const RotateTransformOperation*>(transformOp)->angle())) : 0;
109         break;
110     case TransformOperation::SCALE_X:
111         value = transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->x()) : 1;
112         break;
113     case TransformOperation::SCALE_Y:
114         value = transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->y()) : 1;
115         break;
116     case TransformOperation::SCALE_Z:
117         value = transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->z()) : 1;
118         break;
119     case TransformOperation::TRANSLATE_X:
120         value = transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->x(size)) : 0;
121         break;
122     case TransformOperation::TRANSLATE_Y:
123         value = transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->y(size)) : 0;
124         break;
125     case TransformOperation::TRANSLATE_Z:
126         value = transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->z(size)) : 0;
127         break;
128     default:
129         break;
130     }
131 }
132
133 static void getTransformFunctionValue(const TransformOperation* transformOp, TransformOperation::OperationType transformType, const IntSize& size, FloatPoint3D& value)
134 {
135     switch (transformType) {
136     case TransformOperation::SCALE:
137     case TransformOperation::SCALE_3D:
138         value.setX(transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->x()) : 1);
139         value.setY(transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->y()) : 1);
140         value.setZ(transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->z()) : 1);
141         break;
142     case TransformOperation::TRANSLATE:
143     case TransformOperation::TRANSLATE_3D:
144         value.setX(transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->x(size)) : 0);
145         value.setY(transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->y(size)) : 0);
146         value.setZ(transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->z(size)) : 0);
147         break;
148     default:
149         break;
150     }
151 }
152
153 static void getTransformFunctionValue(const TransformOperation* transformOp, TransformOperation::OperationType transformType, const IntSize& size, TransformationMatrix& value)
154 {
155     switch (transformType) {
156     case TransformOperation::SKEW_X:
157     case TransformOperation::SKEW_Y:
158     case TransformOperation::SKEW:
159     case TransformOperation::MATRIX:
160     case TransformOperation::ROTATE_3D:
161     case TransformOperation::MATRIX_3D:
162     case TransformOperation::PERSPECTIVE:
163     case TransformOperation::IDENTITY:
164     case TransformOperation::NONE:
165         if (transformOp)
166             transformOp->apply(value, size);
167         else
168             value.makeIdentity();
169         break;
170     default:
171         break;
172     }
173 }
174
175 static PlatformCAAnimation::ValueFunctionType getValueFunctionNameForTransformOperation(TransformOperation::OperationType transformType)
176 {
177     // Use literal strings to avoid link-time dependency on those symbols.
178     switch (transformType) {
179     case TransformOperation::ROTATE_X:
180         return PlatformCAAnimation::RotateX;
181     case TransformOperation::ROTATE_Y:
182         return PlatformCAAnimation::RotateY;
183     case TransformOperation::ROTATE:
184         return PlatformCAAnimation::RotateZ;
185     case TransformOperation::SCALE_X:
186         return PlatformCAAnimation::ScaleX;
187     case TransformOperation::SCALE_Y:
188         return PlatformCAAnimation::ScaleY;
189     case TransformOperation::SCALE_Z:
190         return PlatformCAAnimation::ScaleZ;
191     case TransformOperation::TRANSLATE_X:
192         return PlatformCAAnimation::TranslateX;
193     case TransformOperation::TRANSLATE_Y:
194         return PlatformCAAnimation::TranslateY;
195     case TransformOperation::TRANSLATE_Z:
196         return PlatformCAAnimation::TranslateZ;
197     case TransformOperation::SCALE:
198     case TransformOperation::SCALE_3D:
199         return PlatformCAAnimation::Scale;
200     case TransformOperation::TRANSLATE:
201     case TransformOperation::TRANSLATE_3D:
202         return PlatformCAAnimation::Translate;
203     default:
204         return PlatformCAAnimation::NoValueFunction;
205     }
206 }
207
208 static String propertyIdToString(AnimatedPropertyID property)
209 {
210     switch (property) {
211     case AnimatedPropertyWebkitTransform:
212         return "transform";
213     case AnimatedPropertyOpacity:
214         return "opacity";
215     case AnimatedPropertyBackgroundColor:
216         return "backgroundColor";
217     case AnimatedPropertyWebkitFilter:
218 #if ENABLE(CSS_FILTERS)
219         return "filters";
220 #else
221         ASSERT_NOT_REACHED();
222 #endif
223     case AnimatedPropertyInvalid:
224         ASSERT_NOT_REACHED();
225     }
226     ASSERT_NOT_REACHED();
227     return "";
228 }
229
230 static String animationIdentifier(const String& animationName, AnimatedPropertyID property, int index)
231 {
232     return animationName + '_' + String::number(property) + '_' + String::number(index);
233 }
234
235 static bool animationHasStepsTimingFunction(const KeyframeValueList& valueList, const Animation* anim)
236 {
237     if (anim->timingFunction()->isStepsTimingFunction())
238         return true;
239     
240     for (unsigned i = 0; i < valueList.size(); ++i) {
241         const TimingFunction* timingFunction = valueList.at(i)->timingFunction();
242         if (timingFunction && timingFunction->isStepsTimingFunction())
243             return true;
244     }
245
246     return false;
247 }
248
249 #if ENABLE(CSS_FILTERS) || !ASSERT_DISABLED
250 static inline bool supportsAcceleratedFilterAnimations()
251 {
252 // <rdar://problem/10907251> - WebKit2 doesn't support CA animations of CI filters on Lion and below
253 #if PLATFORM(MAC) && (PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080)
254     return true;
255 #else
256     return false;
257 #endif
258 }
259 #endif
260
261 PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerFactory* factory, GraphicsLayerClient* client)
262 {
263     if (!factory)
264         return adoptPtr(new GraphicsLayerCA(client));
265
266     return factory->createGraphicsLayer(client);
267 }
268
269 PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
270 {
271     return adoptPtr(new GraphicsLayerCA(client));
272 }
273
274 GraphicsLayerCA::GraphicsLayerCA(GraphicsLayerClient* client)
275     : GraphicsLayer(client)
276     , m_contentsLayerPurpose(NoContentsLayer)
277     , m_allowTiledLayer(true)
278     , m_isPageTileCacheLayer(false)
279     , m_uncommittedChanges(0)
280 {
281     PlatformCALayer::LayerType layerType = PlatformCALayer::LayerTypeWebLayer;
282     if (client && client->shouldUseTileCache(this)) {
283         layerType = PlatformCALayer::LayerTypePageTileCacheLayer;
284         m_isPageTileCacheLayer = true;
285     }
286
287     m_layer = PlatformCALayer::create(layerType, this);
288     noteLayerPropertyChanged(ContentsScaleChanged);
289 }
290
291 GraphicsLayerCA::~GraphicsLayerCA()
292 {
293     // Do cleanup while we can still safely call methods on the derived class.
294     willBeDestroyed();
295 }
296
297 void GraphicsLayerCA::willBeDestroyed()
298 {
299     // We release our references to the PlatformCALayers here, but do not actively unparent them,
300     // since that will cause a commit and break our batched commit model. The layers will
301     // get released when the rootmost modified GraphicsLayerCA rebuilds its child layers.
302     
303     // Clean up the layer.
304     if (m_layer)
305         m_layer->setOwner(0);
306     
307     if (m_contentsLayer)
308         m_contentsLayer->setOwner(0);
309         
310     if (m_structuralLayer)
311         m_structuralLayer->setOwner(0);
312     
313     removeCloneLayers();
314
315     GraphicsLayer::willBeDestroyed();
316 }
317
318 void GraphicsLayerCA::setName(const String& name)
319 {
320     String longName = String::format("CALayer(%p) GraphicsLayer(%p) ", m_layer->platformLayer(), this) + name;
321     GraphicsLayer::setName(longName);
322     noteLayerPropertyChanged(NameChanged);
323 }
324
325 PlatformLayer* GraphicsLayerCA::platformLayer() const
326 {
327     return primaryLayer()->platformLayer();
328 }
329
330 bool GraphicsLayerCA::setChildren(const Vector<GraphicsLayer*>& children)
331 {
332     bool childrenChanged = GraphicsLayer::setChildren(children);
333     if (childrenChanged)
334         noteSublayersChanged();
335     
336     return childrenChanged;
337 }
338
339 void GraphicsLayerCA::addChild(GraphicsLayer* childLayer)
340 {
341     GraphicsLayer::addChild(childLayer);
342     noteSublayersChanged();
343 }
344
345 void GraphicsLayerCA::addChildAtIndex(GraphicsLayer* childLayer, int index)
346 {
347     GraphicsLayer::addChildAtIndex(childLayer, index);
348     noteSublayersChanged();
349 }
350
351 void GraphicsLayerCA::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibling)
352 {
353     GraphicsLayer::addChildBelow(childLayer, sibling);
354     noteSublayersChanged();
355 }
356
357 void GraphicsLayerCA::addChildAbove(GraphicsLayer* childLayer, GraphicsLayer* sibling)
358 {
359     GraphicsLayer::addChildAbove(childLayer, sibling);
360     noteSublayersChanged();
361 }
362
363 bool GraphicsLayerCA::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
364 {
365     if (GraphicsLayer::replaceChild(oldChild, newChild)) {
366         noteSublayersChanged();
367         return true;
368     }
369     return false;
370 }
371
372 void GraphicsLayerCA::removeFromParent()
373 {
374     if (m_parent)
375         static_cast<GraphicsLayerCA*>(m_parent)->noteSublayersChanged();
376     GraphicsLayer::removeFromParent();
377 }
378
379 void GraphicsLayerCA::setMaskLayer(GraphicsLayer* layer)
380 {
381     if (layer == m_maskLayer)
382         return;
383
384     GraphicsLayer::setMaskLayer(layer);
385     noteLayerPropertyChanged(MaskLayerChanged);
386
387     propagateLayerChangeToReplicas();
388     
389     if (m_replicatedLayer)
390         static_cast<GraphicsLayerCA*>(m_replicatedLayer)->propagateLayerChangeToReplicas();
391 }
392
393 void GraphicsLayerCA::setReplicatedLayer(GraphicsLayer* layer)
394 {
395     if (layer == m_replicatedLayer)
396         return;
397
398     GraphicsLayer::setReplicatedLayer(layer);
399     noteLayerPropertyChanged(ReplicatedLayerChanged);
400 }
401
402 void GraphicsLayerCA::setReplicatedByLayer(GraphicsLayer* layer)
403 {
404     if (layer == m_replicaLayer)
405         return;
406
407     GraphicsLayer::setReplicatedByLayer(layer);
408     noteSublayersChanged();
409     noteLayerPropertyChanged(ReplicatedLayerChanged);
410 }
411
412 void GraphicsLayerCA::setPosition(const FloatPoint& point)
413 {
414     if (point == m_position)
415         return;
416
417     GraphicsLayer::setPosition(point);
418     noteLayerPropertyChanged(GeometryChanged);
419 }
420
421 void GraphicsLayerCA::setAnchorPoint(const FloatPoint3D& point)
422 {
423     if (point == m_anchorPoint)
424         return;
425
426     GraphicsLayer::setAnchorPoint(point);
427     noteLayerPropertyChanged(GeometryChanged);
428 }
429
430 void GraphicsLayerCA::setSize(const FloatSize& size)
431 {
432     if (size == m_size)
433         return;
434
435     GraphicsLayer::setSize(size);
436     noteLayerPropertyChanged(GeometryChanged);
437 }
438
439 void GraphicsLayerCA::setBoundsOrigin(const FloatPoint& origin)
440 {
441     if (origin == m_boundsOrigin)
442         return;
443
444     GraphicsLayer::setBoundsOrigin(origin);
445     noteLayerPropertyChanged(GeometryChanged);
446 }
447
448 void GraphicsLayerCA::setTransform(const TransformationMatrix& t)
449 {
450     if (t == m_transform)
451         return;
452
453     GraphicsLayer::setTransform(t);
454     noteLayerPropertyChanged(TransformChanged);
455 }
456
457 void GraphicsLayerCA::setChildrenTransform(const TransformationMatrix& t)
458 {
459     if (t == m_childrenTransform)
460         return;
461
462     GraphicsLayer::setChildrenTransform(t);
463     noteLayerPropertyChanged(ChildrenTransformChanged);
464 }
465
466 void GraphicsLayerCA::moveOrCopyLayerAnimation(MoveOrCopy operation, const String& animationIdentifier, PlatformCALayer *fromLayer, PlatformCALayer *toLayer)
467 {
468     RefPtr<PlatformCAAnimation> anim = fromLayer->animationForKey(animationIdentifier);
469     if (!anim)
470         return;
471
472     switch (operation) {
473     case Move:
474         fromLayer->removeAnimationForKey(animationIdentifier);
475         toLayer->addAnimationForKey(animationIdentifier, anim.get());
476         break;
477
478     case Copy:
479         toLayer->addAnimationForKey(animationIdentifier, anim.get());
480         break;
481     }
482 }
483
484 void GraphicsLayerCA::moveOrCopyAnimations(MoveOrCopy operation, PlatformCALayer *fromLayer, PlatformCALayer *toLayer)
485 {
486     // Look for running animations affecting this property.
487     AnimationsMap::const_iterator end = m_runningAnimations.end();
488     for (AnimationsMap::const_iterator it = m_runningAnimations.begin(); it != end; ++it) {
489         const Vector<LayerPropertyAnimation>& propertyAnimations = it->value;
490         size_t numAnimations = propertyAnimations.size();
491         for (size_t i = 0; i < numAnimations; ++i) {
492             const LayerPropertyAnimation& currAnimation = propertyAnimations[i];
493             
494             if (currAnimation.m_property == AnimatedPropertyWebkitTransform || currAnimation.m_property == AnimatedPropertyOpacity
495                     || currAnimation.m_property == AnimatedPropertyBackgroundColor
496 #if ENABLE(CSS_FILTERS)
497                     || currAnimation.m_property == AnimatedPropertyWebkitFilter
498 #endif
499                 )
500                 moveOrCopyLayerAnimation(operation, animationIdentifier(currAnimation.m_name, currAnimation.m_property, currAnimation.m_index), fromLayer, toLayer);
501         }
502     }
503 }
504
505 void GraphicsLayerCA::setPreserves3D(bool preserves3D)
506 {
507     if (preserves3D == m_preserves3D)
508         return;
509
510     GraphicsLayer::setPreserves3D(preserves3D);
511     noteLayerPropertyChanged(Preserves3DChanged);
512 }
513
514 void GraphicsLayerCA::setMasksToBounds(bool masksToBounds)
515 {
516     if (masksToBounds == m_masksToBounds)
517         return;
518
519     GraphicsLayer::setMasksToBounds(masksToBounds);
520     noteLayerPropertyChanged(MasksToBoundsChanged | DebugIndicatorsChanged);
521 }
522
523 void GraphicsLayerCA::setDrawsContent(bool drawsContent)
524 {
525     if (drawsContent == m_drawsContent)
526         return;
527
528     GraphicsLayer::setDrawsContent(drawsContent);
529     noteLayerPropertyChanged(DrawsContentChanged | DebugIndicatorsChanged);
530 }
531
532 void GraphicsLayerCA::setContentsVisible(bool contentsVisible)
533 {
534     if (contentsVisible == m_contentsVisible)
535         return;
536
537     GraphicsLayer::setContentsVisible(contentsVisible);
538     noteLayerPropertyChanged(ContentsVisibilityChanged);
539     // Visibility affects whether the contentsLayer is parented.
540     if (m_contentsLayer)
541         noteSublayersChanged();
542 }
543
544 void GraphicsLayerCA::setAcceleratesDrawing(bool acceleratesDrawing)
545 {
546     if (acceleratesDrawing == m_acceleratesDrawing)
547         return;
548
549     GraphicsLayer::setAcceleratesDrawing(acceleratesDrawing);
550     noteLayerPropertyChanged(AcceleratesDrawingChanged);
551 }
552
553 void GraphicsLayerCA::setAllowTiledLayer(bool allowTiledLayer)
554 {
555     if (allowTiledLayer == m_allowTiledLayer)
556         return;
557
558     m_allowTiledLayer = allowTiledLayer;
559     
560     // Handling this as a BoundsChanged will cause use to switch in or out of tiled layer as needed
561     noteLayerPropertyChanged(GeometryChanged);
562 }
563
564 void GraphicsLayerCA::setBackgroundColor(const Color& color)
565 {
566     if (m_backgroundColor == color)
567         return;
568
569     GraphicsLayer::setBackgroundColor(color);
570     noteLayerPropertyChanged(BackgroundColorChanged);
571 }
572
573 void GraphicsLayerCA::setContentsOpaque(bool opaque)
574 {
575     if (m_contentsOpaque == opaque)
576         return;
577
578     GraphicsLayer::setContentsOpaque(opaque);
579     noteLayerPropertyChanged(ContentsOpaqueChanged);
580 }
581
582 void GraphicsLayerCA::setBackfaceVisibility(bool visible)
583 {
584     if (m_backfaceVisibility == visible)
585         return;
586     
587     GraphicsLayer::setBackfaceVisibility(visible);
588     noteLayerPropertyChanged(BackfaceVisibilityChanged);
589 }
590
591 void GraphicsLayerCA::setOpacity(float opacity)
592 {
593     float clampedOpacity = max(0.0f, min(opacity, 1.0f));
594
595     if (clampedOpacity == m_opacity)
596         return;
597
598     GraphicsLayer::setOpacity(clampedOpacity);
599     noteLayerPropertyChanged(OpacityChanged);
600 }
601
602 #if ENABLE(CSS_FILTERS)
603 bool GraphicsLayerCA::setFilters(const FilterOperations& filterOperations)
604 {
605     bool canCompositeFilters = PlatformCALayer::filtersCanBeComposited(filterOperations);
606
607     if (m_filters == filterOperations)
608         return canCompositeFilters;
609
610     // Filters cause flattening, so we should never have filters on a layer with preserves3D().
611     ASSERT(!filterOperations.size() || !preserves3D());
612
613     if (canCompositeFilters) {
614         GraphicsLayer::setFilters(filterOperations);
615         noteLayerPropertyChanged(FiltersChanged);
616     } else if (filters().size()) {
617         // In this case filters are rendered in software, so we need to remove any 
618         // previously attached hardware filters.
619         clearFilters();
620         noteLayerPropertyChanged(FiltersChanged);
621     }
622     return canCompositeFilters;
623 }
624 #endif
625
626 void GraphicsLayerCA::setNeedsDisplay()
627 {
628     FloatRect hugeRect(-numeric_limits<float>::max() / 2, -numeric_limits<float>::max() / 2,
629                        numeric_limits<float>::max(), numeric_limits<float>::max());
630
631     setNeedsDisplayInRect(hugeRect);
632 }
633
634 void GraphicsLayerCA::setNeedsDisplayInRect(const FloatRect& r)
635 {
636     if (!drawsContent())
637         return;
638
639     FloatRect rect(r);
640     FloatRect layerBounds(FloatPoint(), m_size);
641     rect.intersect(layerBounds);
642     if (rect.isEmpty())
643         return;
644     
645     const size_t maxDirtyRects = 32;
646     
647     for (size_t i = 0; i < m_dirtyRects.size(); ++i) {
648         if (m_dirtyRects[i].contains(rect))
649             return;
650     }
651     
652     if (m_dirtyRects.size() < maxDirtyRects)
653         m_dirtyRects.append(rect);
654     else
655         m_dirtyRects[0].unite(rect);
656
657     noteLayerPropertyChanged(DirtyRectsChanged);
658
659     addRepaintRect(rect);
660 }
661
662 void GraphicsLayerCA::setContentsNeedsDisplay()
663 {
664     noteLayerPropertyChanged(ContentsNeedsDisplay);
665 }
666
667 void GraphicsLayerCA::setContentsRect(const IntRect& rect)
668 {
669     if (rect == m_contentsRect)
670         return;
671
672     GraphicsLayer::setContentsRect(rect);
673     noteLayerPropertyChanged(ContentsRectChanged);
674 }
675
676 bool GraphicsLayerCA::addAnimation(const KeyframeValueList& valueList, const IntSize& boxSize, const Animation* anim, const String& animationName, double timeOffset)
677 {
678     ASSERT(!animationName.isEmpty());
679
680     if (!anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2)
681         return false;
682
683     // CoreAnimation does not handle the steps() timing function. Fall back
684     // to software animation in that case.
685     if (animationHasStepsTimingFunction(valueList, anim))
686         return false;
687
688 #if PLATFORM(WIN)
689     // CoreAnimation on Windows does not handle a reverse direction. Fall
690     // back to software animation in that case.
691     // https://bugs.webkit.org/show_bug.cgi?id=85121
692     if (!anim->directionIsForwards())
693         return false;
694 #endif
695
696     bool createdAnimations = false;
697     if (valueList.property() == AnimatedPropertyWebkitTransform)
698         createdAnimations = createTransformAnimationsFromKeyframes(valueList, anim, animationName, timeOffset, boxSize);
699 #if ENABLE(CSS_FILTERS)
700     else if (valueList.property() == AnimatedPropertyWebkitFilter) {
701         if (supportsAcceleratedFilterAnimations())
702             createdAnimations = createFilterAnimationsFromKeyframes(valueList, anim, animationName, timeOffset);
703     }
704 #endif
705     else
706         createdAnimations = createAnimationFromKeyframes(valueList, anim, animationName, timeOffset);
707
708     if (createdAnimations)
709         noteLayerPropertyChanged(AnimationChanged);
710         
711     return createdAnimations;
712 }
713
714 void GraphicsLayerCA::pauseAnimation(const String& animationName, double timeOffset)
715 {
716     if (!animationIsRunning(animationName))
717         return;
718
719     AnimationsToProcessMap::iterator it = m_animationsToProcess.find(animationName);
720     if (it != m_animationsToProcess.end()) {
721         AnimationProcessingAction& processingInfo = it->value;
722         // If an animation is scheduled to be removed, don't change the remove to a pause.
723         if (processingInfo.action != Remove)
724             processingInfo.action = Pause;
725     } else
726         m_animationsToProcess.add(animationName, AnimationProcessingAction(Pause, timeOffset));
727
728     noteLayerPropertyChanged(AnimationChanged);
729 }
730
731 void GraphicsLayerCA::removeAnimation(const String& animationName)
732 {
733     if (!animationIsRunning(animationName))
734         return;
735
736     m_animationsToProcess.add(animationName, AnimationProcessingAction(Remove));
737     noteLayerPropertyChanged(AnimationChanged);
738 }
739
740 void GraphicsLayerCA::platformCALayerAnimationStarted(CFTimeInterval startTime)
741 {
742     if (m_client)
743         m_client->notifyAnimationStarted(this, startTime);
744 }
745
746 void GraphicsLayerCA::setContentsToSolidColor(const Color& color)
747 {
748     if (color == m_contentsSolidColor)
749         return;
750
751     m_contentsSolidColor = color;
752
753     if (m_contentsSolidColor.isValid()) {
754         m_contentsLayerPurpose = ContentsLayerForBackgroundColor;
755         m_contentsLayer = PlatformCALayer::create(PlatformCALayer::LayerTypeLayer, this);
756 #ifndef NDEBUG
757         m_contentsLayer->setName("Background Color Layer");
758 #endif
759     } else {
760         m_contentsLayerPurpose = NoContentsLayer;
761         m_contentsLayer = 0;
762     }
763
764     noteSublayersChanged();
765     noteLayerPropertyChanged(ContentsColorLayerChanged);
766 }
767
768 void GraphicsLayerCA::setContentsToImage(Image* image)
769 {
770     if (image) {
771         CGImageRef newImage = image->nativeImageForCurrentFrame();
772         if (!newImage)
773             return;
774
775         // Check to see if the image changed; we have to do this because the call to
776         // CGImageCreateCopyWithColorSpace() below can create a new image every time.
777         if (m_uncorrectedContentsImage && m_uncorrectedContentsImage.get() == newImage)
778             return;
779         
780         m_uncorrectedContentsImage = newImage;
781         m_pendingContentsImage = newImage;
782
783 #if !PLATFORM(WIN)
784         CGColorSpaceRef colorSpace = CGImageGetColorSpace(m_pendingContentsImage.get());
785
786         static CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
787         if (colorSpace && CFEqual(colorSpace, deviceRGB)) {
788             // CoreGraphics renders images tagged with DeviceRGB using the color space of the main display. When we hand such
789             // images to CA we need to tag them similarly so CA rendering matches CG rendering.
790             static CGColorSpaceRef genericRGB = CGDisplayCopyColorSpace(kCGDirectMainDisplay);
791             m_pendingContentsImage.adoptCF(CGImageCreateCopyWithColorSpace(m_pendingContentsImage.get(), genericRGB));
792         }
793 #endif
794         m_contentsLayerPurpose = ContentsLayerForImage;
795         if (!m_contentsLayer)
796             noteSublayersChanged();
797     } else {
798         m_uncorrectedContentsImage = 0;
799         m_pendingContentsImage = 0;
800         m_contentsLayerPurpose = NoContentsLayer;
801         if (m_contentsLayer)
802             noteSublayersChanged();
803     }
804
805     noteLayerPropertyChanged(ContentsImageChanged);
806 }
807
808 void GraphicsLayerCA::setContentsToMedia(PlatformLayer* mediaLayer)
809 {
810     if (m_contentsLayer && mediaLayer == m_contentsLayer->platformLayer())
811         return;
812         
813     // FIXME: The passed in layer might be a raw layer or an externally created 
814     // PlatformCALayer. To determine this we attempt to get the
815     // PlatformCALayer pointer. If this returns a null pointer we assume it's
816     // raw. This test might be invalid if the raw layer is, for instance, the
817     // PlatformCALayer is using a user data pointer in the raw layer, and
818     // the creator of the raw layer is using it for some other purpose.
819     // For now we don't support such a case.
820     PlatformCALayer* platformCALayer = PlatformCALayer::platformCALayer(mediaLayer);
821     m_contentsLayer = mediaLayer ? (platformCALayer ? platformCALayer : PlatformCALayer::create(mediaLayer, this)) : 0;
822     m_contentsLayerPurpose = mediaLayer ? ContentsLayerForMedia : NoContentsLayer;
823
824     noteSublayersChanged();
825     noteLayerPropertyChanged(ContentsMediaLayerChanged);
826 }
827
828 void GraphicsLayerCA::setContentsToCanvas(PlatformLayer* canvasLayer)
829 {
830     if (m_contentsLayer && canvasLayer == m_contentsLayer->platformLayer())
831         return;
832     
833     // Create the PlatformCALayer to wrap the incoming layer
834     m_contentsLayer = canvasLayer ? PlatformCALayer::create(canvasLayer, this) : 0;
835     
836     m_contentsLayerPurpose = canvasLayer ? ContentsLayerForCanvas : NoContentsLayer;
837
838     noteSublayersChanged();
839     noteLayerPropertyChanged(ContentsCanvasLayerChanged);
840 }
841     
842 void GraphicsLayerCA::layerDidDisplay(PlatformLayer* layer)
843 {
844     PlatformCALayer* currentLayer = PlatformCALayer::platformCALayer(layer);
845     PlatformCALayer* sourceLayer;
846     LayerMap* layerCloneMap;
847
848     if (currentLayer == m_layer) {
849         sourceLayer = m_layer.get();
850         layerCloneMap = m_layerClones.get();
851     } else if (currentLayer == m_contentsLayer) {
852         sourceLayer = m_contentsLayer.get();
853         layerCloneMap = m_contentsLayerClones.get();
854     } else
855         return;
856
857     if (layerCloneMap) {
858         LayerMap::const_iterator end = layerCloneMap->end();
859         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
860             PlatformCALayer* currClone = it->value.get();
861             if (!currClone)
862                 continue;
863
864             if (currClone->contents() != sourceLayer->contents())
865                 currClone->setContents(sourceLayer->contents());
866             else
867                 currClone->setContentsChanged();
868         }
869     }
870 }
871
872 FloatPoint GraphicsLayerCA::computePositionRelativeToBase(float& pageScale) const
873 {
874     pageScale = 1;
875
876     FloatPoint offset;
877     for (const GraphicsLayer* currLayer = this; currLayer; currLayer = currLayer->parent()) {
878         if (currLayer->appliesPageScale()) {
879             if (currLayer->client())
880                 pageScale = currLayer->pageScaleFactor();
881             return offset;
882         }
883
884         offset += currLayer->position();
885     }
886
887     return FloatPoint();
888 }
889
890 void GraphicsLayerCA::flushCompositingState(const FloatRect& clipRect)
891 {
892     TransformState state(TransformState::UnapplyInverseTransformDirection, FloatQuad(clipRect));
893     recursiveCommitChanges(CommitState(), state);
894 }
895
896 void GraphicsLayerCA::flushCompositingStateForThisLayerOnly()
897 {
898     float pageScaleFactor;
899     bool hadChanges = m_uncommittedChanges;
900
901     FloatPoint offset = computePositionRelativeToBase(pageScaleFactor);
902     commitLayerChangesBeforeSublayers(pageScaleFactor, offset, m_visibleRect);
903     commitLayerChangesAfterSublayers();
904
905     if (hadChanges && client())
906         client()->didCommitChangesForLayer(this);
907 }
908
909 TiledBacking* GraphicsLayerCA::tiledBacking() const
910 {
911     return m_layer->tiledBacking();
912 }
913
914 FloatRect GraphicsLayerCA::computeVisibleRect(TransformState& state) const
915 {
916     bool preserve3D = preserves3D() || (parent() ? parent()->preserves3D() : false);
917     TransformState::TransformAccumulation accumulation = preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform;
918
919     TransformationMatrix layerTransform;
920     FloatPoint position = m_position;
921     if (m_client)
922         m_client->customPositionForVisibleRectComputation(this, position);
923
924     layerTransform.translate(position.x(), position.y());
925
926     TransformationMatrix currentTransform;
927     if (client() && client()->getCurrentTransform(this, currentTransform) && !currentTransform.isIdentity()) {
928         FloatPoint3D absoluteAnchorPoint(anchorPoint());
929         absoluteAnchorPoint.scale(size().width(), size().height(), 1);
930         layerTransform.translate3d(absoluteAnchorPoint.x(), absoluteAnchorPoint.y(), absoluteAnchorPoint.z());
931         layerTransform.multiply(currentTransform);
932         layerTransform.translate3d(-absoluteAnchorPoint.x(), -absoluteAnchorPoint.y(), -absoluteAnchorPoint.z());
933     }
934
935     if (GraphicsLayer* parentLayer = parent()) {
936         if (!parentLayer->childrenTransform().isIdentity()) {
937             FloatPoint3D parentAnchorPoint(parentLayer->anchorPoint());
938             parentAnchorPoint.scale(parentLayer->size().width(), parentLayer->size().height(), 1);
939
940             layerTransform.translateRight3d(-parentAnchorPoint.x(), -parentAnchorPoint.y(), -parentAnchorPoint.z());
941             layerTransform = parentLayer->childrenTransform() * layerTransform;
942             layerTransform.translateRight3d(parentAnchorPoint.x(), parentAnchorPoint.y(), parentAnchorPoint.z());
943         }
944     }
945
946     bool applyWasClamped;
947     state.applyTransform(layerTransform, accumulation, &applyWasClamped);
948     
949     bool mapWasClamped;
950     FloatRect clipRectForChildren = state.mappedQuad(&mapWasClamped).boundingBox();
951     FloatRect clipRectForSelf(0, 0, m_size.width(), m_size.height());
952     if (!applyWasClamped && !mapWasClamped)
953         clipRectForSelf.intersect(clipRectForChildren);
954     
955     if (masksToBounds()) {
956         ASSERT(accumulation == TransformState::FlattenTransform);
957         // Replace the quad in the TransformState with one that is clipped to this layer's bounds
958         state.setQuad(clipRectForSelf);
959     }
960
961     return clipRectForSelf;
962 }
963
964 void GraphicsLayerCA::recursiveCommitChanges(const CommitState& commitState, const TransformState& state, float pageScaleFactor, const FloatPoint& positionRelativeToBase, bool affectedByPageScale)
965 {
966     TransformState localState = state;
967     CommitState childCommitState = commitState;
968     bool affectedByTransformAnimation = commitState.ancestorHasTransformAnimation;
969     
970     FloatRect visibleRect = computeVisibleRect(localState);
971     FloatRect oldVisibleRect = m_visibleRect;
972     if (visibleRect != m_visibleRect) {
973         m_uncommittedChanges |= VisibleRectChanged;
974         m_visibleRect = visibleRect;
975     }
976
977 #ifdef VISIBLE_TILE_WASH
978     // Use having a transform as a key to making the tile wash layer. If every layer gets a wash,
979     // they start to obscure useful information.
980     if ((!m_transform.isIdentity() || m_usingTiledLayer) && !m_visibleTileWashLayer) {
981         static Color washFillColor(255, 0, 0, 50);
982         static Color washBorderColor(255, 0, 0, 100);
983         
984         m_visibleTileWashLayer = PlatformCALayer::create(PlatformCALayer::LayerTypeLayer, this);
985         String name = String::format("Visible Tile Wash Layer %p", m_visibleTileWashLayer->platformLayer());
986         m_visibleTileWashLayer->setName(name);
987         m_visibleTileWashLayer->setAnchorPoint(FloatPoint3D(0, 0, 0));
988         m_visibleTileWashLayer->setBorderColor(washBorderColor);
989         m_visibleTileWashLayer->setBorderWidth(8);
990         m_visibleTileWashLayer->setBackgroundColor(washFillColor);
991         noteSublayersChanged();
992     }
993
994     if (m_visibleTileWashLayer)
995         m_visibleTileWashLayer->setFrame(m_visibleRect);
996 #endif
997
998     bool hadChanges = m_uncommittedChanges;
999     
1000     if (appliesPageScale()) {
1001         pageScaleFactor = this->pageScaleFactor();
1002         affectedByPageScale = true;
1003     }
1004
1005     // Accumulate an offset from the ancestral pixel-aligned layer.
1006     FloatPoint baseRelativePosition = positionRelativeToBase;
1007     if (affectedByPageScale)
1008         baseRelativePosition += m_position;
1009     
1010     commitLayerChangesBeforeSublayers(pageScaleFactor, baseRelativePosition, oldVisibleRect);
1011
1012     if (isRunningTransformAnimation()) {
1013         childCommitState.ancestorHasTransformAnimation = true;
1014         affectedByTransformAnimation = true;
1015     }
1016
1017     if (m_maskLayer) {
1018         GraphicsLayerCA* maskLayerCA = static_cast<GraphicsLayerCA*>(m_maskLayer);
1019         maskLayerCA->commitLayerChangesBeforeSublayers(pageScaleFactor, baseRelativePosition, maskLayerCA->visibleRect());
1020     }
1021
1022     const Vector<GraphicsLayer*>& childLayers = children();
1023     size_t numChildren = childLayers.size();
1024     
1025     for (size_t i = 0; i < numChildren; ++i) {
1026         GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
1027         curChild->recursiveCommitChanges(childCommitState, localState, pageScaleFactor, baseRelativePosition, affectedByPageScale);
1028     }
1029
1030     if (m_replicaLayer)
1031         static_cast<GraphicsLayerCA*>(m_replicaLayer)->recursiveCommitChanges(childCommitState, localState, pageScaleFactor, baseRelativePosition, affectedByPageScale);
1032
1033     if (m_maskLayer)
1034         static_cast<GraphicsLayerCA*>(m_maskLayer)->commitLayerChangesAfterSublayers();
1035
1036     commitLayerChangesAfterSublayers();
1037
1038     if (affectedByTransformAnimation && client() && m_layer->layerType() == PlatformCALayer::LayerTypeTileCacheLayer)
1039         client()->notifyFlushBeforeDisplayRefresh(this);
1040
1041     if (hadChanges && client())
1042         client()->didCommitChangesForLayer(this);
1043 }
1044
1045 bool GraphicsLayerCA::platformCALayerShowRepaintCounter(PlatformCALayer* platformLayer) const
1046 {
1047     // The repaint counters are painted into the TileCache tiles (which have no corresponding platform layer),
1048     // so we don't want to overpaint the repaint counter when called with the TileCache's own layer.
1049     if (m_isPageTileCacheLayer && platformLayer)
1050         return false;
1051     
1052     return isShowingRepaintCounter();
1053 }
1054
1055 void GraphicsLayerCA::platformCALayerPaintContents(GraphicsContext& context, const IntRect& clip)
1056 {
1057     paintGraphicsLayerContents(context, clip);
1058 }
1059
1060 void GraphicsLayerCA::platformCALayerDidCreateTiles(const Vector<FloatRect>& dirtyRects)
1061 {
1062     ASSERT(m_layer->usesTileCacheLayer());
1063
1064     for (size_t i = 0; i < dirtyRects.size(); ++i)
1065         setNeedsDisplayInRect(dirtyRects[i]);
1066
1067     // Ensure that the layout is up to date before any individual tiles are painted by telling the client
1068     // that it needs to flush its layer state, which will end up scheduling the layer flusher.
1069     client()->notifyFlushRequired(this);
1070 }
1071
1072 float GraphicsLayerCA::platformCALayerDeviceScaleFactor()
1073 {
1074     return deviceScaleFactor();
1075 }
1076
1077 void GraphicsLayerCA::commitLayerChangesBeforeSublayers(float pageScaleFactor, const FloatPoint& positionRelativeToBase, const FloatRect& oldVisibleRect)
1078 {
1079     if (!m_uncommittedChanges)
1080         return;
1081
1082     // Need to handle Preserves3DChanged first, because it affects which layers subsequent properties are applied to
1083     if (m_uncommittedChanges & (Preserves3DChanged | ReplicatedLayerChanged))
1084         updateStructuralLayer();
1085
1086     if (m_uncommittedChanges & GeometryChanged)
1087         updateGeometry(pageScaleFactor, positionRelativeToBase);
1088
1089     if (m_uncommittedChanges & DrawsContentChanged)
1090         updateLayerDrawsContent(pageScaleFactor);
1091
1092     if (m_uncommittedChanges & NameChanged)
1093         updateLayerNames();
1094
1095     if (m_uncommittedChanges & ContentsImageChanged) // Needs to happen before ChildrenChanged
1096         updateContentsImage();
1097         
1098     if (m_uncommittedChanges & ContentsMediaLayerChanged) // Needs to happen before ChildrenChanged
1099         updateContentsMediaLayer();
1100     
1101     if (m_uncommittedChanges & ContentsCanvasLayerChanged) // Needs to happen before ChildrenChanged
1102         updateContentsCanvasLayer();
1103
1104     if (m_uncommittedChanges & ContentsColorLayerChanged) // Needs to happen before ChildrenChanged
1105         updateContentsColorLayer();
1106     
1107     if (m_uncommittedChanges & BackgroundColorChanged)
1108         updateBackgroundColor();
1109
1110     if (m_uncommittedChanges & TransformChanged)
1111         updateTransform();
1112
1113     if (m_uncommittedChanges & ChildrenTransformChanged)
1114         updateChildrenTransform();
1115     
1116     if (m_uncommittedChanges & MasksToBoundsChanged)
1117         updateMasksToBounds();
1118     
1119     if (m_uncommittedChanges & ContentsVisibilityChanged)
1120         updateContentsVisibility();
1121
1122     if (m_uncommittedChanges & ContentsOpaqueChanged)
1123         updateContentsOpaque();
1124
1125     if (m_uncommittedChanges & BackfaceVisibilityChanged)
1126         updateBackfaceVisibility();
1127
1128     if (m_uncommittedChanges & OpacityChanged)
1129         updateOpacityOnLayer();
1130     
1131 #if ENABLE(CSS_FILTERS)
1132     if (m_uncommittedChanges & FiltersChanged)
1133         updateFilters();
1134 #endif
1135     
1136     if (m_uncommittedChanges & AnimationChanged)
1137         updateAnimations();
1138
1139     // Updating the contents scale can cause parts of the layer to be invalidated,
1140     // so make sure to update the contents scale before updating the dirty rects.
1141     if (m_uncommittedChanges & ContentsScaleChanged)
1142         updateContentsScale(pageScaleFactor);
1143
1144     if (m_uncommittedChanges & VisibleRectChanged)
1145         updateVisibleRect(oldVisibleRect);
1146
1147     if (m_uncommittedChanges & DirtyRectsChanged)
1148         repaintLayerDirtyRects();
1149     
1150     if (m_uncommittedChanges & ContentsRectChanged)
1151         updateContentsRect();
1152
1153     if (m_uncommittedChanges & MaskLayerChanged)
1154         updateMaskLayer();
1155
1156     if (m_uncommittedChanges & ContentsNeedsDisplay)
1157         updateContentsNeedsDisplay();
1158     
1159     if (m_uncommittedChanges & AcceleratesDrawingChanged)
1160         updateAcceleratesDrawing();
1161
1162     if (m_uncommittedChanges & DebugIndicatorsChanged)
1163         updateDebugBorder();
1164
1165     if (m_uncommittedChanges & ChildrenChanged) {
1166         updateSublayerList();
1167         // Sublayers may set this flag again, so clear it to avoid always updating sublayers in commitLayerChangesAfterSublayers().
1168         m_uncommittedChanges &= ~ChildrenChanged;
1169     }
1170 }
1171
1172 void GraphicsLayerCA::commitLayerChangesAfterSublayers()
1173 {
1174     if (!m_uncommittedChanges)
1175         return;
1176
1177     if (m_uncommittedChanges & ChildrenChanged)
1178         updateSublayerList();
1179
1180     if (m_uncommittedChanges & ReplicatedLayerChanged)
1181         updateReplicatedLayers();
1182
1183     m_uncommittedChanges = NoChange;
1184 }
1185
1186 void GraphicsLayerCA::updateLayerNames()
1187 {
1188     switch (structuralLayerPurpose()) {
1189     case StructuralLayerForPreserves3D:
1190         m_structuralLayer->setName("Transform layer " + name());
1191         break;
1192     case StructuralLayerForReplicaFlattening:
1193         m_structuralLayer->setName("Replica flattening layer " + name());
1194         break;
1195     case NoStructuralLayer:
1196         break;
1197     }
1198     m_layer->setName(name());
1199 }
1200
1201 void GraphicsLayerCA::updateSublayerList()
1202 {
1203     const PlatformCALayerList* customSublayers = m_layer->customSublayers();
1204
1205     PlatformCALayerList structuralLayerChildren;
1206     PlatformCALayerList primaryLayerChildren;
1207
1208     PlatformCALayerList& childListForSublayers = m_structuralLayer ? structuralLayerChildren : primaryLayerChildren;
1209
1210     if (customSublayers)
1211         primaryLayerChildren.append(*customSublayers);
1212
1213     if (m_structuralLayer) {
1214         if (m_replicaLayer)
1215             structuralLayerChildren.append(static_cast<GraphicsLayerCA*>(m_replicaLayer)->primaryLayer());
1216     
1217         structuralLayerChildren.append(m_layer);
1218     }
1219
1220     if (m_contentsLayer && m_contentsVisible) {
1221         // FIXME: add the contents layer in the correct order with negative z-order children.
1222         // This does not cause visible rendering issues because currently contents layers are only used
1223         // for replaced elements that don't have children.
1224         primaryLayerChildren.append(m_contentsLayer);
1225     }
1226     
1227     const Vector<GraphicsLayer*>& childLayers = children();
1228     size_t numChildren = childLayers.size();
1229     for (size_t i = 0; i < numChildren; ++i) {
1230         GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
1231         PlatformCALayer* childLayer = curChild->layerForSuperlayer();
1232         childListForSublayers.append(childLayer);
1233     }
1234
1235 #ifdef VISIBLE_TILE_WASH
1236     if (m_visibleTileWashLayer)
1237         childListForSublayers.append(m_visibleTileWashLayer);
1238 #endif
1239
1240     if (m_structuralLayer)
1241         m_structuralLayer->setSublayers(structuralLayerChildren);
1242     
1243     m_layer->setSublayers(primaryLayerChildren);
1244 }
1245
1246 void GraphicsLayerCA::updateGeometry(float pageScaleFactor, const FloatPoint& positionRelativeToBase)
1247 {
1248     FloatPoint scaledPosition;
1249     FloatPoint3D scaledAnchorPoint;
1250     FloatSize scaledSize;
1251     FloatSize pixelAlignmentOffset;
1252     computePixelAlignment(pageScaleFactor, positionRelativeToBase, scaledPosition, scaledSize, scaledAnchorPoint, pixelAlignmentOffset);
1253
1254     bool needTiledLayer = requiresTiledLayer(pageScaleFactor);
1255     if (needTiledLayer != m_usingTiledLayer)
1256         swapFromOrToTiledLayer(needTiledLayer);
1257
1258     FloatSize usedSize = m_usingTiledLayer ? constrainedSize() : scaledSize;
1259     FloatRect adjustedBounds(m_boundsOrigin - pixelAlignmentOffset, usedSize);
1260
1261     // Update position.
1262     // Position is offset on the layer by the layer anchor point.
1263     FloatPoint adjustedPosition(scaledPosition.x() + scaledAnchorPoint.x() * usedSize.width(), scaledPosition.y() + scaledAnchorPoint.y() * usedSize.height());
1264
1265     if (m_structuralLayer) {
1266         FloatPoint layerPosition(m_position.x() + m_anchorPoint.x() * m_size.width(), m_position.y() + m_anchorPoint.y() * m_size.height());
1267         FloatRect layerBounds(m_boundsOrigin, m_size);
1268         
1269         m_structuralLayer->setPosition(layerPosition);
1270         m_structuralLayer->setBounds(layerBounds);
1271         m_structuralLayer->setAnchorPoint(m_anchorPoint);
1272
1273         if (LayerMap* layerCloneMap = m_structuralLayerClones.get()) {
1274             LayerMap::const_iterator end = layerCloneMap->end();
1275             for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1276                 PlatformCALayer* clone = it->value.get();
1277                 FloatPoint clonePosition = layerPosition;
1278
1279                 if (m_replicaLayer && isReplicatedRootClone(it->key)) {
1280                     // Maintain the special-case position for the root of a clone subtree,
1281                     // which we set up in replicatedLayerRoot().
1282                     clonePosition = positionForCloneRootLayer();
1283                 }
1284
1285                 clone->setPosition(clonePosition);
1286                 clone->setBounds(layerBounds);
1287                 clone->setAnchorPoint(m_anchorPoint);
1288             }
1289         }
1290
1291         // If we have a structural layer, we just use 0.5, 0.5 for the anchor point of the main layer.
1292         scaledAnchorPoint = FloatPoint(0.5f, 0.5f);
1293         adjustedPosition = FloatPoint(scaledAnchorPoint.x() * usedSize.width() - pixelAlignmentOffset.width(), scaledAnchorPoint.y() * usedSize.height() - pixelAlignmentOffset.height());
1294     }
1295     
1296     m_layer->setPosition(adjustedPosition);
1297     m_layer->setBounds(adjustedBounds);
1298     m_layer->setAnchorPoint(scaledAnchorPoint);
1299
1300     if (LayerMap* layerCloneMap = m_layerClones.get()) {
1301         LayerMap::const_iterator end = layerCloneMap->end();
1302         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1303             PlatformCALayer* clone = it->value.get();
1304             FloatPoint clonePosition = adjustedPosition;
1305
1306             if (!m_structuralLayer && m_replicaLayer && isReplicatedRootClone(it->key)) {
1307                 // Maintain the special-case position for the root of a clone subtree,
1308                 // which we set up in replicatedLayerRoot().
1309                 clonePosition = positionForCloneRootLayer();
1310             }
1311
1312             clone->setPosition(clonePosition);
1313             clone->setBounds(adjustedBounds);
1314             clone->setAnchorPoint(scaledAnchorPoint);
1315         }
1316     }
1317 }
1318
1319 void GraphicsLayerCA::updateTransform()
1320 {
1321     primaryLayer()->setTransform(m_transform);
1322
1323     if (LayerMap* layerCloneMap = primaryLayerClones()) {
1324         LayerMap::const_iterator end = layerCloneMap->end();
1325         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1326             PlatformCALayer* currLayer = it->value.get();
1327             if (m_replicaLayer && isReplicatedRootClone(it->key)) {
1328                 // Maintain the special-case transform for the root of a clone subtree,
1329                 // which we set up in replicatedLayerRoot().
1330                 currLayer->setTransform(TransformationMatrix());
1331             } else
1332                 currLayer->setTransform(m_transform);
1333         }
1334     }
1335 }
1336
1337 void GraphicsLayerCA::updateChildrenTransform()
1338 {
1339     primaryLayer()->setSublayerTransform(m_childrenTransform);
1340
1341     if (LayerMap* layerCloneMap = primaryLayerClones()) {
1342         LayerMap::const_iterator end = layerCloneMap->end();
1343         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
1344             it->value->setSublayerTransform(m_childrenTransform);
1345     }
1346 }
1347
1348 void GraphicsLayerCA::updateMasksToBounds()
1349 {
1350     m_layer->setMasksToBounds(m_masksToBounds);
1351
1352     if (LayerMap* layerCloneMap = m_layerClones.get()) {
1353         LayerMap::const_iterator end = layerCloneMap->end();
1354         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
1355             it->value->setMasksToBounds(m_masksToBounds);
1356     }
1357 }
1358
1359 void GraphicsLayerCA::updateContentsVisibility()
1360 {
1361     // Note that m_contentsVisible also affects whether m_contentsLayer is parented.
1362     if (m_contentsVisible) {
1363         if (m_drawsContent)
1364             m_layer->setNeedsDisplay();
1365     } else {
1366         m_layer->setContents(0);
1367
1368         if (LayerMap* layerCloneMap = m_layerClones.get()) {
1369             LayerMap::const_iterator end = layerCloneMap->end();
1370             for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
1371                 it->value->setContents(0);
1372         }
1373     }
1374 }
1375
1376 void GraphicsLayerCA::updateContentsOpaque()
1377 {
1378     m_layer->setOpaque(m_contentsOpaque);
1379
1380     if (LayerMap* layerCloneMap = m_layerClones.get()) {
1381         LayerMap::const_iterator end = layerCloneMap->end();
1382         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
1383             it->value->setOpaque(m_contentsOpaque);
1384     }
1385 }
1386
1387 void GraphicsLayerCA::updateBackfaceVisibility()
1388 {
1389     if (m_structuralLayer && structuralLayerPurpose() == StructuralLayerForReplicaFlattening) {
1390         m_structuralLayer->setDoubleSided(m_backfaceVisibility);
1391
1392         if (LayerMap* layerCloneMap = m_structuralLayerClones.get()) {
1393             LayerMap::const_iterator end = layerCloneMap->end();
1394             for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
1395                 it->value->setDoubleSided(m_backfaceVisibility);
1396         }
1397     }
1398
1399     m_layer->setDoubleSided(m_backfaceVisibility);
1400
1401     if (LayerMap* layerCloneMap = m_layerClones.get()) {
1402         LayerMap::const_iterator end = layerCloneMap->end();
1403         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
1404             it->value->setDoubleSided(m_backfaceVisibility);
1405     }
1406 }
1407
1408 #if ENABLE(CSS_FILTERS)
1409 void GraphicsLayerCA::updateFilters()
1410 {
1411     m_layer->setFilters(m_filters);
1412
1413     if (LayerMap* layerCloneMap = m_layerClones.get()) {
1414         LayerMap::const_iterator end = layerCloneMap->end();
1415         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1416             if (m_replicaLayer && isReplicatedRootClone(it->key))
1417                 continue;
1418
1419             it->value->setFilters(m_filters);
1420         }
1421     }
1422 }
1423 #endif
1424
1425 void GraphicsLayerCA::updateStructuralLayer()
1426 {
1427     ensureStructuralLayer(structuralLayerPurpose());
1428 }
1429
1430 void GraphicsLayerCA::ensureStructuralLayer(StructuralLayerPurpose purpose)
1431 {
1432     const LayerChangeFlags structuralLayerChangeFlags = NameChanged
1433         | GeometryChanged
1434         | TransformChanged
1435         | ChildrenTransformChanged
1436         | ChildrenChanged
1437         | BackfaceVisibilityChanged
1438 #if ENABLE(CSS_FILTERS)
1439         | FiltersChanged
1440 #endif
1441         | OpacityChanged;
1442
1443     if (purpose == NoStructuralLayer) {
1444         if (m_structuralLayer) {
1445             // Replace the transformLayer in the parent with this layer.
1446             m_layer->removeFromSuperlayer();
1447  
1448             // If m_layer doesn't have a parent, it means it's the root layer and
1449             // is likely hosted by something that is not expecting to be changed
1450             ASSERT(m_structuralLayer->superlayer());
1451             m_structuralLayer->superlayer()->replaceSublayer(m_structuralLayer.get(), m_layer.get());
1452
1453             moveOrCopyAnimations(Move, m_structuralLayer.get(), m_layer.get());
1454
1455             // Release the structural layer.
1456             m_structuralLayer = 0;
1457
1458             m_uncommittedChanges |= structuralLayerChangeFlags;
1459         }
1460         return;
1461     }
1462     
1463     bool structuralLayerChanged = false;
1464     
1465     if (purpose == StructuralLayerForPreserves3D) {
1466         if (m_structuralLayer && m_structuralLayer->layerType() != PlatformCALayer::LayerTypeTransformLayer)
1467             m_structuralLayer = 0;
1468         
1469         if (!m_structuralLayer) {
1470             m_structuralLayer = PlatformCALayer::create(PlatformCALayer::LayerTypeTransformLayer, this);
1471             structuralLayerChanged = true;
1472         }
1473     } else {
1474         if (m_structuralLayer && m_structuralLayer->layerType() != PlatformCALayer::LayerTypeLayer)
1475             m_structuralLayer = 0;
1476
1477         if (!m_structuralLayer) {
1478             m_structuralLayer = PlatformCALayer::create(PlatformCALayer::LayerTypeLayer, this);
1479             structuralLayerChanged = true;
1480         }
1481     }
1482     
1483     if (!structuralLayerChanged)
1484         return;
1485     
1486     m_uncommittedChanges |= structuralLayerChangeFlags;
1487
1488     // We've changed the layer that our parent added to its sublayer list, so tell it to update
1489     // sublayers again in its commitLayerChangesAfterSublayers().
1490     static_cast<GraphicsLayerCA*>(parent())->noteSublayersChanged();
1491
1492     // Set properties of m_layer to their default values, since these are expressed on on the structural layer.
1493     FloatPoint point(m_size.width() / 2.0f, m_size.height() / 2.0f);
1494     FloatPoint3D anchorPoint(0.5f, 0.5f, 0);
1495     m_layer->setPosition(point);
1496     m_layer->setAnchorPoint(anchorPoint);
1497     m_layer->setTransform(TransformationMatrix());
1498     m_layer->setOpacity(1);
1499     if (m_layerClones) {
1500         LayerMap::const_iterator end = m_layerClones->end();
1501         for (LayerMap::const_iterator it = m_layerClones->begin(); it != end; ++it) {
1502             PlatformCALayer* currLayer = it->value.get();
1503             currLayer->setPosition(point);
1504             currLayer->setAnchorPoint(anchorPoint);
1505             currLayer->setTransform(TransformationMatrix());
1506             currLayer->setOpacity(1);
1507         }
1508     }
1509
1510     moveOrCopyAnimations(Move, m_layer.get(), m_structuralLayer.get());
1511 }
1512
1513 GraphicsLayerCA::StructuralLayerPurpose GraphicsLayerCA::structuralLayerPurpose() const
1514 {
1515     if (preserves3D())
1516         return StructuralLayerForPreserves3D;
1517     
1518     if (isReplicated())
1519         return StructuralLayerForReplicaFlattening;
1520     
1521     return NoStructuralLayer;
1522 }
1523
1524 void GraphicsLayerCA::updateLayerDrawsContent(float pageScaleFactor)
1525 {
1526     bool needTiledLayer = requiresTiledLayer(pageScaleFactor);
1527     if (needTiledLayer != m_usingTiledLayer)
1528         swapFromOrToTiledLayer(needTiledLayer);
1529
1530     if (m_drawsContent)
1531         m_layer->setNeedsDisplay();
1532     else {
1533         m_layer->setContents(0);
1534         if (m_layerClones) {
1535             LayerMap::const_iterator end = m_layerClones->end();
1536             for (LayerMap::const_iterator it = m_layerClones->begin(); it != end; ++it)
1537                 it->value->setContents(0);
1538         }
1539     }
1540 }
1541
1542 void GraphicsLayerCA::updateAcceleratesDrawing()
1543 {
1544     m_layer->setAcceleratesDrawing(m_acceleratesDrawing);
1545 }
1546
1547 void GraphicsLayerCA::updateDebugBorder()
1548 {
1549     if (isShowingDebugBorder())
1550         updateDebugIndicators();
1551     else
1552         m_layer->setBorderWidth(0);
1553 }
1554
1555 FloatRect GraphicsLayerCA::adjustTiledLayerVisibleRect(TiledBacking* tiledBacking, const FloatRect& oldVisibleRect, const FloatSize& oldSize) const
1556 {
1557     // If the old visible rect is empty, we have no information about how the visible area is changing
1558     // (maybe the layer was just created), so don't attempt to expand. Also don't attempt to expand
1559     // if the size changed.
1560     if (oldVisibleRect.isEmpty() || m_size != oldSize)
1561         return m_visibleRect;
1562
1563     const float paddingMultiplier = 2;
1564
1565     float leftEdgeDelta = paddingMultiplier * (m_visibleRect.x() - oldVisibleRect.x());
1566     float rightEdgeDelta = paddingMultiplier * (m_visibleRect.maxX() - oldVisibleRect.maxX());
1567
1568     float topEdgeDelta = paddingMultiplier * (m_visibleRect.y() - oldVisibleRect.y());
1569     float bottomEdgeDelta = paddingMultiplier * (m_visibleRect.maxY() - oldVisibleRect.maxY());
1570     
1571     FloatRect existingTileBackingRect = tiledBacking->visibleRect();
1572     FloatRect expandedRect = m_visibleRect;
1573
1574     // More exposed on left side.
1575     if (leftEdgeDelta < 0) {
1576         float newLeft = expandedRect.x() + leftEdgeDelta;
1577         // Pad to the left, but don't reduce padding that's already in the backing store (since we're still exposing to the left).
1578         if (newLeft < existingTileBackingRect.x())
1579             expandedRect.shiftXEdgeTo(newLeft);
1580         else
1581             expandedRect.shiftXEdgeTo(existingTileBackingRect.x());
1582     }
1583
1584     // More exposed on right.
1585     if (rightEdgeDelta > 0) {
1586         float newRight = expandedRect.maxX() + rightEdgeDelta;
1587         // Pad to the right, but don't reduce padding that's already in the backing store (since we're still exposing to the right).
1588         if (newRight > existingTileBackingRect.maxX())
1589             expandedRect.setWidth(newRight - expandedRect.x());
1590         else
1591             expandedRect.setWidth(existingTileBackingRect.maxX() - expandedRect.x());
1592     }
1593
1594     // More exposed at top.
1595     if (topEdgeDelta < 0) {
1596         float newTop = expandedRect.y() + topEdgeDelta;
1597         if (newTop < existingTileBackingRect.y())
1598             expandedRect.shiftYEdgeTo(newTop);
1599         else
1600             expandedRect.shiftYEdgeTo(existingTileBackingRect.y());
1601     }
1602
1603     // More exposed on bottom.
1604     if (bottomEdgeDelta > 0) {
1605         float newBottom = expandedRect.maxY() + bottomEdgeDelta;
1606         if (newBottom > existingTileBackingRect.maxY())
1607             expandedRect.setHeight(newBottom - expandedRect.y());
1608         else
1609             expandedRect.setHeight(existingTileBackingRect.maxY() - expandedRect.y());
1610     }
1611     
1612     return expandedRect;
1613 }
1614
1615 void GraphicsLayerCA::updateVisibleRect(const FloatRect& oldVisibleRect)
1616 {
1617     if (!m_layer->usesTileCacheLayer())
1618         return;
1619
1620     FloatRect tileArea = m_visibleRect;
1621     if (m_layer->layerType() == PlatformCALayer::LayerTypeTileCacheLayer)
1622         tileArea = adjustTiledLayerVisibleRect(tiledBacking(), oldVisibleRect, m_sizeAtLastVisibleRectUpdate);
1623
1624     tiledBacking()->setVisibleRect(enclosingIntRect(tileArea));
1625
1626     m_sizeAtLastVisibleRectUpdate = m_size;
1627 }
1628
1629 void GraphicsLayerCA::updateBackgroundColor()
1630 {
1631     m_layer->setBackgroundColor(m_backgroundColor);
1632 }
1633
1634 void GraphicsLayerCA::updateContentsImage()
1635 {
1636     if (m_pendingContentsImage) {
1637         if (!m_contentsLayer.get()) {
1638             m_contentsLayer = PlatformCALayer::create(PlatformCALayer::LayerTypeLayer, this);
1639 #ifndef NDEBUG
1640             m_contentsLayer->setName("Image Layer");
1641 #endif
1642             setupContentsLayer(m_contentsLayer.get());
1643             // m_contentsLayer will be parented by updateSublayerList
1644         }
1645
1646         // FIXME: maybe only do trilinear if the image is being scaled down,
1647         // but then what if the layer size changes?
1648         m_contentsLayer->setMinificationFilter(PlatformCALayer::Trilinear);
1649         m_contentsLayer->setContents(m_pendingContentsImage.get());
1650         m_pendingContentsImage = 0;
1651
1652         if (m_contentsLayerClones) {
1653             LayerMap::const_iterator end = m_contentsLayerClones->end();
1654             for (LayerMap::const_iterator it = m_contentsLayerClones->begin(); it != end; ++it)
1655                 it->value->setContents(m_contentsLayer->contents());
1656         }
1657         
1658         updateContentsRect();
1659     } else {
1660         // No image.
1661         // m_contentsLayer will be removed via updateSublayerList.
1662         m_contentsLayer = 0;
1663     }
1664 }
1665
1666 void GraphicsLayerCA::updateContentsMediaLayer()
1667 {
1668     // Video layer was set as m_contentsLayer, and will get parented in updateSublayerList().
1669     if (m_contentsLayer) {
1670         setupContentsLayer(m_contentsLayer.get());
1671         updateContentsRect();
1672     }
1673 }
1674
1675 void GraphicsLayerCA::updateContentsCanvasLayer()
1676 {
1677     // CanvasLayer was set as m_contentsLayer, and will get parented in updateSublayerList().
1678     if (m_contentsLayer) {
1679         setupContentsLayer(m_contentsLayer.get());
1680         m_contentsLayer->setNeedsDisplay();
1681         updateContentsRect();
1682     }
1683 }
1684
1685 void GraphicsLayerCA::updateContentsColorLayer()
1686 {
1687     // Color layer was set as m_contentsLayer, and will get parented in updateSublayerList().
1688     if (m_contentsLayer) {
1689         setupContentsLayer(m_contentsLayer.get());
1690         updateContentsRect();
1691         ASSERT(m_contentsSolidColor.isValid()); // An invalid color should have removed the contents layer.
1692         m_contentsLayer->setBackgroundColor(m_contentsSolidColor);
1693
1694         if (m_contentsLayerClones) {
1695             LayerMap::const_iterator end = m_contentsLayerClones->end();
1696             for (LayerMap::const_iterator it = m_contentsLayerClones->begin(); it != end; ++it)
1697                 it->value->setBackgroundColor(m_contentsSolidColor);
1698         }
1699     }
1700 }
1701
1702 void GraphicsLayerCA::updateContentsRect()
1703 {
1704     if (!m_contentsLayer)
1705         return;
1706
1707     FloatPoint point(m_contentsRect.x(), m_contentsRect.y());
1708     FloatRect rect(0, 0, m_contentsRect.width(), m_contentsRect.height());
1709
1710     m_contentsLayer->setPosition(point);
1711     m_contentsLayer->setBounds(rect);
1712
1713     if (m_contentsLayerClones) {
1714         LayerMap::const_iterator end = m_contentsLayerClones->end();
1715         for (LayerMap::const_iterator it = m_contentsLayerClones->begin(); it != end; ++it) {
1716             it->value->setPosition(point);
1717             it->value->setBounds(rect);
1718         }
1719     }
1720 }
1721
1722 void GraphicsLayerCA::updateMaskLayer()
1723 {
1724     PlatformCALayer* maskCALayer = m_maskLayer ? static_cast<GraphicsLayerCA*>(m_maskLayer)->primaryLayer() : 0;
1725     m_layer->setMask(maskCALayer);
1726
1727     LayerMap* maskLayerCloneMap = m_maskLayer ? static_cast<GraphicsLayerCA*>(m_maskLayer)->primaryLayerClones() : 0;
1728     
1729     if (LayerMap* layerCloneMap = m_layerClones.get()) {
1730         LayerMap::const_iterator end = layerCloneMap->end();
1731         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {            
1732             PlatformCALayer* maskClone = maskLayerCloneMap ? maskLayerCloneMap->get(it->key).get() : 0;
1733             it->value->setMask(maskClone);
1734         }
1735     }
1736 }
1737
1738 void GraphicsLayerCA::updateReplicatedLayers()
1739 {
1740     // Clone the descendants of the replicated layer, and parent under us.
1741     ReplicaState replicaState(ReplicaState::ReplicaBranch);
1742
1743     RefPtr<PlatformCALayer>replicaRoot = replicatedLayerRoot(replicaState);
1744     if (!replicaRoot)
1745         return;
1746
1747     if (m_structuralLayer)
1748         m_structuralLayer->insertSublayer(replicaRoot.get(), 0);
1749     else
1750         m_layer->insertSublayer(replicaRoot.get(), 0);
1751 }
1752
1753 // For now, this assumes that layers only ever have one replica, so replicaIndices contains only 0 and 1.
1754 GraphicsLayerCA::CloneID GraphicsLayerCA::ReplicaState::cloneID() const
1755 {
1756     size_t depth = m_replicaBranches.size();
1757
1758     const size_t bitsPerUChar = sizeof(UChar) * 8;
1759     size_t vectorSize = (depth + bitsPerUChar - 1) / bitsPerUChar;
1760     
1761     Vector<UChar> result(vectorSize);
1762     result.fill(0);
1763
1764     // Create a string from the bit sequence which we can use to identify the clone.
1765     // Note that the string may contain embedded nulls, but that's OK.
1766     for (size_t i = 0; i < depth; ++i) {
1767         UChar& currChar = result[i / bitsPerUChar];
1768         currChar = (currChar << 1) | m_replicaBranches[i];
1769     }
1770     
1771     return String::adopt(result);
1772 }
1773
1774 PassRefPtr<PlatformCALayer> GraphicsLayerCA::replicatedLayerRoot(ReplicaState& replicaState)
1775 {
1776     // Limit replica nesting, to avoid 2^N explosion of replica layers.
1777     if (!m_replicatedLayer || replicaState.replicaDepth() == ReplicaState::maxReplicaDepth)
1778         return 0;
1779
1780     GraphicsLayerCA* replicatedLayer = static_cast<GraphicsLayerCA*>(m_replicatedLayer);
1781     
1782     RefPtr<PlatformCALayer> clonedLayerRoot = replicatedLayer->fetchCloneLayers(this, replicaState, RootCloneLevel);
1783     FloatPoint cloneRootPosition = replicatedLayer->positionForCloneRootLayer();
1784
1785     // Replica root has no offset or transform
1786     clonedLayerRoot->setPosition(cloneRootPosition);
1787     clonedLayerRoot->setTransform(TransformationMatrix());
1788
1789     return clonedLayerRoot;
1790 }
1791
1792 void GraphicsLayerCA::updateAnimations()
1793 {
1794     if (m_animationsToProcess.size()) {
1795         AnimationsToProcessMap::const_iterator end = m_animationsToProcess.end();
1796         for (AnimationsToProcessMap::const_iterator it = m_animationsToProcess.begin(); it != end; ++it) {
1797             const String& currAnimationName = it->key;
1798             AnimationsMap::iterator animationIt = m_runningAnimations.find(currAnimationName);
1799             if (animationIt == m_runningAnimations.end())
1800                 continue;
1801
1802             const AnimationProcessingAction& processingInfo = it->value;
1803             const Vector<LayerPropertyAnimation>& animations = animationIt->value;
1804             for (size_t i = 0; i < animations.size(); ++i) {
1805                 const LayerPropertyAnimation& currAnimation = animations[i];
1806                 switch (processingInfo.action) {
1807                 case Remove:
1808                     removeCAAnimationFromLayer(currAnimation.m_property, currAnimationName, currAnimation.m_index);
1809                     break;
1810                 case Pause:
1811                     pauseCAAnimationOnLayer(currAnimation.m_property, currAnimationName, currAnimation.m_index, processingInfo.timeOffset);
1812                     break;
1813                 }
1814             }
1815
1816             if (processingInfo.action == Remove)
1817                 m_runningAnimations.remove(currAnimationName);
1818         }
1819     
1820         m_animationsToProcess.clear();
1821     }
1822     
1823     size_t numAnimations;
1824     if ((numAnimations = m_uncomittedAnimations.size())) {
1825         for (size_t i = 0; i < numAnimations; ++i) {
1826             const LayerPropertyAnimation& pendingAnimation = m_uncomittedAnimations[i];
1827             setAnimationOnLayer(pendingAnimation.m_animation.get(), pendingAnimation.m_property, pendingAnimation.m_name, pendingAnimation.m_index, pendingAnimation.m_timeOffset);
1828             
1829             AnimationsMap::iterator it = m_runningAnimations.find(pendingAnimation.m_name);
1830             if (it == m_runningAnimations.end()) {
1831                 Vector<LayerPropertyAnimation> animations;
1832                 animations.append(pendingAnimation);
1833                 m_runningAnimations.add(pendingAnimation.m_name, animations);
1834             } else {
1835                 Vector<LayerPropertyAnimation>& animations = it->value;
1836                 animations.append(pendingAnimation);
1837             }
1838         }
1839         
1840         m_uncomittedAnimations.clear();
1841     }
1842 }
1843
1844 bool GraphicsLayerCA::isRunningTransformAnimation() const
1845 {
1846     AnimationsMap::const_iterator end = m_runningAnimations.end();
1847     for (AnimationsMap::const_iterator it = m_runningAnimations.begin(); it != end; ++it) {
1848         const Vector<LayerPropertyAnimation>& propertyAnimations = it->value;
1849         size_t numAnimations = propertyAnimations.size();
1850         for (size_t i = 0; i < numAnimations; ++i) {
1851             const LayerPropertyAnimation& currAnimation = propertyAnimations[i];
1852             if (currAnimation.m_property == AnimatedPropertyWebkitTransform)
1853                 return true;
1854         }
1855     }
1856     return false;
1857 }
1858
1859 void GraphicsLayerCA::setAnimationOnLayer(PlatformCAAnimation* caAnim, AnimatedPropertyID property, const String& animationName, int index, double timeOffset)
1860 {
1861     PlatformCALayer* layer = animatedLayer(property);
1862     
1863     if (timeOffset)
1864         caAnim->setBeginTime(CACurrentMediaTime() - timeOffset);
1865
1866     String animationID = animationIdentifier(animationName, property, index);
1867
1868     layer->removeAnimationForKey(animationID);
1869     layer->addAnimationForKey(animationID, caAnim);
1870
1871     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
1872         LayerMap::const_iterator end = layerCloneMap->end();
1873         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1874             // Skip immediate replicas, since they move with the original.
1875             if (m_replicaLayer && isReplicatedRootClone(it->key))
1876                 continue;
1877
1878             it->value->removeAnimationForKey(animationID);
1879             it->value->addAnimationForKey(animationID, caAnim);
1880         }
1881     }
1882 }
1883
1884 // Workaround for <rdar://problem/7311367>
1885 static void bug7311367Workaround(PlatformCALayer* transformLayer, const TransformationMatrix& transform)
1886 {
1887     if (!transformLayer)
1888         return;
1889
1890     TransformationMatrix caTransform = transform;
1891     caTransform.setM41(caTransform.m41() + 1);
1892     transformLayer->setTransform(caTransform);
1893
1894     caTransform.setM41(caTransform.m41() - 1);
1895     transformLayer->setTransform(caTransform);
1896 }
1897
1898 bool GraphicsLayerCA::removeCAAnimationFromLayer(AnimatedPropertyID property, const String& animationName, int index)
1899 {
1900     PlatformCALayer* layer = animatedLayer(property);
1901
1902     String animationID = animationIdentifier(animationName, property, index);
1903
1904     if (!layer->animationForKey(animationID))
1905         return false;
1906     
1907     layer->removeAnimationForKey(animationID);
1908     bug7311367Workaround(m_structuralLayer.get(), m_transform);
1909
1910     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
1911         LayerMap::const_iterator end = layerCloneMap->end();
1912         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1913             // Skip immediate replicas, since they move with the original.
1914             if (m_replicaLayer && isReplicatedRootClone(it->key))
1915                 continue;
1916
1917             it->value->removeAnimationForKey(animationID);
1918         }
1919     }
1920     return true;
1921 }
1922
1923 void GraphicsLayerCA::pauseCAAnimationOnLayer(AnimatedPropertyID property, const String& animationName, int index, double timeOffset)
1924 {
1925     PlatformCALayer* layer = animatedLayer(property);
1926
1927     String animationID = animationIdentifier(animationName, property, index);
1928
1929     RefPtr<PlatformCAAnimation> curAnim = layer->animationForKey(animationID);
1930     if (!curAnim)
1931         return;
1932
1933     // Animations on the layer are immutable, so we have to clone and modify.
1934     RefPtr<PlatformCAAnimation> newAnim = curAnim->copy();
1935
1936     newAnim->setSpeed(0);
1937     newAnim->setTimeOffset(timeOffset);
1938     
1939     layer->addAnimationForKey(animationID, newAnim.get()); // This will replace the running animation.
1940
1941     // Pause the animations on the clones too.
1942     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
1943         LayerMap::const_iterator end = layerCloneMap->end();
1944         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1945             // Skip immediate replicas, since they move with the original.
1946             if (m_replicaLayer && isReplicatedRootClone(it->key))
1947                 continue;
1948             it->value->addAnimationForKey(animationID, newAnim.get());
1949         }
1950     }
1951 }
1952
1953 void GraphicsLayerCA::repaintLayerDirtyRects()
1954 {
1955     if (!m_dirtyRects.size())
1956         return;
1957
1958     for (size_t i = 0; i < m_dirtyRects.size(); ++i)
1959         m_layer->setNeedsDisplay(&(m_dirtyRects[i]));
1960     
1961     m_dirtyRects.clear();
1962 }
1963
1964 void GraphicsLayerCA::updateContentsNeedsDisplay()
1965 {
1966     if (m_contentsLayer)
1967         m_contentsLayer->setNeedsDisplay();
1968 }
1969
1970 bool GraphicsLayerCA::createAnimationFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset)
1971 {
1972     ASSERT(valueList.property() != AnimatedPropertyWebkitTransform && (!supportsAcceleratedFilterAnimations() || valueList.property() != AnimatedPropertyWebkitFilter));
1973     
1974     bool isKeyframe = valueList.size() > 2;
1975     bool valuesOK;
1976     
1977     bool additive = false;
1978     int animationIndex = 0;
1979     
1980     RefPtr<PlatformCAAnimation> caAnimation;
1981     
1982     if (isKeyframe) {
1983         caAnimation = createKeyframeAnimation(animation, propertyIdToString(valueList.property()), additive);
1984         valuesOK = setAnimationKeyframes(valueList, animation, caAnimation.get());
1985     } else {
1986         caAnimation = createBasicAnimation(animation, propertyIdToString(valueList.property()), additive);
1987         valuesOK = setAnimationEndpoints(valueList, animation, caAnimation.get());
1988     }
1989     
1990     if (!valuesOK)
1991         return false;
1992
1993     m_uncomittedAnimations.append(LayerPropertyAnimation(caAnimation, animationName, valueList.property(), animationIndex, timeOffset));
1994
1995     return true;
1996 }
1997
1998 bool GraphicsLayerCA::appendToUncommittedAnimations(const KeyframeValueList& valueList, const TransformOperations* operations, const Animation* animation, const String& animationName, const IntSize& boxSize, int animationIndex, double timeOffset, bool isMatrixAnimation)
1999 {
2000     TransformOperation::OperationType transformOp = isMatrixAnimation ? TransformOperation::MATRIX_3D : operations->operations().at(animationIndex)->getOperationType();
2001     bool additive = animationIndex > 0;
2002     bool isKeyframe = valueList.size() > 2;
2003
2004     RefPtr<PlatformCAAnimation> caAnimation;
2005     bool validMatrices = true;
2006     if (isKeyframe) {
2007         caAnimation = createKeyframeAnimation(animation, propertyIdToString(valueList.property()), additive);
2008         validMatrices = setTransformAnimationKeyframes(valueList, animation, caAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize);
2009     } else {
2010         caAnimation = createBasicAnimation(animation, propertyIdToString(valueList.property()), additive);
2011         validMatrices = setTransformAnimationEndpoints(valueList, animation, caAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize);
2012     }
2013     
2014     if (!validMatrices)
2015         return false;
2016
2017     m_uncomittedAnimations.append(LayerPropertyAnimation(caAnimation, animationName, valueList.property(), animationIndex, timeOffset));
2018     return true;
2019 }
2020
2021 bool GraphicsLayerCA::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset, const IntSize& boxSize)
2022 {
2023     ASSERT(valueList.property() == AnimatedPropertyWebkitTransform);
2024
2025     bool hasBigRotation;
2026     int listIndex = validateTransformOperations(valueList, hasBigRotation);
2027     const TransformOperations* operations = (listIndex >= 0) ? static_cast<const TransformAnimationValue*>(valueList.at(listIndex))->value() : 0;
2028
2029     // We need to fall back to software animation if we don't have setValueFunction:, and
2030     // we would need to animate each incoming transform function separately. This is the
2031     // case if we have a rotation >= 180 or we have more than one transform function.
2032     if ((hasBigRotation || (operations && operations->size() > 1)) && !PlatformCAAnimation::supportsValueFunction())
2033         return false;
2034
2035     bool validMatrices = true;
2036
2037     // If function lists don't match we do a matrix animation, otherwise we do a component hardware animation.
2038     // Also, we can't do component animation unless we have valueFunction, so we need to do matrix animation
2039     // if that's not true as well.
2040     bool isMatrixAnimation = listIndex < 0 || !PlatformCAAnimation::supportsValueFunction();
2041     int numAnimations = isMatrixAnimation ? 1 : operations->size();
2042
2043     bool reverseAnimationList = true;
2044 #if !PLATFORM(IOS) && !PLATFORM(WIN) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
2045         // Old versions of Core Animation apply animations in reverse order (<rdar://problem/7095638>) so we need to flip the list.
2046         // to be non-additive. For binary compatibility, the current version of Core Animation preserves this behavior for applications linked
2047         // on or before Snow Leopard.
2048         // FIXME: This fix has not been added to QuartzCore on Windows yet (<rdar://problem/9112233>) so we expect the
2049         // reversed animation behavior
2050         static bool executableWasLinkedOnOrBeforeSnowLeopard = wkExecutableWasLinkedOnOrBeforeSnowLeopard();
2051         if (!executableWasLinkedOnOrBeforeSnowLeopard)
2052             reverseAnimationList = false;
2053 #endif
2054     if (reverseAnimationList) {
2055         for (int animationIndex = numAnimations - 1; animationIndex >= 0; --animationIndex) {
2056             if (!appendToUncommittedAnimations(valueList, operations, animation, animationName, boxSize, animationIndex, timeOffset, isMatrixAnimation)) {
2057                 validMatrices = false;
2058                 break;
2059             }
2060         }
2061     } else {
2062         for (int animationIndex = 0; animationIndex < numAnimations; ++animationIndex) {
2063             if (!appendToUncommittedAnimations(valueList, operations, animation, animationName, boxSize, animationIndex, timeOffset, isMatrixAnimation)) {
2064                 validMatrices = false;
2065                 break;
2066             }
2067         }
2068     }
2069
2070     return validMatrices;
2071 }
2072
2073 #if ENABLE(CSS_FILTERS)
2074 bool GraphicsLayerCA::appendToUncommittedAnimations(const KeyframeValueList& valueList, const FilterOperation* operation, const Animation* animation, const String& animationName, int animationIndex, double timeOffset)
2075 {
2076     bool isKeyframe = valueList.size() > 2;
2077     
2078     FilterOperation::OperationType filterOp = operation->getOperationType();
2079     int numAnimatedProperties = PlatformCAAnimation::numAnimatedFilterProperties(filterOp);
2080     
2081     // Each filter might need to animate multiple properties, each with their own keyPath. The keyPath is always of the form:
2082     //
2083     //      filter.filter_<animationIndex>.<filterPropertyName>
2084     //
2085     // PlatformCAAnimation tells us how many properties each filter has and we iterate that many times and create an animation
2086     // for each. This internalFilterPropertyIndex gets passed to PlatformCAAnimation so it can properly create the property animation
2087     // values.
2088     for (int internalFilterPropertyIndex = 0; internalFilterPropertyIndex < numAnimatedProperties; ++internalFilterPropertyIndex) {
2089         bool valuesOK;
2090         RefPtr<PlatformCAAnimation> caAnimation;
2091         String keyPath = String::format("filters.filter_%d.%s", animationIndex, PlatformCAAnimation::animatedFilterPropertyName(filterOp, internalFilterPropertyIndex));
2092         
2093         if (isKeyframe) {
2094             caAnimation = createKeyframeAnimation(animation, keyPath, false);
2095             valuesOK = setFilterAnimationKeyframes(valueList, animation, caAnimation.get(), animationIndex, internalFilterPropertyIndex, filterOp);
2096         } else {
2097             caAnimation = createBasicAnimation(animation, keyPath, false);
2098             valuesOK = setFilterAnimationEndpoints(valueList, animation, caAnimation.get(), animationIndex, internalFilterPropertyIndex);
2099         }
2100         
2101         ASSERT(valuesOK);
2102
2103         m_uncomittedAnimations.append(LayerPropertyAnimation(caAnimation, animationName, valueList.property(), animationIndex, timeOffset));
2104     }
2105
2106     return true;
2107 }
2108
2109 bool GraphicsLayerCA::createFilterAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset)
2110 {
2111     ASSERT(valueList.property() == AnimatedPropertyWebkitFilter);
2112
2113     int listIndex = validateFilterOperations(valueList);
2114     if (listIndex < 0)
2115         return false;
2116         
2117     const FilterOperations* operations = static_cast<const FilterAnimationValue*>(valueList.at(listIndex))->value();
2118     // Make sure the platform layer didn't fallback to using software filter compositing instead.
2119     if (!PlatformCALayer::filtersCanBeComposited(*operations))
2120         return false;
2121
2122     int numAnimations = operations->size();
2123
2124     // FIXME: We can't currently hardware animate shadows.
2125     for (int i = 0; i < numAnimations; ++i) {
2126         if (operations->at(i)->getOperationType() == FilterOperation::DROP_SHADOW)
2127             return false;
2128     }
2129
2130     for (int animationIndex = 0; animationIndex < numAnimations; ++animationIndex) {
2131         if (!appendToUncommittedAnimations(valueList, operations->operations().at(animationIndex).get(), animation, animationName, animationIndex, timeOffset))
2132             return false;
2133     }
2134
2135     return true;
2136 }
2137 #endif
2138
2139 PassRefPtr<PlatformCAAnimation> GraphicsLayerCA::createBasicAnimation(const Animation* anim, const String& keyPath, bool additive)
2140 {
2141     RefPtr<PlatformCAAnimation> basicAnim = PlatformCAAnimation::create(PlatformCAAnimation::Basic, keyPath);
2142     setupAnimation(basicAnim.get(), anim, additive);
2143     return basicAnim;
2144 }
2145
2146 PassRefPtr<PlatformCAAnimation>GraphicsLayerCA::createKeyframeAnimation(const Animation* anim, const String& keyPath, bool additive)
2147 {
2148     RefPtr<PlatformCAAnimation> keyframeAnim = PlatformCAAnimation::create(PlatformCAAnimation::Keyframe, keyPath);
2149     setupAnimation(keyframeAnim.get(), anim, additive);
2150     return keyframeAnim;
2151 }
2152
2153 void GraphicsLayerCA::setupAnimation(PlatformCAAnimation* propertyAnim, const Animation* anim, bool additive)
2154 {
2155     double duration = anim->duration();
2156     if (duration <= 0)
2157         duration = cAnimationAlmostZeroDuration;
2158
2159     float repeatCount = anim->iterationCount();
2160     if (repeatCount == Animation::IterationCountInfinite)
2161         repeatCount = numeric_limits<float>::max();
2162     else if (anim->direction() == Animation::AnimationDirectionAlternate || anim->direction() == Animation::AnimationDirectionAlternateReverse)
2163         repeatCount /= 2;
2164
2165     PlatformCAAnimation::FillModeType fillMode = PlatformCAAnimation::NoFillMode;
2166     switch (anim->fillMode()) {
2167     case AnimationFillModeNone:
2168         fillMode = PlatformCAAnimation::Forwards; // Use "forwards" rather than "removed" because the style system will remove the animation when it is finished. This avoids a flash.
2169         break;
2170     case AnimationFillModeBackwards:
2171         fillMode = PlatformCAAnimation::Both; // Use "both" rather than "backwards" because the style system will remove the animation when it is finished. This avoids a flash.
2172         break;
2173     case AnimationFillModeForwards:
2174         fillMode = PlatformCAAnimation::Forwards;
2175         break;
2176     case AnimationFillModeBoth:
2177         fillMode = PlatformCAAnimation::Both;
2178         break;
2179     }
2180
2181     propertyAnim->setDuration(duration);
2182     propertyAnim->setRepeatCount(repeatCount);
2183     propertyAnim->setAutoreverses(anim->direction() == Animation::AnimationDirectionAlternate || anim->direction() == Animation::AnimationDirectionAlternateReverse);
2184     propertyAnim->setRemovedOnCompletion(false);
2185     propertyAnim->setAdditive(additive);
2186     propertyAnim->setFillMode(fillMode);
2187 }
2188
2189 const TimingFunction* GraphicsLayerCA::timingFunctionForAnimationValue(const AnimationValue* animValue, const Animation* anim)
2190 {
2191     if (animValue->timingFunction())
2192         return animValue->timingFunction();
2193     if (anim->isTimingFunctionSet())
2194         return anim->timingFunction().get();
2195     
2196     return CubicBezierTimingFunction::defaultTimingFunction();
2197 }
2198
2199 bool GraphicsLayerCA::setAnimationEndpoints(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* basicAnim)
2200 {
2201     bool forwards = animation->directionIsForwards();
2202
2203     unsigned fromIndex = !forwards;
2204     unsigned toIndex = forwards;
2205     
2206     switch (valueList.property()) {
2207     case AnimatedPropertyOpacity: {
2208         basicAnim->setFromValue(static_cast<const FloatAnimationValue*>(valueList.at(fromIndex))->value());
2209         basicAnim->setToValue(static_cast<const FloatAnimationValue*>(valueList.at(toIndex))->value());
2210         break;
2211     }
2212     default:
2213         ASSERT_NOT_REACHED(); // we don't animate color yet
2214         break;
2215     }
2216
2217     // This codepath is used for 2-keyframe animations, so we still need to look in the start
2218     // for a timing function. Even in the reversing animation case, the first keyframe provides the timing function.
2219     const TimingFunction* timingFunction = timingFunctionForAnimationValue(valueList.at(0), animation);
2220     if (timingFunction)
2221         basicAnim->setTimingFunction(timingFunction, !forwards);
2222
2223     return true;
2224 }
2225
2226 bool GraphicsLayerCA::setAnimationKeyframes(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* keyframeAnim)
2227 {
2228     Vector<float> keyTimes;
2229     Vector<float> values;
2230     Vector<const TimingFunction*> timingFunctions;
2231
2232     bool forwards = animation->directionIsForwards();
2233     
2234     for (unsigned i = 0; i < valueList.size(); ++i) {
2235         unsigned index = forwards ? i : (valueList.size() - i - 1);
2236         const AnimationValue* curValue = valueList.at(index);
2237         keyTimes.append(forwards ? curValue->keyTime() : (1 - curValue->keyTime()));
2238
2239         switch (valueList.property()) {
2240         case AnimatedPropertyOpacity: {
2241             const FloatAnimationValue* floatValue = static_cast<const FloatAnimationValue*>(curValue);
2242             values.append(floatValue->value());
2243             break;
2244         }
2245         default:
2246             ASSERT_NOT_REACHED(); // we don't animate color yet
2247             break;
2248         }
2249
2250         if (i < (valueList.size() - 1))
2251             timingFunctions.append(timingFunctionForAnimationValue(forwards ? curValue : valueList.at(index - 1), animation));
2252     }
2253     
2254     keyframeAnim->setKeyTimes(keyTimes);
2255     keyframeAnim->setValues(values);
2256     keyframeAnim->setTimingFunctions(timingFunctions, !forwards);
2257     
2258     return true;
2259 }
2260
2261 bool GraphicsLayerCA::setTransformAnimationEndpoints(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* basicAnim, int functionIndex, TransformOperation::OperationType transformOpType, bool isMatrixAnimation, const IntSize& boxSize)
2262 {
2263     ASSERT(valueList.size() == 2);
2264
2265     bool forwards = animation->directionIsForwards();
2266     
2267     unsigned fromIndex = !forwards;
2268     unsigned toIndex = forwards;
2269     
2270     const TransformAnimationValue* startValue = static_cast<const TransformAnimationValue*>(valueList.at(fromIndex));
2271     const TransformAnimationValue* endValue = static_cast<const TransformAnimationValue*>(valueList.at(toIndex));
2272     
2273     if (isMatrixAnimation) {
2274         TransformationMatrix fromTransform, toTransform;
2275         startValue->value()->apply(boxSize, fromTransform);
2276         endValue->value()->apply(boxSize, toTransform);
2277
2278         // If any matrix is singular, CA won't animate it correctly. So fall back to software animation
2279         if (!fromTransform.isInvertible() || !toTransform.isInvertible())
2280             return false;
2281             
2282         basicAnim->setFromValue(fromTransform);
2283         basicAnim->setToValue(toTransform);
2284     } else {
2285         if (isTransformTypeNumber(transformOpType)) {
2286             float fromValue;
2287             getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue);
2288             basicAnim->setFromValue(fromValue);
2289             
2290             float toValue;
2291             getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue);
2292             basicAnim->setToValue(toValue);
2293         } else if (isTransformTypeFloatPoint3D(transformOpType)) {
2294             FloatPoint3D fromValue;
2295             getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue);
2296             basicAnim->setFromValue(fromValue);
2297             
2298             FloatPoint3D toValue;
2299             getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue);
2300             basicAnim->setToValue(toValue);
2301         } else {
2302             TransformationMatrix fromValue;
2303             getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue);
2304             basicAnim->setFromValue(fromValue);
2305
2306             TransformationMatrix toValue;
2307             getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue);
2308             basicAnim->setToValue(toValue);
2309         }
2310     }
2311
2312     // This codepath is used for 2-keyframe animations, so we still need to look in the start
2313     // for a timing function. Even in the reversing animation case, the first keyframe provides the timing function.
2314     const TimingFunction* timingFunction = timingFunctionForAnimationValue(valueList.at(0), animation);
2315     basicAnim->setTimingFunction(timingFunction, !forwards);
2316
2317     PlatformCAAnimation::ValueFunctionType valueFunction = getValueFunctionNameForTransformOperation(transformOpType);
2318     if (valueFunction != PlatformCAAnimation::NoValueFunction)
2319         basicAnim->setValueFunction(valueFunction);
2320
2321     return true;
2322 }
2323
2324 bool GraphicsLayerCA::setTransformAnimationKeyframes(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* keyframeAnim, int functionIndex, TransformOperation::OperationType transformOpType, bool isMatrixAnimation, const IntSize& boxSize)
2325 {
2326     Vector<float> keyTimes;
2327     Vector<float> floatValues;
2328     Vector<FloatPoint3D> floatPoint3DValues;
2329     Vector<TransformationMatrix> transformationMatrixValues;
2330     Vector<const TimingFunction*> timingFunctions;
2331
2332     bool forwards = animation->directionIsForwards();
2333
2334     for (unsigned i = 0; i < valueList.size(); ++i) {
2335         unsigned index = forwards ? i : (valueList.size() - i - 1);
2336         const TransformAnimationValue* curValue = static_cast<const TransformAnimationValue*>(valueList.at(index));
2337         keyTimes.append(forwards ? curValue->keyTime() : (1 - curValue->keyTime()));
2338
2339         if (isMatrixAnimation) {
2340             TransformationMatrix transform;
2341             curValue->value()->apply(boxSize, transform);
2342
2343             // If any matrix is singular, CA won't animate it correctly. So fall back to software animation
2344             if (!transform.isInvertible())
2345                 return false;
2346
2347             transformationMatrixValues.append(transform);
2348         } else {
2349             const TransformOperation* transformOp = curValue->value()->at(functionIndex);
2350             if (isTransformTypeNumber(transformOpType)) {
2351                 float value;
2352                 getTransformFunctionValue(transformOp, transformOpType, boxSize, value);
2353                 floatValues.append(value);
2354             } else if (isTransformTypeFloatPoint3D(transformOpType)) {
2355                 FloatPoint3D value;
2356                 getTransformFunctionValue(transformOp, transformOpType, boxSize, value);
2357                 floatPoint3DValues.append(value);
2358             } else {
2359                 TransformationMatrix value;
2360                 getTransformFunctionValue(transformOp, transformOpType, boxSize, value);
2361                 transformationMatrixValues.append(value);
2362             }
2363         }
2364
2365         if (i < (valueList.size() - 1))
2366             timingFunctions.append(timingFunctionForAnimationValue(forwards ? curValue : valueList.at(index - 1), animation));
2367     }
2368     
2369     keyframeAnim->setKeyTimes(keyTimes);
2370     
2371     if (isTransformTypeNumber(transformOpType))
2372         keyframeAnim->setValues(floatValues);
2373     else if (isTransformTypeFloatPoint3D(transformOpType))
2374         keyframeAnim->setValues(floatPoint3DValues);
2375     else
2376         keyframeAnim->setValues(transformationMatrixValues);
2377         
2378     keyframeAnim->setTimingFunctions(timingFunctions, !forwards);
2379
2380     PlatformCAAnimation::ValueFunctionType valueFunction = getValueFunctionNameForTransformOperation(transformOpType);
2381     if (valueFunction != PlatformCAAnimation::NoValueFunction)
2382         keyframeAnim->setValueFunction(valueFunction);
2383
2384     return true;
2385 }
2386
2387 #if ENABLE(CSS_FILTERS)
2388 bool GraphicsLayerCA::setFilterAnimationEndpoints(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* basicAnim, int functionIndex, int internalFilterPropertyIndex)
2389 {
2390     ASSERT(valueList.size() == 2);
2391
2392     bool forwards = animation->directionIsForwards();
2393
2394     unsigned fromIndex = !forwards;
2395     unsigned toIndex = forwards;
2396
2397     const FilterAnimationValue* fromValue = static_cast<const FilterAnimationValue*>(valueList.at(fromIndex));
2398     const FilterAnimationValue* toValue = static_cast<const FilterAnimationValue*>(valueList.at(toIndex));
2399
2400     const FilterOperation* fromOperation = fromValue->value()->at(functionIndex);
2401     const FilterOperation* toOperation = toValue->value()->at(functionIndex);
2402
2403     RefPtr<DefaultFilterOperation> defaultFromOperation;
2404     RefPtr<DefaultFilterOperation> defaultToOperation;
2405
2406     ASSERT(fromOperation || toOperation);
2407
2408     if (!fromOperation) {
2409         defaultFromOperation = DefaultFilterOperation::create(toOperation->getOperationType());
2410         fromOperation = defaultFromOperation.get();
2411     }
2412
2413     if (!toOperation) {
2414         defaultToOperation = DefaultFilterOperation::create(fromOperation->getOperationType());
2415         toOperation = defaultToOperation.get();
2416     }
2417
2418     basicAnim->setFromValue(fromOperation, internalFilterPropertyIndex);
2419     basicAnim->setToValue(toOperation, internalFilterPropertyIndex);
2420
2421     // This codepath is used for 2-keyframe animations, so we still need to look in the start
2422     // for a timing function. Even in the reversing animation case, the first keyframe provides the timing function.
2423     basicAnim->setTimingFunction(timingFunctionForAnimationValue(valueList.at(0), animation), !forwards);
2424
2425     return true;
2426 }
2427
2428 bool GraphicsLayerCA::setFilterAnimationKeyframes(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* keyframeAnim, int functionIndex, int internalFilterPropertyIndex, FilterOperation::OperationType filterOp)
2429 {
2430     Vector<float> keyTimes;
2431     Vector<RefPtr<FilterOperation> > values;
2432     Vector<const TimingFunction*> timingFunctions;
2433     RefPtr<DefaultFilterOperation> defaultOperation;
2434
2435     bool forwards = animation->directionIsForwards();
2436
2437     for (unsigned i = 0; i < valueList.size(); ++i) {
2438         unsigned index = forwards ? i : (valueList.size() - i - 1);
2439         const FilterAnimationValue* curValue = static_cast<const FilterAnimationValue*>(valueList.at(index));
2440         keyTimes.append(forwards ? curValue->keyTime() : (1 - curValue->keyTime()));
2441
2442         if (curValue->value()->operations().size() > static_cast<size_t>(functionIndex))
2443             values.append(curValue->value()->operations()[functionIndex]);
2444         else {
2445             if (!defaultOperation)
2446                 defaultOperation = DefaultFilterOperation::create(filterOp);
2447             values.append(defaultOperation);
2448         }
2449
2450         if (i < (valueList.size() - 1))
2451             timingFunctions.append(timingFunctionForAnimationValue(forwards ? curValue : valueList.at(index - 1), animation));
2452     }
2453     
2454     keyframeAnim->setKeyTimes(keyTimes);
2455     keyframeAnim->setValues(values, internalFilterPropertyIndex);
2456     keyframeAnim->setTimingFunctions(timingFunctions, !forwards);
2457
2458     return true;
2459 }
2460 #endif
2461
2462 void GraphicsLayerCA::suspendAnimations(double time)
2463 {
2464     double t = PlatformCALayer::currentTimeToMediaTime(time ? time : currentTime());
2465     primaryLayer()->setSpeed(0);
2466     primaryLayer()->setTimeOffset(t);
2467
2468     // Suspend the animations on the clones too.
2469     if (LayerMap* layerCloneMap = primaryLayerClones()) {
2470         LayerMap::const_iterator end = layerCloneMap->end();
2471         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
2472             it->value->setSpeed(0);
2473             it->value->setTimeOffset(t);
2474         }
2475     }
2476 }
2477
2478 void GraphicsLayerCA::resumeAnimations()
2479 {
2480     primaryLayer()->setSpeed(1);
2481     primaryLayer()->setTimeOffset(0);
2482
2483     // Resume the animations on the clones too.
2484     if (LayerMap* layerCloneMap = primaryLayerClones()) {
2485         LayerMap::const_iterator end = layerCloneMap->end();
2486         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
2487             it->value->setSpeed(1);
2488             it->value->setTimeOffset(0);
2489         }
2490     }
2491 }
2492
2493 PlatformCALayer* GraphicsLayerCA::hostLayerForSublayers() const
2494 {
2495     return m_structuralLayer.get() ? m_structuralLayer.get() : m_layer.get(); 
2496 }
2497
2498 PlatformCALayer* GraphicsLayerCA::layerForSuperlayer() const
2499 {
2500     return m_structuralLayer ? m_structuralLayer.get() : m_layer.get();
2501 }
2502
2503 PlatformCALayer* GraphicsLayerCA::animatedLayer(AnimatedPropertyID property) const
2504 {
2505     return (property == AnimatedPropertyBackgroundColor) ? m_contentsLayer.get() : primaryLayer();
2506 }
2507
2508 GraphicsLayerCA::LayerMap* GraphicsLayerCA::animatedLayerClones(AnimatedPropertyID property) const
2509 {
2510     return (property == AnimatedPropertyBackgroundColor) ? m_contentsLayerClones.get() : primaryLayerClones();
2511 }
2512
2513 static float clampedContentsScaleForScale(float scale)
2514 {
2515     // Define some limits as a sanity check for the incoming scale value
2516     // those too small to see.
2517     const float maxScale = 10.0f;
2518     const float minScale = 0.01f;
2519     return max(minScale, min(scale, maxScale));
2520 }
2521
2522 void GraphicsLayerCA::updateContentsScale(float pageScaleFactor)
2523 {
2524     bool needTiledLayer = requiresTiledLayer(pageScaleFactor);
2525     if (needTiledLayer != m_usingTiledLayer)
2526         swapFromOrToTiledLayer(needTiledLayer);
2527
2528     float contentsScale = clampedContentsScaleForScale(pageScaleFactor * deviceScaleFactor());
2529     
2530     m_layer->setContentsScale(contentsScale);
2531     if (drawsContent())
2532         m_layer->setNeedsDisplay();
2533 }
2534
2535 void GraphicsLayerCA::setShowDebugBorder(bool showBorder)
2536 {
2537     if (showBorder == m_showDebugBorder)
2538         return;
2539
2540     GraphicsLayer::setShowDebugBorder(showBorder);
2541     noteLayerPropertyChanged(DebugIndicatorsChanged);
2542 }
2543
2544 void GraphicsLayerCA::setShowRepaintCounter(bool showCounter)
2545 {
2546     if (showCounter == m_showRepaintCounter)
2547         return;
2548
2549     GraphicsLayer::setShowRepaintCounter(showCounter);
2550     noteLayerPropertyChanged(DebugIndicatorsChanged);
2551 }
2552
2553 void GraphicsLayerCA::setDebugBackgroundColor(const Color& color)
2554 {    
2555     if (color.isValid())
2556         m_layer->setBackgroundColor(color);
2557     else
2558         m_layer->setBackgroundColor(Color::transparent);
2559 }
2560
2561 void GraphicsLayerCA::getDebugBorderInfo(Color& color, float& width) const
2562 {
2563     if (m_isPageTileCacheLayer) {
2564         color = Color(0, 0, 128, 128); // tile cache layer: dark blue
2565         width = 0.5;
2566         return;
2567     }
2568
2569     GraphicsLayer::getDebugBorderInfo(color, width);
2570 }
2571
2572 void GraphicsLayerCA::dumpAdditionalProperties(TextStream& textStream, int indent, LayerTreeAsTextBehavior behavior) const
2573 {
2574     if (behavior & LayerTreeAsTextIncludeVisibleRects) {
2575         writeIndent(textStream, indent + 1);
2576         textStream << "(visible rect " << m_visibleRect.x() << ", " << m_visibleRect.y() << " " << m_visibleRect.width() << " x " << m_visibleRect.height() << ")\n";
2577     }
2578
2579     if (tiledBacking() && (behavior & LayerTreeAsTextIncludeTileCaches)) {
2580         if (behavior & LayerTreeAsTextDebug) {
2581             writeIndent(textStream, indent + 1);
2582             textStream << "(tiled backing " << tiledBacking() << ")\n";
2583         }
2584
2585         IntRect tileCoverageRect = tiledBacking()->tileCoverageRect();
2586         writeIndent(textStream, indent + 1);
2587         textStream << "(tile cache coverage " << tileCoverageRect.x() << ", " << tileCoverageRect.y() << " " << tileCoverageRect.width() << " x " << tileCoverageRect.height() << ")\n";
2588
2589         IntSize tileSize = tiledBacking()->tileSize();
2590         writeIndent(textStream, indent + 1);
2591         textStream << "(tile size " << tileSize.width() << " x " << tileSize.height() << ")\n";
2592         
2593         IntRect gridExtent = tiledBacking()->tileGridExtent();
2594         writeIndent(textStream, indent + 1);
2595         textStream << "(top left tile " << gridExtent.x() << ", " << gridExtent.y() << " tiles grid " << gridExtent.width() << " x " << gridExtent.height() << ")\n";
2596     }
2597 }
2598
2599 void GraphicsLayerCA::setDebugBorder(const Color& color, float borderWidth)
2600 {    
2601     if (color.isValid()) {
2602         m_layer->setBorderColor(color);
2603         m_layer->setBorderWidth(borderWidth);
2604     } else {
2605         m_layer->setBorderColor(Color::transparent);
2606         m_layer->setBorderWidth(0);
2607     }
2608 }
2609
2610 FloatSize GraphicsLayerCA::constrainedSize() const
2611 {
2612     FloatSize constrainedSize = m_size;
2613 #if !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED == 1060
2614     float tileColumns = ceilf(m_size.width() / kTiledLayerTileSize);
2615     float tileRows = ceilf(m_size.height() / kTiledLayerTileSize);
2616     double numTiles = tileColumns * tileRows;
2617     
2618     const unsigned cMaxTileCount = 512;
2619     while (numTiles > cMaxTileCount) {
2620         // Constrain the wider dimension.
2621         if (constrainedSize.width() >= constrainedSize.height()) {
2622             tileColumns = max(floorf(cMaxTileCount / tileRows), 1.0f);
2623             constrainedSize.setWidth(tileColumns * kTiledLayerTileSize);
2624         } else {
2625             tileRows = max(floorf(cMaxTileCount / tileColumns), 1.0f);
2626             constrainedSize.setHeight(tileRows * kTiledLayerTileSize);
2627         }
2628         numTiles = tileColumns * tileRows;
2629     }
2630 #endif
2631     return constrainedSize;
2632 }
2633
2634 bool GraphicsLayerCA::requiresTiledLayer(float pageScaleFactor) const
2635 {
2636     if (!m_drawsContent || !m_allowTiledLayer || m_isPageTileCacheLayer)
2637         return false;
2638
2639     // FIXME: catch zero-size height or width here (or earlier)?
2640     return m_size.width() * pageScaleFactor > cMaxPixelDimension || m_size.height() * pageScaleFactor > cMaxPixelDimension;
2641 }
2642
2643 void GraphicsLayerCA::swapFromOrToTiledLayer(bool useTiledLayer)
2644 {
2645     ASSERT(m_layer->layerType() != PlatformCALayer::LayerTypePageTileCacheLayer);
2646     ASSERT(useTiledLayer != m_usingTiledLayer);
2647     RefPtr<PlatformCALayer> oldLayer = m_layer;
2648     
2649     m_layer = PlatformCALayer::create(useTiledLayer ? PlatformCALayer::LayerTypeTileCacheLayer : PlatformCALayer::LayerTypeWebLayer, this);
2650     m_usingTiledLayer = useTiledLayer;
2651     
2652     m_layer->adoptSublayers(oldLayer.get());
2653
2654 #ifdef VISIBLE_TILE_WASH
2655     if (m_visibleTileWashLayer)
2656         m_layer->appendSublayer(m_visibleTileWashLayer.get());
2657 #endif
2658
2659     // Skip this step if we don't have a superlayer. This is probably a benign
2660     // case that happens while restructuring the layer tree, and also occurs with
2661     // WebKit2 page overlays, which can become tiled but are out-of-tree.
2662     if (oldLayer->superlayer())
2663         oldLayer->superlayer()->replaceSublayer(oldLayer.get(), m_layer.get());
2664
2665     m_uncommittedChanges |= ChildrenChanged
2666         | GeometryChanged
2667         | TransformChanged
2668         | ChildrenTransformChanged
2669         | MasksToBoundsChanged
2670         | ContentsOpaqueChanged
2671         | BackfaceVisibilityChanged
2672         | BackgroundColorChanged
2673         | ContentsScaleChanged
2674         | AcceleratesDrawingChanged
2675         | FiltersChanged
2676         | OpacityChanged
2677         | DebugIndicatorsChanged;
2678     
2679     if (m_usingTiledLayer)
2680         m_uncommittedChanges |= VisibleRectChanged;
2681
2682 #ifndef NDEBUG
2683     String name = String::format("%sCALayer(%p) GraphicsLayer(%p) ", (m_layer->layerType() == PlatformCALayer::LayerTypeWebTiledLayer) ? "Tiled " : "", m_layer->platformLayer(), this) + m_name;
2684     m_layer->setName(name);
2685 #endif
2686
2687     // move over animations
2688     moveOrCopyAnimations(Move, oldLayer.get(), m_layer.get());
2689     
2690     // need to tell new layer to draw itself
2691     setNeedsDisplay();
2692 }
2693
2694 GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayerCA::defaultContentsOrientation() const
2695 {
2696     return CompositingCoordinatesTopDown;
2697 }
2698
2699 void GraphicsLayerCA::setupContentsLayer(PlatformCALayer* contentsLayer)
2700 {
2701     // Turn off implicit animations on the inner layer.
2702     contentsLayer->setMasksToBounds(true);
2703
2704     if (defaultContentsOrientation() == CompositingCoordinatesBottomUp) {
2705         TransformationMatrix flipper(
2706             1.0f, 0.0f, 0.0f, 0.0f,
2707             0.0f, -1.0f, 0.0f, 0.0f,
2708             0.0f, 0.0f, 1.0f, 0.0f,
2709             0.0f, 0.0f, 0.0f, 1.0f);
2710         contentsLayer->setTransform(flipper);
2711         contentsLayer->setAnchorPoint(FloatPoint3D(0, 1, 0));
2712     } else
2713         contentsLayer->setAnchorPoint(FloatPoint3D());
2714
2715     if (isShowingDebugBorder()) {
2716         contentsLayer->setBorderColor(Color(0, 0, 128, 180));
2717         contentsLayer->setBorderWidth(1.0f);
2718     }
2719 }
2720
2721 PassRefPtr<PlatformCALayer> GraphicsLayerCA::findOrMakeClone(CloneID cloneID, PlatformCALayer *sourceLayer, LayerMap* clones, CloneLevel cloneLevel)
2722 {
2723     if (!sourceLayer)
2724         return 0;
2725
2726     RefPtr<PlatformCALayer> resultLayer;
2727
2728     // Add with a dummy value to get an iterator for the insertion position, and a boolean that tells
2729     // us whether there's an item there. This technique avoids two hash lookups.
2730     RefPtr<PlatformCALayer> dummy;
2731     LayerMap::AddResult addResult = clones->add(cloneID, dummy);
2732     if (!addResult.isNewEntry) {
2733         // Value was not added, so it exists already.
2734         resultLayer = addResult.iterator->value.get();
2735     } else {
2736         resultLayer = cloneLayer(sourceLayer, cloneLevel);
2737 #ifndef NDEBUG
2738         resultLayer->setName(String::format("Clone %d of layer %p", cloneID[0U], sourceLayer->platformLayer()));
2739 #endif
2740         addResult.iterator->value = resultLayer;
2741     }
2742
2743     return resultLayer;
2744 }   
2745
2746 void GraphicsLayerCA::ensureCloneLayers(CloneID cloneID, RefPtr<PlatformCALayer>& primaryLayer, RefPtr<PlatformCALayer>& structuralLayer, RefPtr<PlatformCALayer>& contentsLayer, CloneLevel cloneLevel)
2747 {
2748     structuralLayer = 0;
2749     contentsLayer = 0;
2750
2751     if (!m_layerClones)
2752         m_layerClones = adoptPtr(new LayerMap);
2753
2754     if (!m_structuralLayerClones && m_structuralLayer)
2755         m_structuralLayerClones = adoptPtr(new LayerMap);
2756
2757     if (!m_contentsLayerClones && m_contentsLayer)
2758         m_contentsLayerClones = adoptPtr(new LayerMap);
2759
2760     primaryLayer = findOrMakeClone(cloneID, m_layer.get(), m_layerClones.get(), cloneLevel);
2761     structuralLayer = findOrMakeClone(cloneID, m_structuralLayer.get(), m_structuralLayerClones.get(), cloneLevel);
2762     contentsLayer = findOrMakeClone(cloneID, m_contentsLayer.get(), m_contentsLayerClones.get(), cloneLevel);
2763 }
2764
2765 void GraphicsLayerCA::removeCloneLayers()
2766 {
2767     m_layerClones = nullptr;
2768     m_structuralLayerClones = nullptr;
2769     m_contentsLayerClones = nullptr;
2770 }
2771
2772 FloatPoint GraphicsLayerCA::positionForCloneRootLayer() const
2773 {
2774     // This can get called during a flush when we've just removed the m_replicaLayer.
2775     if (!m_replicaLayer)
2776         return FloatPoint();
2777
2778     FloatPoint replicaPosition = m_replicaLayer->replicatedLayerPosition();
2779     return FloatPoint(replicaPosition.x() + m_anchorPoint.x() * m_size.width(),
2780                       replicaPosition.y() + m_anchorPoint.y() * m_size.height());
2781 }
2782
2783 void GraphicsLayerCA::propagateLayerChangeToReplicas()
2784 {
2785     for (GraphicsLayer* currLayer = this; currLayer; currLayer = currLayer->parent()) {
2786         GraphicsLayerCA* currLayerCA = static_cast<GraphicsLayerCA*>(currLayer);
2787         if (!currLayerCA->hasCloneLayers())
2788             break;
2789
2790         if (currLayerCA->replicaLayer())
2791             static_cast<GraphicsLayerCA*>(currLayerCA->replicaLayer())->noteLayerPropertyChanged(ReplicatedLayerChanged);
2792     }
2793 }
2794
2795 PassRefPtr<PlatformCALayer> GraphicsLayerCA::fetchCloneLayers(GraphicsLayer* replicaRoot, ReplicaState& replicaState, CloneLevel cloneLevel)
2796 {
2797     RefPtr<PlatformCALayer> primaryLayer;
2798     RefPtr<PlatformCALayer> structuralLayer;
2799     RefPtr<PlatformCALayer> contentsLayer;
2800     ensureCloneLayers(replicaState.cloneID(), primaryLayer, structuralLayer, contentsLayer, cloneLevel);
2801
2802     if (m_maskLayer) {
2803         RefPtr<PlatformCALayer> maskClone = static_cast<GraphicsLayerCA*>(m_maskLayer)->fetchCloneLayers(replicaRoot, replicaState, IntermediateCloneLevel);
2804         primaryLayer->setMask(maskClone.get());
2805     }
2806
2807     if (m_replicatedLayer) {
2808         // We are a replica being asked for clones of our layers.
2809         RefPtr<PlatformCALayer> replicaRoot = replicatedLayerRoot(replicaState);
2810         if (!replicaRoot)
2811             return 0;
2812
2813         if (structuralLayer) {
2814             structuralLayer->insertSublayer(replicaRoot.get(), 0);
2815             return structuralLayer;
2816         }
2817         
2818         primaryLayer->insertSublayer(replicaRoot.get(), 0);
2819         return primaryLayer;
2820     }
2821
2822     const Vector<GraphicsLayer*>& childLayers = children();
2823     Vector<RefPtr<PlatformCALayer> > clonalSublayers;
2824
2825     RefPtr<PlatformCALayer> replicaLayer;
2826     
2827     if (m_replicaLayer && m_replicaLayer != replicaRoot) {
2828         // We have nested replicas. Ask the replica layer for a clone of its contents.
2829         replicaState.setBranchType(ReplicaState::ReplicaBranch);
2830         replicaLayer = static_cast<GraphicsLayerCA*>(m_replicaLayer)->fetchCloneLayers(replicaRoot, replicaState, RootCloneLevel);
2831         replicaState.setBranchType(ReplicaState::ChildBranch);
2832     }
2833     
2834     if (replicaLayer || structuralLayer || contentsLayer || childLayers.size() > 0) {
2835         if (structuralLayer) {
2836             // Replicas render behind the actual layer content.
2837             if (replicaLayer)
2838                 clonalSublayers.append(replicaLayer);
2839                 
2840             // Add the primary layer next. Even if we have negative z-order children, the primary layer always comes behind.
2841             clonalSublayers.append(primaryLayer);
2842         } else if (contentsLayer) {
2843             // FIXME: add the contents layer in the correct order with negative z-order children.
2844             // This does not cause visible rendering issues because currently contents layers are only used
2845             // for replaced elements that don't have children.
2846             clonalSublayers.append(contentsLayer);
2847         }
2848         
2849         replicaState.push(ReplicaState::ChildBranch);
2850
2851         size_t numChildren = childLayers.size();
2852         for (size_t i = 0; i < numChildren; ++i) {
2853             GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
2854
2855             RefPtr<PlatformCALayer> childLayer = curChild->fetchCloneLayers(replicaRoot, replicaState, IntermediateCloneLevel);
2856             if (childLayer)
2857                 clonalSublayers.append(childLayer);
2858         }
2859
2860         replicaState.pop();
2861
2862         for (size_t i = 0; i < clonalSublayers.size(); ++i)
2863             clonalSublayers[i]->removeFromSuperlayer();
2864     }
2865     
2866     RefPtr<PlatformCALayer> result;
2867     if (structuralLayer) {
2868         structuralLayer->setSublayers(clonalSublayers);
2869
2870         if (contentsLayer) {
2871             // If we have a transform layer, then the contents layer is parented in the 
2872             // primary layer (which is itself a child of the transform layer).
2873             primaryLayer->removeAllSublayers();
2874             primaryLayer->appendSublayer(contentsLayer.get());
2875         }
2876
2877         result = structuralLayer;
2878     } else {
2879         primaryLayer->setSublayers(clonalSublayers);
2880         result = primaryLayer;
2881     }
2882
2883     return result;
2884 }
2885
2886 PassRefPtr<PlatformCALayer> GraphicsLayerCA::cloneLayer(PlatformCALayer *layer, CloneLevel cloneLevel)
2887 {
2888     PlatformCALayer::LayerType layerType = (layer->layerType() == PlatformCALayer::LayerTypeTransformLayer) ? 
2889                                                 PlatformCALayer::LayerTypeTransformLayer : PlatformCALayer::LayerTypeLayer;
2890     RefPtr<PlatformCALayer> newLayer = PlatformCALayer::create(layerType, this);
2891     
2892     newLayer->setPosition(layer->position());
2893     newLayer->setBounds(layer->bounds());
2894     newLayer->setAnchorPoint(layer->anchorPoint());
2895     newLayer->setTransform(layer->transform());
2896     newLayer->setSublayerTransform(layer->sublayerTransform());
2897     newLayer->setContents(layer->contents());
2898     newLayer->setMasksToBounds(layer->masksToBounds());
2899     newLayer->setDoubleSided(layer->isDoubleSided());
2900     newLayer->setOpaque(layer->isOpaque());
2901     newLayer->setBackgroundColor(layer->backgroundColor());
2902     newLayer->setContentsScale(layer->contentsScale());
2903 #if ENABLE(CSS_FILTERS)
2904     newLayer->copyFiltersFrom(layer);
2905 #endif
2906
2907     if (cloneLevel == IntermediateCloneLevel) {
2908         newLayer->setOpacity(layer->opacity());
2909         moveOrCopyAnimations(Copy, layer, newLayer.get());
2910     }
2911     
2912     if (isShowingDebugBorder()) {
2913         newLayer->setBorderColor(Color(255, 122, 251));
2914         newLayer->setBorderWidth(2);
2915     }
2916     
2917     return newLayer;
2918 }
2919
2920 void GraphicsLayerCA::setOpacityInternal(float accumulatedOpacity)
2921 {
2922     LayerMap* layerCloneMap = 0;
2923     
2924     if (preserves3D()) {
2925         m_layer->setOpacity(accumulatedOpacity);
2926         layerCloneMap = m_layerClones.get();
2927     } else {
2928         primaryLayer()->setOpacity(accumulatedOpacity);
2929         layerCloneMap = primaryLayerClones();
2930     }
2931
2932     if (layerCloneMap) {
2933         LayerMap::const_iterator end = layerCloneMap->end();
2934         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
2935             if (m_replicaLayer && isReplicatedRootClone(it->key))
2936                 continue;
2937             it->value->setOpacity(m_opacity);
2938         }
2939     }
2940 }
2941
2942 void GraphicsLayerCA::updateOpacityOnLayer()
2943 {
2944     primaryLayer()->setOpacity(m_opacity);
2945
2946     if (LayerMap* layerCloneMap = primaryLayerClones()) {
2947         LayerMap::const_iterator end = layerCloneMap->end();
2948         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
2949             if (m_replicaLayer && isReplicatedRootClone(it->key))
2950                 continue;
2951
2952             it->value->setOpacity(m_opacity);
2953         }
2954         
2955     }
2956 }
2957
2958 void GraphicsLayerCA::setMaintainsPixelAlignment(bool maintainsAlignment)
2959 {
2960     if (maintainsAlignment == m_maintainsPixelAlignment)
2961         return;
2962
2963     GraphicsLayer::setMaintainsPixelAlignment(maintainsAlignment);
2964     noteChangesForScaleSensitiveProperties();
2965 }
2966
2967 void GraphicsLayerCA::deviceOrPageScaleFactorChanged()
2968 {
2969     noteChangesForScaleSensitiveProperties();
2970 }
2971
2972 void GraphicsLayerCA::noteChangesForScaleSensitiveProperties()
2973 {
2974     noteLayerPropertyChanged(GeometryChanged | ContentsScaleChanged);
2975 }
2976
2977 static inline bool isIntegral(float value)
2978 {
2979     return static_cast<int>(value) == value;
2980 }
2981
2982 void GraphicsLayerCA::computePixelAlignment(float pageScaleFactor, const FloatPoint& positionRelativeToBase,
2983     FloatPoint& position, FloatSize& size, FloatPoint3D& anchorPoint, FloatSize& alignmentOffset) const
2984 {
2985     if (!m_maintainsPixelAlignment || isIntegral(pageScaleFactor) || !m_drawsContent || m_masksToBounds) {
2986         position = m_position;
2987         size = m_size;
2988         anchorPoint = m_anchorPoint;
2989         alignmentOffset = FloatSize();
2990         return;
2991     }
2992     
2993     FloatRect baseRelativeBounds(positionRelativeToBase, m_size);
2994     FloatRect scaledBounds = baseRelativeBounds;
2995     // Scale by the page scale factor to compute the screen-relative bounds.
2996     scaledBounds.scale(pageScaleFactor);
2997     // Round to integer boundaries.
2998     FloatRect alignedBounds = enclosingIntRect(scaledBounds);
2999     
3000     // Convert back to layer coordinates.
3001     alignedBounds.scale(1 / pageScaleFactor);
3002     
3003     // Epsilon is necessary to ensure that backing store size computation in CA, which involves integer truncation,
3004     // will match our aligned bounds.
3005     const float epsilon = 1e-5f;
3006     alignedBounds.expand(epsilon, epsilon);
3007     
3008     alignmentOffset = baseRelativeBounds.location() - alignedBounds.location();
3009     position = m_position - alignmentOffset;
3010     size = alignedBounds.size();
3011
3012     // Now we have to compute a new anchor point which compensates for rounding.
3013     float anchorPointX = m_anchorPoint.x();
3014     float anchorPointY = m_anchorPoint.y();
3015     
3016     if (alignedBounds.width())
3017         anchorPointX = (baseRelativeBounds.width() * anchorPointX + alignmentOffset.width()) / alignedBounds.width();
3018     
3019     if (alignedBounds.height())
3020         anchorPointY = (baseRelativeBounds.height() * anchorPointY + alignmentOffset.height()) / alignedBounds.height();
3021      
3022     anchorPoint = FloatPoint3D(anchorPointX, anchorPointY, m_anchorPoint.z() * pageScaleFactor);
3023 }
3024
3025 void GraphicsLayerCA::noteSublayersChanged()
3026 {
3027     noteLayerPropertyChanged(ChildrenChanged);
3028     propagateLayerChangeToReplicas();
3029 }
3030
3031 void GraphicsLayerCA::noteLayerPropertyChanged(LayerChangeFlags flags)
3032 {
3033     if (!m_uncommittedChanges && m_client)
3034         m_client->notifyFlushRequired(this);
3035
3036     m_uncommittedChanges |= flags;
3037 }
3038
3039 double GraphicsLayerCA::backingStoreMemoryEstimate() const
3040 {
3041     if (!drawsContent())
3042         return 0;
3043     
3044     // contentsLayer is given to us, so we don't really know anything about its contents.
3045     return static_cast<double>(4 * size().width()) * size().height() * m_layer->contentsScale();
3046 }
3047
3048 } // namespace WebCore
3049
3050 #endif // USE(ACCELERATED_COMPOSITING)