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