Fix GraphicsLayerCA::recursiveVisibleRectChangeRequiresFlush() to do predictive visib...
[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 bool GraphicsLayerCA::recursiveVisibleRectChangeRequiresFlush(const TransformState& state) const
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 newVisibleRect = computeVisibleRect(localState, 0);
917     if (m_layer->layerType() == PlatformCALayer::LayerTypeTiledBackingLayer)
918         newVisibleRect = adjustTiledLayerVisibleRect(tiledBacking(), m_visibleRect, newVisibleRect, m_sizeAtLastVisibleRectUpdate, m_size);
919
920     if (newVisibleRect != m_visibleRect) {
921         if (TiledBacking* tiledBacking = this->tiledBacking()) {
922             if (tiledBacking->tilesWouldChangeForVisibleRect(newVisibleRect))
923                 return true;
924         }
925     }
926
927     if (m_maskLayer) {
928         GraphicsLayerCA* maskLayerCA = static_cast<GraphicsLayerCA*>(m_maskLayer);
929         if (maskLayerCA->recursiveVisibleRectChangeRequiresFlush(localState))
930             return true;
931     }
932
933     const Vector<GraphicsLayer*>& childLayers = children();
934     size_t numChildren = childLayers.size();
935     
936     for (size_t i = 0; i < numChildren; ++i) {
937         GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
938         if (curChild->recursiveVisibleRectChangeRequiresFlush(localState))
939             return true;
940     }
941
942     if (m_replicaLayer)
943         if (static_cast<GraphicsLayerCA*>(m_replicaLayer)->recursiveVisibleRectChangeRequiresFlush(localState))
944             return true;
945     
946     return false;
947 }
948
949 bool GraphicsLayerCA::visibleRectChangeRequiresFlush(const FloatRect& clipRect) const
950 {
951     TransformState state(TransformState::UnapplyInverseTransformDirection, FloatQuad(clipRect));
952     return recursiveVisibleRectChangeRequiresFlush(state);
953 }
954
955 TiledBacking* GraphicsLayerCA::tiledBacking() const
956 {
957     return m_layer->tiledBacking();
958 }
959
960 FloatRect GraphicsLayerCA::computeVisibleRect(TransformState& state, ComputeVisibleRectFlags flags) const
961 {
962     bool preserve3D = preserves3D() || (parent() ? parent()->preserves3D() : false);
963     TransformState::TransformAccumulation accumulation = preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform;
964
965     TransformationMatrix layerTransform;
966     FloatPoint position = m_position;
967     if (client())
968         client()->customPositionForVisibleRectComputation(this, position);
969
970     layerTransform.translate(position.x(), position.y());
971
972     TransformationMatrix currentTransform;
973     if (!(flags & RespectAnimatingTransforms) || !client() || !client()->getCurrentTransform(this, currentTransform))
974         currentTransform = m_transform;
975     
976     if (!currentTransform.isIdentity()) {
977         FloatPoint3D absoluteAnchorPoint(anchorPoint());
978         absoluteAnchorPoint.scale(size().width(), size().height(), 1);
979         layerTransform.translate3d(absoluteAnchorPoint.x(), absoluteAnchorPoint.y(), absoluteAnchorPoint.z());
980         layerTransform.multiply(currentTransform);
981         layerTransform.translate3d(-absoluteAnchorPoint.x(), -absoluteAnchorPoint.y(), -absoluteAnchorPoint.z());
982     }
983
984     if (GraphicsLayer* parentLayer = parent()) {
985         if (!parentLayer->childrenTransform().isIdentity()) {
986             FloatPoint3D parentAnchorPoint(parentLayer->anchorPoint());
987             parentAnchorPoint.scale(parentLayer->size().width(), parentLayer->size().height(), 1);
988
989             layerTransform.translateRight3d(-parentAnchorPoint.x(), -parentAnchorPoint.y(), -parentAnchorPoint.z());
990             layerTransform = parentLayer->childrenTransform() * layerTransform;
991             layerTransform.translateRight3d(parentAnchorPoint.x(), parentAnchorPoint.y(), parentAnchorPoint.z());
992         }
993     }
994
995     bool applyWasClamped;
996     state.applyTransform(layerTransform, accumulation, &applyWasClamped);
997     
998     bool mapWasClamped;
999     FloatRect clipRectForChildren = state.mappedQuad(&mapWasClamped).boundingBox();
1000     FloatPoint boundsOrigin = m_boundsOrigin;
1001     clipRectForChildren.move(boundsOrigin.x(), boundsOrigin.y());
1002     
1003     FloatRect clipRectForSelf(boundsOrigin, m_size);
1004     if (!applyWasClamped && !mapWasClamped)
1005         clipRectForSelf.intersect(clipRectForChildren);
1006     
1007     if (masksToBounds()) {
1008         ASSERT(accumulation == TransformState::FlattenTransform);
1009         // Replace the quad in the TransformState with one that is clipped to this layer's bounds
1010         state.setQuad(clipRectForSelf);
1011     }
1012
1013     return clipRectForSelf;
1014 }
1015
1016 void GraphicsLayerCA::recursiveCommitChanges(const CommitState& commitState, const TransformState& state, float pageScaleFactor, const FloatPoint& positionRelativeToBase, bool affectedByPageScale)
1017 {
1018     TransformState localState = state;
1019     CommitState childCommitState = commitState;
1020     bool affectedByTransformAnimation = commitState.ancestorHasTransformAnimation;
1021     
1022     FloatRect visibleRect = computeVisibleRect(localState);
1023     FloatRect oldVisibleRect = m_visibleRect;
1024     if (visibleRect != m_visibleRect) {
1025         m_uncommittedChanges |= VisibleRectChanged;
1026         m_visibleRect = visibleRect;
1027     }
1028
1029 #ifdef VISIBLE_TILE_WASH
1030     // Use having a transform as a key to making the tile wash layer. If every layer gets a wash,
1031     // they start to obscure useful information.
1032     if ((!m_transform.isIdentity() || m_usingTiledBacking) && !m_visibleTileWashLayer) {
1033         static Color washFillColor(255, 0, 0, 50);
1034         static Color washBorderColor(255, 0, 0, 100);
1035         
1036         m_visibleTileWashLayer = PlatformCALayer::create(PlatformCALayer::LayerTypeLayer, this);
1037         String name = String::format("Visible Tile Wash Layer %p", m_visibleTileWashLayer->platformLayer());
1038         m_visibleTileWashLayer->setName(name);
1039         m_visibleTileWashLayer->setAnchorPoint(FloatPoint3D(0, 0, 0));
1040         m_visibleTileWashLayer->setBorderColor(washBorderColor);
1041         m_visibleTileWashLayer->setBorderWidth(8);
1042         m_visibleTileWashLayer->setBackgroundColor(washFillColor);
1043         noteSublayersChanged();
1044     }
1045
1046     if (m_visibleTileWashLayer)
1047         m_visibleTileWashLayer->setFrame(m_visibleRect);
1048 #endif
1049
1050     bool hadChanges = m_uncommittedChanges;
1051     
1052     if (appliesPageScale()) {
1053         pageScaleFactor = this->pageScaleFactor();
1054         affectedByPageScale = true;
1055     }
1056
1057     // Accumulate an offset from the ancestral pixel-aligned layer.
1058     FloatPoint baseRelativePosition = positionRelativeToBase;
1059     if (affectedByPageScale)
1060         baseRelativePosition += m_position;
1061     
1062     commitLayerChangesBeforeSublayers(pageScaleFactor, baseRelativePosition, oldVisibleRect);
1063
1064     if (isRunningTransformAnimation()) {
1065         childCommitState.ancestorHasTransformAnimation = true;
1066         affectedByTransformAnimation = true;
1067     }
1068
1069     if (m_maskLayer) {
1070         GraphicsLayerCA* maskLayerCA = static_cast<GraphicsLayerCA*>(m_maskLayer);
1071         maskLayerCA->commitLayerChangesBeforeSublayers(pageScaleFactor, baseRelativePosition, maskLayerCA->visibleRect());
1072     }
1073
1074     const Vector<GraphicsLayer*>& childLayers = children();
1075     size_t numChildren = childLayers.size();
1076     
1077     for (size_t i = 0; i < numChildren; ++i) {
1078         GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
1079         curChild->recursiveCommitChanges(childCommitState, localState, pageScaleFactor, baseRelativePosition, affectedByPageScale);
1080     }
1081
1082     if (m_replicaLayer)
1083         static_cast<GraphicsLayerCA*>(m_replicaLayer)->recursiveCommitChanges(childCommitState, localState, pageScaleFactor, baseRelativePosition, affectedByPageScale);
1084
1085     if (m_maskLayer)
1086         static_cast<GraphicsLayerCA*>(m_maskLayer)->commitLayerChangesAfterSublayers();
1087
1088     commitLayerChangesAfterSublayers();
1089
1090     if (affectedByTransformAnimation && client() && m_layer->layerType() == PlatformCALayer::LayerTypeTiledBackingLayer)
1091         client()->notifyFlushBeforeDisplayRefresh(this);
1092
1093     if (hadChanges && client())
1094         client()->didCommitChangesForLayer(this);
1095 }
1096
1097 bool GraphicsLayerCA::platformCALayerShowRepaintCounter(PlatformCALayer* platformLayer) const
1098 {
1099     // The repaint counters are painted into the TileController tiles (which have no corresponding platform layer),
1100     // so we don't want to overpaint the repaint counter when called with the TileController's own layer.
1101     if (m_isPageTiledBackingLayer && platformLayer)
1102         return false;
1103     
1104     return isShowingRepaintCounter();
1105 }
1106
1107 void GraphicsLayerCA::platformCALayerPaintContents(GraphicsContext& context, const IntRect& clip)
1108 {
1109     paintGraphicsLayerContents(context, clip);
1110 }
1111
1112 void GraphicsLayerCA::platformCALayerDidCreateTiles(const Vector<FloatRect>& dirtyRects)
1113 {
1114     ASSERT(m_layer->usesTiledBackingLayer());
1115
1116     for (size_t i = 0; i < dirtyRects.size(); ++i)
1117         setNeedsDisplayInRect(dirtyRects[i]);
1118
1119     noteLayerPropertyChanged(TilesAdded);
1120 }
1121
1122 float GraphicsLayerCA::platformCALayerDeviceScaleFactor()
1123 {
1124     return deviceScaleFactor();
1125 }
1126
1127 void GraphicsLayerCA::commitLayerChangesBeforeSublayers(float pageScaleFactor, const FloatPoint& positionRelativeToBase, const FloatRect& oldVisibleRect)
1128 {
1129     if (!m_uncommittedChanges)
1130         return;
1131
1132     bool needTiledLayer = requiresTiledLayer(pageScaleFactor);
1133     if (needTiledLayer != m_usingTiledBacking)
1134         swapFromOrToTiledLayer(needTiledLayer);
1135
1136     // Need to handle Preserves3DChanged first, because it affects which layers subsequent properties are applied to
1137     if (m_uncommittedChanges & (Preserves3DChanged | ReplicatedLayerChanged))
1138         updateStructuralLayer();
1139
1140     if (m_uncommittedChanges & GeometryChanged)
1141         updateGeometry(pageScaleFactor, positionRelativeToBase);
1142
1143     if (m_uncommittedChanges & DrawsContentChanged)
1144         updateLayerDrawsContent();
1145
1146     if (m_uncommittedChanges & NameChanged)
1147         updateLayerNames();
1148
1149     if (m_uncommittedChanges & ContentsImageChanged) // Needs to happen before ChildrenChanged
1150         updateContentsImage();
1151         
1152     if (m_uncommittedChanges & ContentsMediaLayerChanged) // Needs to happen before ChildrenChanged
1153         updateContentsMediaLayer();
1154     
1155     if (m_uncommittedChanges & ContentsCanvasLayerChanged) // Needs to happen before ChildrenChanged
1156         updateContentsCanvasLayer();
1157
1158     if (m_uncommittedChanges & ContentsColorLayerChanged) // Needs to happen before ChildrenChanged
1159         updateContentsColorLayer();
1160     
1161     if (m_uncommittedChanges & BackgroundColorChanged)
1162         updateBackgroundColor();
1163
1164     if (m_uncommittedChanges & TransformChanged)
1165         updateTransform();
1166
1167     if (m_uncommittedChanges & ChildrenTransformChanged)
1168         updateChildrenTransform();
1169     
1170     if (m_uncommittedChanges & MasksToBoundsChanged)
1171         updateMasksToBounds();
1172     
1173     if (m_uncommittedChanges & ContentsVisibilityChanged)
1174         updateContentsVisibility();
1175
1176     if (m_uncommittedChanges & ContentsOpaqueChanged)
1177         updateContentsOpaque();
1178
1179     if (m_uncommittedChanges & BackfaceVisibilityChanged)
1180         updateBackfaceVisibility();
1181
1182     if (m_uncommittedChanges & OpacityChanged)
1183         updateOpacityOnLayer();
1184     
1185 #if ENABLE(CSS_FILTERS)
1186     if (m_uncommittedChanges & FiltersChanged)
1187         updateFilters();
1188 #endif
1189     
1190     if (m_uncommittedChanges & AnimationChanged)
1191         updateAnimations();
1192
1193     // Updating the contents scale can cause parts of the layer to be invalidated,
1194     // so make sure to update the contents scale before updating the dirty rects.
1195     if (m_uncommittedChanges & ContentsScaleChanged)
1196         updateContentsScale(pageScaleFactor);
1197
1198     if (m_uncommittedChanges & VisibleRectChanged)
1199         updateVisibleRect(oldVisibleRect);
1200
1201     if (m_uncommittedChanges & DirtyRectsChanged)
1202         repaintLayerDirtyRects();
1203     
1204     if (m_uncommittedChanges & ContentsRectChanged)
1205         updateContentsRect();
1206
1207     if (m_uncommittedChanges & MaskLayerChanged)
1208         updateMaskLayer();
1209
1210     if (m_uncommittedChanges & ContentsNeedsDisplay)
1211         updateContentsNeedsDisplay();
1212     
1213     if (m_uncommittedChanges & AcceleratesDrawingChanged)
1214         updateAcceleratesDrawing();
1215
1216     if (m_uncommittedChanges & DebugIndicatorsChanged)
1217         updateDebugBorder();
1218
1219     if (m_uncommittedChanges & ChildrenChanged) {
1220         updateSublayerList();
1221         // Sublayers may set this flag again, so clear it to avoid always updating sublayers in commitLayerChangesAfterSublayers().
1222         m_uncommittedChanges &= ~ChildrenChanged;
1223     }
1224 }
1225
1226 void GraphicsLayerCA::commitLayerChangesAfterSublayers()
1227 {
1228     if (!m_uncommittedChanges)
1229         return;
1230
1231     if (m_uncommittedChanges & ChildrenChanged)
1232         updateSublayerList();
1233
1234     if (m_uncommittedChanges & ReplicatedLayerChanged)
1235         updateReplicatedLayers();
1236
1237     m_uncommittedChanges = NoChange;
1238 }
1239
1240 void GraphicsLayerCA::updateLayerNames()
1241 {
1242     switch (structuralLayerPurpose()) {
1243     case StructuralLayerForPreserves3D:
1244         m_structuralLayer->setName("Transform layer " + name());
1245         break;
1246     case StructuralLayerForReplicaFlattening:
1247         m_structuralLayer->setName("Replica flattening layer " + name());
1248         break;
1249     case NoStructuralLayer:
1250         break;
1251     }
1252     m_layer->setName(name());
1253 }
1254
1255 void GraphicsLayerCA::updateSublayerList()
1256 {
1257     const PlatformCALayerList* customSublayers = m_layer->customSublayers();
1258
1259     PlatformCALayerList structuralLayerChildren;
1260     PlatformCALayerList primaryLayerChildren;
1261
1262     PlatformCALayerList& childListForSublayers = m_structuralLayer ? structuralLayerChildren : primaryLayerChildren;
1263
1264     if (customSublayers)
1265         primaryLayerChildren.append(*customSublayers);
1266
1267     if (m_structuralLayer) {
1268         if (m_replicaLayer)
1269             structuralLayerChildren.append(static_cast<GraphicsLayerCA*>(m_replicaLayer)->primaryLayer());
1270     
1271         structuralLayerChildren.append(m_layer);
1272     }
1273
1274     if (m_contentsLayer && m_contentsVisible) {
1275         // FIXME: add the contents layer in the correct order with negative z-order children.
1276         // This does not cause visible rendering issues because currently contents layers are only used
1277         // for replaced elements that don't have children.
1278         primaryLayerChildren.append(m_contentsLayer);
1279     }
1280     
1281     const Vector<GraphicsLayer*>& childLayers = children();
1282     size_t numChildren = childLayers.size();
1283     for (size_t i = 0; i < numChildren; ++i) {
1284         GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
1285         PlatformCALayer* childLayer = curChild->layerForSuperlayer();
1286         childListForSublayers.append(childLayer);
1287     }
1288
1289 #ifdef VISIBLE_TILE_WASH
1290     if (m_visibleTileWashLayer)
1291         childListForSublayers.append(m_visibleTileWashLayer);
1292 #endif
1293
1294     if (m_structuralLayer)
1295         m_structuralLayer->setSublayers(structuralLayerChildren);
1296     
1297     m_layer->setSublayers(primaryLayerChildren);
1298 }
1299
1300 void GraphicsLayerCA::updateGeometry(float pageScaleFactor, const FloatPoint& positionRelativeToBase)
1301 {
1302     FloatPoint scaledPosition;
1303     FloatPoint3D scaledAnchorPoint;
1304     FloatSize scaledSize;
1305     FloatSize pixelAlignmentOffset;
1306     computePixelAlignment(pageScaleFactor, positionRelativeToBase, scaledPosition, scaledSize, scaledAnchorPoint, pixelAlignmentOffset);
1307
1308     FloatSize usedSize = m_usingTiledBacking ? constrainedSize() : scaledSize;
1309     FloatRect adjustedBounds(m_boundsOrigin - pixelAlignmentOffset, usedSize);
1310
1311     // Update position.
1312     // Position is offset on the layer by the layer anchor point.
1313     FloatPoint adjustedPosition(scaledPosition.x() + scaledAnchorPoint.x() * usedSize.width(), scaledPosition.y() + scaledAnchorPoint.y() * usedSize.height());
1314
1315     if (m_structuralLayer) {
1316         FloatPoint layerPosition(m_position.x() + m_anchorPoint.x() * m_size.width(), m_position.y() + m_anchorPoint.y() * m_size.height());
1317         FloatRect layerBounds(m_boundsOrigin, m_size);
1318         
1319         m_structuralLayer->setPosition(layerPosition);
1320         m_structuralLayer->setBounds(layerBounds);
1321         m_structuralLayer->setAnchorPoint(m_anchorPoint);
1322
1323         if (LayerMap* layerCloneMap = m_structuralLayerClones.get()) {
1324             LayerMap::const_iterator end = layerCloneMap->end();
1325             for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1326                 PlatformCALayer* clone = it->value.get();
1327                 FloatPoint clonePosition = layerPosition;
1328
1329                 if (m_replicaLayer && isReplicatedRootClone(it->key)) {
1330                     // Maintain the special-case position for the root of a clone subtree,
1331                     // which we set up in replicatedLayerRoot().
1332                     clonePosition = positionForCloneRootLayer();
1333                 }
1334
1335                 clone->setPosition(clonePosition);
1336                 clone->setBounds(layerBounds);
1337                 clone->setAnchorPoint(m_anchorPoint);
1338             }
1339         }
1340
1341         // If we have a structural layer, we just use 0.5, 0.5 for the anchor point of the main layer.
1342         scaledAnchorPoint = FloatPoint(0.5f, 0.5f);
1343         adjustedPosition = FloatPoint(scaledAnchorPoint.x() * usedSize.width() - pixelAlignmentOffset.width(), scaledAnchorPoint.y() * usedSize.height() - pixelAlignmentOffset.height());
1344     }
1345     
1346     m_layer->setPosition(adjustedPosition);
1347     m_layer->setBounds(adjustedBounds);
1348     m_layer->setAnchorPoint(scaledAnchorPoint);
1349
1350     if (LayerMap* layerCloneMap = m_layerClones.get()) {
1351         LayerMap::const_iterator end = layerCloneMap->end();
1352         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1353             PlatformCALayer* clone = it->value.get();
1354             FloatPoint clonePosition = adjustedPosition;
1355
1356             if (!m_structuralLayer && m_replicaLayer && isReplicatedRootClone(it->key)) {
1357                 // Maintain the special-case position for the root of a clone subtree,
1358                 // which we set up in replicatedLayerRoot().
1359                 clonePosition = positionForCloneRootLayer();
1360             }
1361
1362             clone->setPosition(clonePosition);
1363             clone->setBounds(adjustedBounds);
1364             clone->setAnchorPoint(scaledAnchorPoint);
1365         }
1366     }
1367 }
1368
1369 void GraphicsLayerCA::updateTransform()
1370 {
1371     primaryLayer()->setTransform(m_transform);
1372
1373     if (LayerMap* layerCloneMap = primaryLayerClones()) {
1374         LayerMap::const_iterator end = layerCloneMap->end();
1375         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1376             PlatformCALayer* currLayer = it->value.get();
1377             if (m_replicaLayer && isReplicatedRootClone(it->key)) {
1378                 // Maintain the special-case transform for the root of a clone subtree,
1379                 // which we set up in replicatedLayerRoot().
1380                 currLayer->setTransform(TransformationMatrix());
1381             } else
1382                 currLayer->setTransform(m_transform);
1383         }
1384     }
1385 }
1386
1387 void GraphicsLayerCA::updateChildrenTransform()
1388 {
1389     primaryLayer()->setSublayerTransform(m_childrenTransform);
1390
1391     if (LayerMap* layerCloneMap = primaryLayerClones()) {
1392         LayerMap::const_iterator end = layerCloneMap->end();
1393         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
1394             it->value->setSublayerTransform(m_childrenTransform);
1395     }
1396 }
1397
1398 void GraphicsLayerCA::updateMasksToBounds()
1399 {
1400     m_layer->setMasksToBounds(m_masksToBounds);
1401
1402     if (LayerMap* layerCloneMap = m_layerClones.get()) {
1403         LayerMap::const_iterator end = layerCloneMap->end();
1404         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
1405             it->value->setMasksToBounds(m_masksToBounds);
1406     }
1407 }
1408
1409 void GraphicsLayerCA::updateContentsVisibility()
1410 {
1411     // Note that m_contentsVisible also affects whether m_contentsLayer is parented.
1412     if (m_contentsVisible) {
1413         if (m_drawsContent)
1414             m_layer->setNeedsDisplay();
1415     } else {
1416         m_layer->setContents(0);
1417
1418         if (LayerMap* layerCloneMap = m_layerClones.get()) {
1419             LayerMap::const_iterator end = layerCloneMap->end();
1420             for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
1421                 it->value->setContents(0);
1422         }
1423     }
1424 }
1425
1426 void GraphicsLayerCA::updateContentsOpaque()
1427 {
1428     m_layer->setOpaque(m_contentsOpaque);
1429
1430     if (LayerMap* layerCloneMap = m_layerClones.get()) {
1431         LayerMap::const_iterator end = layerCloneMap->end();
1432         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
1433             it->value->setOpaque(m_contentsOpaque);
1434     }
1435 }
1436
1437 void GraphicsLayerCA::updateBackfaceVisibility()
1438 {
1439     if (m_structuralLayer && structuralLayerPurpose() == StructuralLayerForReplicaFlattening) {
1440         m_structuralLayer->setDoubleSided(m_backfaceVisibility);
1441
1442         if (LayerMap* layerCloneMap = m_structuralLayerClones.get()) {
1443             LayerMap::const_iterator end = layerCloneMap->end();
1444             for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
1445                 it->value->setDoubleSided(m_backfaceVisibility);
1446         }
1447     }
1448
1449     m_layer->setDoubleSided(m_backfaceVisibility);
1450
1451     if (LayerMap* layerCloneMap = m_layerClones.get()) {
1452         LayerMap::const_iterator end = layerCloneMap->end();
1453         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
1454             it->value->setDoubleSided(m_backfaceVisibility);
1455     }
1456 }
1457
1458 #if ENABLE(CSS_FILTERS)
1459 void GraphicsLayerCA::updateFilters()
1460 {
1461     m_layer->setFilters(m_filters);
1462
1463     if (LayerMap* layerCloneMap = m_layerClones.get()) {
1464         LayerMap::const_iterator end = layerCloneMap->end();
1465         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1466             if (m_replicaLayer && isReplicatedRootClone(it->key))
1467                 continue;
1468
1469             it->value->setFilters(m_filters);
1470         }
1471     }
1472 }
1473 #endif
1474
1475 void GraphicsLayerCA::updateStructuralLayer()
1476 {
1477     ensureStructuralLayer(structuralLayerPurpose());
1478 }
1479
1480 void GraphicsLayerCA::ensureStructuralLayer(StructuralLayerPurpose purpose)
1481 {
1482     const LayerChangeFlags structuralLayerChangeFlags = NameChanged
1483         | GeometryChanged
1484         | TransformChanged
1485         | ChildrenTransformChanged
1486         | ChildrenChanged
1487         | BackfaceVisibilityChanged
1488 #if ENABLE(CSS_FILTERS)
1489         | FiltersChanged
1490 #endif
1491         | OpacityChanged;
1492
1493     if (purpose == NoStructuralLayer) {
1494         if (m_structuralLayer) {
1495             // Replace the transformLayer in the parent with this layer.
1496             m_layer->removeFromSuperlayer();
1497  
1498             // If m_layer doesn't have a parent, it means it's the root layer and
1499             // is likely hosted by something that is not expecting to be changed
1500             ASSERT(m_structuralLayer->superlayer());
1501             m_structuralLayer->superlayer()->replaceSublayer(m_structuralLayer.get(), m_layer.get());
1502
1503             moveOrCopyAnimations(Move, m_structuralLayer.get(), m_layer.get());
1504
1505             // Release the structural layer.
1506             m_structuralLayer = 0;
1507
1508             m_uncommittedChanges |= structuralLayerChangeFlags;
1509         }
1510         return;
1511     }
1512     
1513     bool structuralLayerChanged = false;
1514     
1515     if (purpose == StructuralLayerForPreserves3D) {
1516         if (m_structuralLayer && m_structuralLayer->layerType() != PlatformCALayer::LayerTypeTransformLayer)
1517             m_structuralLayer = 0;
1518         
1519         if (!m_structuralLayer) {
1520             m_structuralLayer = PlatformCALayer::create(PlatformCALayer::LayerTypeTransformLayer, this);
1521             structuralLayerChanged = true;
1522         }
1523     } else {
1524         if (m_structuralLayer && m_structuralLayer->layerType() != PlatformCALayer::LayerTypeLayer)
1525             m_structuralLayer = 0;
1526
1527         if (!m_structuralLayer) {
1528             m_structuralLayer = PlatformCALayer::create(PlatformCALayer::LayerTypeLayer, this);
1529             structuralLayerChanged = true;
1530         }
1531     }
1532     
1533     if (!structuralLayerChanged)
1534         return;
1535     
1536     m_uncommittedChanges |= structuralLayerChangeFlags;
1537
1538     // We've changed the layer that our parent added to its sublayer list, so tell it to update
1539     // sublayers again in its commitLayerChangesAfterSublayers().
1540     static_cast<GraphicsLayerCA*>(parent())->noteSublayersChanged();
1541
1542     // Set properties of m_layer to their default values, since these are expressed on on the structural layer.
1543     FloatPoint point(m_size.width() / 2.0f, m_size.height() / 2.0f);
1544     FloatPoint3D anchorPoint(0.5f, 0.5f, 0);
1545     m_layer->setPosition(point);
1546     m_layer->setAnchorPoint(anchorPoint);
1547     m_layer->setTransform(TransformationMatrix());
1548     m_layer->setOpacity(1);
1549     if (m_layerClones) {
1550         LayerMap::const_iterator end = m_layerClones->end();
1551         for (LayerMap::const_iterator it = m_layerClones->begin(); it != end; ++it) {
1552             PlatformCALayer* currLayer = it->value.get();
1553             currLayer->setPosition(point);
1554             currLayer->setAnchorPoint(anchorPoint);
1555             currLayer->setTransform(TransformationMatrix());
1556             currLayer->setOpacity(1);
1557         }
1558     }
1559
1560     moveOrCopyAnimations(Move, m_layer.get(), m_structuralLayer.get());
1561 }
1562
1563 GraphicsLayerCA::StructuralLayerPurpose GraphicsLayerCA::structuralLayerPurpose() const
1564 {
1565     if (preserves3D())
1566         return StructuralLayerForPreserves3D;
1567     
1568     if (isReplicated())
1569         return StructuralLayerForReplicaFlattening;
1570     
1571     return NoStructuralLayer;
1572 }
1573
1574 void GraphicsLayerCA::updateLayerDrawsContent()
1575 {
1576     if (m_drawsContent)
1577         m_layer->setNeedsDisplay();
1578     else {
1579         m_layer->setContents(0);
1580         if (m_layerClones) {
1581             LayerMap::const_iterator end = m_layerClones->end();
1582             for (LayerMap::const_iterator it = m_layerClones->begin(); it != end; ++it)
1583                 it->value->setContents(0);
1584         }
1585     }
1586 }
1587
1588 void GraphicsLayerCA::updateAcceleratesDrawing()
1589 {
1590     m_layer->setAcceleratesDrawing(m_acceleratesDrawing);
1591 }
1592
1593 void GraphicsLayerCA::updateDebugBorder()
1594 {
1595     if (isShowingDebugBorder())
1596         updateDebugIndicators();
1597     else
1598         m_layer->setBorderWidth(0);
1599 }
1600
1601 FloatRect GraphicsLayerCA::adjustTiledLayerVisibleRect(TiledBacking* tiledBacking, const FloatRect& oldVisibleRect, const FloatRect& newVisibleRect, const FloatSize& oldSize, const FloatSize& newSize)
1602 {
1603     // If the old visible rect is empty, we have no information about how the visible area is changing
1604     // (maybe the layer was just created), so don't attempt to expand. Also don't attempt to expand
1605     // if the size changed.
1606     if (oldVisibleRect.isEmpty() || newSize != oldSize)
1607         return newVisibleRect;
1608
1609     const float paddingMultiplier = 2;
1610
1611     float leftEdgeDelta = paddingMultiplier * (newVisibleRect.x() - oldVisibleRect.x());
1612     float rightEdgeDelta = paddingMultiplier * (newVisibleRect.maxX() - oldVisibleRect.maxX());
1613
1614     float topEdgeDelta = paddingMultiplier * (newVisibleRect.y() - oldVisibleRect.y());
1615     float bottomEdgeDelta = paddingMultiplier * (newVisibleRect.maxY() - oldVisibleRect.maxY());
1616     
1617     FloatRect existingTileBackingRect = tiledBacking->visibleRect();
1618     FloatRect expandedRect = newVisibleRect;
1619
1620     // More exposed on left side.
1621     if (leftEdgeDelta < 0) {
1622         float newLeft = expandedRect.x() + leftEdgeDelta;
1623         // Pad to the left, but don't reduce padding that's already in the backing store (since we're still exposing to the left).
1624         if (newLeft < existingTileBackingRect.x())
1625             expandedRect.shiftXEdgeTo(newLeft);
1626         else
1627             expandedRect.shiftXEdgeTo(existingTileBackingRect.x());
1628     }
1629
1630     // More exposed on right.
1631     if (rightEdgeDelta > 0) {
1632         float newRight = expandedRect.maxX() + rightEdgeDelta;
1633         // Pad to the right, but don't reduce padding that's already in the backing store (since we're still exposing to the right).
1634         if (newRight > existingTileBackingRect.maxX())
1635             expandedRect.setWidth(newRight - expandedRect.x());
1636         else
1637             expandedRect.setWidth(existingTileBackingRect.maxX() - expandedRect.x());
1638     }
1639
1640     // More exposed at top.
1641     if (topEdgeDelta < 0) {
1642         float newTop = expandedRect.y() + topEdgeDelta;
1643         if (newTop < existingTileBackingRect.y())
1644             expandedRect.shiftYEdgeTo(newTop);
1645         else
1646             expandedRect.shiftYEdgeTo(existingTileBackingRect.y());
1647     }
1648
1649     // More exposed on bottom.
1650     if (bottomEdgeDelta > 0) {
1651         float newBottom = expandedRect.maxY() + bottomEdgeDelta;
1652         if (newBottom > existingTileBackingRect.maxY())
1653             expandedRect.setHeight(newBottom - expandedRect.y());
1654         else
1655             expandedRect.setHeight(existingTileBackingRect.maxY() - expandedRect.y());
1656     }
1657     
1658     return expandedRect;
1659 }
1660
1661 void GraphicsLayerCA::updateVisibleRect(const FloatRect& oldVisibleRect)
1662 {
1663     if (!m_layer->usesTiledBackingLayer())
1664         return;
1665
1666     FloatRect tileArea = m_visibleRect;
1667     if (m_layer->layerType() == PlatformCALayer::LayerTypeTiledBackingLayer)
1668         tileArea = adjustTiledLayerVisibleRect(tiledBacking(), oldVisibleRect, tileArea, m_sizeAtLastVisibleRectUpdate, m_size);
1669
1670     tiledBacking()->setVisibleRect(tileArea);
1671
1672     m_sizeAtLastVisibleRectUpdate = m_size;
1673 }
1674
1675 void GraphicsLayerCA::updateBackgroundColor()
1676 {
1677     m_layer->setBackgroundColor(m_backgroundColor);
1678 }
1679
1680 void GraphicsLayerCA::updateContentsImage()
1681 {
1682     if (m_pendingContentsImage) {
1683         if (!m_contentsLayer.get()) {
1684             m_contentsLayer = PlatformCALayer::create(PlatformCALayer::LayerTypeLayer, this);
1685 #ifndef NDEBUG
1686             m_contentsLayer->setName("Image Layer");
1687 #endif
1688             setupContentsLayer(m_contentsLayer.get());
1689             // m_contentsLayer will be parented by updateSublayerList
1690         }
1691
1692         // FIXME: maybe only do trilinear if the image is being scaled down,
1693         // but then what if the layer size changes?
1694         m_contentsLayer->setMinificationFilter(PlatformCALayer::Trilinear);
1695         m_contentsLayer->setContents(m_pendingContentsImage.get());
1696         m_pendingContentsImage = 0;
1697
1698         if (m_contentsLayerClones) {
1699             LayerMap::const_iterator end = m_contentsLayerClones->end();
1700             for (LayerMap::const_iterator it = m_contentsLayerClones->begin(); it != end; ++it)
1701                 it->value->setContents(m_contentsLayer->contents());
1702         }
1703         
1704         updateContentsRect();
1705     } else {
1706         // No image.
1707         // m_contentsLayer will be removed via updateSublayerList.
1708         m_contentsLayer = 0;
1709     }
1710 }
1711
1712 void GraphicsLayerCA::updateContentsMediaLayer()
1713 {
1714     // Video layer was set as m_contentsLayer, and will get parented in updateSublayerList().
1715     if (m_contentsLayer) {
1716         setupContentsLayer(m_contentsLayer.get());
1717         updateContentsRect();
1718     }
1719 }
1720
1721 void GraphicsLayerCA::updateContentsCanvasLayer()
1722 {
1723     // CanvasLayer was set as m_contentsLayer, and will get parented in updateSublayerList().
1724     if (m_contentsLayer) {
1725         setupContentsLayer(m_contentsLayer.get());
1726         m_contentsLayer->setNeedsDisplay();
1727         updateContentsRect();
1728     }
1729 }
1730
1731 void GraphicsLayerCA::updateContentsColorLayer()
1732 {
1733     // Color layer was set as m_contentsLayer, and will get parented in updateSublayerList().
1734     if (m_contentsLayer) {
1735         setupContentsLayer(m_contentsLayer.get());
1736         updateContentsRect();
1737         ASSERT(m_contentsSolidColor.isValid()); // An invalid color should have removed the contents layer.
1738         m_contentsLayer->setBackgroundColor(m_contentsSolidColor);
1739
1740         if (m_contentsLayerClones) {
1741             LayerMap::const_iterator end = m_contentsLayerClones->end();
1742             for (LayerMap::const_iterator it = m_contentsLayerClones->begin(); it != end; ++it)
1743                 it->value->setBackgroundColor(m_contentsSolidColor);
1744         }
1745     }
1746 }
1747
1748 void GraphicsLayerCA::updateContentsRect()
1749 {
1750     if (!m_contentsLayer)
1751         return;
1752
1753     FloatPoint point(m_contentsRect.x(), m_contentsRect.y());
1754     FloatRect rect(0, 0, m_contentsRect.width(), m_contentsRect.height());
1755
1756     m_contentsLayer->setPosition(point);
1757     m_contentsLayer->setBounds(rect);
1758
1759     if (m_contentsLayerClones) {
1760         LayerMap::const_iterator end = m_contentsLayerClones->end();
1761         for (LayerMap::const_iterator it = m_contentsLayerClones->begin(); it != end; ++it) {
1762             it->value->setPosition(point);
1763             it->value->setBounds(rect);
1764         }
1765     }
1766 }
1767
1768 void GraphicsLayerCA::updateMaskLayer()
1769 {
1770     PlatformCALayer* maskCALayer = m_maskLayer ? static_cast<GraphicsLayerCA*>(m_maskLayer)->primaryLayer() : 0;
1771     m_layer->setMask(maskCALayer);
1772
1773     LayerMap* maskLayerCloneMap = m_maskLayer ? static_cast<GraphicsLayerCA*>(m_maskLayer)->primaryLayerClones() : 0;
1774     
1775     if (LayerMap* layerCloneMap = m_layerClones.get()) {
1776         LayerMap::const_iterator end = layerCloneMap->end();
1777         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {            
1778             PlatformCALayer* maskClone = maskLayerCloneMap ? maskLayerCloneMap->get(it->key).get() : 0;
1779             it->value->setMask(maskClone);
1780         }
1781     }
1782 }
1783
1784 void GraphicsLayerCA::updateReplicatedLayers()
1785 {
1786     // Clone the descendants of the replicated layer, and parent under us.
1787     ReplicaState replicaState(ReplicaState::ReplicaBranch);
1788
1789     RefPtr<PlatformCALayer>replicaRoot = replicatedLayerRoot(replicaState);
1790     if (!replicaRoot)
1791         return;
1792
1793     if (m_structuralLayer)
1794         m_structuralLayer->insertSublayer(replicaRoot.get(), 0);
1795     else
1796         m_layer->insertSublayer(replicaRoot.get(), 0);
1797 }
1798
1799 // For now, this assumes that layers only ever have one replica, so replicaIndices contains only 0 and 1.
1800 GraphicsLayerCA::CloneID GraphicsLayerCA::ReplicaState::cloneID() const
1801 {
1802     size_t depth = m_replicaBranches.size();
1803
1804     const size_t bitsPerUChar = sizeof(UChar) * 8;
1805     size_t vectorSize = (depth + bitsPerUChar - 1) / bitsPerUChar;
1806     
1807     Vector<UChar> result(vectorSize);
1808     result.fill(0);
1809
1810     // Create a string from the bit sequence which we can use to identify the clone.
1811     // Note that the string may contain embedded nulls, but that's OK.
1812     for (size_t i = 0; i < depth; ++i) {
1813         UChar& currChar = result[i / bitsPerUChar];
1814         currChar = (currChar << 1) | m_replicaBranches[i];
1815     }
1816     
1817     return String::adopt(result);
1818 }
1819
1820 PassRefPtr<PlatformCALayer> GraphicsLayerCA::replicatedLayerRoot(ReplicaState& replicaState)
1821 {
1822     // Limit replica nesting, to avoid 2^N explosion of replica layers.
1823     if (!m_replicatedLayer || replicaState.replicaDepth() == ReplicaState::maxReplicaDepth)
1824         return 0;
1825
1826     GraphicsLayerCA* replicatedLayer = static_cast<GraphicsLayerCA*>(m_replicatedLayer);
1827     
1828     RefPtr<PlatformCALayer> clonedLayerRoot = replicatedLayer->fetchCloneLayers(this, replicaState, RootCloneLevel);
1829     FloatPoint cloneRootPosition = replicatedLayer->positionForCloneRootLayer();
1830
1831     // Replica root has no offset or transform
1832     clonedLayerRoot->setPosition(cloneRootPosition);
1833     clonedLayerRoot->setTransform(TransformationMatrix());
1834
1835     return clonedLayerRoot;
1836 }
1837
1838 void GraphicsLayerCA::updateAnimations()
1839 {
1840     if (m_animationsToProcess.size()) {
1841         AnimationsToProcessMap::const_iterator end = m_animationsToProcess.end();
1842         for (AnimationsToProcessMap::const_iterator it = m_animationsToProcess.begin(); it != end; ++it) {
1843             const String& currAnimationName = it->key;
1844             AnimationsMap::iterator animationIt = m_runningAnimations.find(currAnimationName);
1845             if (animationIt == m_runningAnimations.end())
1846                 continue;
1847
1848             const AnimationProcessingAction& processingInfo = it->value;
1849             const Vector<LayerPropertyAnimation>& animations = animationIt->value;
1850             for (size_t i = 0; i < animations.size(); ++i) {
1851                 const LayerPropertyAnimation& currAnimation = animations[i];
1852                 switch (processingInfo.action) {
1853                 case Remove:
1854                     removeCAAnimationFromLayer(currAnimation.m_property, currAnimationName, currAnimation.m_index, currAnimation.m_subIndex);
1855                     break;
1856                 case Pause:
1857                     pauseCAAnimationOnLayer(currAnimation.m_property, currAnimationName, currAnimation.m_index, currAnimation.m_subIndex, processingInfo.timeOffset);
1858                     break;
1859                 }
1860             }
1861
1862             if (processingInfo.action == Remove)
1863                 m_runningAnimations.remove(currAnimationName);
1864         }
1865     
1866         m_animationsToProcess.clear();
1867     }
1868     
1869     size_t numAnimations;
1870     if ((numAnimations = m_uncomittedAnimations.size())) {
1871         for (size_t i = 0; i < numAnimations; ++i) {
1872             const LayerPropertyAnimation& pendingAnimation = m_uncomittedAnimations[i];
1873             setAnimationOnLayer(pendingAnimation.m_animation.get(), pendingAnimation.m_property, pendingAnimation.m_name, pendingAnimation.m_index, pendingAnimation.m_subIndex, pendingAnimation.m_timeOffset);
1874             
1875             AnimationsMap::iterator it = m_runningAnimations.find(pendingAnimation.m_name);
1876             if (it == m_runningAnimations.end()) {
1877                 Vector<LayerPropertyAnimation> animations;
1878                 animations.append(pendingAnimation);
1879                 m_runningAnimations.add(pendingAnimation.m_name, animations);
1880             } else {
1881                 Vector<LayerPropertyAnimation>& animations = it->value;
1882                 animations.append(pendingAnimation);
1883             }
1884         }
1885         
1886         m_uncomittedAnimations.clear();
1887     }
1888 }
1889
1890 bool GraphicsLayerCA::isRunningTransformAnimation() const
1891 {
1892     AnimationsMap::const_iterator end = m_runningAnimations.end();
1893     for (AnimationsMap::const_iterator it = m_runningAnimations.begin(); it != end; ++it) {
1894         const Vector<LayerPropertyAnimation>& propertyAnimations = it->value;
1895         size_t numAnimations = propertyAnimations.size();
1896         for (size_t i = 0; i < numAnimations; ++i) {
1897             const LayerPropertyAnimation& currAnimation = propertyAnimations[i];
1898             if (currAnimation.m_property == AnimatedPropertyWebkitTransform)
1899                 return true;
1900         }
1901     }
1902     return false;
1903 }
1904
1905 void GraphicsLayerCA::setAnimationOnLayer(PlatformCAAnimation* caAnim, AnimatedPropertyID property, const String& animationName, int index, int subIndex, double timeOffset)
1906 {
1907     PlatformCALayer* layer = animatedLayer(property);
1908     
1909     if (timeOffset)
1910         caAnim->setBeginTime(CACurrentMediaTime() - timeOffset);
1911
1912     String animationID = animationIdentifier(animationName, property, index, subIndex);
1913
1914     layer->removeAnimationForKey(animationID);
1915     layer->addAnimationForKey(animationID, caAnim);
1916
1917     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
1918         LayerMap::const_iterator end = layerCloneMap->end();
1919         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1920             // Skip immediate replicas, since they move with the original.
1921             if (m_replicaLayer && isReplicatedRootClone(it->key))
1922                 continue;
1923
1924             it->value->removeAnimationForKey(animationID);
1925             it->value->addAnimationForKey(animationID, caAnim);
1926         }
1927     }
1928 }
1929
1930 // Workaround for <rdar://problem/7311367>
1931 static void bug7311367Workaround(PlatformCALayer* transformLayer, const TransformationMatrix& transform)
1932 {
1933     if (!transformLayer)
1934         return;
1935
1936     TransformationMatrix caTransform = transform;
1937     caTransform.setM41(caTransform.m41() + 1);
1938     transformLayer->setTransform(caTransform);
1939
1940     caTransform.setM41(caTransform.m41() - 1);
1941     transformLayer->setTransform(caTransform);
1942 }
1943
1944 bool GraphicsLayerCA::removeCAAnimationFromLayer(AnimatedPropertyID property, const String& animationName, int index, int subIndex)
1945 {
1946     PlatformCALayer* layer = animatedLayer(property);
1947
1948     String animationID = animationIdentifier(animationName, property, index, subIndex);
1949
1950     if (!layer->animationForKey(animationID))
1951         return false;
1952     
1953     layer->removeAnimationForKey(animationID);
1954     bug7311367Workaround(m_structuralLayer.get(), m_transform);
1955
1956     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
1957         LayerMap::const_iterator end = layerCloneMap->end();
1958         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1959             // Skip immediate replicas, since they move with the original.
1960             if (m_replicaLayer && isReplicatedRootClone(it->key))
1961                 continue;
1962
1963             it->value->removeAnimationForKey(animationID);
1964         }
1965     }
1966     return true;
1967 }
1968
1969 void GraphicsLayerCA::pauseCAAnimationOnLayer(AnimatedPropertyID property, const String& animationName, int index, int subIndex, double timeOffset)
1970 {
1971     PlatformCALayer* layer = animatedLayer(property);
1972
1973     String animationID = animationIdentifier(animationName, property, index, subIndex);
1974
1975     RefPtr<PlatformCAAnimation> curAnim = layer->animationForKey(animationID);
1976     if (!curAnim)
1977         return;
1978
1979     // Animations on the layer are immutable, so we have to clone and modify.
1980     RefPtr<PlatformCAAnimation> newAnim = curAnim->copy();
1981
1982     newAnim->setSpeed(0);
1983     newAnim->setTimeOffset(timeOffset);
1984     
1985     layer->addAnimationForKey(animationID, newAnim.get()); // This will replace the running animation.
1986
1987     // Pause the animations on the clones too.
1988     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
1989         LayerMap::const_iterator end = layerCloneMap->end();
1990         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1991             // Skip immediate replicas, since they move with the original.
1992             if (m_replicaLayer && isReplicatedRootClone(it->key))
1993                 continue;
1994             it->value->addAnimationForKey(animationID, newAnim.get());
1995         }
1996     }
1997 }
1998
1999 void GraphicsLayerCA::repaintLayerDirtyRects()
2000 {
2001     if (!m_dirtyRects.size())
2002         return;
2003
2004     for (size_t i = 0; i < m_dirtyRects.size(); ++i)
2005         m_layer->setNeedsDisplay(&(m_dirtyRects[i]));
2006     
2007     m_dirtyRects.clear();
2008 }
2009
2010 void GraphicsLayerCA::updateContentsNeedsDisplay()
2011 {
2012     if (m_contentsLayer)
2013         m_contentsLayer->setNeedsDisplay();
2014 }
2015
2016 bool GraphicsLayerCA::createAnimationFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset)
2017 {
2018     ASSERT(valueList.property() != AnimatedPropertyWebkitTransform && (!supportsAcceleratedFilterAnimations() || valueList.property() != AnimatedPropertyWebkitFilter));
2019     
2020     bool isKeyframe = valueList.size() > 2;
2021     bool valuesOK;
2022     
2023     bool additive = false;
2024     int animationIndex = 0;
2025     
2026     RefPtr<PlatformCAAnimation> caAnimation;
2027     
2028     if (isKeyframe) {
2029         caAnimation = createKeyframeAnimation(animation, propertyIdToString(valueList.property()), additive);
2030         valuesOK = setAnimationKeyframes(valueList, animation, caAnimation.get());
2031     } else {
2032         caAnimation = createBasicAnimation(animation, propertyIdToString(valueList.property()), additive);
2033         valuesOK = setAnimationEndpoints(valueList, animation, caAnimation.get());
2034     }
2035     
2036     if (!valuesOK)
2037         return false;
2038
2039     m_uncomittedAnimations.append(LayerPropertyAnimation(caAnimation, animationName, valueList.property(), animationIndex, 0, timeOffset));
2040
2041     return true;
2042 }
2043
2044 bool GraphicsLayerCA::appendToUncommittedAnimations(const KeyframeValueList& valueList, const TransformOperations* operations, const Animation* animation, const String& animationName, const IntSize& boxSize, int animationIndex, double timeOffset, bool isMatrixAnimation)
2045 {
2046     TransformOperation::OperationType transformOp = isMatrixAnimation ? TransformOperation::MATRIX_3D : operations->operations().at(animationIndex)->getOperationType();
2047     bool additive = animationIndex > 0;
2048     bool isKeyframe = valueList.size() > 2;
2049
2050     RefPtr<PlatformCAAnimation> caAnimation;
2051     bool validMatrices = true;
2052     if (isKeyframe) {
2053         caAnimation = createKeyframeAnimation(animation, propertyIdToString(valueList.property()), additive);
2054         validMatrices = setTransformAnimationKeyframes(valueList, animation, caAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize);
2055     } else {
2056         caAnimation = createBasicAnimation(animation, propertyIdToString(valueList.property()), additive);
2057         validMatrices = setTransformAnimationEndpoints(valueList, animation, caAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize);
2058     }
2059     
2060     if (!validMatrices)
2061         return false;
2062
2063     m_uncomittedAnimations.append(LayerPropertyAnimation(caAnimation, animationName, valueList.property(), animationIndex, 0, timeOffset));
2064     return true;
2065 }
2066
2067 bool GraphicsLayerCA::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset, const IntSize& boxSize)
2068 {
2069     ASSERT(valueList.property() == AnimatedPropertyWebkitTransform);
2070
2071     bool hasBigRotation;
2072     int listIndex = validateTransformOperations(valueList, hasBigRotation);
2073     const TransformOperations* operations = (listIndex >= 0) ? static_cast<const TransformAnimationValue*>(valueList.at(listIndex))->value() : 0;
2074
2075     // We need to fall back to software animation if we don't have setValueFunction:, and
2076     // we would need to animate each incoming transform function separately. This is the
2077     // case if we have a rotation >= 180 or we have more than one transform function.
2078     if ((hasBigRotation || (operations && operations->size() > 1)) && !PlatformCAAnimation::supportsValueFunction())
2079         return false;
2080
2081     bool validMatrices = true;
2082
2083     // If function lists don't match we do a matrix animation, otherwise we do a component hardware animation.
2084     // Also, we can't do component animation unless we have valueFunction, so we need to do matrix animation
2085     // if that's not true as well.
2086     bool isMatrixAnimation = listIndex < 0 || !PlatformCAAnimation::supportsValueFunction();
2087     int numAnimations = isMatrixAnimation ? 1 : operations->size();
2088
2089     bool reverseAnimationList = true;
2090 #if !PLATFORM(IOS) && !PLATFORM(WIN) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
2091         // Old versions of Core Animation apply animations in reverse order (<rdar://problem/7095638>) so we need to flip the list.
2092         // to be non-additive. For binary compatibility, the current version of Core Animation preserves this behavior for applications linked
2093         // on or before Snow Leopard.
2094         // FIXME: This fix has not been added to QuartzCore on Windows yet (<rdar://problem/9112233>) so we expect the
2095         // reversed animation behavior
2096         static bool executableWasLinkedOnOrBeforeSnowLeopard = wkExecutableWasLinkedOnOrBeforeSnowLeopard();
2097         if (!executableWasLinkedOnOrBeforeSnowLeopard)
2098             reverseAnimationList = false;
2099 #endif
2100     if (reverseAnimationList) {
2101         for (int animationIndex = numAnimations - 1; animationIndex >= 0; --animationIndex) {
2102             if (!appendToUncommittedAnimations(valueList, operations, animation, animationName, boxSize, animationIndex, timeOffset, isMatrixAnimation)) {
2103                 validMatrices = false;
2104                 break;
2105             }
2106         }
2107     } else {
2108         for (int animationIndex = 0; animationIndex < numAnimations; ++animationIndex) {
2109             if (!appendToUncommittedAnimations(valueList, operations, animation, animationName, boxSize, animationIndex, timeOffset, isMatrixAnimation)) {
2110                 validMatrices = false;
2111                 break;
2112             }
2113         }
2114     }
2115
2116     return validMatrices;
2117 }
2118
2119 #if ENABLE(CSS_FILTERS)
2120 bool GraphicsLayerCA::appendToUncommittedAnimations(const KeyframeValueList& valueList, const FilterOperation* operation, const Animation* animation, const String& animationName, int animationIndex, double timeOffset)
2121 {
2122     bool isKeyframe = valueList.size() > 2;
2123     
2124     FilterOperation::OperationType filterOp = operation->getOperationType();
2125     int numAnimatedProperties = PlatformCAFilters::numAnimatedFilterProperties(filterOp);
2126     
2127     // Each filter might need to animate multiple properties, each with their own keyPath. The keyPath is always of the form:
2128     //
2129     //      filter.filter_<animationIndex>.<filterPropertyName>
2130     //
2131     // PlatformCAAnimation tells us how many properties each filter has and we iterate that many times and create an animation
2132     // for each. This internalFilterPropertyIndex gets passed to PlatformCAAnimation so it can properly create the property animation
2133     // values.
2134     for (int internalFilterPropertyIndex = 0; internalFilterPropertyIndex < numAnimatedProperties; ++internalFilterPropertyIndex) {
2135         bool valuesOK;
2136         RefPtr<PlatformCAAnimation> caAnimation;
2137         String keyPath = String::format("filters.filter_%d.%s", animationIndex, PlatformCAFilters::animatedFilterPropertyName(filterOp, internalFilterPropertyIndex));
2138         
2139         if (isKeyframe) {
2140             caAnimation = createKeyframeAnimation(animation, keyPath, false);
2141             valuesOK = setFilterAnimationKeyframes(valueList, animation, caAnimation.get(), animationIndex, internalFilterPropertyIndex, filterOp);
2142         } else {
2143             caAnimation = createBasicAnimation(animation, keyPath, false);
2144             valuesOK = setFilterAnimationEndpoints(valueList, animation, caAnimation.get(), animationIndex, internalFilterPropertyIndex);
2145         }
2146         
2147         ASSERT(valuesOK);
2148
2149         m_uncomittedAnimations.append(LayerPropertyAnimation(caAnimation, animationName, valueList.property(), animationIndex, internalFilterPropertyIndex, timeOffset));
2150     }
2151
2152     return true;
2153 }
2154
2155 bool GraphicsLayerCA::createFilterAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset)
2156 {
2157     ASSERT(valueList.property() == AnimatedPropertyWebkitFilter);
2158
2159     int listIndex = validateFilterOperations(valueList);
2160     if (listIndex < 0)
2161         return false;
2162         
2163     const FilterOperations* operations = static_cast<const FilterAnimationValue*>(valueList.at(listIndex))->value();
2164     // Make sure the platform layer didn't fallback to using software filter compositing instead.
2165     if (!PlatformCALayer::filtersCanBeComposited(*operations))
2166         return false;
2167
2168     int numAnimations = operations->size();
2169
2170     // FIXME: We can't currently hardware animate shadows.
2171     for (int i = 0; i < numAnimations; ++i) {
2172         if (operations->at(i)->getOperationType() == FilterOperation::DROP_SHADOW)
2173             return false;
2174     }
2175
2176     for (int animationIndex = 0; animationIndex < numAnimations; ++animationIndex) {
2177         if (!appendToUncommittedAnimations(valueList, operations->operations().at(animationIndex).get(), animation, animationName, animationIndex, timeOffset))
2178             return false;
2179     }
2180
2181     return true;
2182 }
2183 #endif
2184
2185 PassRefPtr<PlatformCAAnimation> GraphicsLayerCA::createBasicAnimation(const Animation* anim, const String& keyPath, bool additive)
2186 {
2187     RefPtr<PlatformCAAnimation> basicAnim = PlatformCAAnimation::create(PlatformCAAnimation::Basic, keyPath);
2188     setupAnimation(basicAnim.get(), anim, additive);
2189     return basicAnim;
2190 }
2191
2192 PassRefPtr<PlatformCAAnimation>GraphicsLayerCA::createKeyframeAnimation(const Animation* anim, const String& keyPath, bool additive)
2193 {
2194     RefPtr<PlatformCAAnimation> keyframeAnim = PlatformCAAnimation::create(PlatformCAAnimation::Keyframe, keyPath);
2195     setupAnimation(keyframeAnim.get(), anim, additive);
2196     return keyframeAnim;
2197 }
2198
2199 void GraphicsLayerCA::setupAnimation(PlatformCAAnimation* propertyAnim, const Animation* anim, bool additive)
2200 {
2201     double duration = anim->duration();
2202     if (duration <= 0)
2203         duration = cAnimationAlmostZeroDuration;
2204
2205     float repeatCount = anim->iterationCount();
2206     if (repeatCount == Animation::IterationCountInfinite)
2207         repeatCount = numeric_limits<float>::max();
2208     else if (anim->direction() == Animation::AnimationDirectionAlternate || anim->direction() == Animation::AnimationDirectionAlternateReverse)
2209         repeatCount /= 2;
2210
2211     PlatformCAAnimation::FillModeType fillMode = PlatformCAAnimation::NoFillMode;
2212     switch (anim->fillMode()) {
2213     case AnimationFillModeNone:
2214         fillMode = PlatformCAAnimation::Forwards; // Use "forwards" rather than "removed" because the style system will remove the animation when it is finished. This avoids a flash.
2215         break;
2216     case AnimationFillModeBackwards:
2217         fillMode = PlatformCAAnimation::Both; // Use "both" rather than "backwards" because the style system will remove the animation when it is finished. This avoids a flash.
2218         break;
2219     case AnimationFillModeForwards:
2220         fillMode = PlatformCAAnimation::Forwards;
2221         break;
2222     case AnimationFillModeBoth:
2223         fillMode = PlatformCAAnimation::Both;
2224         break;
2225     }
2226
2227     propertyAnim->setDuration(duration);
2228     propertyAnim->setRepeatCount(repeatCount);
2229     propertyAnim->setAutoreverses(anim->direction() == Animation::AnimationDirectionAlternate || anim->direction() == Animation::AnimationDirectionAlternateReverse);
2230     propertyAnim->setRemovedOnCompletion(false);
2231     propertyAnim->setAdditive(additive);
2232     propertyAnim->setFillMode(fillMode);
2233 }
2234
2235 const TimingFunction* GraphicsLayerCA::timingFunctionForAnimationValue(const AnimationValue* animValue, const Animation* anim)
2236 {
2237     if (animValue->timingFunction())
2238         return animValue->timingFunction();
2239     if (anim->isTimingFunctionSet())
2240         return anim->timingFunction().get();
2241     
2242     return CubicBezierTimingFunction::defaultTimingFunction();
2243 }
2244
2245 bool GraphicsLayerCA::setAnimationEndpoints(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* basicAnim)
2246 {
2247     bool forwards = animation->directionIsForwards();
2248
2249     unsigned fromIndex = !forwards;
2250     unsigned toIndex = forwards;
2251     
2252     switch (valueList.property()) {
2253     case AnimatedPropertyOpacity: {
2254         basicAnim->setFromValue(static_cast<const FloatAnimationValue*>(valueList.at(fromIndex))->value());
2255         basicAnim->setToValue(static_cast<const FloatAnimationValue*>(valueList.at(toIndex))->value());
2256         break;
2257     }
2258     default:
2259         ASSERT_NOT_REACHED(); // we don't animate color yet
2260         break;
2261     }
2262
2263     // This codepath is used for 2-keyframe animations, so we still need to look in the start
2264     // for a timing function. Even in the reversing animation case, the first keyframe provides the timing function.
2265     const TimingFunction* timingFunction = timingFunctionForAnimationValue(valueList.at(0), animation);
2266     if (timingFunction)
2267         basicAnim->setTimingFunction(timingFunction, !forwards);
2268
2269     return true;
2270 }
2271
2272 bool GraphicsLayerCA::setAnimationKeyframes(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* keyframeAnim)
2273 {
2274     Vector<float> keyTimes;
2275     Vector<float> values;
2276     Vector<const TimingFunction*> timingFunctions;
2277
2278     bool forwards = animation->directionIsForwards();
2279     
2280     for (unsigned i = 0; i < valueList.size(); ++i) {
2281         unsigned index = forwards ? i : (valueList.size() - i - 1);
2282         const AnimationValue* curValue = valueList.at(index);
2283         keyTimes.append(forwards ? curValue->keyTime() : (1 - curValue->keyTime()));
2284
2285         switch (valueList.property()) {
2286         case AnimatedPropertyOpacity: {
2287             const FloatAnimationValue* floatValue = static_cast<const FloatAnimationValue*>(curValue);
2288             values.append(floatValue->value());
2289             break;
2290         }
2291         default:
2292             ASSERT_NOT_REACHED(); // we don't animate color yet
2293             break;
2294         }
2295
2296         if (i < (valueList.size() - 1))
2297             timingFunctions.append(timingFunctionForAnimationValue(forwards ? curValue : valueList.at(index - 1), animation));
2298     }
2299     
2300     keyframeAnim->setKeyTimes(keyTimes);
2301     keyframeAnim->setValues(values);
2302     keyframeAnim->setTimingFunctions(timingFunctions, !forwards);
2303     
2304     return true;
2305 }
2306
2307 bool GraphicsLayerCA::setTransformAnimationEndpoints(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* basicAnim, int functionIndex, TransformOperation::OperationType transformOpType, bool isMatrixAnimation, const IntSize& boxSize)
2308 {
2309     ASSERT(valueList.size() == 2);
2310
2311     bool forwards = animation->directionIsForwards();
2312     
2313     unsigned fromIndex = !forwards;
2314     unsigned toIndex = forwards;
2315     
2316     const TransformAnimationValue* startValue = static_cast<const TransformAnimationValue*>(valueList.at(fromIndex));
2317     const TransformAnimationValue* endValue = static_cast<const TransformAnimationValue*>(valueList.at(toIndex));
2318     
2319     if (isMatrixAnimation) {
2320         TransformationMatrix fromTransform, toTransform;
2321         startValue->value()->apply(boxSize, fromTransform);
2322         endValue->value()->apply(boxSize, toTransform);
2323
2324         // If any matrix is singular, CA won't animate it correctly. So fall back to software animation
2325         if (!fromTransform.isInvertible() || !toTransform.isInvertible())
2326             return false;
2327             
2328         basicAnim->setFromValue(fromTransform);
2329         basicAnim->setToValue(toTransform);
2330     } else {
2331         if (isTransformTypeNumber(transformOpType)) {
2332             float fromValue;
2333             getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue);
2334             basicAnim->setFromValue(fromValue);
2335             
2336             float toValue;
2337             getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue);
2338             basicAnim->setToValue(toValue);
2339         } else if (isTransformTypeFloatPoint3D(transformOpType)) {
2340             FloatPoint3D fromValue;
2341             getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue);
2342             basicAnim->setFromValue(fromValue);
2343             
2344             FloatPoint3D toValue;
2345             getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue);
2346             basicAnim->setToValue(toValue);
2347         } else {
2348             TransformationMatrix fromValue;
2349             getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue);
2350             basicAnim->setFromValue(fromValue);
2351
2352             TransformationMatrix toValue;
2353             getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue);
2354             basicAnim->setToValue(toValue);
2355         }
2356     }
2357
2358     // This codepath is used for 2-keyframe animations, so we still need to look in the start
2359     // for a timing function. Even in the reversing animation case, the first keyframe provides the timing function.
2360     const TimingFunction* timingFunction = timingFunctionForAnimationValue(valueList.at(0), animation);
2361     basicAnim->setTimingFunction(timingFunction, !forwards);
2362
2363     PlatformCAAnimation::ValueFunctionType valueFunction = getValueFunctionNameForTransformOperation(transformOpType);
2364     if (valueFunction != PlatformCAAnimation::NoValueFunction)
2365         basicAnim->setValueFunction(valueFunction);
2366
2367     return true;
2368 }
2369
2370 bool GraphicsLayerCA::setTransformAnimationKeyframes(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* keyframeAnim, int functionIndex, TransformOperation::OperationType transformOpType, bool isMatrixAnimation, const IntSize& boxSize)
2371 {
2372     Vector<float> keyTimes;
2373     Vector<float> floatValues;
2374     Vector<FloatPoint3D> floatPoint3DValues;
2375     Vector<TransformationMatrix> transformationMatrixValues;
2376     Vector<const TimingFunction*> timingFunctions;
2377
2378     bool forwards = animation->directionIsForwards();
2379
2380     for (unsigned i = 0; i < valueList.size(); ++i) {
2381         unsigned index = forwards ? i : (valueList.size() - i - 1);
2382         const TransformAnimationValue* curValue = static_cast<const TransformAnimationValue*>(valueList.at(index));
2383         keyTimes.append(forwards ? curValue->keyTime() : (1 - curValue->keyTime()));
2384
2385         if (isMatrixAnimation) {
2386             TransformationMatrix transform;
2387             curValue->value()->apply(boxSize, transform);
2388
2389             // If any matrix is singular, CA won't animate it correctly. So fall back to software animation
2390             if (!transform.isInvertible())
2391                 return false;
2392
2393             transformationMatrixValues.append(transform);
2394         } else {
2395             const TransformOperation* transformOp = curValue->value()->at(functionIndex);
2396             if (isTransformTypeNumber(transformOpType)) {
2397                 float value;
2398                 getTransformFunctionValue(transformOp, transformOpType, boxSize, value);
2399                 floatValues.append(value);
2400             } else if (isTransformTypeFloatPoint3D(transformOpType)) {
2401                 FloatPoint3D value;
2402                 getTransformFunctionValue(transformOp, transformOpType, boxSize, value);
2403                 floatPoint3DValues.append(value);
2404             } else {
2405                 TransformationMatrix value;
2406                 getTransformFunctionValue(transformOp, transformOpType, boxSize, value);
2407                 transformationMatrixValues.append(value);
2408             }
2409         }
2410
2411         if (i < (valueList.size() - 1))
2412             timingFunctions.append(timingFunctionForAnimationValue(forwards ? curValue : valueList.at(index - 1), animation));
2413     }
2414     
2415     keyframeAnim->setKeyTimes(keyTimes);
2416     
2417     if (isTransformTypeNumber(transformOpType))
2418         keyframeAnim->setValues(floatValues);
2419     else if (isTransformTypeFloatPoint3D(transformOpType))
2420         keyframeAnim->setValues(floatPoint3DValues);
2421     else
2422         keyframeAnim->setValues(transformationMatrixValues);
2423         
2424     keyframeAnim->setTimingFunctions(timingFunctions, !forwards);
2425
2426     PlatformCAAnimation::ValueFunctionType valueFunction = getValueFunctionNameForTransformOperation(transformOpType);
2427     if (valueFunction != PlatformCAAnimation::NoValueFunction)
2428         keyframeAnim->setValueFunction(valueFunction);
2429
2430     return true;
2431 }
2432
2433 #if ENABLE(CSS_FILTERS)
2434 bool GraphicsLayerCA::setFilterAnimationEndpoints(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* basicAnim, int functionIndex, int internalFilterPropertyIndex)
2435 {
2436     ASSERT(valueList.size() == 2);
2437
2438     bool forwards = animation->directionIsForwards();
2439
2440     unsigned fromIndex = !forwards;
2441     unsigned toIndex = forwards;
2442
2443     const FilterAnimationValue* fromValue = static_cast<const FilterAnimationValue*>(valueList.at(fromIndex));
2444     const FilterAnimationValue* toValue = static_cast<const FilterAnimationValue*>(valueList.at(toIndex));
2445
2446     const FilterOperation* fromOperation = fromValue->value()->at(functionIndex);
2447     const FilterOperation* toOperation = toValue->value()->at(functionIndex);
2448
2449     RefPtr<DefaultFilterOperation> defaultFromOperation;
2450     RefPtr<DefaultFilterOperation> defaultToOperation;
2451
2452     ASSERT(fromOperation || toOperation);
2453
2454     if (!fromOperation) {
2455         defaultFromOperation = DefaultFilterOperation::create(toOperation->getOperationType());
2456         fromOperation = defaultFromOperation.get();
2457     }
2458
2459     if (!toOperation) {
2460         defaultToOperation = DefaultFilterOperation::create(fromOperation->getOperationType());
2461         toOperation = defaultToOperation.get();
2462     }
2463
2464     basicAnim->setFromValue(fromOperation, internalFilterPropertyIndex);
2465     basicAnim->setToValue(toOperation, internalFilterPropertyIndex);
2466
2467     // This codepath is used for 2-keyframe animations, so we still need to look in the start
2468     // for a timing function. Even in the reversing animation case, the first keyframe provides the timing function.
2469     basicAnim->setTimingFunction(timingFunctionForAnimationValue(valueList.at(0), animation), !forwards);
2470
2471     return true;
2472 }
2473
2474 bool GraphicsLayerCA::setFilterAnimationKeyframes(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* keyframeAnim, int functionIndex, int internalFilterPropertyIndex, FilterOperation::OperationType filterOp)
2475 {
2476     Vector<float> keyTimes;
2477     Vector<RefPtr<FilterOperation> > values;
2478     Vector<const TimingFunction*> timingFunctions;
2479     RefPtr<DefaultFilterOperation> defaultOperation;
2480
2481     bool forwards = animation->directionIsForwards();
2482
2483     for (unsigned i = 0; i < valueList.size(); ++i) {
2484         unsigned index = forwards ? i : (valueList.size() - i - 1);
2485         const FilterAnimationValue* curValue = static_cast<const FilterAnimationValue*>(valueList.at(index));
2486         keyTimes.append(forwards ? curValue->keyTime() : (1 - curValue->keyTime()));
2487
2488         if (curValue->value()->operations().size() > static_cast<size_t>(functionIndex))
2489             values.append(curValue->value()->operations()[functionIndex]);
2490         else {
2491             if (!defaultOperation)
2492                 defaultOperation = DefaultFilterOperation::create(filterOp);
2493             values.append(defaultOperation);
2494         }
2495
2496         if (i < (valueList.size() - 1))
2497             timingFunctions.append(timingFunctionForAnimationValue(forwards ? curValue : valueList.at(index - 1), animation));
2498     }
2499     
2500     keyframeAnim->setKeyTimes(keyTimes);
2501     keyframeAnim->setValues(values, internalFilterPropertyIndex);
2502     keyframeAnim->setTimingFunctions(timingFunctions, !forwards);
2503
2504     return true;
2505 }
2506 #endif
2507
2508 void GraphicsLayerCA::suspendAnimations(double time)
2509 {
2510     double t = PlatformCALayer::currentTimeToMediaTime(time ? time : currentTime());
2511     primaryLayer()->setSpeed(0);
2512     primaryLayer()->setTimeOffset(t);
2513
2514     // Suspend the animations on the clones too.
2515     if (LayerMap* layerCloneMap = primaryLayerClones()) {
2516         LayerMap::const_iterator end = layerCloneMap->end();
2517         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
2518             it->value->setSpeed(0);
2519             it->value->setTimeOffset(t);
2520         }
2521     }
2522 }
2523
2524 void GraphicsLayerCA::resumeAnimations()
2525 {
2526     primaryLayer()->setSpeed(1);
2527     primaryLayer()->setTimeOffset(0);
2528
2529     // Resume the animations on the clones too.
2530     if (LayerMap* layerCloneMap = primaryLayerClones()) {
2531         LayerMap::const_iterator end = layerCloneMap->end();
2532         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
2533             it->value->setSpeed(1);
2534             it->value->setTimeOffset(0);
2535         }
2536     }
2537 }
2538
2539 PlatformCALayer* GraphicsLayerCA::hostLayerForSublayers() const
2540 {
2541     return m_structuralLayer.get() ? m_structuralLayer.get() : m_layer.get(); 
2542 }
2543
2544 PlatformCALayer* GraphicsLayerCA::layerForSuperlayer() const
2545 {
2546     return m_structuralLayer ? m_structuralLayer.get() : m_layer.get();
2547 }
2548
2549 PlatformCALayer* GraphicsLayerCA::animatedLayer(AnimatedPropertyID property) const
2550 {
2551     return (property == AnimatedPropertyBackgroundColor) ? m_contentsLayer.get() : primaryLayer();
2552 }
2553
2554 GraphicsLayerCA::LayerMap* GraphicsLayerCA::animatedLayerClones(AnimatedPropertyID property) const
2555 {
2556     return (property == AnimatedPropertyBackgroundColor) ? m_contentsLayerClones.get() : primaryLayerClones();
2557 }
2558
2559 static float clampedContentsScaleForScale(float scale)
2560 {
2561     // Define some limits as a sanity check for the incoming scale value
2562     // those too small to see.
2563     const float maxScale = 10.0f;
2564     const float minScale = 0.01f;
2565     return max(minScale, min(scale, maxScale));
2566 }
2567
2568 void GraphicsLayerCA::updateContentsScale(float pageScaleFactor)
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 bool GraphicsLayerCA::canThrottleLayerFlush() const
3060 {
3061     // Tile layers are currently plain CA layers, attached directly by TileController. They require immediate flush as they may contain garbage.
3062     return !(m_uncommittedChanges & TilesAdded);
3063 }
3064
3065 void GraphicsLayerCA::noteLayerPropertyChanged(LayerChangeFlags flags)
3066 {
3067     bool hadUncommittedChanges = !!m_uncommittedChanges;
3068     bool oldCanThrottleLayerFlush = canThrottleLayerFlush();
3069
3070     m_uncommittedChanges |= flags;
3071
3072     bool needsFlush = !hadUncommittedChanges || oldCanThrottleLayerFlush != canThrottleLayerFlush();
3073     if (needsFlush && m_client)
3074         m_client->notifyFlushRequired(this);
3075 }
3076
3077 double GraphicsLayerCA::backingStoreMemoryEstimate() const
3078 {
3079     if (!drawsContent())
3080         return 0;
3081
3082     // contentsLayer is given to us, so we don't really know anything about its contents.
3083     // FIXME: ignores layer clones.
3084     
3085     if (TiledBacking* tiledBacking = this->tiledBacking())
3086         return tiledBacking->retainedTileBackingStoreMemory();
3087
3088     return 4.0 * size().width() * m_layer->contentsScale() * size().height() * m_layer->contentsScale();
3089 }
3090
3091 } // namespace WebCore
3092
3093 #endif // USE(ACCELERATED_COMPOSITING)