Unreviewed, rolling out r105906.
[WebKit-https.git] / Source / WebCore / rendering / RenderLayerBacking.cpp
1 /*
2  * Copyright (C) 2009, 2010, 2011 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 "RenderLayerBacking.h"
31
32 #include "AnimationController.h"
33 #include "CanvasRenderingContext.h"
34 #include "CSSPropertyNames.h"
35 #include "CSSStyleSelector.h"
36 #include "Chrome.h"
37 #include "FontCache.h"
38 #include "FrameView.h"
39 #include "GraphicsContext.h"
40 #include "GraphicsLayer.h"
41 #include "HTMLCanvasElement.h"
42 #include "HTMLIFrameElement.h"
43 #include "HTMLMediaElement.h"
44 #include "HTMLNames.h"
45 #include "InspectorInstrumentation.h"
46 #include "KeyframeList.h"
47 #include "PluginViewBase.h"
48 #include "RenderApplet.h"
49 #include "RenderIFrame.h"
50 #include "RenderImage.h"
51 #include "RenderLayerCompositor.h"
52 #include "RenderEmbeddedObject.h"
53 #include "RenderVideo.h"
54 #include "RenderView.h"
55
56 #if ENABLE(CSS_FILTERS)
57 #include "FilterEffectRenderer.h"
58 #endif
59
60 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
61 #include "GraphicsContext3D.h"
62 #endif
63
64 using namespace std;
65
66 namespace WebCore {
67
68 using namespace HTMLNames;
69
70 static bool hasBoxDecorations(const RenderStyle*);
71 static bool hasBoxDecorationsOrBackground(const RenderObject*);
72 static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle*);
73 static LayoutRect clipBox(RenderBox* renderer);
74
75 static inline bool isAcceleratedCanvas(RenderObject* renderer)
76 {
77 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
78     if (renderer->isCanvas()) {
79         HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
80         if (CanvasRenderingContext* context = canvas->renderingContext())
81             return context->isAccelerated();
82     }
83 #else
84     UNUSED_PARAM(renderer);
85 #endif
86     return false;
87 }
88
89 RenderLayerBacking::RenderLayerBacking(RenderLayer* layer)
90     : m_owningLayer(layer)
91     , m_artificiallyInflatedBounds(false)
92     , m_isMainFrameRenderViewLayer(false)
93     , m_usingTiledCacheLayer(false)
94 #if ENABLE(CSS_FILTERS)
95     , m_canCompositeFilters(false)
96 #endif
97 {
98     if (renderer()->isRenderView()) {
99         Frame* frame = toRenderView(renderer())->frameView()->frame();
100         Page* page = frame ? frame->page() : 0;
101         if (page && frame && page->mainFrame() == frame) {
102             m_isMainFrameRenderViewLayer = true;
103
104 #if ENABLE(THREADED_SCROLLING)
105             // FIXME: It's a little weird that we base this decision on whether there's a scrolling coordinator or not.
106             if (page->scrollingCoordinator())
107                 m_usingTiledCacheLayer = true;
108 #endif
109         }
110     }
111     
112     createPrimaryGraphicsLayer();
113 }
114
115 RenderLayerBacking::~RenderLayerBacking()
116 {
117     updateClippingLayers(false, false);
118     updateOverflowControlsLayers(false, false, false);
119     updateForegroundLayer(false);
120     updateMaskLayer(false);
121     destroyGraphicsLayers();
122 }
123
124 PassOwnPtr<GraphicsLayer> RenderLayerBacking::createGraphicsLayer(const String& name)
125 {
126     OwnPtr<GraphicsLayer> graphicsLayer = GraphicsLayer::create(this);
127 #ifndef NDEBUG
128     graphicsLayer->setName(name);
129 #else
130     UNUSED_PARAM(name);
131 #endif
132     graphicsLayer->setMaintainsPixelAlignment(compositor()->keepLayersPixelAligned());
133     return graphicsLayer.release();
134 }
135
136 bool RenderLayerBacking::shouldUseTileCache(const GraphicsLayer*) const
137 {
138     return m_usingTiledCacheLayer;
139 }
140
141 void RenderLayerBacking::createPrimaryGraphicsLayer()
142 {
143     String layerName;
144 #ifndef NDEBUG
145     layerName = nameForLayer();
146 #endif
147     m_graphicsLayer = createGraphicsLayer(layerName);
148
149     if (m_isMainFrameRenderViewLayer) {
150         m_graphicsLayer->setContentsOpaque(true);
151         m_graphicsLayer->setAppliesPageScale();
152     }
153     
154     updateLayerOpacity(renderer()->style());
155     updateLayerTransform(renderer()->style());
156 #if ENABLE(CSS_FILTERS)
157     updateLayerFilters(renderer()->style());
158 #endif
159 }
160
161 void RenderLayerBacking::destroyGraphicsLayers()
162 {
163     if (m_graphicsLayer)
164         m_graphicsLayer->removeFromParent();
165
166     m_graphicsLayer = nullptr;
167     m_foregroundLayer = nullptr;
168     m_clippingLayer = nullptr;
169     m_maskLayer = nullptr;
170 }
171
172 void RenderLayerBacking::updateLayerOpacity(const RenderStyle* style)
173 {
174     m_graphicsLayer->setOpacity(compositingOpacity(style->opacity()));
175 }
176
177 void RenderLayerBacking::updateLayerTransform(const RenderStyle* style)
178 {
179     // FIXME: This could use m_owningLayer->transform(), but that currently has transform-origin
180     // baked into it, and we don't want that.
181     TransformationMatrix t;
182     if (m_owningLayer->hasTransform()) {
183         style->applyTransform(t, toRenderBox(renderer())->borderBoxRect().size(), RenderStyle::ExcludeTransformOrigin);
184         makeMatrixRenderable(t, compositor()->canRender3DTransforms());
185     }
186     
187     m_graphicsLayer->setTransform(t);
188 }
189
190 #if ENABLE(CSS_FILTERS)
191 void RenderLayerBacking::updateLayerFilters(const RenderStyle* style)
192 {
193     m_canCompositeFilters = m_graphicsLayer->setFilters(style->filter());
194 }
195 #endif
196
197 static bool hasNonZeroTransformOrigin(const RenderObject* renderer)
198 {
199     RenderStyle* style = renderer->style();
200     return (style->transformOriginX().type() == Fixed && style->transformOriginX().value())
201         || (style->transformOriginY().type() == Fixed && style->transformOriginY().value());
202 }
203
204 static bool layerOrAncestorIsTransformed(RenderLayer* layer)
205 {
206     for (RenderLayer* curr = layer; curr; curr = curr->parent()) {
207         if (curr->hasTransform())
208             return true;
209     }
210     
211     return false;
212 }
213     
214 #if ENABLE(FULLSCREEN_API)
215 static bool layerOrAncestorIsFullScreen(RenderLayer* layer)
216 {
217     // Don't traverse through the render layer tree if we do not yet have a full screen renderer.        
218     if (!layer->renderer()->document()->fullScreenRenderer())
219         return false;
220
221     for (RenderLayer* curr = layer; curr; curr = curr->parent()) {
222         if (curr->renderer()->isRenderFullScreen())
223             return true;
224     }
225     
226     return false;
227 }
228 #endif
229
230 void RenderLayerBacking::updateCompositedBounds()
231 {
232     LayoutRect layerBounds = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer);
233
234     // Clip to the size of the document or enclosing overflow-scroll layer.
235     // If this or an ancestor is transformed, we can't currently compute the correct rect to intersect with.
236     // We'd need RenderObject::convertContainerToLocalQuad(), which doesn't yet exist.  If this
237     // is a fullscreen renderer, don't clip to the viewport, as the renderer will be asked to
238     // display outside of the viewport bounds.
239     if (compositor()->compositingConsultsOverlap() && !layerOrAncestorIsTransformed(m_owningLayer) 
240 #if ENABLE(FULLSCREEN_API)
241         && !layerOrAncestorIsFullScreen(m_owningLayer)
242 #endif
243         ) {
244         RenderView* view = m_owningLayer->renderer()->view();
245         RenderLayer* rootLayer = view->layer();
246
247         // Start by clipping to the view's bounds.
248         LayoutRect clippingBounds = view->layoutOverflowRect();
249
250         if (m_owningLayer != rootLayer)
251             clippingBounds.intersect(m_owningLayer->backgroundClipRect(rootLayer, 0, true).rect()); // FIXME: Incorrect for CSS regions.
252
253         LayoutPoint delta;
254         m_owningLayer->convertToLayerCoords(rootLayer, delta);
255         clippingBounds.move(-delta.x(), -delta.y());
256
257         layerBounds.intersect(clippingBounds);
258     }
259     
260     // If the element has a transform-origin that has fixed lengths, and the renderer has zero size,
261     // then we need to ensure that the compositing layer has non-zero size so that we can apply
262     // the transform-origin via the GraphicsLayer anchorPoint (which is expressed as a fractional value).
263     if (layerBounds.isEmpty() && hasNonZeroTransformOrigin(renderer())) {
264         layerBounds.setWidth(1);
265         layerBounds.setHeight(1);
266         m_artificiallyInflatedBounds = true;
267     } else
268         m_artificiallyInflatedBounds = false;
269
270     setCompositedBounds(layerBounds);
271 }
272
273 void RenderLayerBacking::updateAfterWidgetResize()
274 {
275     if (renderer()->isRenderPart()) {
276         if (RenderLayerCompositor* innerCompositor = RenderLayerCompositor::frameContentsCompositor(toRenderPart(renderer()))) {
277             innerCompositor->frameViewDidChangeSize();
278             innerCompositor->frameViewDidChangeLocation(contentsBox().location());
279         }
280     }
281 }
282
283 void RenderLayerBacking::updateAfterLayout(UpdateDepth updateDepth, bool isUpdateRoot)
284 {
285     RenderLayerCompositor* layerCompositor = compositor();
286     if (!layerCompositor->compositingLayersNeedRebuild()) {
287         // Calling updateGraphicsLayerGeometry() here gives incorrect results, because the
288         // position of this layer's GraphicsLayer depends on the position of our compositing
289         // ancestor's GraphicsLayer. That cannot be determined until all the descendant 
290         // RenderLayers of that ancestor have been processed via updateLayerPositions().
291         //
292         // The solution is to update compositing children of this layer here,
293         // via updateCompositingChildrenGeometry().
294         updateCompositedBounds();
295         layerCompositor->updateCompositingDescendantGeometry(m_owningLayer, m_owningLayer, updateDepth);
296         
297         if (isUpdateRoot) {
298             updateGraphicsLayerGeometry();
299             layerCompositor->updateRootLayerPosition();
300         }
301     }
302 }
303
304 bool RenderLayerBacking::updateGraphicsLayerConfiguration()
305 {
306     RenderLayerCompositor* compositor = this->compositor();
307     RenderObject* renderer = this->renderer();
308
309     bool layerConfigChanged = false;
310     if (updateForegroundLayer(compositor->needsContentsCompositingLayer(m_owningLayer)))
311         layerConfigChanged = true;
312     
313     if (updateClippingLayers(compositor->clippedByAncestor(m_owningLayer), compositor->clipsCompositingDescendants(m_owningLayer)))
314         layerConfigChanged = true;
315
316     if (updateOverflowControlsLayers(requiresHorizontalScrollbarLayer(), requiresVerticalScrollbarLayer(), requiresScrollCornerLayer()))
317         layerConfigChanged = true;
318
319     if (layerConfigChanged)
320         updateInternalHierarchy();
321
322     if (updateMaskLayer(renderer->hasMask()))
323         m_graphicsLayer->setMaskLayer(m_maskLayer.get());
324
325     if (m_owningLayer->hasReflection()) {
326         if (m_owningLayer->reflectionLayer()->backing()) {
327             GraphicsLayer* reflectionLayer = m_owningLayer->reflectionLayer()->backing()->graphicsLayer();
328             m_graphicsLayer->setReplicatedByLayer(reflectionLayer);
329         }
330     } else
331         m_graphicsLayer->setReplicatedByLayer(0);
332
333     if (isDirectlyCompositedImage())
334         updateImageContents();
335
336     if ((renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing())
337         || (renderer->isApplet() && toRenderApplet(renderer)->allowsAcceleratedCompositing())) {
338         PluginViewBase* pluginViewBase = static_cast<PluginViewBase*>(toRenderWidget(renderer)->widget());
339         m_graphicsLayer->setContentsToMedia(pluginViewBase->platformLayer());
340     }
341 #if ENABLE(VIDEO)
342     else if (renderer->isVideo()) {
343         HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(renderer->node());
344         m_graphicsLayer->setContentsToMedia(mediaElement->platformLayer());
345     }
346 #endif
347 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
348     else if (isAcceleratedCanvas(renderer)) {
349         HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
350         if (CanvasRenderingContext* context = canvas->renderingContext())
351             m_graphicsLayer->setContentsToCanvas(context->platformLayer());
352         layerConfigChanged = true;
353     }
354 #endif
355 #if ENABLE(FULLSCREEN_API)
356     else if (renderer->isRenderFullScreen()) {
357         // RenderFullScreen renderers have no content, and only a solid
358         // background color.  They also can be large enough to trigger the
359         // creation of a tiled-layer, which can cause flashing problems
360         // during repainting.  Special case the RenderFullScreen case because
361         // we know its style does not come from CSS and it is therefore will
362         // not contain paintable content (e.g. background images, gradients,
363         // etc), so safe to set the layer's background color to the renderer's 
364         // style's background color.
365         updateBackgroundColor();
366     }
367 #endif
368     if (renderer->isRenderPart())
369         layerConfigChanged = RenderLayerCompositor::parentFrameContentLayers(toRenderPart(renderer));
370
371     return layerConfigChanged;
372 }
373
374 static LayoutRect clipBox(RenderBox* renderer)
375 {
376     LayoutRect result = PaintInfo::infiniteRect();
377     if (renderer->hasOverflowClip())
378         result = renderer->overflowClipRect(LayoutPoint(), 0); // FIXME: Incorrect for CSS regions.
379
380     if (renderer->hasClip())
381         result.intersect(renderer->clipRect(LayoutPoint(), 0)); // FIXME: Incorrect for CSS regions.
382
383     return result;
384 }
385
386 void RenderLayerBacking::updateGraphicsLayerGeometry()
387 {
388     // If we haven't built z-order lists yet, wait until later.
389     if (m_owningLayer->isStackingContext() && m_owningLayer->m_zOrderListsDirty)
390         return;
391
392     // Set transform property, if it is not animating. We have to do this here because the transform
393     // is affected by the layer dimensions.
394     if (!renderer()->animation()->isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyWebkitTransform))
395         updateLayerTransform(renderer()->style());
396
397     // Set opacity, if it is not animating.
398     if (!renderer()->animation()->isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyOpacity))
399         updateLayerOpacity(renderer()->style());
400         
401 #if ENABLE(CSS_FILTERS)
402     updateLayerFilters(renderer()->style());
403 #endif
404     
405     m_owningLayer->updateVisibilityStatus();
406     m_graphicsLayer->setContentsVisible(m_owningLayer->hasVisibleContent());
407     
408     RenderStyle* style = renderer()->style();
409     m_graphicsLayer->setPreserves3D(style->transformStyle3D() == TransformStyle3DPreserve3D && !renderer()->hasReflection());
410     m_graphicsLayer->setBackfaceVisibility(style->backfaceVisibility() == BackfaceVisibilityVisible);
411
412     RenderLayer* compAncestor = m_owningLayer->ancestorCompositingLayer();
413     
414     // We compute everything relative to the enclosing compositing layer.
415     LayoutRect ancestorCompositingBounds;
416     if (compAncestor) {
417         ASSERT(compAncestor->backing());
418         ancestorCompositingBounds = compAncestor->backing()->compositedBounds();
419     }
420
421     LayoutRect localCompositingBounds = compositedBounds();
422
423     LayoutRect relativeCompositingBounds(localCompositingBounds);
424     LayoutPoint delta;
425     m_owningLayer->convertToLayerCoords(compAncestor, delta);
426     relativeCompositingBounds.moveBy(delta);
427
428     LayoutPoint graphicsLayerParentLocation;
429     if (compAncestor && compAncestor->backing()->hasClippingLayer()) {
430         // If the compositing ancestor has a layer to clip children, we parent in that, and therefore
431         // position relative to it.
432         LayoutRect clippingBox = clipBox(toRenderBox(compAncestor->renderer()));
433         graphicsLayerParentLocation = clippingBox.location();
434     } else if (compAncestor)
435         graphicsLayerParentLocation = ancestorCompositingBounds.location();
436     else
437         graphicsLayerParentLocation = renderer()->view()->documentRect().location();
438     
439     if (compAncestor && m_ancestorClippingLayer) {
440         // Call calculateRects to get the backgroundRect which is what is used to clip the contents of this
441         // layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects
442         // for a compositing layer, rootLayer is the layer itself.
443         LayoutRect parentClipRect = m_owningLayer->backgroundClipRect(compAncestor, 0, true).rect(); // FIXME: Incorrect for CSS regions.
444         ASSERT(parentClipRect != PaintInfo::infiniteRect());
445         m_ancestorClippingLayer->setPosition(FloatPoint() + (parentClipRect.location() - graphicsLayerParentLocation));
446         m_ancestorClippingLayer->setSize(parentClipRect.size());
447
448         // backgroundRect is relative to compAncestor, so subtract deltaX/deltaY to get back to local coords.
449         m_ancestorClippingLayer->setOffsetFromRenderer(parentClipRect.location() - delta);
450
451         // The primary layer is then parented in, and positioned relative to this clipping layer.
452         graphicsLayerParentLocation = parentClipRect.location();
453     }
454
455     m_graphicsLayer->setPosition(FloatPoint() + (relativeCompositingBounds.location() - graphicsLayerParentLocation));
456     m_graphicsLayer->setOffsetFromRenderer(localCompositingBounds.location() - LayoutPoint());
457     
458     FloatSize oldSize = m_graphicsLayer->size();
459     FloatSize newSize = relativeCompositingBounds.size();
460     if (oldSize != newSize) {
461         m_graphicsLayer->setSize(newSize);
462         // A bounds change will almost always require redisplay. Usually that redisplay
463         // will happen because of a repaint elsewhere, but not always:
464         // e.g. see RenderView::setMaximalOutlineSize()
465         m_graphicsLayer->setNeedsDisplay();
466     }
467
468     // If we have a layer that clips children, position it.
469     LayoutRect clippingBox;
470     if (m_clippingLayer) {
471         clippingBox = clipBox(toRenderBox(renderer()));
472         m_clippingLayer->setPosition(FloatPoint() + (clippingBox.location() - localCompositingBounds.location()));
473         m_clippingLayer->setSize(clippingBox.size());
474         m_clippingLayer->setOffsetFromRenderer(clippingBox.location() - LayoutPoint());
475     }
476     
477     if (m_maskLayer) {
478         if (m_maskLayer->size() != m_graphicsLayer->size()) {
479             m_maskLayer->setSize(m_graphicsLayer->size());
480             m_maskLayer->setNeedsDisplay();
481         }
482         m_maskLayer->setPosition(FloatPoint());
483         m_maskLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
484     }
485     
486     if (m_owningLayer->hasTransform()) {
487         const LayoutRect borderBox = toRenderBox(renderer())->borderBoxRect();
488
489         // Get layout bounds in the coords of compAncestor to match relativeCompositingBounds.
490         LayoutRect layerBounds = LayoutRect(delta, borderBox.size());
491
492         // Update properties that depend on layer dimensions
493         FloatPoint3D transformOrigin = computeTransformOrigin(borderBox);
494         // Compute the anchor point, which is in the center of the renderer box unless transform-origin is set.
495         FloatPoint3D anchor(relativeCompositingBounds.width()  != 0.0f ? ((layerBounds.x() - relativeCompositingBounds.x()) + transformOrigin.x()) / relativeCompositingBounds.width()  : 0.5f,
496                             relativeCompositingBounds.height() != 0.0f ? ((layerBounds.y() - relativeCompositingBounds.y()) + transformOrigin.y()) / relativeCompositingBounds.height() : 0.5f,
497                             transformOrigin.z());
498         m_graphicsLayer->setAnchorPoint(anchor);
499
500         RenderStyle* style = renderer()->style();
501         if (style->hasPerspective()) {
502             TransformationMatrix t = owningLayer()->perspectiveTransform();
503             
504             if (m_clippingLayer) {
505                 m_clippingLayer->setChildrenTransform(t);
506                 m_graphicsLayer->setChildrenTransform(TransformationMatrix());
507             }
508             else
509                 m_graphicsLayer->setChildrenTransform(t);
510         } else {
511             if (m_clippingLayer)
512                 m_clippingLayer->setChildrenTransform(TransformationMatrix());
513             else
514                 m_graphicsLayer->setChildrenTransform(TransformationMatrix());
515         }
516     } else {
517         m_graphicsLayer->setAnchorPoint(FloatPoint3D(0.5f, 0.5f, 0));
518     }
519
520     if (m_foregroundLayer) {
521         FloatPoint foregroundPosition;
522         FloatSize foregroundSize = newSize;
523         LayoutSize foregroundOffset = m_graphicsLayer->offsetFromRenderer();
524         if (m_clippingLayer) {
525             // If we have a clipping layer (which clips descendants), then the foreground layer is a child of it,
526             // so that it gets correctly sorted with children. In that case, position relative to the clipping layer.
527             foregroundSize = FloatSize(clippingBox.size());
528             foregroundOffset = clippingBox.location() - LayoutPoint();
529         }
530
531         m_foregroundLayer->setPosition(foregroundPosition);
532         m_foregroundLayer->setSize(foregroundSize);
533         m_foregroundLayer->setOffsetFromRenderer(foregroundOffset);
534     }
535
536     if (m_owningLayer->reflectionLayer() && m_owningLayer->reflectionLayer()->isComposited()) {
537         RenderLayerBacking* reflectionBacking = m_owningLayer->reflectionLayer()->backing();
538         reflectionBacking->updateGraphicsLayerGeometry();
539         
540         // The reflection layer has the bounds of m_owningLayer->reflectionLayer(),
541         // but the reflected layer is the bounds of this layer, so we need to position it appropriately.
542         FloatRect layerBounds = compositedBounds();
543         FloatRect reflectionLayerBounds = reflectionBacking->compositedBounds();
544         reflectionBacking->graphicsLayer()->setReplicatedLayerPosition(FloatPoint() + (layerBounds.location() - reflectionLayerBounds.location()));
545     }
546
547     m_graphicsLayer->setContentsRect(contentsBox());
548     updateDrawsContent();
549     updateAfterWidgetResize();
550 }
551
552 void RenderLayerBacking::updateInternalHierarchy()
553 {
554     // m_foregroundLayer has to be inserted in the correct order with child layers,
555     // so it's not inserted here.
556     if (m_ancestorClippingLayer) {
557         m_ancestorClippingLayer->removeAllChildren();
558         m_graphicsLayer->removeFromParent();
559         m_ancestorClippingLayer->addChild(m_graphicsLayer.get());
560     }
561
562     if (m_clippingLayer) {
563         m_clippingLayer->removeFromParent();
564         m_graphicsLayer->addChild(m_clippingLayer.get());
565
566         // The clip for child layers does not include space for overflow controls, so they exist as
567         // siblings of the clipping layer if we have one. Normal children of this layer are set as
568         // children of the clipping layer.
569         if (m_layerForHorizontalScrollbar) {
570             m_layerForHorizontalScrollbar->removeFromParent();
571             m_graphicsLayer->addChild(m_layerForHorizontalScrollbar.get());
572         }
573         if (m_layerForVerticalScrollbar) {
574             m_layerForVerticalScrollbar->removeFromParent();
575             m_graphicsLayer->addChild(m_layerForVerticalScrollbar.get());
576         }
577         if (m_layerForScrollCorner) {
578             m_layerForScrollCorner->removeFromParent();
579             m_graphicsLayer->addChild(m_layerForScrollCorner.get());
580         }
581     }
582 }
583
584 void RenderLayerBacking::updateDrawsContent()
585 {
586     m_graphicsLayer->setDrawsContent(containsPaintedContent());
587 }
588
589 // Return true if the layers changed.
590 bool RenderLayerBacking::updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip)
591 {
592     bool layersChanged = false;
593
594     if (needsAncestorClip) {
595         if (!m_ancestorClippingLayer) {
596             m_ancestorClippingLayer = createGraphicsLayer("Ancestor clipping Layer");
597             m_ancestorClippingLayer->setMasksToBounds(true);
598             layersChanged = true;
599         }
600     } else if (m_ancestorClippingLayer) {
601         m_ancestorClippingLayer->removeFromParent();
602         m_ancestorClippingLayer = nullptr;
603         layersChanged = true;
604     }
605     
606     if (needsDescendantClip) {
607         if (!m_clippingLayer) {
608             m_clippingLayer = createGraphicsLayer("Child clipping Layer");
609             m_clippingLayer->setMasksToBounds(true);
610             layersChanged = true;
611         }
612     } else if (m_clippingLayer) {
613         m_clippingLayer->removeFromParent();
614         m_clippingLayer = nullptr;
615         layersChanged = true;
616     }
617     
618     return layersChanged;
619 }
620
621 bool RenderLayerBacking::requiresHorizontalScrollbarLayer() const
622 {
623 #if !PLATFORM(CHROMIUM)
624     if (!m_owningLayer->hasOverlayScrollbars())
625         return false;
626 #endif
627     return m_owningLayer->horizontalScrollbar();
628 }
629
630 bool RenderLayerBacking::requiresVerticalScrollbarLayer() const
631 {
632 #if !PLATFORM(CHROMIUM)
633     if (!m_owningLayer->hasOverlayScrollbars())
634         return false;
635 #endif
636     return m_owningLayer->verticalScrollbar();
637 }
638
639 bool RenderLayerBacking::requiresScrollCornerLayer() const
640 {
641 #if !PLATFORM(CHROMIUM)
642     if (!m_owningLayer->hasOverlayScrollbars())
643         return false;
644 #endif
645     return !m_owningLayer->scrollCornerAndResizerRect().isEmpty();
646 }
647
648 bool RenderLayerBacking::updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer)
649 {
650     bool layersChanged = false;
651     if (needsHorizontalScrollbarLayer) {
652         if (!m_layerForHorizontalScrollbar) {
653             m_layerForHorizontalScrollbar = createGraphicsLayer("horizontal scrollbar");
654             layersChanged = true;
655         }
656     } else if (m_layerForHorizontalScrollbar) {
657         m_layerForHorizontalScrollbar.clear();
658         layersChanged = true;
659     }
660
661     if (needsVerticalScrollbarLayer) {
662         if (!m_layerForVerticalScrollbar) {
663             m_layerForVerticalScrollbar = createGraphicsLayer("vertical scrollbar");
664             layersChanged = true;
665         }
666     } else if (m_layerForVerticalScrollbar) {
667         m_layerForVerticalScrollbar.clear();
668         layersChanged = true;
669     }
670
671     if (needsScrollCornerLayer) {
672         if (!m_layerForScrollCorner) {
673             m_layerForScrollCorner = createGraphicsLayer("scroll corner");
674             layersChanged = true;
675         }
676     } else if (m_layerForScrollCorner) {
677         m_layerForScrollCorner.clear();
678         layersChanged = true;
679     }
680
681     return layersChanged;
682 }
683
684 bool RenderLayerBacking::updateForegroundLayer(bool needsForegroundLayer)
685 {
686     bool layerChanged = false;
687     if (needsForegroundLayer) {
688         if (!m_foregroundLayer) {
689             String layerName;
690 #ifndef NDEBUG
691             layerName = nameForLayer() + " (foreground)";
692 #endif
693             m_foregroundLayer = createGraphicsLayer(layerName);
694             m_foregroundLayer->setDrawsContent(true);
695             m_foregroundLayer->setPaintingPhase(GraphicsLayerPaintForeground);
696             layerChanged = true;
697         }
698     } else if (m_foregroundLayer) {
699         m_foregroundLayer->removeFromParent();
700         m_foregroundLayer = nullptr;
701         layerChanged = true;
702     }
703
704     if (layerChanged)
705         m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
706
707     return layerChanged;
708 }
709
710 bool RenderLayerBacking::updateMaskLayer(bool needsMaskLayer)
711 {
712     bool layerChanged = false;
713     if (needsMaskLayer) {
714         if (!m_maskLayer) {
715             m_maskLayer = createGraphicsLayer("Mask");
716             m_maskLayer->setDrawsContent(true);
717             m_maskLayer->setPaintingPhase(GraphicsLayerPaintMask);
718             layerChanged = true;
719         }
720     } else if (m_maskLayer) {
721         m_maskLayer = nullptr;
722         layerChanged = true;
723     }
724
725     if (layerChanged)
726         m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
727
728     return layerChanged;
729 }
730
731 GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() const
732 {
733     unsigned phase = GraphicsLayerPaintBackground;
734     if (!m_foregroundLayer)
735         phase |= GraphicsLayerPaintForeground;
736     if (!m_maskLayer)
737         phase |= GraphicsLayerPaintMask;
738
739     return static_cast<GraphicsLayerPaintingPhase>(phase);
740 }
741
742 float RenderLayerBacking::compositingOpacity(float rendererOpacity) const
743 {
744     float finalOpacity = rendererOpacity;
745     
746     for (RenderLayer* curr = m_owningLayer->parent(); curr; curr = curr->parent()) {
747         // We only care about parents that are stacking contexts.
748         // Recall that opacity creates stacking context.
749         if (!curr->isStackingContext())
750             continue;
751         
752         // If we found a compositing layer, we want to compute opacity
753         // relative to it. So we can break here.
754         if (curr->isComposited())
755             break;
756         
757         finalOpacity *= curr->renderer()->opacity();
758     }
759
760     return finalOpacity;
761 }
762
763 static bool hasBoxDecorations(const RenderStyle* style)
764 {
765     return style->hasBorder() || style->hasBorderRadius() || style->hasOutline() || style->hasAppearance() || style->boxShadow() || style->hasFilter();
766 }
767
768 static bool hasBoxDecorationsOrBackground(const RenderObject* renderer)
769 {
770     return hasBoxDecorations(renderer->style()) || renderer->hasBackground();
771 }
772
773 static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle* style)
774 {
775     return hasBoxDecorations(style) || style->hasBackgroundImage();
776 }
777
778 Color RenderLayerBacking::rendererBackgroundColor() const
779 {
780     RenderObject* backgroundRenderer = renderer();
781     if (backgroundRenderer->isRoot())
782         backgroundRenderer = backgroundRenderer->rendererForRootBackground();
783
784     return backgroundRenderer->style()->visitedDependentColor(CSSPropertyBackgroundColor);
785 }
786
787 void RenderLayerBacking::updateBackgroundColor()
788 {
789     m_graphicsLayer->setContentsToBackgroundColor(rendererBackgroundColor());
790 }
791
792 // A "simple container layer" is a RenderLayer which has no visible content to render.
793 // It may have no children, or all its children may be themselves composited.
794 // This is a useful optimization, because it allows us to avoid allocating backing store.
795 bool RenderLayerBacking::isSimpleContainerCompositingLayer() const
796 {
797     RenderObject* renderObject = renderer();
798     if (renderObject->isReplaced() ||       // replaced objects are not containers
799         renderObject->hasMask())            // masks require special treatment
800         return false;
801
802     RenderStyle* style = renderObject->style();
803     bool isVisible = m_owningLayer->hasVisibleContent();
804
805     // Reject anything that has a border, a border-radius or outline,
806     // or any background (color or image).
807     // FIXME: we could optimize layers for simple backgrounds.
808     if (isVisible && hasBoxDecorationsOrBackground(renderObject))
809         return false;
810
811     if (isVisible && m_owningLayer->hasOverflowControls())
812         return false;
813
814     // If we have got this far and the renderer has no children, then we're ok.
815     if (!renderObject->firstChild())
816         return true;
817     
818     if (renderObject->node() && renderObject->node()->isDocumentNode()) {
819         // Look to see if the root object has a non-simple background
820         RenderObject* rootObject = renderObject->document()->documentElement()->renderer();
821         if (!rootObject)
822             return false;
823         
824         style = rootObject->style();
825         
826         // Reject anything that has a border, a border-radius or outline,
827         // or is not a simple background (no background, or solid color).
828         if (hasBoxDecorationsOrBackgroundImage(style))
829             return false;
830         
831         // Now look at the body's renderer.
832         HTMLElement* body = renderObject->document()->body();
833         RenderObject* bodyObject = (body && body->hasLocalName(bodyTag)) ? body->renderer() : 0;
834         if (!bodyObject)
835             return false;
836         
837         style = bodyObject->style();
838         
839         if (hasBoxDecorationsOrBackgroundImage(style))
840             return false;
841     }
842
843     // Check to see if all the renderer's children are compositing layers.
844     if (isVisible && containsNonEmptyRenderers())
845         return false;
846         
847     if (hasVisibleNonCompositingDescendantLayers())
848         return false;
849     
850     return true;
851 }
852
853 bool RenderLayerBacking::containsNonEmptyRenderers() const
854 {
855     // Some HTML can cause whitespace text nodes to have renderers, like:
856     // <div>
857     // <img src=...>
858     // </div>
859     // so test for 0x0 RenderTexts here
860     for (RenderObject* child = renderer()->firstChild(); child; child = child->nextSibling()) {
861         if (!child->hasLayer()) {
862             if (child->isRenderInline() || !child->isBox())
863                 return true;
864             
865             if (toRenderBox(child)->width() > 0 || toRenderBox(child)->height() > 0)
866                 return true;
867         }
868     }
869     return false;
870 }
871
872 // Conservative test for having no rendered children.
873 bool RenderLayerBacking::hasVisibleNonCompositingDescendantLayers() const
874 {
875     if (Vector<RenderLayer*>* normalFlowList = m_owningLayer->normalFlowList()) {
876         size_t listSize = normalFlowList->size();
877         for (size_t i = 0; i < listSize; ++i) {
878             RenderLayer* curLayer = normalFlowList->at(i);
879             if (!curLayer->isComposited() && curLayer->hasVisibleContent())
880                 return true;
881         }
882     }
883
884     if (m_owningLayer->isStackingContext()) {
885         if (!m_owningLayer->hasVisibleDescendant())
886             return false;
887
888         // Use the m_hasCompositingDescendant bit to optimize?
889         if (Vector<RenderLayer*>* negZOrderList = m_owningLayer->negZOrderList()) {
890             size_t listSize = negZOrderList->size();
891             for (size_t i = 0; i < listSize; ++i) {
892                 RenderLayer* curLayer = negZOrderList->at(i);
893                 if (!curLayer->isComposited() && curLayer->hasVisibleContent())
894                     return true;
895             }
896         }
897
898         if (Vector<RenderLayer*>* posZOrderList = m_owningLayer->posZOrderList()) {
899             size_t listSize = posZOrderList->size();
900             for (size_t i = 0; i < listSize; ++i) {
901                 RenderLayer* curLayer = posZOrderList->at(i);
902                 if (!curLayer->isComposited() && curLayer->hasVisibleContent())
903                     return true;
904             }
905         }
906     }
907
908     return false;
909 }
910
911 bool RenderLayerBacking::containsPaintedContent() const
912 {
913     if (isSimpleContainerCompositingLayer() || paintingGoesToWindow() || m_artificiallyInflatedBounds || m_owningLayer->isReflection())
914         return false;
915
916     if (isDirectlyCompositedImage())
917         return false;
918
919     // FIXME: we could optimize cases where the image, video or canvas is known to fill the border box entirely,
920     // and set background color on the layer in that case, instead of allocating backing store and painting.
921 #if ENABLE(VIDEO)
922     if (renderer()->isVideo() && toRenderVideo(renderer())->shouldDisplayVideo())
923         return hasBoxDecorationsOrBackground(renderer());
924 #endif
925 #if PLATFORM(MAC) && USE(CA) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
926 #elif ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
927     if (isAcceleratedCanvas(renderer()))
928         return hasBoxDecorationsOrBackground(renderer());
929 #endif
930
931     return true;
932 }
933
934 // An image can be directly compositing if it's the sole content of the layer, and has no box decorations
935 // that require painting. Direct compositing saves backing store.
936 bool RenderLayerBacking::isDirectlyCompositedImage() const
937 {
938     RenderObject* renderObject = renderer();
939     
940     if (!renderObject->isImage() || hasBoxDecorationsOrBackground(renderObject) || renderObject->hasClip())
941         return false;
942
943     RenderImage* imageRenderer = toRenderImage(renderObject);
944     if (CachedImage* cachedImage = imageRenderer->cachedImage()) {
945         if (cachedImage->hasImage())
946             return cachedImage->imageForRenderer(imageRenderer)->isBitmapImage();
947     }
948
949     return false;
950 }
951
952 void RenderLayerBacking::contentChanged(RenderLayer::ContentChangeType changeType)
953 {
954     if ((changeType == RenderLayer::ImageChanged) && isDirectlyCompositedImage()) {
955         updateImageContents();
956         return;
957     }
958     
959     if ((changeType == RenderLayer::MaskImageChanged) && m_maskLayer) {
960         // The composited layer bounds relies on box->maskClipRect(), which changes
961         // when the mask image becomes available.
962         bool isUpdateRoot = true;
963         updateAfterLayout(CompositingChildren, isUpdateRoot);
964     }
965
966 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
967     if ((changeType == RenderLayer::CanvasChanged) && isAcceleratedCanvas(renderer())) {
968         m_graphicsLayer->setContentsNeedsDisplay();
969         return;
970     }
971 #endif
972 }
973
974 void RenderLayerBacking::updateImageContents()
975 {
976     ASSERT(renderer()->isImage());
977     RenderImage* imageRenderer = toRenderImage(renderer());
978
979     CachedImage* cachedImage = imageRenderer->cachedImage();
980     if (!cachedImage)
981         return;
982
983     Image* image = cachedImage->imageForRenderer(imageRenderer);
984     if (!image)
985         return;
986
987     // We have to wait until the image is fully loaded before setting it on the layer.
988     if (!cachedImage->isLoaded())
989         return;
990
991     // This is a no-op if the layer doesn't have an inner layer for the image.
992     m_graphicsLayer->setContentsToImage(image);
993     updateDrawsContent();
994     
995     // Image animation is "lazy", in that it automatically stops unless someone is drawing
996     // the image. So we have to kick the animation each time; this has the downside that the
997     // image will keep animating, even if its layer is not visible.
998     image->startAnimation();
999 }
1000
1001 FloatPoint3D RenderLayerBacking::computeTransformOrigin(const LayoutRect& borderBox) const
1002 {
1003     RenderStyle* style = renderer()->style();
1004
1005     FloatPoint3D origin;
1006     origin.setX(style->transformOriginX().calcFloatValue(borderBox.width()));
1007     origin.setY(style->transformOriginY().calcFloatValue(borderBox.height()));
1008     origin.setZ(style->transformOriginZ());
1009
1010     return origin;
1011 }
1012
1013 FloatPoint RenderLayerBacking::computePerspectiveOrigin(const LayoutRect& borderBox) const
1014 {
1015     RenderStyle* style = renderer()->style();
1016
1017     float boxWidth = borderBox.width();
1018     float boxHeight = borderBox.height();
1019
1020     FloatPoint origin;
1021     origin.setX(style->perspectiveOriginX().calcFloatValue(boxWidth));
1022     origin.setY(style->perspectiveOriginY().calcFloatValue(boxHeight));
1023
1024     return origin;
1025 }
1026
1027 // Return the offset from the top-left of this compositing layer at which the renderer's contents are painted.
1028 LayoutSize RenderLayerBacking::contentOffsetInCompostingLayer() const
1029 {
1030     return LayoutSize(-m_compositedBounds.x(), -m_compositedBounds.y());
1031 }
1032
1033 LayoutRect RenderLayerBacking::contentsBox() const
1034 {
1035     if (!renderer()->isBox())
1036         return LayoutRect();
1037
1038     LayoutRect contentsRect;
1039 #if ENABLE(VIDEO)
1040     if (renderer()->isVideo()) {
1041         RenderVideo* videoRenderer = toRenderVideo(renderer());
1042         contentsRect = videoRenderer->videoBox();
1043     } else
1044 #endif
1045         contentsRect = toRenderBox(renderer())->contentBoxRect();
1046
1047     LayoutSize contentOffset = contentOffsetInCompostingLayer();
1048     contentsRect.move(contentOffset);
1049     return contentsRect;
1050 }
1051
1052 bool RenderLayerBacking::paintingGoesToWindow() const
1053 {
1054     if (m_usingTiledCacheLayer)
1055         return false;
1056
1057     if (m_owningLayer->isRootLayer())
1058         return compositor()->rootLayerAttachment() != RenderLayerCompositor::RootLayerAttachedViaEnclosingFrame;
1059     
1060     return false;
1061 }
1062
1063 void RenderLayerBacking::setContentsNeedDisplay()
1064 {
1065     if (m_graphicsLayer && m_graphicsLayer->drawsContent())
1066         m_graphicsLayer->setNeedsDisplay();
1067     
1068     if (m_foregroundLayer && m_foregroundLayer->drawsContent())
1069         m_foregroundLayer->setNeedsDisplay();
1070
1071     if (m_maskLayer && m_maskLayer->drawsContent())
1072         m_maskLayer->setNeedsDisplay();
1073 }
1074
1075 // r is in the coordinate space of the layer's render object
1076 void RenderLayerBacking::setContentsNeedDisplayInRect(const LayoutRect& r)
1077 {
1078     if (m_graphicsLayer && m_graphicsLayer->drawsContent()) {
1079         LayoutRect layerDirtyRect = r;
1080         layerDirtyRect.move(-m_graphicsLayer->offsetFromRenderer());
1081         m_graphicsLayer->setNeedsDisplayInRect(layerDirtyRect);
1082     }
1083
1084     if (m_foregroundLayer && m_foregroundLayer->drawsContent()) {
1085         LayoutRect layerDirtyRect = r;
1086         layerDirtyRect.move(-m_foregroundLayer->offsetFromRenderer());
1087         m_foregroundLayer->setNeedsDisplayInRect(layerDirtyRect);
1088     }
1089
1090     if (m_maskLayer && m_maskLayer->drawsContent()) {
1091         LayoutRect layerDirtyRect = r;
1092         layerDirtyRect.move(-m_maskLayer->offsetFromRenderer());
1093         m_maskLayer->setNeedsDisplayInRect(layerDirtyRect);
1094     }
1095 }
1096
1097 void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* context,
1098                     const LayoutRect& paintDirtyRect, // In the coords of rootLayer.
1099                     PaintBehavior paintBehavior, GraphicsLayerPaintingPhase paintingPhase,
1100                     RenderObject* paintingRoot)
1101 {
1102     if (paintingGoesToWindow()) {
1103         ASSERT_NOT_REACHED();
1104         return;
1105     }
1106
1107     FontCachePurgePreventer fontCachePurgePreventer;
1108     
1109     RenderLayer::PaintLayerFlags paintFlags = 0;
1110     if (paintingPhase & GraphicsLayerPaintBackground)
1111         paintFlags |= RenderLayer::PaintLayerPaintingCompositingBackgroundPhase;
1112     if (paintingPhase & GraphicsLayerPaintForeground)
1113         paintFlags |= RenderLayer::PaintLayerPaintingCompositingForegroundPhase;
1114     if (paintingPhase & GraphicsLayerPaintMask)
1115         paintFlags |= RenderLayer::PaintLayerPaintingCompositingMaskPhase;
1116         
1117     // FIXME: GraphicsLayers need a way to split for RenderRegions.
1118     m_owningLayer->paintLayerContents(rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, 0, 0, paintFlags);
1119
1120     ASSERT(!m_owningLayer->m_usedTransparency);
1121 }
1122
1123 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const LayoutRect& clip)
1124 {
1125     if (!scrollbar)
1126         return;
1127
1128     context.save();
1129     const LayoutRect& scrollbarRect = scrollbar->frameRect();
1130     context.translate(-scrollbarRect.x(), -scrollbarRect.y());
1131     LayoutRect transformedClip = clip;
1132     transformedClip.moveBy(scrollbarRect.location());
1133     scrollbar->paint(&context, transformedClip);
1134     context.restore();
1135 }
1136
1137 // Up-call from compositing layer drawing callback.
1138 void RenderLayerBacking::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase paintingPhase, const LayoutRect& clip)
1139 {
1140     if (graphicsLayer == m_graphicsLayer.get() || graphicsLayer == m_foregroundLayer.get() || graphicsLayer == m_maskLayer.get()) {
1141         InspectorInstrumentationCookie cookie = InspectorInstrumentation::willPaint(m_owningLayer->renderer()->frame(), clip);
1142
1143         // The dirtyRect is in the coords of the painting root.
1144         LayoutRect dirtyRect = compositedBounds();
1145         dirtyRect.intersect(clip);
1146
1147         // We have to use the same root as for hit testing, because both methods can compute and cache clipRects.
1148         paintIntoLayer(m_owningLayer, &context, dirtyRect, PaintBehaviorNormal, paintingPhase, renderer());
1149
1150         InspectorInstrumentation::didPaint(cookie);
1151     } else if (graphicsLayer == layerForHorizontalScrollbar()) {
1152         paintScrollbar(m_owningLayer->horizontalScrollbar(), context, clip);
1153     } else if (graphicsLayer == layerForVerticalScrollbar()) {
1154         paintScrollbar(m_owningLayer->verticalScrollbar(), context, clip);
1155     } else if (graphicsLayer == layerForScrollCorner()) {
1156         const LayoutRect& scrollCornerAndResizer = m_owningLayer->scrollCornerAndResizerRect();
1157         context.save();
1158         context.translate(-scrollCornerAndResizer.x(), -scrollCornerAndResizer.y());
1159         LayoutRect transformedClip = clip;
1160         transformedClip.moveBy(scrollCornerAndResizer.location());
1161         m_owningLayer->paintScrollCorner(&context, LayoutPoint(), transformedClip);
1162         m_owningLayer->paintResizer(&context, LayoutPoint(), transformedClip);
1163         context.restore();
1164     }
1165 }
1166
1167 float RenderLayerBacking::pageScaleFactor() const
1168 {
1169     return compositor()->pageScaleFactor();
1170 }
1171
1172 float RenderLayerBacking::deviceScaleFactor() const
1173 {
1174     return compositor()->deviceScaleFactor();
1175 }
1176
1177 void RenderLayerBacking::didCommitChangesForLayer(const GraphicsLayer*) const
1178 {
1179     compositor()->didFlushChangesForLayer(m_owningLayer);
1180 }
1181
1182 bool RenderLayerBacking::showDebugBorders(const GraphicsLayer*) const
1183 {
1184     return compositor() ? compositor()->compositorShowDebugBorders() : false;
1185 }
1186
1187 bool RenderLayerBacking::showRepaintCounter(const GraphicsLayer*) const
1188 {
1189     return compositor() ? compositor()->compositorShowRepaintCounter() : false;
1190 }
1191
1192 bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim, const KeyframeList& keyframes)
1193 {
1194     bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity);
1195     bool hasTransform = renderer()->isBox() && keyframes.containsProperty(CSSPropertyWebkitTransform);
1196     
1197     if (!hasOpacity && !hasTransform)
1198         return false;
1199     
1200     KeyframeValueList transformVector(AnimatedPropertyWebkitTransform);
1201     KeyframeValueList opacityVector(AnimatedPropertyOpacity);
1202
1203     size_t numKeyframes = keyframes.size();
1204     for (size_t i = 0; i < numKeyframes; ++i) {
1205         const KeyframeValue& currentKeyframe = keyframes[i];
1206         const RenderStyle* keyframeStyle = currentKeyframe.style();
1207         float key = currentKeyframe.key();
1208
1209         if (!keyframeStyle)
1210             continue;
1211             
1212         // Get timing function.
1213         RefPtr<TimingFunction> tf = keyframeStyle->hasAnimations() ? (*keyframeStyle->animations()).animation(0)->timingFunction() : 0;
1214         
1215         bool isFirstOrLastKeyframe = key == 0 || key == 1;
1216         if ((hasTransform && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitTransform))
1217             transformVector.insert(new TransformAnimationValue(key, &(keyframeStyle->transform()), tf));
1218         
1219         if ((hasOpacity && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyOpacity))
1220             opacityVector.insert(new FloatAnimationValue(key, keyframeStyle->opacity(), tf));
1221     }
1222
1223     bool didAnimateTransform = false;
1224     bool didAnimateOpacity = false;
1225     
1226     if (hasTransform && m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->borderBoxRect().size(), anim, keyframes.animationName(), timeOffset)) {
1227         didAnimateTransform = true;
1228         compositor()->didStartAcceleratedAnimation(CSSPropertyWebkitTransform);
1229     }
1230
1231     if (hasOpacity && m_graphicsLayer->addAnimation(opacityVector, LayoutSize(), anim, keyframes.animationName(), timeOffset)) {
1232         didAnimateOpacity = true;
1233         compositor()->didStartAcceleratedAnimation(CSSPropertyOpacity);
1234     }
1235
1236     return didAnimateTransform || didAnimateOpacity;
1237 }
1238
1239 void RenderLayerBacking::animationPaused(double timeOffset, const String& animationName)
1240 {
1241     m_graphicsLayer->pauseAnimation(animationName, timeOffset);
1242 }
1243
1244 void RenderLayerBacking::animationFinished(const String& animationName)
1245 {
1246     m_graphicsLayer->removeAnimation(animationName);
1247 }
1248
1249 bool RenderLayerBacking::startTransition(double timeOffset, int property, const RenderStyle* fromStyle, const RenderStyle* toStyle)
1250 {
1251     bool didAnimateOpacity = false;
1252     bool didAnimateTransform = false;
1253     ASSERT(property != cAnimateAll);
1254
1255     if (property == (int)CSSPropertyOpacity) {
1256         const Animation* opacityAnim = toStyle->transitionForProperty(CSSPropertyOpacity);
1257         if (opacityAnim && !opacityAnim->isEmptyOrZeroDuration()) {
1258             KeyframeValueList opacityVector(AnimatedPropertyOpacity);
1259             opacityVector.insert(new FloatAnimationValue(0, compositingOpacity(fromStyle->opacity())));
1260             opacityVector.insert(new FloatAnimationValue(1, compositingOpacity(toStyle->opacity())));
1261             // The boxSize param is only used for transform animations (which can only run on RenderBoxes), so we pass an empty size here.
1262             if (m_graphicsLayer->addAnimation(opacityVector, LayoutSize(), opacityAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyOpacity), timeOffset)) {
1263                 // To ensure that the correct opacity is visible when the animation ends, also set the final opacity.
1264                 updateLayerOpacity(toStyle);
1265                 didAnimateOpacity = true;
1266             }
1267         }
1268     }
1269
1270     if (property == (int)CSSPropertyWebkitTransform && m_owningLayer->hasTransform()) {
1271         const Animation* transformAnim = toStyle->transitionForProperty(CSSPropertyWebkitTransform);
1272         if (transformAnim && !transformAnim->isEmptyOrZeroDuration()) {
1273             KeyframeValueList transformVector(AnimatedPropertyWebkitTransform);
1274             transformVector.insert(new TransformAnimationValue(0, &fromStyle->transform()));
1275             transformVector.insert(new TransformAnimationValue(1, &toStyle->transform()));
1276             if (m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->borderBoxRect().size(), transformAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitTransform), timeOffset)) {
1277                 // To ensure that the correct transform is visible when the animation ends, also set the final opacity.
1278                 updateLayerTransform(toStyle);
1279                 didAnimateTransform = true;
1280             }
1281         }
1282     }
1283
1284     if (didAnimateOpacity)
1285         compositor()->didStartAcceleratedAnimation(CSSPropertyOpacity);
1286
1287     if (didAnimateTransform)
1288         compositor()->didStartAcceleratedAnimation(CSSPropertyWebkitTransform);
1289     
1290     return didAnimateOpacity || didAnimateTransform;
1291 }
1292
1293 void RenderLayerBacking::transitionPaused(double timeOffset, int property)
1294 {
1295     AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
1296     if (animatedProperty != AnimatedPropertyInvalid)
1297         m_graphicsLayer->pauseAnimation(GraphicsLayer::animationNameForTransition(animatedProperty), timeOffset);
1298 }
1299
1300 void RenderLayerBacking::transitionFinished(int property)
1301 {
1302     AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
1303     if (animatedProperty != AnimatedPropertyInvalid)
1304         m_graphicsLayer->removeAnimation(GraphicsLayer::animationNameForTransition(animatedProperty));
1305 }
1306
1307 void RenderLayerBacking::notifyAnimationStarted(const GraphicsLayer*, double time)
1308 {
1309     renderer()->animation()->notifyAnimationStarted(renderer(), time);
1310 }
1311
1312 void RenderLayerBacking::notifySyncRequired(const GraphicsLayer*)
1313 {
1314     if (!renderer()->documentBeingDestroyed())
1315         compositor()->scheduleLayerFlush();
1316 }
1317
1318 // This is used for the 'freeze' API, for testing only.
1319 void RenderLayerBacking::suspendAnimations(double time)
1320 {
1321     m_graphicsLayer->suspendAnimations(time);
1322 }
1323
1324 void RenderLayerBacking::resumeAnimations()
1325 {
1326     m_graphicsLayer->resumeAnimations();
1327 }
1328
1329 LayoutRect RenderLayerBacking::compositedBounds() const
1330 {
1331     return m_compositedBounds;
1332 }
1333
1334 void RenderLayerBacking::setCompositedBounds(const LayoutRect& bounds)
1335 {
1336     m_compositedBounds = bounds;
1337
1338 }
1339 int RenderLayerBacking::graphicsLayerToCSSProperty(AnimatedPropertyID property)
1340 {
1341     int cssProperty = CSSPropertyInvalid;
1342     switch (property) {
1343         case AnimatedPropertyWebkitTransform:
1344             cssProperty = CSSPropertyWebkitTransform;
1345             break;
1346         case AnimatedPropertyOpacity:
1347             cssProperty = CSSPropertyOpacity;
1348             break;
1349         case AnimatedPropertyBackgroundColor:
1350             cssProperty = CSSPropertyBackgroundColor;
1351             break;
1352         case AnimatedPropertyInvalid:
1353             ASSERT_NOT_REACHED();
1354     }
1355     return cssProperty;
1356 }
1357
1358 AnimatedPropertyID RenderLayerBacking::cssToGraphicsLayerProperty(int cssProperty)
1359 {
1360     switch (cssProperty) {
1361         case CSSPropertyWebkitTransform:
1362             return AnimatedPropertyWebkitTransform;
1363         case CSSPropertyOpacity:
1364             return AnimatedPropertyOpacity;
1365         case CSSPropertyBackgroundColor:
1366             return AnimatedPropertyBackgroundColor;
1367         // It's fine if we see other css properties here; they are just not accelerated.
1368     }
1369     return AnimatedPropertyInvalid;
1370 }
1371
1372 #ifndef NDEBUG
1373 String RenderLayerBacking::nameForLayer() const
1374 {
1375     String name = renderer()->renderName();
1376     if (Node* node = renderer()->node()) {
1377         if (node->isElementNode())
1378             name += " " + static_cast<Element*>(node)->tagName();
1379         if (node->hasID())
1380             name += " \'" + static_cast<Element*>(node)->getIdAttribute() + "\'";
1381     }
1382
1383     if (m_owningLayer->isReflection())
1384         name += " (reflection)";
1385
1386     return name;
1387 }
1388 #endif
1389
1390 CompositingLayerType RenderLayerBacking::compositingLayerType() const
1391 {
1392     if (m_graphicsLayer->hasContentsLayer())
1393         return MediaCompositingLayer;
1394
1395     if (m_graphicsLayer->drawsContent())
1396         return m_graphicsLayer->usingTiledLayer() ? TiledCompositingLayer : NormalCompositingLayer;
1397     
1398     return ContainerCompositingLayer;
1399 }
1400
1401 } // namespace WebCore
1402
1403 #endif // USE(ACCELERATED_COMPOSITING)