Add a way to update GraphicsLayerCA visibleRects without having to do a flush
[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 void GraphicsLayerCA::recursiveComputeVisibleRect(const TransformState& state)
911 {
912     TransformState localState = state;
913     
914     // This may be called at times when layout has not been updated, so we want to avoid calling out to the client
915     // for animating transforms.
916     FloatRect visibleRect = computeVisibleRect(localState, 0);
917     if (visibleRect != m_visibleRect) {
918         m_visibleRect = visibleRect;
919         if (TiledBacking* tiledBacking = this->tiledBacking()) {
920             if (tiledBacking->tilesWouldChangeForVisibleRect(m_visibleRect))
921                 noteLayerPropertyChanged(VisibleRectChanged);
922         }
923     }
924
925     if (m_maskLayer) {
926         GraphicsLayerCA* maskLayerCA = static_cast<GraphicsLayerCA*>(m_maskLayer);
927         maskLayerCA->recursiveComputeVisibleRect(localState);
928     }
929
930     const Vector<GraphicsLayer*>& childLayers = children();
931     size_t numChildren = childLayers.size();
932     
933     for (size_t i = 0; i < numChildren; ++i) {
934         GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
935         curChild->recursiveComputeVisibleRect(localState);
936     }
937
938     if (m_replicaLayer)
939         static_cast<GraphicsLayerCA*>(m_replicaLayer)->recursiveComputeVisibleRect(localState);
940 }
941
942 void GraphicsLayerCA::recomputeVisibleRects(const FloatRect& clipRect)
943 {
944     TransformState state(TransformState::UnapplyInverseTransformDirection, FloatQuad(clipRect));
945     recursiveComputeVisibleRect(state);
946 }
947
948 TiledBacking* GraphicsLayerCA::tiledBacking() const
949 {
950     return m_layer->tiledBacking();
951 }
952
953 FloatRect GraphicsLayerCA::computeVisibleRect(TransformState& state, ComputeVisibleRectFlags flags) const
954 {
955     bool preserve3D = preserves3D() || (parent() ? parent()->preserves3D() : false);
956     TransformState::TransformAccumulation accumulation = preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform;
957
958     TransformationMatrix layerTransform;
959     FloatPoint position = m_position;
960     if (client())
961         client()->customPositionForVisibleRectComputation(this, position);
962
963     layerTransform.translate(position.x(), position.y());
964
965     TransformationMatrix currentTransform;
966     if (!(flags & RespectAnimatingTransforms) || !client() || !client()->getCurrentTransform(this, currentTransform))
967         currentTransform = m_transform;
968     
969     if (!currentTransform.isIdentity()) {
970         FloatPoint3D absoluteAnchorPoint(anchorPoint());
971         absoluteAnchorPoint.scale(size().width(), size().height(), 1);
972         layerTransform.translate3d(absoluteAnchorPoint.x(), absoluteAnchorPoint.y(), absoluteAnchorPoint.z());
973         layerTransform.multiply(currentTransform);
974         layerTransform.translate3d(-absoluteAnchorPoint.x(), -absoluteAnchorPoint.y(), -absoluteAnchorPoint.z());
975     }
976
977     if (GraphicsLayer* parentLayer = parent()) {
978         if (!parentLayer->childrenTransform().isIdentity()) {
979             FloatPoint3D parentAnchorPoint(parentLayer->anchorPoint());
980             parentAnchorPoint.scale(parentLayer->size().width(), parentLayer->size().height(), 1);
981
982             layerTransform.translateRight3d(-parentAnchorPoint.x(), -parentAnchorPoint.y(), -parentAnchorPoint.z());
983             layerTransform = parentLayer->childrenTransform() * layerTransform;
984             layerTransform.translateRight3d(parentAnchorPoint.x(), parentAnchorPoint.y(), parentAnchorPoint.z());
985         }
986     }
987
988     bool applyWasClamped;
989     state.applyTransform(layerTransform, accumulation, &applyWasClamped);
990     
991     bool mapWasClamped;
992     FloatRect clipRectForChildren = state.mappedQuad(&mapWasClamped).boundingBox();
993     FloatRect clipRectForSelf(0, 0, m_size.width(), m_size.height());
994     if (!applyWasClamped && !mapWasClamped)
995         clipRectForSelf.intersect(clipRectForChildren);
996     
997     if (masksToBounds()) {
998         ASSERT(accumulation == TransformState::FlattenTransform);
999         // Replace the quad in the TransformState with one that is clipped to this layer's bounds
1000         state.setQuad(clipRectForSelf);
1001     }
1002
1003     return clipRectForSelf;
1004 }
1005
1006 void GraphicsLayerCA::recursiveCommitChanges(const CommitState& commitState, const TransformState& state, float pageScaleFactor, const FloatPoint& positionRelativeToBase, bool affectedByPageScale)
1007 {
1008     TransformState localState = state;
1009     CommitState childCommitState = commitState;
1010     bool affectedByTransformAnimation = commitState.ancestorHasTransformAnimation;
1011     
1012     FloatRect visibleRect = computeVisibleRect(localState);
1013     FloatRect oldVisibleRect = m_visibleRect;
1014     if (visibleRect != m_visibleRect) {
1015         m_uncommittedChanges |= VisibleRectChanged;
1016         m_visibleRect = visibleRect;
1017     }
1018
1019 #ifdef VISIBLE_TILE_WASH
1020     // Use having a transform as a key to making the tile wash layer. If every layer gets a wash,
1021     // they start to obscure useful information.
1022     if ((!m_transform.isIdentity() || m_usingTiledBacking) && !m_visibleTileWashLayer) {
1023         static Color washFillColor(255, 0, 0, 50);
1024         static Color washBorderColor(255, 0, 0, 100);
1025         
1026         m_visibleTileWashLayer = PlatformCALayer::create(PlatformCALayer::LayerTypeLayer, this);
1027         String name = String::format("Visible Tile Wash Layer %p", m_visibleTileWashLayer->platformLayer());
1028         m_visibleTileWashLayer->setName(name);
1029         m_visibleTileWashLayer->setAnchorPoint(FloatPoint3D(0, 0, 0));
1030         m_visibleTileWashLayer->setBorderColor(washBorderColor);
1031         m_visibleTileWashLayer->setBorderWidth(8);
1032         m_visibleTileWashLayer->setBackgroundColor(washFillColor);
1033         noteSublayersChanged();
1034     }
1035
1036     if (m_visibleTileWashLayer)
1037         m_visibleTileWashLayer->setFrame(m_visibleRect);
1038 #endif
1039
1040     bool hadChanges = m_uncommittedChanges;
1041     
1042     if (appliesPageScale()) {
1043         pageScaleFactor = this->pageScaleFactor();
1044         affectedByPageScale = true;
1045     }
1046
1047     // Accumulate an offset from the ancestral pixel-aligned layer.
1048     FloatPoint baseRelativePosition = positionRelativeToBase;
1049     if (affectedByPageScale)
1050         baseRelativePosition += m_position;
1051     
1052     commitLayerChangesBeforeSublayers(pageScaleFactor, baseRelativePosition, oldVisibleRect);
1053
1054     if (isRunningTransformAnimation()) {
1055         childCommitState.ancestorHasTransformAnimation = true;
1056         affectedByTransformAnimation = true;
1057     }
1058
1059     if (m_maskLayer) {
1060         GraphicsLayerCA* maskLayerCA = static_cast<GraphicsLayerCA*>(m_maskLayer);
1061         maskLayerCA->commitLayerChangesBeforeSublayers(pageScaleFactor, baseRelativePosition, maskLayerCA->visibleRect());
1062     }
1063
1064     const Vector<GraphicsLayer*>& childLayers = children();
1065     size_t numChildren = childLayers.size();
1066     
1067     for (size_t i = 0; i < numChildren; ++i) {
1068         GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
1069         curChild->recursiveCommitChanges(childCommitState, localState, pageScaleFactor, baseRelativePosition, affectedByPageScale);
1070     }
1071
1072     if (m_replicaLayer)
1073         static_cast<GraphicsLayerCA*>(m_replicaLayer)->recursiveCommitChanges(childCommitState, localState, pageScaleFactor, baseRelativePosition, affectedByPageScale);
1074
1075     if (m_maskLayer)
1076         static_cast<GraphicsLayerCA*>(m_maskLayer)->commitLayerChangesAfterSublayers();
1077
1078     commitLayerChangesAfterSublayers();
1079
1080     if (affectedByTransformAnimation && client() && m_layer->layerType() == PlatformCALayer::LayerTypeTiledBackingLayer)
1081         client()->notifyFlushBeforeDisplayRefresh(this);
1082
1083     if (hadChanges && client())
1084         client()->didCommitChangesForLayer(this);
1085 }
1086
1087 bool GraphicsLayerCA::platformCALayerShowRepaintCounter(PlatformCALayer* platformLayer) const
1088 {
1089     // The repaint counters are painted into the TileController tiles (which have no corresponding platform layer),
1090     // so we don't want to overpaint the repaint counter when called with the TileController's own layer.
1091     if (m_isPageTiledBackingLayer && platformLayer)
1092         return false;
1093     
1094     return isShowingRepaintCounter();
1095 }
1096
1097 void GraphicsLayerCA::platformCALayerPaintContents(GraphicsContext& context, const IntRect& clip)
1098 {
1099     paintGraphicsLayerContents(context, clip);
1100 }
1101
1102 void GraphicsLayerCA::platformCALayerDidCreateTiles(const Vector<FloatRect>& dirtyRects)
1103 {
1104     ASSERT(m_layer->usesTiledBackingLayer());
1105
1106     for (size_t i = 0; i < dirtyRects.size(); ++i)
1107         setNeedsDisplayInRect(dirtyRects[i]);
1108
1109     // Ensure that the layout is up to date before any individual tiles are painted by telling the client
1110     // that it needs to flush its layer state, which will end up scheduling the layer flusher.
1111     client()->notifyFlushRequired(this);
1112 }
1113
1114 float GraphicsLayerCA::platformCALayerDeviceScaleFactor()
1115 {
1116     return deviceScaleFactor();
1117 }
1118
1119 void GraphicsLayerCA::commitLayerChangesBeforeSublayers(float pageScaleFactor, const FloatPoint& positionRelativeToBase, const FloatRect& oldVisibleRect)
1120 {
1121     if (!m_uncommittedChanges)
1122         return;
1123
1124     // Need to handle Preserves3DChanged first, because it affects which layers subsequent properties are applied to
1125     if (m_uncommittedChanges & (Preserves3DChanged | ReplicatedLayerChanged))
1126         updateStructuralLayer();
1127
1128     if (m_uncommittedChanges & GeometryChanged)
1129         updateGeometry(pageScaleFactor, positionRelativeToBase);
1130
1131     if (m_uncommittedChanges & DrawsContentChanged)
1132         updateLayerDrawsContent(pageScaleFactor);
1133
1134     if (m_uncommittedChanges & NameChanged)
1135         updateLayerNames();
1136
1137     if (m_uncommittedChanges & ContentsImageChanged) // Needs to happen before ChildrenChanged
1138         updateContentsImage();
1139         
1140     if (m_uncommittedChanges & ContentsMediaLayerChanged) // Needs to happen before ChildrenChanged
1141         updateContentsMediaLayer();
1142     
1143     if (m_uncommittedChanges & ContentsCanvasLayerChanged) // Needs to happen before ChildrenChanged
1144         updateContentsCanvasLayer();
1145
1146     if (m_uncommittedChanges & ContentsColorLayerChanged) // Needs to happen before ChildrenChanged
1147         updateContentsColorLayer();
1148     
1149     if (m_uncommittedChanges & BackgroundColorChanged)
1150         updateBackgroundColor();
1151
1152     if (m_uncommittedChanges & TransformChanged)
1153         updateTransform();
1154
1155     if (m_uncommittedChanges & ChildrenTransformChanged)
1156         updateChildrenTransform();
1157     
1158     if (m_uncommittedChanges & MasksToBoundsChanged)
1159         updateMasksToBounds();
1160     
1161     if (m_uncommittedChanges & ContentsVisibilityChanged)
1162         updateContentsVisibility();
1163
1164     if (m_uncommittedChanges & ContentsOpaqueChanged)
1165         updateContentsOpaque();
1166
1167     if (m_uncommittedChanges & BackfaceVisibilityChanged)
1168         updateBackfaceVisibility();
1169
1170     if (m_uncommittedChanges & OpacityChanged)
1171         updateOpacityOnLayer();
1172     
1173 #if ENABLE(CSS_FILTERS)
1174     if (m_uncommittedChanges & FiltersChanged)
1175         updateFilters();
1176 #endif
1177     
1178     if (m_uncommittedChanges & AnimationChanged)
1179         updateAnimations();
1180
1181     // Updating the contents scale can cause parts of the layer to be invalidated,
1182     // so make sure to update the contents scale before updating the dirty rects.
1183     if (m_uncommittedChanges & ContentsScaleChanged)
1184         updateContentsScale(pageScaleFactor);
1185
1186     if (m_uncommittedChanges & VisibleRectChanged)
1187         updateVisibleRect(oldVisibleRect);
1188
1189     if (m_uncommittedChanges & DirtyRectsChanged)
1190         repaintLayerDirtyRects();
1191     
1192     if (m_uncommittedChanges & ContentsRectChanged)
1193         updateContentsRect();
1194
1195     if (m_uncommittedChanges & MaskLayerChanged)
1196         updateMaskLayer();
1197
1198     if (m_uncommittedChanges & ContentsNeedsDisplay)
1199         updateContentsNeedsDisplay();
1200     
1201     if (m_uncommittedChanges & AcceleratesDrawingChanged)
1202         updateAcceleratesDrawing();
1203
1204     if (m_uncommittedChanges & DebugIndicatorsChanged)
1205         updateDebugBorder();
1206
1207     if (m_uncommittedChanges & ChildrenChanged) {
1208         updateSublayerList();
1209         // Sublayers may set this flag again, so clear it to avoid always updating sublayers in commitLayerChangesAfterSublayers().
1210         m_uncommittedChanges &= ~ChildrenChanged;
1211     }
1212 }
1213
1214 void GraphicsLayerCA::commitLayerChangesAfterSublayers()
1215 {
1216     if (!m_uncommittedChanges)
1217         return;
1218
1219     if (m_uncommittedChanges & ChildrenChanged)
1220         updateSublayerList();
1221
1222     if (m_uncommittedChanges & ReplicatedLayerChanged)
1223         updateReplicatedLayers();
1224
1225     m_uncommittedChanges = NoChange;
1226 }
1227
1228 void GraphicsLayerCA::updateLayerNames()
1229 {
1230     switch (structuralLayerPurpose()) {
1231     case StructuralLayerForPreserves3D:
1232         m_structuralLayer->setName("Transform layer " + name());
1233         break;
1234     case StructuralLayerForReplicaFlattening:
1235         m_structuralLayer->setName("Replica flattening layer " + name());
1236         break;
1237     case NoStructuralLayer:
1238         break;
1239     }
1240     m_layer->setName(name());
1241 }
1242
1243 void GraphicsLayerCA::updateSublayerList()
1244 {
1245     const PlatformCALayerList* customSublayers = m_layer->customSublayers();
1246
1247     PlatformCALayerList structuralLayerChildren;
1248     PlatformCALayerList primaryLayerChildren;
1249
1250     PlatformCALayerList& childListForSublayers = m_structuralLayer ? structuralLayerChildren : primaryLayerChildren;
1251
1252     if (customSublayers)
1253         primaryLayerChildren.append(*customSublayers);
1254
1255     if (m_structuralLayer) {
1256         if (m_replicaLayer)
1257             structuralLayerChildren.append(static_cast<GraphicsLayerCA*>(m_replicaLayer)->primaryLayer());
1258     
1259         structuralLayerChildren.append(m_layer);
1260     }
1261
1262     if (m_contentsLayer && m_contentsVisible) {
1263         // FIXME: add the contents layer in the correct order with negative z-order children.
1264         // This does not cause visible rendering issues because currently contents layers are only used
1265         // for replaced elements that don't have children.
1266         primaryLayerChildren.append(m_contentsLayer);
1267     }
1268     
1269     const Vector<GraphicsLayer*>& childLayers = children();
1270     size_t numChildren = childLayers.size();
1271     for (size_t i = 0; i < numChildren; ++i) {
1272         GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
1273         PlatformCALayer* childLayer = curChild->layerForSuperlayer();
1274         childListForSublayers.append(childLayer);
1275     }
1276
1277 #ifdef VISIBLE_TILE_WASH
1278     if (m_visibleTileWashLayer)
1279         childListForSublayers.append(m_visibleTileWashLayer);
1280 #endif
1281
1282     if (m_structuralLayer)
1283         m_structuralLayer->setSublayers(structuralLayerChildren);
1284     
1285     m_layer->setSublayers(primaryLayerChildren);
1286 }
1287
1288 void GraphicsLayerCA::updateGeometry(float pageScaleFactor, const FloatPoint& positionRelativeToBase)
1289 {
1290     FloatPoint scaledPosition;
1291     FloatPoint3D scaledAnchorPoint;
1292     FloatSize scaledSize;
1293     FloatSize pixelAlignmentOffset;
1294     computePixelAlignment(pageScaleFactor, positionRelativeToBase, scaledPosition, scaledSize, scaledAnchorPoint, pixelAlignmentOffset);
1295
1296     bool needTiledLayer = requiresTiledLayer(pageScaleFactor);
1297     if (needTiledLayer != m_usingTiledBacking)
1298         swapFromOrToTiledLayer(needTiledLayer);
1299
1300     FloatSize usedSize = m_usingTiledBacking ? constrainedSize() : scaledSize;
1301     FloatRect adjustedBounds(m_boundsOrigin - pixelAlignmentOffset, usedSize);
1302
1303     // Update position.
1304     // Position is offset on the layer by the layer anchor point.
1305     FloatPoint adjustedPosition(scaledPosition.x() + scaledAnchorPoint.x() * usedSize.width(), scaledPosition.y() + scaledAnchorPoint.y() * usedSize.height());
1306
1307     if (m_structuralLayer) {
1308         FloatPoint layerPosition(m_position.x() + m_anchorPoint.x() * m_size.width(), m_position.y() + m_anchorPoint.y() * m_size.height());
1309         FloatRect layerBounds(m_boundsOrigin, m_size);
1310         
1311         m_structuralLayer->setPosition(layerPosition);
1312         m_structuralLayer->setBounds(layerBounds);
1313         m_structuralLayer->setAnchorPoint(m_anchorPoint);
1314
1315         if (LayerMap* layerCloneMap = m_structuralLayerClones.get()) {
1316             LayerMap::const_iterator end = layerCloneMap->end();
1317             for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1318                 PlatformCALayer* clone = it->value.get();
1319                 FloatPoint clonePosition = layerPosition;
1320
1321                 if (m_replicaLayer && isReplicatedRootClone(it->key)) {
1322                     // Maintain the special-case position for the root of a clone subtree,
1323                     // which we set up in replicatedLayerRoot().
1324                     clonePosition = positionForCloneRootLayer();
1325                 }
1326
1327                 clone->setPosition(clonePosition);
1328                 clone->setBounds(layerBounds);
1329                 clone->setAnchorPoint(m_anchorPoint);
1330             }
1331         }
1332
1333         // If we have a structural layer, we just use 0.5, 0.5 for the anchor point of the main layer.
1334         scaledAnchorPoint = FloatPoint(0.5f, 0.5f);
1335         adjustedPosition = FloatPoint(scaledAnchorPoint.x() * usedSize.width() - pixelAlignmentOffset.width(), scaledAnchorPoint.y() * usedSize.height() - pixelAlignmentOffset.height());
1336     }
1337     
1338     m_layer->setPosition(adjustedPosition);
1339     m_layer->setBounds(adjustedBounds);
1340     m_layer->setAnchorPoint(scaledAnchorPoint);
1341
1342     if (LayerMap* layerCloneMap = m_layerClones.get()) {
1343         LayerMap::const_iterator end = layerCloneMap->end();
1344         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1345             PlatformCALayer* clone = it->value.get();
1346             FloatPoint clonePosition = adjustedPosition;
1347
1348             if (!m_structuralLayer && m_replicaLayer && isReplicatedRootClone(it->key)) {
1349                 // Maintain the special-case position for the root of a clone subtree,
1350                 // which we set up in replicatedLayerRoot().
1351                 clonePosition = positionForCloneRootLayer();
1352             }
1353
1354             clone->setPosition(clonePosition);
1355             clone->setBounds(adjustedBounds);
1356             clone->setAnchorPoint(scaledAnchorPoint);
1357         }
1358     }
1359 }
1360
1361 void GraphicsLayerCA::updateTransform()
1362 {
1363     primaryLayer()->setTransform(m_transform);
1364
1365     if (LayerMap* layerCloneMap = primaryLayerClones()) {
1366         LayerMap::const_iterator end = layerCloneMap->end();
1367         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1368             PlatformCALayer* currLayer = it->value.get();
1369             if (m_replicaLayer && isReplicatedRootClone(it->key)) {
1370                 // Maintain the special-case transform for the root of a clone subtree,
1371                 // which we set up in replicatedLayerRoot().
1372                 currLayer->setTransform(TransformationMatrix());
1373             } else
1374                 currLayer->setTransform(m_transform);
1375         }
1376     }
1377 }
1378
1379 void GraphicsLayerCA::updateChildrenTransform()
1380 {
1381     primaryLayer()->setSublayerTransform(m_childrenTransform);
1382
1383     if (LayerMap* layerCloneMap = primaryLayerClones()) {
1384         LayerMap::const_iterator end = layerCloneMap->end();
1385         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
1386             it->value->setSublayerTransform(m_childrenTransform);
1387     }
1388 }
1389
1390 void GraphicsLayerCA::updateMasksToBounds()
1391 {
1392     m_layer->setMasksToBounds(m_masksToBounds);
1393
1394     if (LayerMap* layerCloneMap = m_layerClones.get()) {
1395         LayerMap::const_iterator end = layerCloneMap->end();
1396         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
1397             it->value->setMasksToBounds(m_masksToBounds);
1398     }
1399 }
1400
1401 void GraphicsLayerCA::updateContentsVisibility()
1402 {
1403     // Note that m_contentsVisible also affects whether m_contentsLayer is parented.
1404     if (m_contentsVisible) {
1405         if (m_drawsContent)
1406             m_layer->setNeedsDisplay();
1407     } else {
1408         m_layer->setContents(0);
1409
1410         if (LayerMap* layerCloneMap = m_layerClones.get()) {
1411             LayerMap::const_iterator end = layerCloneMap->end();
1412             for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
1413                 it->value->setContents(0);
1414         }
1415     }
1416 }
1417
1418 void GraphicsLayerCA::updateContentsOpaque()
1419 {
1420     m_layer->setOpaque(m_contentsOpaque);
1421
1422     if (LayerMap* layerCloneMap = m_layerClones.get()) {
1423         LayerMap::const_iterator end = layerCloneMap->end();
1424         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
1425             it->value->setOpaque(m_contentsOpaque);
1426     }
1427 }
1428
1429 void GraphicsLayerCA::updateBackfaceVisibility()
1430 {
1431     if (m_structuralLayer && structuralLayerPurpose() == StructuralLayerForReplicaFlattening) {
1432         m_structuralLayer->setDoubleSided(m_backfaceVisibility);
1433
1434         if (LayerMap* layerCloneMap = m_structuralLayerClones.get()) {
1435             LayerMap::const_iterator end = layerCloneMap->end();
1436             for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
1437                 it->value->setDoubleSided(m_backfaceVisibility);
1438         }
1439     }
1440
1441     m_layer->setDoubleSided(m_backfaceVisibility);
1442
1443     if (LayerMap* layerCloneMap = m_layerClones.get()) {
1444         LayerMap::const_iterator end = layerCloneMap->end();
1445         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
1446             it->value->setDoubleSided(m_backfaceVisibility);
1447     }
1448 }
1449
1450 #if ENABLE(CSS_FILTERS)
1451 void GraphicsLayerCA::updateFilters()
1452 {
1453     m_layer->setFilters(m_filters);
1454
1455     if (LayerMap* layerCloneMap = m_layerClones.get()) {
1456         LayerMap::const_iterator end = layerCloneMap->end();
1457         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1458             if (m_replicaLayer && isReplicatedRootClone(it->key))
1459                 continue;
1460
1461             it->value->setFilters(m_filters);
1462         }
1463     }
1464 }
1465 #endif
1466
1467 void GraphicsLayerCA::updateStructuralLayer()
1468 {
1469     ensureStructuralLayer(structuralLayerPurpose());
1470 }
1471
1472 void GraphicsLayerCA::ensureStructuralLayer(StructuralLayerPurpose purpose)
1473 {
1474     const LayerChangeFlags structuralLayerChangeFlags = NameChanged
1475         | GeometryChanged
1476         | TransformChanged
1477         | ChildrenTransformChanged
1478         | ChildrenChanged
1479         | BackfaceVisibilityChanged
1480 #if ENABLE(CSS_FILTERS)
1481         | FiltersChanged
1482 #endif
1483         | OpacityChanged;
1484
1485     if (purpose == NoStructuralLayer) {
1486         if (m_structuralLayer) {
1487             // Replace the transformLayer in the parent with this layer.
1488             m_layer->removeFromSuperlayer();
1489  
1490             // If m_layer doesn't have a parent, it means it's the root layer and
1491             // is likely hosted by something that is not expecting to be changed
1492             ASSERT(m_structuralLayer->superlayer());
1493             m_structuralLayer->superlayer()->replaceSublayer(m_structuralLayer.get(), m_layer.get());
1494
1495             moveOrCopyAnimations(Move, m_structuralLayer.get(), m_layer.get());
1496
1497             // Release the structural layer.
1498             m_structuralLayer = 0;
1499
1500             m_uncommittedChanges |= structuralLayerChangeFlags;
1501         }
1502         return;
1503     }
1504     
1505     bool structuralLayerChanged = false;
1506     
1507     if (purpose == StructuralLayerForPreserves3D) {
1508         if (m_structuralLayer && m_structuralLayer->layerType() != PlatformCALayer::LayerTypeTransformLayer)
1509             m_structuralLayer = 0;
1510         
1511         if (!m_structuralLayer) {
1512             m_structuralLayer = PlatformCALayer::create(PlatformCALayer::LayerTypeTransformLayer, this);
1513             structuralLayerChanged = true;
1514         }
1515     } else {
1516         if (m_structuralLayer && m_structuralLayer->layerType() != PlatformCALayer::LayerTypeLayer)
1517             m_structuralLayer = 0;
1518
1519         if (!m_structuralLayer) {
1520             m_structuralLayer = PlatformCALayer::create(PlatformCALayer::LayerTypeLayer, this);
1521             structuralLayerChanged = true;
1522         }
1523     }
1524     
1525     if (!structuralLayerChanged)
1526         return;
1527     
1528     m_uncommittedChanges |= structuralLayerChangeFlags;
1529
1530     // We've changed the layer that our parent added to its sublayer list, so tell it to update
1531     // sublayers again in its commitLayerChangesAfterSublayers().
1532     static_cast<GraphicsLayerCA*>(parent())->noteSublayersChanged();
1533
1534     // Set properties of m_layer to their default values, since these are expressed on on the structural layer.
1535     FloatPoint point(m_size.width() / 2.0f, m_size.height() / 2.0f);
1536     FloatPoint3D anchorPoint(0.5f, 0.5f, 0);
1537     m_layer->setPosition(point);
1538     m_layer->setAnchorPoint(anchorPoint);
1539     m_layer->setTransform(TransformationMatrix());
1540     m_layer->setOpacity(1);
1541     if (m_layerClones) {
1542         LayerMap::const_iterator end = m_layerClones->end();
1543         for (LayerMap::const_iterator it = m_layerClones->begin(); it != end; ++it) {
1544             PlatformCALayer* currLayer = it->value.get();
1545             currLayer->setPosition(point);
1546             currLayer->setAnchorPoint(anchorPoint);
1547             currLayer->setTransform(TransformationMatrix());
1548             currLayer->setOpacity(1);
1549         }
1550     }
1551
1552     moveOrCopyAnimations(Move, m_layer.get(), m_structuralLayer.get());
1553 }
1554
1555 GraphicsLayerCA::StructuralLayerPurpose GraphicsLayerCA::structuralLayerPurpose() const
1556 {
1557     if (preserves3D())
1558         return StructuralLayerForPreserves3D;
1559     
1560     if (isReplicated())
1561         return StructuralLayerForReplicaFlattening;
1562     
1563     return NoStructuralLayer;
1564 }
1565
1566 void GraphicsLayerCA::updateLayerDrawsContent(float pageScaleFactor)
1567 {
1568     bool needTiledLayer = requiresTiledLayer(pageScaleFactor);
1569     if (needTiledLayer != m_usingTiledBacking)
1570         swapFromOrToTiledLayer(needTiledLayer);
1571
1572     if (m_drawsContent)
1573         m_layer->setNeedsDisplay();
1574     else {
1575         m_layer->setContents(0);
1576         if (m_layerClones) {
1577             LayerMap::const_iterator end = m_layerClones->end();
1578             for (LayerMap::const_iterator it = m_layerClones->begin(); it != end; ++it)
1579                 it->value->setContents(0);
1580         }
1581     }
1582 }
1583
1584 void GraphicsLayerCA::updateAcceleratesDrawing()
1585 {
1586     m_layer->setAcceleratesDrawing(m_acceleratesDrawing);
1587 }
1588
1589 void GraphicsLayerCA::updateDebugBorder()
1590 {
1591     if (isShowingDebugBorder())
1592         updateDebugIndicators();
1593     else
1594         m_layer->setBorderWidth(0);
1595 }
1596
1597 FloatRect GraphicsLayerCA::adjustTiledLayerVisibleRect(TiledBacking* tiledBacking, const FloatRect& oldVisibleRect, const FloatSize& oldSize) const
1598 {
1599     // If the old visible rect is empty, we have no information about how the visible area is changing
1600     // (maybe the layer was just created), so don't attempt to expand. Also don't attempt to expand
1601     // if the size changed.
1602     if (oldVisibleRect.isEmpty() || m_size != oldSize)
1603         return m_visibleRect;
1604
1605     const float paddingMultiplier = 2;
1606
1607     float leftEdgeDelta = paddingMultiplier * (m_visibleRect.x() - oldVisibleRect.x());
1608     float rightEdgeDelta = paddingMultiplier * (m_visibleRect.maxX() - oldVisibleRect.maxX());
1609
1610     float topEdgeDelta = paddingMultiplier * (m_visibleRect.y() - oldVisibleRect.y());
1611     float bottomEdgeDelta = paddingMultiplier * (m_visibleRect.maxY() - oldVisibleRect.maxY());
1612     
1613     FloatRect existingTileBackingRect = tiledBacking->visibleRect();
1614     FloatRect expandedRect = m_visibleRect;
1615
1616     // More exposed on left side.
1617     if (leftEdgeDelta < 0) {
1618         float newLeft = expandedRect.x() + leftEdgeDelta;
1619         // Pad to the left, but don't reduce padding that's already in the backing store (since we're still exposing to the left).
1620         if (newLeft < existingTileBackingRect.x())
1621             expandedRect.shiftXEdgeTo(newLeft);
1622         else
1623             expandedRect.shiftXEdgeTo(existingTileBackingRect.x());
1624     }
1625
1626     // More exposed on right.
1627     if (rightEdgeDelta > 0) {
1628         float newRight = expandedRect.maxX() + rightEdgeDelta;
1629         // Pad to the right, but don't reduce padding that's already in the backing store (since we're still exposing to the right).
1630         if (newRight > existingTileBackingRect.maxX())
1631             expandedRect.setWidth(newRight - expandedRect.x());
1632         else
1633             expandedRect.setWidth(existingTileBackingRect.maxX() - expandedRect.x());
1634     }
1635
1636     // More exposed at top.
1637     if (topEdgeDelta < 0) {
1638         float newTop = expandedRect.y() + topEdgeDelta;
1639         if (newTop < existingTileBackingRect.y())
1640             expandedRect.shiftYEdgeTo(newTop);
1641         else
1642             expandedRect.shiftYEdgeTo(existingTileBackingRect.y());
1643     }
1644
1645     // More exposed on bottom.
1646     if (bottomEdgeDelta > 0) {
1647         float newBottom = expandedRect.maxY() + bottomEdgeDelta;
1648         if (newBottom > existingTileBackingRect.maxY())
1649             expandedRect.setHeight(newBottom - expandedRect.y());
1650         else
1651             expandedRect.setHeight(existingTileBackingRect.maxY() - expandedRect.y());
1652     }
1653     
1654     return expandedRect;
1655 }
1656
1657 void GraphicsLayerCA::updateVisibleRect(const FloatRect& oldVisibleRect)
1658 {
1659     if (!m_layer->usesTiledBackingLayer())
1660         return;
1661
1662     FloatRect tileArea = m_visibleRect;
1663     if (m_layer->layerType() == PlatformCALayer::LayerTypeTiledBackingLayer)
1664         tileArea = adjustTiledLayerVisibleRect(tiledBacking(), oldVisibleRect, m_sizeAtLastVisibleRectUpdate);
1665
1666     tiledBacking()->setVisibleRect(tileArea);
1667
1668     m_sizeAtLastVisibleRectUpdate = m_size;
1669 }
1670
1671 void GraphicsLayerCA::updateBackgroundColor()
1672 {
1673     m_layer->setBackgroundColor(m_backgroundColor);
1674 }
1675
1676 void GraphicsLayerCA::updateContentsImage()
1677 {
1678     if (m_pendingContentsImage) {
1679         if (!m_contentsLayer.get()) {
1680             m_contentsLayer = PlatformCALayer::create(PlatformCALayer::LayerTypeLayer, this);
1681 #ifndef NDEBUG
1682             m_contentsLayer->setName("Image Layer");
1683 #endif
1684             setupContentsLayer(m_contentsLayer.get());
1685             // m_contentsLayer will be parented by updateSublayerList
1686         }
1687
1688         // FIXME: maybe only do trilinear if the image is being scaled down,
1689         // but then what if the layer size changes?
1690         m_contentsLayer->setMinificationFilter(PlatformCALayer::Trilinear);
1691         m_contentsLayer->setContents(m_pendingContentsImage.get());
1692         m_pendingContentsImage = 0;
1693
1694         if (m_contentsLayerClones) {
1695             LayerMap::const_iterator end = m_contentsLayerClones->end();
1696             for (LayerMap::const_iterator it = m_contentsLayerClones->begin(); it != end; ++it)
1697                 it->value->setContents(m_contentsLayer->contents());
1698         }
1699         
1700         updateContentsRect();
1701     } else {
1702         // No image.
1703         // m_contentsLayer will be removed via updateSublayerList.
1704         m_contentsLayer = 0;
1705     }
1706 }
1707
1708 void GraphicsLayerCA::updateContentsMediaLayer()
1709 {
1710     // Video layer was set as m_contentsLayer, and will get parented in updateSublayerList().
1711     if (m_contentsLayer) {
1712         setupContentsLayer(m_contentsLayer.get());
1713         updateContentsRect();
1714     }
1715 }
1716
1717 void GraphicsLayerCA::updateContentsCanvasLayer()
1718 {
1719     // CanvasLayer was set as m_contentsLayer, and will get parented in updateSublayerList().
1720     if (m_contentsLayer) {
1721         setupContentsLayer(m_contentsLayer.get());
1722         m_contentsLayer->setNeedsDisplay();
1723         updateContentsRect();
1724     }
1725 }
1726
1727 void GraphicsLayerCA::updateContentsColorLayer()
1728 {
1729     // Color layer was set as m_contentsLayer, and will get parented in updateSublayerList().
1730     if (m_contentsLayer) {
1731         setupContentsLayer(m_contentsLayer.get());
1732         updateContentsRect();
1733         ASSERT(m_contentsSolidColor.isValid()); // An invalid color should have removed the contents layer.
1734         m_contentsLayer->setBackgroundColor(m_contentsSolidColor);
1735
1736         if (m_contentsLayerClones) {
1737             LayerMap::const_iterator end = m_contentsLayerClones->end();
1738             for (LayerMap::const_iterator it = m_contentsLayerClones->begin(); it != end; ++it)
1739                 it->value->setBackgroundColor(m_contentsSolidColor);
1740         }
1741     }
1742 }
1743
1744 void GraphicsLayerCA::updateContentsRect()
1745 {
1746     if (!m_contentsLayer)
1747         return;
1748
1749     FloatPoint point(m_contentsRect.x(), m_contentsRect.y());
1750     FloatRect rect(0, 0, m_contentsRect.width(), m_contentsRect.height());
1751
1752     m_contentsLayer->setPosition(point);
1753     m_contentsLayer->setBounds(rect);
1754
1755     if (m_contentsLayerClones) {
1756         LayerMap::const_iterator end = m_contentsLayerClones->end();
1757         for (LayerMap::const_iterator it = m_contentsLayerClones->begin(); it != end; ++it) {
1758             it->value->setPosition(point);
1759             it->value->setBounds(rect);
1760         }
1761     }
1762 }
1763
1764 void GraphicsLayerCA::updateMaskLayer()
1765 {
1766     PlatformCALayer* maskCALayer = m_maskLayer ? static_cast<GraphicsLayerCA*>(m_maskLayer)->primaryLayer() : 0;
1767     m_layer->setMask(maskCALayer);
1768
1769     LayerMap* maskLayerCloneMap = m_maskLayer ? static_cast<GraphicsLayerCA*>(m_maskLayer)->primaryLayerClones() : 0;
1770     
1771     if (LayerMap* layerCloneMap = m_layerClones.get()) {
1772         LayerMap::const_iterator end = layerCloneMap->end();
1773         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {            
1774             PlatformCALayer* maskClone = maskLayerCloneMap ? maskLayerCloneMap->get(it->key).get() : 0;
1775             it->value->setMask(maskClone);
1776         }
1777     }
1778 }
1779
1780 void GraphicsLayerCA::updateReplicatedLayers()
1781 {
1782     // Clone the descendants of the replicated layer, and parent under us.
1783     ReplicaState replicaState(ReplicaState::ReplicaBranch);
1784
1785     RefPtr<PlatformCALayer>replicaRoot = replicatedLayerRoot(replicaState);
1786     if (!replicaRoot)
1787         return;
1788
1789     if (m_structuralLayer)
1790         m_structuralLayer->insertSublayer(replicaRoot.get(), 0);
1791     else
1792         m_layer->insertSublayer(replicaRoot.get(), 0);
1793 }
1794
1795 // For now, this assumes that layers only ever have one replica, so replicaIndices contains only 0 and 1.
1796 GraphicsLayerCA::CloneID GraphicsLayerCA::ReplicaState::cloneID() const
1797 {
1798     size_t depth = m_replicaBranches.size();
1799
1800     const size_t bitsPerUChar = sizeof(UChar) * 8;
1801     size_t vectorSize = (depth + bitsPerUChar - 1) / bitsPerUChar;
1802     
1803     Vector<UChar> result(vectorSize);
1804     result.fill(0);
1805
1806     // Create a string from the bit sequence which we can use to identify the clone.
1807     // Note that the string may contain embedded nulls, but that's OK.
1808     for (size_t i = 0; i < depth; ++i) {
1809         UChar& currChar = result[i / bitsPerUChar];
1810         currChar = (currChar << 1) | m_replicaBranches[i];
1811     }
1812     
1813     return String::adopt(result);
1814 }
1815
1816 PassRefPtr<PlatformCALayer> GraphicsLayerCA::replicatedLayerRoot(ReplicaState& replicaState)
1817 {
1818     // Limit replica nesting, to avoid 2^N explosion of replica layers.
1819     if (!m_replicatedLayer || replicaState.replicaDepth() == ReplicaState::maxReplicaDepth)
1820         return 0;
1821
1822     GraphicsLayerCA* replicatedLayer = static_cast<GraphicsLayerCA*>(m_replicatedLayer);
1823     
1824     RefPtr<PlatformCALayer> clonedLayerRoot = replicatedLayer->fetchCloneLayers(this, replicaState, RootCloneLevel);
1825     FloatPoint cloneRootPosition = replicatedLayer->positionForCloneRootLayer();
1826
1827     // Replica root has no offset or transform
1828     clonedLayerRoot->setPosition(cloneRootPosition);
1829     clonedLayerRoot->setTransform(TransformationMatrix());
1830
1831     return clonedLayerRoot;
1832 }
1833
1834 void GraphicsLayerCA::updateAnimations()
1835 {
1836     if (m_animationsToProcess.size()) {
1837         AnimationsToProcessMap::const_iterator end = m_animationsToProcess.end();
1838         for (AnimationsToProcessMap::const_iterator it = m_animationsToProcess.begin(); it != end; ++it) {
1839             const String& currAnimationName = it->key;
1840             AnimationsMap::iterator animationIt = m_runningAnimations.find(currAnimationName);
1841             if (animationIt == m_runningAnimations.end())
1842                 continue;
1843
1844             const AnimationProcessingAction& processingInfo = it->value;
1845             const Vector<LayerPropertyAnimation>& animations = animationIt->value;
1846             for (size_t i = 0; i < animations.size(); ++i) {
1847                 const LayerPropertyAnimation& currAnimation = animations[i];
1848                 switch (processingInfo.action) {
1849                 case Remove:
1850                     removeCAAnimationFromLayer(currAnimation.m_property, currAnimationName, currAnimation.m_index, currAnimation.m_subIndex);
1851                     break;
1852                 case Pause:
1853                     pauseCAAnimationOnLayer(currAnimation.m_property, currAnimationName, currAnimation.m_index, currAnimation.m_subIndex, processingInfo.timeOffset);
1854                     break;
1855                 }
1856             }
1857
1858             if (processingInfo.action == Remove)
1859                 m_runningAnimations.remove(currAnimationName);
1860         }
1861     
1862         m_animationsToProcess.clear();
1863     }
1864     
1865     size_t numAnimations;
1866     if ((numAnimations = m_uncomittedAnimations.size())) {
1867         for (size_t i = 0; i < numAnimations; ++i) {
1868             const LayerPropertyAnimation& pendingAnimation = m_uncomittedAnimations[i];
1869             setAnimationOnLayer(pendingAnimation.m_animation.get(), pendingAnimation.m_property, pendingAnimation.m_name, pendingAnimation.m_index, pendingAnimation.m_subIndex, pendingAnimation.m_timeOffset);
1870             
1871             AnimationsMap::iterator it = m_runningAnimations.find(pendingAnimation.m_name);
1872             if (it == m_runningAnimations.end()) {
1873                 Vector<LayerPropertyAnimation> animations;
1874                 animations.append(pendingAnimation);
1875                 m_runningAnimations.add(pendingAnimation.m_name, animations);
1876             } else {
1877                 Vector<LayerPropertyAnimation>& animations = it->value;
1878                 animations.append(pendingAnimation);
1879             }
1880         }
1881         
1882         m_uncomittedAnimations.clear();
1883     }
1884 }
1885
1886 bool GraphicsLayerCA::isRunningTransformAnimation() const
1887 {
1888     AnimationsMap::const_iterator end = m_runningAnimations.end();
1889     for (AnimationsMap::const_iterator it = m_runningAnimations.begin(); it != end; ++it) {
1890         const Vector<LayerPropertyAnimation>& propertyAnimations = it->value;
1891         size_t numAnimations = propertyAnimations.size();
1892         for (size_t i = 0; i < numAnimations; ++i) {
1893             const LayerPropertyAnimation& currAnimation = propertyAnimations[i];
1894             if (currAnimation.m_property == AnimatedPropertyWebkitTransform)
1895                 return true;
1896         }
1897     }
1898     return false;
1899 }
1900
1901 void GraphicsLayerCA::setAnimationOnLayer(PlatformCAAnimation* caAnim, AnimatedPropertyID property, const String& animationName, int index, int subIndex, double timeOffset)
1902 {
1903     PlatformCALayer* layer = animatedLayer(property);
1904     
1905     if (timeOffset)
1906         caAnim->setBeginTime(CACurrentMediaTime() - timeOffset);
1907
1908     String animationID = animationIdentifier(animationName, property, index, subIndex);
1909
1910     layer->removeAnimationForKey(animationID);
1911     layer->addAnimationForKey(animationID, caAnim);
1912
1913     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
1914         LayerMap::const_iterator end = layerCloneMap->end();
1915         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1916             // Skip immediate replicas, since they move with the original.
1917             if (m_replicaLayer && isReplicatedRootClone(it->key))
1918                 continue;
1919
1920             it->value->removeAnimationForKey(animationID);
1921             it->value->addAnimationForKey(animationID, caAnim);
1922         }
1923     }
1924 }
1925
1926 // Workaround for <rdar://problem/7311367>
1927 static void bug7311367Workaround(PlatformCALayer* transformLayer, const TransformationMatrix& transform)
1928 {
1929     if (!transformLayer)
1930         return;
1931
1932     TransformationMatrix caTransform = transform;
1933     caTransform.setM41(caTransform.m41() + 1);
1934     transformLayer->setTransform(caTransform);
1935
1936     caTransform.setM41(caTransform.m41() - 1);
1937     transformLayer->setTransform(caTransform);
1938 }
1939
1940 bool GraphicsLayerCA::removeCAAnimationFromLayer(AnimatedPropertyID property, const String& animationName, int index, int subIndex)
1941 {
1942     PlatformCALayer* layer = animatedLayer(property);
1943
1944     String animationID = animationIdentifier(animationName, property, index, subIndex);
1945
1946     if (!layer->animationForKey(animationID))
1947         return false;
1948     
1949     layer->removeAnimationForKey(animationID);
1950     bug7311367Workaround(m_structuralLayer.get(), m_transform);
1951
1952     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
1953         LayerMap::const_iterator end = layerCloneMap->end();
1954         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1955             // Skip immediate replicas, since they move with the original.
1956             if (m_replicaLayer && isReplicatedRootClone(it->key))
1957                 continue;
1958
1959             it->value->removeAnimationForKey(animationID);
1960         }
1961     }
1962     return true;
1963 }
1964
1965 void GraphicsLayerCA::pauseCAAnimationOnLayer(AnimatedPropertyID property, const String& animationName, int index, int subIndex, double timeOffset)
1966 {
1967     PlatformCALayer* layer = animatedLayer(property);
1968
1969     String animationID = animationIdentifier(animationName, property, index, subIndex);
1970
1971     RefPtr<PlatformCAAnimation> curAnim = layer->animationForKey(animationID);
1972     if (!curAnim)
1973         return;
1974
1975     // Animations on the layer are immutable, so we have to clone and modify.
1976     RefPtr<PlatformCAAnimation> newAnim = curAnim->copy();
1977
1978     newAnim->setSpeed(0);
1979     newAnim->setTimeOffset(timeOffset);
1980     
1981     layer->addAnimationForKey(animationID, newAnim.get()); // This will replace the running animation.
1982
1983     // Pause the animations on the clones too.
1984     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
1985         LayerMap::const_iterator end = layerCloneMap->end();
1986         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1987             // Skip immediate replicas, since they move with the original.
1988             if (m_replicaLayer && isReplicatedRootClone(it->key))
1989                 continue;
1990             it->value->addAnimationForKey(animationID, newAnim.get());
1991         }
1992     }
1993 }
1994
1995 void GraphicsLayerCA::repaintLayerDirtyRects()
1996 {
1997     if (!m_dirtyRects.size())
1998         return;
1999
2000     for (size_t i = 0; i < m_dirtyRects.size(); ++i)
2001         m_layer->setNeedsDisplay(&(m_dirtyRects[i]));
2002     
2003     m_dirtyRects.clear();
2004 }
2005
2006 void GraphicsLayerCA::updateContentsNeedsDisplay()
2007 {
2008     if (m_contentsLayer)
2009         m_contentsLayer->setNeedsDisplay();
2010 }
2011
2012 bool GraphicsLayerCA::createAnimationFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset)
2013 {
2014     ASSERT(valueList.property() != AnimatedPropertyWebkitTransform && (!supportsAcceleratedFilterAnimations() || valueList.property() != AnimatedPropertyWebkitFilter));
2015     
2016     bool isKeyframe = valueList.size() > 2;
2017     bool valuesOK;
2018     
2019     bool additive = false;
2020     int animationIndex = 0;
2021     
2022     RefPtr<PlatformCAAnimation> caAnimation;
2023     
2024     if (isKeyframe) {
2025         caAnimation = createKeyframeAnimation(animation, propertyIdToString(valueList.property()), additive);
2026         valuesOK = setAnimationKeyframes(valueList, animation, caAnimation.get());
2027     } else {
2028         caAnimation = createBasicAnimation(animation, propertyIdToString(valueList.property()), additive);
2029         valuesOK = setAnimationEndpoints(valueList, animation, caAnimation.get());
2030     }
2031     
2032     if (!valuesOK)
2033         return false;
2034
2035     m_uncomittedAnimations.append(LayerPropertyAnimation(caAnimation, animationName, valueList.property(), animationIndex, 0, timeOffset));
2036
2037     return true;
2038 }
2039
2040 bool GraphicsLayerCA::appendToUncommittedAnimations(const KeyframeValueList& valueList, const TransformOperations* operations, const Animation* animation, const String& animationName, const IntSize& boxSize, int animationIndex, double timeOffset, bool isMatrixAnimation)
2041 {
2042     TransformOperation::OperationType transformOp = isMatrixAnimation ? TransformOperation::MATRIX_3D : operations->operations().at(animationIndex)->getOperationType();
2043     bool additive = animationIndex > 0;
2044     bool isKeyframe = valueList.size() > 2;
2045
2046     RefPtr<PlatformCAAnimation> caAnimation;
2047     bool validMatrices = true;
2048     if (isKeyframe) {
2049         caAnimation = createKeyframeAnimation(animation, propertyIdToString(valueList.property()), additive);
2050         validMatrices = setTransformAnimationKeyframes(valueList, animation, caAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize);
2051     } else {
2052         caAnimation = createBasicAnimation(animation, propertyIdToString(valueList.property()), additive);
2053         validMatrices = setTransformAnimationEndpoints(valueList, animation, caAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize);
2054     }
2055     
2056     if (!validMatrices)
2057         return false;
2058
2059     m_uncomittedAnimations.append(LayerPropertyAnimation(caAnimation, animationName, valueList.property(), animationIndex, 0, timeOffset));
2060     return true;
2061 }
2062
2063 bool GraphicsLayerCA::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset, const IntSize& boxSize)
2064 {
2065     ASSERT(valueList.property() == AnimatedPropertyWebkitTransform);
2066
2067     bool hasBigRotation;
2068     int listIndex = validateTransformOperations(valueList, hasBigRotation);
2069     const TransformOperations* operations = (listIndex >= 0) ? static_cast<const TransformAnimationValue*>(valueList.at(listIndex))->value() : 0;
2070
2071     // We need to fall back to software animation if we don't have setValueFunction:, and
2072     // we would need to animate each incoming transform function separately. This is the
2073     // case if we have a rotation >= 180 or we have more than one transform function.
2074     if ((hasBigRotation || (operations && operations->size() > 1)) && !PlatformCAAnimation::supportsValueFunction())
2075         return false;
2076
2077     bool validMatrices = true;
2078
2079     // If function lists don't match we do a matrix animation, otherwise we do a component hardware animation.
2080     // Also, we can't do component animation unless we have valueFunction, so we need to do matrix animation
2081     // if that's not true as well.
2082     bool isMatrixAnimation = listIndex < 0 || !PlatformCAAnimation::supportsValueFunction();
2083     int numAnimations = isMatrixAnimation ? 1 : operations->size();
2084
2085     bool reverseAnimationList = true;
2086 #if !PLATFORM(IOS) && !PLATFORM(WIN) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
2087         // Old versions of Core Animation apply animations in reverse order (<rdar://problem/7095638>) so we need to flip the list.
2088         // to be non-additive. For binary compatibility, the current version of Core Animation preserves this behavior for applications linked
2089         // on or before Snow Leopard.
2090         // FIXME: This fix has not been added to QuartzCore on Windows yet (<rdar://problem/9112233>) so we expect the
2091         // reversed animation behavior
2092         static bool executableWasLinkedOnOrBeforeSnowLeopard = wkExecutableWasLinkedOnOrBeforeSnowLeopard();
2093         if (!executableWasLinkedOnOrBeforeSnowLeopard)
2094             reverseAnimationList = false;
2095 #endif
2096     if (reverseAnimationList) {
2097         for (int animationIndex = numAnimations - 1; animationIndex >= 0; --animationIndex) {
2098             if (!appendToUncommittedAnimations(valueList, operations, animation, animationName, boxSize, animationIndex, timeOffset, isMatrixAnimation)) {
2099                 validMatrices = false;
2100                 break;
2101             }
2102         }
2103     } else {
2104         for (int animationIndex = 0; animationIndex < numAnimations; ++animationIndex) {
2105             if (!appendToUncommittedAnimations(valueList, operations, animation, animationName, boxSize, animationIndex, timeOffset, isMatrixAnimation)) {
2106                 validMatrices = false;
2107                 break;
2108             }
2109         }
2110     }
2111
2112     return validMatrices;
2113 }
2114
2115 #if ENABLE(CSS_FILTERS)
2116 bool GraphicsLayerCA::appendToUncommittedAnimations(const KeyframeValueList& valueList, const FilterOperation* operation, const Animation* animation, const String& animationName, int animationIndex, double timeOffset)
2117 {
2118     bool isKeyframe = valueList.size() > 2;
2119     
2120     FilterOperation::OperationType filterOp = operation->getOperationType();
2121     int numAnimatedProperties = PlatformCAFilters::numAnimatedFilterProperties(filterOp);
2122     
2123     // Each filter might need to animate multiple properties, each with their own keyPath. The keyPath is always of the form:
2124     //
2125     //      filter.filter_<animationIndex>.<filterPropertyName>
2126     //
2127     // PlatformCAAnimation tells us how many properties each filter has and we iterate that many times and create an animation
2128     // for each. This internalFilterPropertyIndex gets passed to PlatformCAAnimation so it can properly create the property animation
2129     // values.
2130     for (int internalFilterPropertyIndex = 0; internalFilterPropertyIndex < numAnimatedProperties; ++internalFilterPropertyIndex) {
2131         bool valuesOK;
2132         RefPtr<PlatformCAAnimation> caAnimation;
2133         String keyPath = String::format("filters.filter_%d.%s", animationIndex, PlatformCAFilters::animatedFilterPropertyName(filterOp, internalFilterPropertyIndex));
2134         
2135         if (isKeyframe) {
2136             caAnimation = createKeyframeAnimation(animation, keyPath, false);
2137             valuesOK = setFilterAnimationKeyframes(valueList, animation, caAnimation.get(), animationIndex, internalFilterPropertyIndex, filterOp);
2138         } else {
2139             caAnimation = createBasicAnimation(animation, keyPath, false);
2140             valuesOK = setFilterAnimationEndpoints(valueList, animation, caAnimation.get(), animationIndex, internalFilterPropertyIndex);
2141         }
2142         
2143         ASSERT(valuesOK);
2144
2145         m_uncomittedAnimations.append(LayerPropertyAnimation(caAnimation, animationName, valueList.property(), animationIndex, internalFilterPropertyIndex, timeOffset));
2146     }
2147
2148     return true;
2149 }
2150
2151 bool GraphicsLayerCA::createFilterAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset)
2152 {
2153     ASSERT(valueList.property() == AnimatedPropertyWebkitFilter);
2154
2155     int listIndex = validateFilterOperations(valueList);
2156     if (listIndex < 0)
2157         return false;
2158         
2159     const FilterOperations* operations = static_cast<const FilterAnimationValue*>(valueList.at(listIndex))->value();
2160     // Make sure the platform layer didn't fallback to using software filter compositing instead.
2161     if (!PlatformCALayer::filtersCanBeComposited(*operations))
2162         return false;
2163
2164     int numAnimations = operations->size();
2165
2166     // FIXME: We can't currently hardware animate shadows.
2167     for (int i = 0; i < numAnimations; ++i) {
2168         if (operations->at(i)->getOperationType() == FilterOperation::DROP_SHADOW)
2169             return false;
2170     }
2171
2172     for (int animationIndex = 0; animationIndex < numAnimations; ++animationIndex) {
2173         if (!appendToUncommittedAnimations(valueList, operations->operations().at(animationIndex).get(), animation, animationName, animationIndex, timeOffset))
2174             return false;
2175     }
2176
2177     return true;
2178 }
2179 #endif
2180
2181 PassRefPtr<PlatformCAAnimation> GraphicsLayerCA::createBasicAnimation(const Animation* anim, const String& keyPath, bool additive)
2182 {
2183     RefPtr<PlatformCAAnimation> basicAnim = PlatformCAAnimation::create(PlatformCAAnimation::Basic, keyPath);
2184     setupAnimation(basicAnim.get(), anim, additive);
2185     return basicAnim;
2186 }
2187
2188 PassRefPtr<PlatformCAAnimation>GraphicsLayerCA::createKeyframeAnimation(const Animation* anim, const String& keyPath, bool additive)
2189 {
2190     RefPtr<PlatformCAAnimation> keyframeAnim = PlatformCAAnimation::create(PlatformCAAnimation::Keyframe, keyPath);
2191     setupAnimation(keyframeAnim.get(), anim, additive);
2192     return keyframeAnim;
2193 }
2194
2195 void GraphicsLayerCA::setupAnimation(PlatformCAAnimation* propertyAnim, const Animation* anim, bool additive)
2196 {
2197     double duration = anim->duration();
2198     if (duration <= 0)
2199         duration = cAnimationAlmostZeroDuration;
2200
2201     float repeatCount = anim->iterationCount();
2202     if (repeatCount == Animation::IterationCountInfinite)
2203         repeatCount = numeric_limits<float>::max();
2204     else if (anim->direction() == Animation::AnimationDirectionAlternate || anim->direction() == Animation::AnimationDirectionAlternateReverse)
2205         repeatCount /= 2;
2206
2207     PlatformCAAnimation::FillModeType fillMode = PlatformCAAnimation::NoFillMode;
2208     switch (anim->fillMode()) {
2209     case AnimationFillModeNone:
2210         fillMode = PlatformCAAnimation::Forwards; // Use "forwards" rather than "removed" because the style system will remove the animation when it is finished. This avoids a flash.
2211         break;
2212     case AnimationFillModeBackwards:
2213         fillMode = PlatformCAAnimation::Both; // Use "both" rather than "backwards" because the style system will remove the animation when it is finished. This avoids a flash.
2214         break;
2215     case AnimationFillModeForwards:
2216         fillMode = PlatformCAAnimation::Forwards;
2217         break;
2218     case AnimationFillModeBoth:
2219         fillMode = PlatformCAAnimation::Both;
2220         break;
2221     }
2222
2223     propertyAnim->setDuration(duration);
2224     propertyAnim->setRepeatCount(repeatCount);
2225     propertyAnim->setAutoreverses(anim->direction() == Animation::AnimationDirectionAlternate || anim->direction() == Animation::AnimationDirectionAlternateReverse);
2226     propertyAnim->setRemovedOnCompletion(false);
2227     propertyAnim->setAdditive(additive);
2228     propertyAnim->setFillMode(fillMode);
2229 }
2230
2231 const TimingFunction* GraphicsLayerCA::timingFunctionForAnimationValue(const AnimationValue* animValue, const Animation* anim)
2232 {
2233     if (animValue->timingFunction())
2234         return animValue->timingFunction();
2235     if (anim->isTimingFunctionSet())
2236         return anim->timingFunction().get();
2237     
2238     return CubicBezierTimingFunction::defaultTimingFunction();
2239 }
2240
2241 bool GraphicsLayerCA::setAnimationEndpoints(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* basicAnim)
2242 {
2243     bool forwards = animation->directionIsForwards();
2244
2245     unsigned fromIndex = !forwards;
2246     unsigned toIndex = forwards;
2247     
2248     switch (valueList.property()) {
2249     case AnimatedPropertyOpacity: {
2250         basicAnim->setFromValue(static_cast<const FloatAnimationValue*>(valueList.at(fromIndex))->value());
2251         basicAnim->setToValue(static_cast<const FloatAnimationValue*>(valueList.at(toIndex))->value());
2252         break;
2253     }
2254     default:
2255         ASSERT_NOT_REACHED(); // we don't animate color yet
2256         break;
2257     }
2258
2259     // This codepath is used for 2-keyframe animations, so we still need to look in the start
2260     // for a timing function. Even in the reversing animation case, the first keyframe provides the timing function.
2261     const TimingFunction* timingFunction = timingFunctionForAnimationValue(valueList.at(0), animation);
2262     if (timingFunction)
2263         basicAnim->setTimingFunction(timingFunction, !forwards);
2264
2265     return true;
2266 }
2267
2268 bool GraphicsLayerCA::setAnimationKeyframes(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* keyframeAnim)
2269 {
2270     Vector<float> keyTimes;
2271     Vector<float> values;
2272     Vector<const TimingFunction*> timingFunctions;
2273
2274     bool forwards = animation->directionIsForwards();
2275     
2276     for (unsigned i = 0; i < valueList.size(); ++i) {
2277         unsigned index = forwards ? i : (valueList.size() - i - 1);
2278         const AnimationValue* curValue = valueList.at(index);
2279         keyTimes.append(forwards ? curValue->keyTime() : (1 - curValue->keyTime()));
2280
2281         switch (valueList.property()) {
2282         case AnimatedPropertyOpacity: {
2283             const FloatAnimationValue* floatValue = static_cast<const FloatAnimationValue*>(curValue);
2284             values.append(floatValue->value());
2285             break;
2286         }
2287         default:
2288             ASSERT_NOT_REACHED(); // we don't animate color yet
2289             break;
2290         }
2291
2292         if (i < (valueList.size() - 1))
2293             timingFunctions.append(timingFunctionForAnimationValue(forwards ? curValue : valueList.at(index - 1), animation));
2294     }
2295     
2296     keyframeAnim->setKeyTimes(keyTimes);
2297     keyframeAnim->setValues(values);
2298     keyframeAnim->setTimingFunctions(timingFunctions, !forwards);
2299     
2300     return true;
2301 }
2302
2303 bool GraphicsLayerCA::setTransformAnimationEndpoints(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* basicAnim, int functionIndex, TransformOperation::OperationType transformOpType, bool isMatrixAnimation, const IntSize& boxSize)
2304 {
2305     ASSERT(valueList.size() == 2);
2306
2307     bool forwards = animation->directionIsForwards();
2308     
2309     unsigned fromIndex = !forwards;
2310     unsigned toIndex = forwards;
2311     
2312     const TransformAnimationValue* startValue = static_cast<const TransformAnimationValue*>(valueList.at(fromIndex));
2313     const TransformAnimationValue* endValue = static_cast<const TransformAnimationValue*>(valueList.at(toIndex));
2314     
2315     if (isMatrixAnimation) {
2316         TransformationMatrix fromTransform, toTransform;
2317         startValue->value()->apply(boxSize, fromTransform);
2318         endValue->value()->apply(boxSize, toTransform);
2319
2320         // If any matrix is singular, CA won't animate it correctly. So fall back to software animation
2321         if (!fromTransform.isInvertible() || !toTransform.isInvertible())
2322             return false;
2323             
2324         basicAnim->setFromValue(fromTransform);
2325         basicAnim->setToValue(toTransform);
2326     } else {
2327         if (isTransformTypeNumber(transformOpType)) {
2328             float fromValue;
2329             getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue);
2330             basicAnim->setFromValue(fromValue);
2331             
2332             float toValue;
2333             getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue);
2334             basicAnim->setToValue(toValue);
2335         } else if (isTransformTypeFloatPoint3D(transformOpType)) {
2336             FloatPoint3D fromValue;
2337             getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue);
2338             basicAnim->setFromValue(fromValue);
2339             
2340             FloatPoint3D toValue;
2341             getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue);
2342             basicAnim->setToValue(toValue);
2343         } else {
2344             TransformationMatrix fromValue;
2345             getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue);
2346             basicAnim->setFromValue(fromValue);
2347
2348             TransformationMatrix toValue;
2349             getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue);
2350             basicAnim->setToValue(toValue);
2351         }
2352     }
2353
2354     // This codepath is used for 2-keyframe animations, so we still need to look in the start
2355     // for a timing function. Even in the reversing animation case, the first keyframe provides the timing function.
2356     const TimingFunction* timingFunction = timingFunctionForAnimationValue(valueList.at(0), animation);
2357     basicAnim->setTimingFunction(timingFunction, !forwards);
2358
2359     PlatformCAAnimation::ValueFunctionType valueFunction = getValueFunctionNameForTransformOperation(transformOpType);
2360     if (valueFunction != PlatformCAAnimation::NoValueFunction)
2361         basicAnim->setValueFunction(valueFunction);
2362
2363     return true;
2364 }
2365
2366 bool GraphicsLayerCA::setTransformAnimationKeyframes(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* keyframeAnim, int functionIndex, TransformOperation::OperationType transformOpType, bool isMatrixAnimation, const IntSize& boxSize)
2367 {
2368     Vector<float> keyTimes;
2369     Vector<float> floatValues;
2370     Vector<FloatPoint3D> floatPoint3DValues;
2371     Vector<TransformationMatrix> transformationMatrixValues;
2372     Vector<const TimingFunction*> timingFunctions;
2373
2374     bool forwards = animation->directionIsForwards();
2375
2376     for (unsigned i = 0; i < valueList.size(); ++i) {
2377         unsigned index = forwards ? i : (valueList.size() - i - 1);
2378         const TransformAnimationValue* curValue = static_cast<const TransformAnimationValue*>(valueList.at(index));
2379         keyTimes.append(forwards ? curValue->keyTime() : (1 - curValue->keyTime()));
2380
2381         if (isMatrixAnimation) {
2382             TransformationMatrix transform;
2383             curValue->value()->apply(boxSize, transform);
2384
2385             // If any matrix is singular, CA won't animate it correctly. So fall back to software animation
2386             if (!transform.isInvertible())
2387                 return false;
2388
2389             transformationMatrixValues.append(transform);
2390         } else {
2391             const TransformOperation* transformOp = curValue->value()->at(functionIndex);
2392             if (isTransformTypeNumber(transformOpType)) {
2393                 float value;
2394                 getTransformFunctionValue(transformOp, transformOpType, boxSize, value);
2395                 floatValues.append(value);
2396             } else if (isTransformTypeFloatPoint3D(transformOpType)) {
2397                 FloatPoint3D value;
2398                 getTransformFunctionValue(transformOp, transformOpType, boxSize, value);
2399                 floatPoint3DValues.append(value);
2400             } else {
2401                 TransformationMatrix value;
2402                 getTransformFunctionValue(transformOp, transformOpType, boxSize, value);
2403                 transformationMatrixValues.append(value);
2404             }
2405         }
2406
2407         if (i < (valueList.size() - 1))
2408             timingFunctions.append(timingFunctionForAnimationValue(forwards ? curValue : valueList.at(index - 1), animation));
2409     }
2410     
2411     keyframeAnim->setKeyTimes(keyTimes);
2412     
2413     if (isTransformTypeNumber(transformOpType))
2414         keyframeAnim->setValues(floatValues);
2415     else if (isTransformTypeFloatPoint3D(transformOpType))
2416         keyframeAnim->setValues(floatPoint3DValues);
2417     else
2418         keyframeAnim->setValues(transformationMatrixValues);
2419         
2420     keyframeAnim->setTimingFunctions(timingFunctions, !forwards);
2421
2422     PlatformCAAnimation::ValueFunctionType valueFunction = getValueFunctionNameForTransformOperation(transformOpType);
2423     if (valueFunction != PlatformCAAnimation::NoValueFunction)
2424         keyframeAnim->setValueFunction(valueFunction);
2425
2426     return true;
2427 }
2428
2429 #if ENABLE(CSS_FILTERS)
2430 bool GraphicsLayerCA::setFilterAnimationEndpoints(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* basicAnim, int functionIndex, int internalFilterPropertyIndex)
2431 {
2432     ASSERT(valueList.size() == 2);
2433
2434     bool forwards = animation->directionIsForwards();
2435
2436     unsigned fromIndex = !forwards;
2437     unsigned toIndex = forwards;
2438
2439     const FilterAnimationValue* fromValue = static_cast<const FilterAnimationValue*>(valueList.at(fromIndex));
2440     const FilterAnimationValue* toValue = static_cast<const FilterAnimationValue*>(valueList.at(toIndex));
2441
2442     const FilterOperation* fromOperation = fromValue->value()->at(functionIndex);
2443     const FilterOperation* toOperation = toValue->value()->at(functionIndex);
2444
2445     RefPtr<DefaultFilterOperation> defaultFromOperation;
2446     RefPtr<DefaultFilterOperation> defaultToOperation;
2447
2448     ASSERT(fromOperation || toOperation);
2449
2450     if (!fromOperation) {
2451         defaultFromOperation = DefaultFilterOperation::create(toOperation->getOperationType());
2452         fromOperation = defaultFromOperation.get();
2453     }
2454
2455     if (!toOperation) {
2456         defaultToOperation = DefaultFilterOperation::create(fromOperation->getOperationType());
2457         toOperation = defaultToOperation.get();
2458     }
2459
2460     basicAnim->setFromValue(fromOperation, internalFilterPropertyIndex);
2461     basicAnim->setToValue(toOperation, internalFilterPropertyIndex);
2462
2463     // This codepath is used for 2-keyframe animations, so we still need to look in the start
2464     // for a timing function. Even in the reversing animation case, the first keyframe provides the timing function.
2465     basicAnim->setTimingFunction(timingFunctionForAnimationValue(valueList.at(0), animation), !forwards);
2466
2467     return true;
2468 }
2469
2470 bool GraphicsLayerCA::setFilterAnimationKeyframes(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* keyframeAnim, int functionIndex, int internalFilterPropertyIndex, FilterOperation::OperationType filterOp)
2471 {
2472     Vector<float> keyTimes;
2473     Vector<RefPtr<FilterOperation> > values;
2474     Vector<const TimingFunction*> timingFunctions;
2475     RefPtr<DefaultFilterOperation> defaultOperation;
2476
2477     bool forwards = animation->directionIsForwards();
2478
2479     for (unsigned i = 0; i < valueList.size(); ++i) {
2480         unsigned index = forwards ? i : (valueList.size() - i - 1);
2481         const FilterAnimationValue* curValue = static_cast<const FilterAnimationValue*>(valueList.at(index));
2482         keyTimes.append(forwards ? curValue->keyTime() : (1 - curValue->keyTime()));
2483
2484         if (curValue->value()->operations().size() > static_cast<size_t>(functionIndex))
2485             values.append(curValue->value()->operations()[functionIndex]);
2486         else {
2487             if (!defaultOperation)
2488                 defaultOperation = DefaultFilterOperation::create(filterOp);
2489             values.append(defaultOperation);
2490         }
2491
2492         if (i < (valueList.size() - 1))
2493             timingFunctions.append(timingFunctionForAnimationValue(forwards ? curValue : valueList.at(index - 1), animation));
2494     }
2495     
2496     keyframeAnim->setKeyTimes(keyTimes);
2497     keyframeAnim->setValues(values, internalFilterPropertyIndex);
2498     keyframeAnim->setTimingFunctions(timingFunctions, !forwards);
2499
2500     return true;
2501 }
2502 #endif
2503
2504 void GraphicsLayerCA::suspendAnimations(double time)
2505 {
2506     double t = PlatformCALayer::currentTimeToMediaTime(time ? time : currentTime());
2507     primaryLayer()->setSpeed(0);
2508     primaryLayer()->setTimeOffset(t);
2509
2510     // Suspend the animations on the clones too.
2511     if (LayerMap* layerCloneMap = primaryLayerClones()) {
2512         LayerMap::const_iterator end = layerCloneMap->end();
2513         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
2514             it->value->setSpeed(0);
2515             it->value->setTimeOffset(t);
2516         }
2517     }
2518 }
2519
2520 void GraphicsLayerCA::resumeAnimations()
2521 {
2522     primaryLayer()->setSpeed(1);
2523     primaryLayer()->setTimeOffset(0);
2524
2525     // Resume the animations on the clones too.
2526     if (LayerMap* layerCloneMap = primaryLayerClones()) {
2527         LayerMap::const_iterator end = layerCloneMap->end();
2528         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
2529             it->value->setSpeed(1);
2530             it->value->setTimeOffset(0);
2531         }
2532     }
2533 }
2534
2535 PlatformCALayer* GraphicsLayerCA::hostLayerForSublayers() const
2536 {
2537     return m_structuralLayer.get() ? m_structuralLayer.get() : m_layer.get(); 
2538 }
2539
2540 PlatformCALayer* GraphicsLayerCA::layerForSuperlayer() const
2541 {
2542     return m_structuralLayer ? m_structuralLayer.get() : m_layer.get();
2543 }
2544
2545 PlatformCALayer* GraphicsLayerCA::animatedLayer(AnimatedPropertyID property) const
2546 {
2547     return (property == AnimatedPropertyBackgroundColor) ? m_contentsLayer.get() : primaryLayer();
2548 }
2549
2550 GraphicsLayerCA::LayerMap* GraphicsLayerCA::animatedLayerClones(AnimatedPropertyID property) const
2551 {
2552     return (property == AnimatedPropertyBackgroundColor) ? m_contentsLayerClones.get() : primaryLayerClones();
2553 }
2554
2555 static float clampedContentsScaleForScale(float scale)
2556 {
2557     // Define some limits as a sanity check for the incoming scale value
2558     // those too small to see.
2559     const float maxScale = 10.0f;
2560     const float minScale = 0.01f;
2561     return max(minScale, min(scale, maxScale));
2562 }
2563
2564 void GraphicsLayerCA::updateContentsScale(float pageScaleFactor)
2565 {
2566     bool needTiledLayer = requiresTiledLayer(pageScaleFactor);
2567     if (needTiledLayer != m_usingTiledBacking)
2568         swapFromOrToTiledLayer(needTiledLayer);
2569
2570     float contentsScale = clampedContentsScaleForScale(pageScaleFactor * deviceScaleFactor());
2571     
2572     m_layer->setContentsScale(contentsScale);
2573     if (drawsContent())
2574         m_layer->setNeedsDisplay();
2575 }
2576
2577 void GraphicsLayerCA::setShowDebugBorder(bool showBorder)
2578 {
2579     if (showBorder == m_showDebugBorder)
2580         return;
2581
2582     GraphicsLayer::setShowDebugBorder(showBorder);
2583     noteLayerPropertyChanged(DebugIndicatorsChanged);
2584 }
2585
2586 void GraphicsLayerCA::setShowRepaintCounter(bool showCounter)
2587 {
2588     if (showCounter == m_showRepaintCounter)
2589         return;
2590
2591     GraphicsLayer::setShowRepaintCounter(showCounter);
2592     noteLayerPropertyChanged(DebugIndicatorsChanged);
2593 }
2594
2595 void GraphicsLayerCA::setDebugBackgroundColor(const Color& color)
2596 {    
2597     if (color.isValid())
2598         m_layer->setBackgroundColor(color);
2599     else
2600         m_layer->setBackgroundColor(Color::transparent);
2601 }
2602
2603 void GraphicsLayerCA::getDebugBorderInfo(Color& color, float& width) const
2604 {
2605     if (m_isPageTiledBackingLayer) {
2606         color = Color(0, 0, 128, 128); // tile cache layer: dark blue
2607         width = 0.5;
2608         return;
2609     }
2610
2611     GraphicsLayer::getDebugBorderInfo(color, width);
2612 }
2613
2614 void GraphicsLayerCA::dumpAdditionalProperties(TextStream& textStream, int indent, LayerTreeAsTextBehavior behavior) const
2615 {
2616     if (behavior & LayerTreeAsTextIncludeVisibleRects) {
2617         writeIndent(textStream, indent + 1);
2618         textStream << "(visible rect " << m_visibleRect.x() << ", " << m_visibleRect.y() << " " << m_visibleRect.width() << " x " << m_visibleRect.height() << ")\n";
2619     }
2620
2621     if (tiledBacking() && (behavior & LayerTreeAsTextIncludeTileCaches)) {
2622         if (behavior & LayerTreeAsTextDebug) {
2623             writeIndent(textStream, indent + 1);
2624             textStream << "(tiled backing " << tiledBacking() << ")\n";
2625         }
2626
2627         IntRect tileCoverageRect = tiledBacking()->tileCoverageRect();
2628         writeIndent(textStream, indent + 1);
2629         textStream << "(tile cache coverage " << tileCoverageRect.x() << ", " << tileCoverageRect.y() << " " << tileCoverageRect.width() << " x " << tileCoverageRect.height() << ")\n";
2630
2631         IntSize tileSize = tiledBacking()->tileSize();
2632         writeIndent(textStream, indent + 1);
2633         textStream << "(tile size " << tileSize.width() << " x " << tileSize.height() << ")\n";
2634         
2635         IntRect gridExtent = tiledBacking()->tileGridExtent();
2636         writeIndent(textStream, indent + 1);
2637         textStream << "(top left tile " << gridExtent.x() << ", " << gridExtent.y() << " tiles grid " << gridExtent.width() << " x " << gridExtent.height() << ")\n";
2638     }
2639 }
2640
2641 void GraphicsLayerCA::setDebugBorder(const Color& color, float borderWidth)
2642 {    
2643     if (color.isValid()) {
2644         m_layer->setBorderColor(color);
2645         m_layer->setBorderWidth(borderWidth);
2646     } else {
2647         m_layer->setBorderColor(Color::transparent);
2648         m_layer->setBorderWidth(0);
2649     }
2650 }
2651
2652 FloatSize GraphicsLayerCA::constrainedSize() const
2653 {
2654     FloatSize constrainedSize = m_size;
2655 #if !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED == 1060
2656     float tileColumns = ceilf(m_size.width() / kTiledLayerTileSize);
2657     float tileRows = ceilf(m_size.height() / kTiledLayerTileSize);
2658     double numTiles = tileColumns * tileRows;
2659     
2660     const unsigned cMaxTileCount = 512;
2661     while (numTiles > cMaxTileCount) {
2662         // Constrain the wider dimension.
2663         if (constrainedSize.width() >= constrainedSize.height()) {
2664             tileColumns = max(floorf(cMaxTileCount / tileRows), 1.0f);
2665             constrainedSize.setWidth(tileColumns * kTiledLayerTileSize);
2666         } else {
2667             tileRows = max(floorf(cMaxTileCount / tileColumns), 1.0f);
2668             constrainedSize.setHeight(tileRows * kTiledLayerTileSize);
2669         }
2670         numTiles = tileColumns * tileRows;
2671     }
2672 #endif
2673     return constrainedSize;
2674 }
2675
2676 bool GraphicsLayerCA::requiresTiledLayer(float pageScaleFactor) const
2677 {
2678     if (!m_drawsContent || !m_allowTiledLayer || m_isPageTiledBackingLayer)
2679         return false;
2680
2681     // FIXME: catch zero-size height or width here (or earlier)?
2682     return m_size.width() * pageScaleFactor > cMaxPixelDimension || m_size.height() * pageScaleFactor > cMaxPixelDimension;
2683 }
2684
2685 void GraphicsLayerCA::swapFromOrToTiledLayer(bool useTiledLayer)
2686 {
2687     ASSERT(m_layer->layerType() != PlatformCALayer::LayerTypePageTiledBackingLayer);
2688     ASSERT(useTiledLayer != m_usingTiledBacking);
2689     RefPtr<PlatformCALayer> oldLayer = m_layer;
2690     
2691     m_layer = PlatformCALayer::create(useTiledLayer ? PlatformCALayer::LayerTypeTiledBackingLayer : PlatformCALayer::LayerTypeWebLayer, this);
2692     m_usingTiledBacking = useTiledLayer;
2693     
2694     m_layer->adoptSublayers(oldLayer.get());
2695
2696 #ifdef VISIBLE_TILE_WASH
2697     if (m_visibleTileWashLayer)
2698         m_layer->appendSublayer(m_visibleTileWashLayer.get());
2699 #endif
2700
2701     // Skip this step if we don't have a superlayer. This is probably a benign
2702     // case that happens while restructuring the layer tree, and also occurs with
2703     // WebKit2 page overlays, which can become tiled but are out-of-tree.
2704     if (oldLayer->superlayer())
2705         oldLayer->superlayer()->replaceSublayer(oldLayer.get(), m_layer.get());
2706
2707     m_uncommittedChanges |= ChildrenChanged
2708         | GeometryChanged
2709         | TransformChanged
2710         | ChildrenTransformChanged
2711         | MasksToBoundsChanged
2712         | ContentsOpaqueChanged
2713         | BackfaceVisibilityChanged
2714         | BackgroundColorChanged
2715         | ContentsScaleChanged
2716         | AcceleratesDrawingChanged
2717         | FiltersChanged
2718         | OpacityChanged
2719         | DebugIndicatorsChanged;
2720     
2721     if (m_usingTiledBacking)
2722         m_uncommittedChanges |= VisibleRectChanged;
2723
2724 #ifndef NDEBUG
2725     String name = String::format("%sCALayer(%p) GraphicsLayer(%p) ", (m_layer->layerType() == PlatformCALayer::LayerTypeWebTiledLayer) ? "Tiled " : "", m_layer->platformLayer(), this) + m_name;
2726     m_layer->setName(name);
2727 #endif
2728
2729     // move over animations
2730     moveOrCopyAnimations(Move, oldLayer.get(), m_layer.get());
2731     
2732     // need to tell new layer to draw itself
2733     setNeedsDisplay();
2734     
2735     if (client())
2736         client()->tiledBackingUsageChanged(this, m_usingTiledBacking);
2737 }
2738
2739 GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayerCA::defaultContentsOrientation() const
2740 {
2741     return CompositingCoordinatesTopDown;
2742 }
2743
2744 void GraphicsLayerCA::setupContentsLayer(PlatformCALayer* contentsLayer)
2745 {
2746     // Turn off implicit animations on the inner layer.
2747     contentsLayer->setMasksToBounds(true);
2748
2749     if (defaultContentsOrientation() == CompositingCoordinatesBottomUp) {
2750         TransformationMatrix flipper(
2751             1.0f, 0.0f, 0.0f, 0.0f,
2752             0.0f, -1.0f, 0.0f, 0.0f,
2753             0.0f, 0.0f, 1.0f, 0.0f,
2754             0.0f, 0.0f, 0.0f, 1.0f);
2755         contentsLayer->setTransform(flipper);
2756         contentsLayer->setAnchorPoint(FloatPoint3D(0, 1, 0));
2757     } else
2758         contentsLayer->setAnchorPoint(FloatPoint3D());
2759
2760     if (isShowingDebugBorder()) {
2761         contentsLayer->setBorderColor(Color(0, 0, 128, 180));
2762         contentsLayer->setBorderWidth(1.0f);
2763     }
2764 }
2765
2766 PassRefPtr<PlatformCALayer> GraphicsLayerCA::findOrMakeClone(CloneID cloneID, PlatformCALayer *sourceLayer, LayerMap* clones, CloneLevel cloneLevel)
2767 {
2768     if (!sourceLayer)
2769         return 0;
2770
2771     RefPtr<PlatformCALayer> resultLayer;
2772
2773     // Add with a dummy value to get an iterator for the insertion position, and a boolean that tells
2774     // us whether there's an item there. This technique avoids two hash lookups.
2775     RefPtr<PlatformCALayer> dummy;
2776     LayerMap::AddResult addResult = clones->add(cloneID, dummy);
2777     if (!addResult.isNewEntry) {
2778         // Value was not added, so it exists already.
2779         resultLayer = addResult.iterator->value.get();
2780     } else {
2781         resultLayer = cloneLayer(sourceLayer, cloneLevel);
2782 #ifndef NDEBUG
2783         resultLayer->setName(String::format("Clone %d of layer %p", cloneID[0U], sourceLayer->platformLayer()));
2784 #endif
2785         addResult.iterator->value = resultLayer;
2786     }
2787
2788     return resultLayer;
2789 }   
2790
2791 void GraphicsLayerCA::ensureCloneLayers(CloneID cloneID, RefPtr<PlatformCALayer>& primaryLayer, RefPtr<PlatformCALayer>& structuralLayer, RefPtr<PlatformCALayer>& contentsLayer, CloneLevel cloneLevel)
2792 {
2793     structuralLayer = 0;
2794     contentsLayer = 0;
2795
2796     if (!m_layerClones)
2797         m_layerClones = adoptPtr(new LayerMap);
2798
2799     if (!m_structuralLayerClones && m_structuralLayer)
2800         m_structuralLayerClones = adoptPtr(new LayerMap);
2801
2802     if (!m_contentsLayerClones && m_contentsLayer)
2803         m_contentsLayerClones = adoptPtr(new LayerMap);
2804
2805     primaryLayer = findOrMakeClone(cloneID, m_layer.get(), m_layerClones.get(), cloneLevel);
2806     structuralLayer = findOrMakeClone(cloneID, m_structuralLayer.get(), m_structuralLayerClones.get(), cloneLevel);
2807     contentsLayer = findOrMakeClone(cloneID, m_contentsLayer.get(), m_contentsLayerClones.get(), cloneLevel);
2808 }
2809
2810 void GraphicsLayerCA::removeCloneLayers()
2811 {
2812     m_layerClones = nullptr;
2813     m_structuralLayerClones = nullptr;
2814     m_contentsLayerClones = nullptr;
2815 }
2816
2817 FloatPoint GraphicsLayerCA::positionForCloneRootLayer() const
2818 {
2819     // This can get called during a flush when we've just removed the m_replicaLayer.
2820     if (!m_replicaLayer)
2821         return FloatPoint();
2822
2823     FloatPoint replicaPosition = m_replicaLayer->replicatedLayerPosition();
2824     return FloatPoint(replicaPosition.x() + m_anchorPoint.x() * m_size.width(),
2825                       replicaPosition.y() + m_anchorPoint.y() * m_size.height());
2826 }
2827
2828 void GraphicsLayerCA::propagateLayerChangeToReplicas()
2829 {
2830     for (GraphicsLayer* currLayer = this; currLayer; currLayer = currLayer->parent()) {
2831         GraphicsLayerCA* currLayerCA = static_cast<GraphicsLayerCA*>(currLayer);
2832         if (!currLayerCA->hasCloneLayers())
2833             break;
2834
2835         if (currLayerCA->replicaLayer())
2836             static_cast<GraphicsLayerCA*>(currLayerCA->replicaLayer())->noteLayerPropertyChanged(ReplicatedLayerChanged);
2837     }
2838 }
2839
2840 PassRefPtr<PlatformCALayer> GraphicsLayerCA::fetchCloneLayers(GraphicsLayer* replicaRoot, ReplicaState& replicaState, CloneLevel cloneLevel)
2841 {
2842     RefPtr<PlatformCALayer> primaryLayer;
2843     RefPtr<PlatformCALayer> structuralLayer;
2844     RefPtr<PlatformCALayer> contentsLayer;
2845     ensureCloneLayers(replicaState.cloneID(), primaryLayer, structuralLayer, contentsLayer, cloneLevel);
2846
2847     if (m_maskLayer) {
2848         RefPtr<PlatformCALayer> maskClone = static_cast<GraphicsLayerCA*>(m_maskLayer)->fetchCloneLayers(replicaRoot, replicaState, IntermediateCloneLevel);
2849         primaryLayer->setMask(maskClone.get());
2850     }
2851
2852     if (m_replicatedLayer) {
2853         // We are a replica being asked for clones of our layers.
2854         RefPtr<PlatformCALayer> replicaRoot = replicatedLayerRoot(replicaState);
2855         if (!replicaRoot)
2856             return 0;
2857
2858         if (structuralLayer) {
2859             structuralLayer->insertSublayer(replicaRoot.get(), 0);
2860             return structuralLayer;
2861         }
2862         
2863         primaryLayer->insertSublayer(replicaRoot.get(), 0);
2864         return primaryLayer;
2865     }
2866
2867     const Vector<GraphicsLayer*>& childLayers = children();
2868     Vector<RefPtr<PlatformCALayer> > clonalSublayers;
2869
2870     RefPtr<PlatformCALayer> replicaLayer;
2871     
2872     if (m_replicaLayer && m_replicaLayer != replicaRoot) {
2873         // We have nested replicas. Ask the replica layer for a clone of its contents.
2874         replicaState.setBranchType(ReplicaState::ReplicaBranch);
2875         replicaLayer = static_cast<GraphicsLayerCA*>(m_replicaLayer)->fetchCloneLayers(replicaRoot, replicaState, RootCloneLevel);
2876         replicaState.setBranchType(ReplicaState::ChildBranch);
2877     }
2878     
2879     if (replicaLayer || structuralLayer || contentsLayer || childLayers.size() > 0) {
2880         if (structuralLayer) {
2881             // Replicas render behind the actual layer content.
2882             if (replicaLayer)
2883                 clonalSublayers.append(replicaLayer);
2884                 
2885             // Add the primary layer next. Even if we have negative z-order children, the primary layer always comes behind.
2886             clonalSublayers.append(primaryLayer);
2887         } else if (contentsLayer) {
2888             // FIXME: add the contents layer in the correct order with negative z-order children.
2889             // This does not cause visible rendering issues because currently contents layers are only used
2890             // for replaced elements that don't have children.
2891             clonalSublayers.append(contentsLayer);
2892         }
2893         
2894         replicaState.push(ReplicaState::ChildBranch);
2895
2896         size_t numChildren = childLayers.size();
2897         for (size_t i = 0; i < numChildren; ++i) {
2898             GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
2899
2900             RefPtr<PlatformCALayer> childLayer = curChild->fetchCloneLayers(replicaRoot, replicaState, IntermediateCloneLevel);
2901             if (childLayer)
2902                 clonalSublayers.append(childLayer);
2903         }
2904
2905         replicaState.pop();
2906
2907         for (size_t i = 0; i < clonalSublayers.size(); ++i)
2908             clonalSublayers[i]->removeFromSuperlayer();
2909     }
2910     
2911     RefPtr<PlatformCALayer> result;
2912     if (structuralLayer) {
2913         structuralLayer->setSublayers(clonalSublayers);
2914
2915         if (contentsLayer) {
2916             // If we have a transform layer, then the contents layer is parented in the 
2917             // primary layer (which is itself a child of the transform layer).
2918             primaryLayer->removeAllSublayers();
2919             primaryLayer->appendSublayer(contentsLayer.get());
2920         }
2921
2922         result = structuralLayer;
2923     } else {
2924         primaryLayer->setSublayers(clonalSublayers);
2925         result = primaryLayer;
2926     }
2927
2928     return result;
2929 }
2930
2931 PassRefPtr<PlatformCALayer> GraphicsLayerCA::cloneLayer(PlatformCALayer *layer, CloneLevel cloneLevel)
2932 {
2933     RefPtr<PlatformCALayer> newLayer = layer->clone(this);
2934
2935     if (cloneLevel == IntermediateCloneLevel) {
2936         newLayer->setOpacity(layer->opacity());
2937         moveOrCopyAnimations(Copy, layer, newLayer.get());
2938     }
2939     
2940     if (isShowingDebugBorder()) {
2941         newLayer->setBorderColor(Color(255, 122, 251));
2942         newLayer->setBorderWidth(2);
2943     }
2944     
2945     return newLayer;
2946 }
2947
2948 void GraphicsLayerCA::setOpacityInternal(float accumulatedOpacity)
2949 {
2950     LayerMap* layerCloneMap = 0;
2951     
2952     if (preserves3D()) {
2953         m_layer->setOpacity(accumulatedOpacity);
2954         layerCloneMap = m_layerClones.get();
2955     } else {
2956         primaryLayer()->setOpacity(accumulatedOpacity);
2957         layerCloneMap = primaryLayerClones();
2958     }
2959
2960     if (layerCloneMap) {
2961         LayerMap::const_iterator end = layerCloneMap->end();
2962         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
2963             if (m_replicaLayer && isReplicatedRootClone(it->key))
2964                 continue;
2965             it->value->setOpacity(m_opacity);
2966         }
2967     }
2968 }
2969
2970 void GraphicsLayerCA::updateOpacityOnLayer()
2971 {
2972     primaryLayer()->setOpacity(m_opacity);
2973
2974     if (LayerMap* layerCloneMap = primaryLayerClones()) {
2975         LayerMap::const_iterator end = layerCloneMap->end();
2976         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
2977             if (m_replicaLayer && isReplicatedRootClone(it->key))
2978                 continue;
2979
2980             it->value->setOpacity(m_opacity);
2981         }
2982         
2983     }
2984 }
2985
2986 void GraphicsLayerCA::setMaintainsPixelAlignment(bool maintainsAlignment)
2987 {
2988     if (maintainsAlignment == m_maintainsPixelAlignment)
2989         return;
2990
2991     GraphicsLayer::setMaintainsPixelAlignment(maintainsAlignment);
2992     noteChangesForScaleSensitiveProperties();
2993 }
2994
2995 void GraphicsLayerCA::deviceOrPageScaleFactorChanged()
2996 {
2997     noteChangesForScaleSensitiveProperties();
2998 }
2999
3000 void GraphicsLayerCA::noteChangesForScaleSensitiveProperties()
3001 {
3002     noteLayerPropertyChanged(GeometryChanged | ContentsScaleChanged);
3003 }
3004
3005 static inline bool isIntegral(float value)
3006 {
3007     return static_cast<int>(value) == value;
3008 }
3009
3010 void GraphicsLayerCA::computePixelAlignment(float pageScaleFactor, const FloatPoint& positionRelativeToBase,
3011     FloatPoint& position, FloatSize& size, FloatPoint3D& anchorPoint, FloatSize& alignmentOffset) const
3012 {
3013     if (!m_maintainsPixelAlignment || isIntegral(pageScaleFactor) || !m_drawsContent || m_masksToBounds) {
3014         position = m_position;
3015         size = m_size;
3016         anchorPoint = m_anchorPoint;
3017         alignmentOffset = FloatSize();
3018         return;
3019     }
3020     
3021     FloatRect baseRelativeBounds(positionRelativeToBase, m_size);
3022     FloatRect scaledBounds = baseRelativeBounds;
3023     // Scale by the page scale factor to compute the screen-relative bounds.
3024     scaledBounds.scale(pageScaleFactor);
3025     // Round to integer boundaries.
3026     FloatRect alignedBounds = enclosingIntRect(scaledBounds);
3027     
3028     // Convert back to layer coordinates.
3029     alignedBounds.scale(1 / pageScaleFactor);
3030     
3031     // Epsilon is necessary to ensure that backing store size computation in CA, which involves integer truncation,
3032     // will match our aligned bounds.
3033     const float epsilon = 1e-5f;
3034     alignedBounds.expand(epsilon, epsilon);
3035     
3036     alignmentOffset = baseRelativeBounds.location() - alignedBounds.location();
3037     position = m_position - alignmentOffset;
3038     size = alignedBounds.size();
3039
3040     // Now we have to compute a new anchor point which compensates for rounding.
3041     float anchorPointX = m_anchorPoint.x();
3042     float anchorPointY = m_anchorPoint.y();
3043     
3044     if (alignedBounds.width())
3045         anchorPointX = (baseRelativeBounds.width() * anchorPointX + alignmentOffset.width()) / alignedBounds.width();
3046     
3047     if (alignedBounds.height())
3048         anchorPointY = (baseRelativeBounds.height() * anchorPointY + alignmentOffset.height()) / alignedBounds.height();
3049      
3050     anchorPoint = FloatPoint3D(anchorPointX, anchorPointY, m_anchorPoint.z() * pageScaleFactor);
3051 }
3052
3053 void GraphicsLayerCA::noteSublayersChanged()
3054 {
3055     noteLayerPropertyChanged(ChildrenChanged);
3056     propagateLayerChangeToReplicas();
3057 }
3058
3059 void GraphicsLayerCA::noteLayerPropertyChanged(LayerChangeFlags flags)
3060 {
3061     if (!m_uncommittedChanges && m_client)
3062         m_client->notifyFlushRequired(this);
3063
3064     m_uncommittedChanges |= flags;
3065 }
3066
3067 double GraphicsLayerCA::backingStoreMemoryEstimate() const
3068 {
3069     if (!drawsContent())
3070         return 0;
3071
3072     // contentsLayer is given to us, so we don't really know anything about its contents.
3073     // FIXME: ignores layer clones.
3074     
3075     if (TiledBacking* tiledBacking = this->tiledBacking())
3076         return tiledBacking->retainedTileBackingStoreMemory();
3077
3078     return 4.0 * size().width() * m_layer->contentsScale() * size().height() * m_layer->contentsScale();
3079 }
3080
3081 } // namespace WebCore
3082
3083 #endif // USE(ACCELERATED_COMPOSITING)