Should get rid of TileController's CoverageForSlowScrolling mode
[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 #include "RenderLayerBacking.h"
29
30 #include "AnimationController.h"
31 #include "CanvasRenderingContext.h"
32 #include "CSSPropertyNames.h"
33 #include "CachedImage.h"
34 #include "Chrome.h"
35 #include "FontCache.h"
36 #include "FrameView.h"
37 #include "GraphicsContext.h"
38 #include "GraphicsLayer.h"
39 #include "HTMLCanvasElement.h"
40 #include "HTMLIFrameElement.h"
41 #include "HTMLMediaElement.h"
42 #include "HTMLNames.h"
43 #include "HTMLPlugInElement.h"
44 #include "InspectorInstrumentation.h"
45 #include "KeyframeList.h"
46 #include "MainFrame.h"
47 #include "PluginViewBase.h"
48 #include "ProgressTracker.h"
49 #include "RenderFlowThread.h"
50 #include "RenderIFrame.h"
51 #include "RenderImage.h"
52 #include "RenderLayerCompositor.h"
53 #include "RenderEmbeddedObject.h"
54 #include "RenderNamedFlowFragment.h"
55 #include "RenderRegion.h"
56 #include "RenderVideo.h"
57 #include "RenderView.h"
58 #include "ScrollingCoordinator.h"
59 #include "Settings.h"
60 #include "StyleResolver.h"
61 #include "TiledBacking.h"
62 #include <wtf/text/StringBuilder.h>
63
64 #if ENABLE(CSS_FILTERS)
65 #include "FilterEffectRenderer.h"
66 #endif
67
68 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
69 #include "GraphicsContext3D.h"
70 #endif
71
72 namespace WebCore {
73
74 using namespace HTMLNames;
75
76 static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle*);
77 static IntRect clipBox(RenderBox& renderer);
78
79 CanvasCompositingStrategy canvasCompositingStrategy(const RenderObject& renderer)
80 {
81     ASSERT(renderer.isCanvas());
82     
83     const HTMLCanvasElement* canvas = toHTMLCanvasElement(renderer.node());
84     CanvasRenderingContext* context = canvas->renderingContext();
85     if (!context || !context->isAccelerated())
86         return UnacceleratedCanvas;
87     
88     if (context->is3d())
89         return CanvasAsLayerContents;
90
91 #if ENABLE(ACCELERATED_2D_CANVAS)
92     return CanvasAsLayerContents;
93 #else
94     return CanvasPaintedToLayer; // On Mac and iOS we paint accelerated canvases into their layers.
95 #endif
96 }
97
98 // Get the scrolling coordinator in a way that works inside RenderLayerBacking's destructor.
99 static ScrollingCoordinator* scrollingCoordinatorFromLayer(RenderLayer& layer)
100 {
101     Page* page = layer.renderer().frame().page();
102     if (!page)
103         return 0;
104
105     return page->scrollingCoordinator();
106 }
107
108 bool RenderLayerBacking::m_creatingPrimaryGraphicsLayer = false;
109
110 RenderLayerBacking::RenderLayerBacking(RenderLayer& layer)
111     : m_owningLayer(layer)
112     , m_scrollLayerID(0)
113     , m_artificiallyInflatedBounds(false)
114     , m_isMainFrameRenderViewLayer(false)
115     , m_usingTiledCacheLayer(false)
116     , m_requiresOwnBackingStore(true)
117 #if ENABLE(CSS_FILTERS)
118     , m_canCompositeFilters(false)
119 #endif
120     , m_backgroundLayerPaintsFixedRootBackground(false)
121 {
122     Page* page = renderer().frame().page();
123
124     if (layer.isRootLayer() && page) {
125         if (renderer().frame().isMainFrame())
126             m_isMainFrameRenderViewLayer = true;
127
128         m_usingTiledCacheLayer = page->chrome().client().shouldUseTiledBackingForFrameView(renderer().frame().view());
129     }
130     
131     createPrimaryGraphicsLayer();
132
133     if (m_usingTiledCacheLayer && page) {
134         TiledBacking* tiledBacking = this->tiledBacking();
135
136         tiledBacking->setIsInWindow(page->isInWindow());
137
138         if (m_isMainFrameRenderViewLayer) {
139             tiledBacking->setExposedRect(renderer().frame().view()->exposedRect());
140             tiledBacking->setUnparentsOffscreenTiles(true);
141         }
142
143         tiledBacking->setScrollingPerformanceLoggingEnabled(page->settings().scrollingPerformanceLoggingEnabled());
144         adjustTiledBackingCoverage();
145     }
146 }
147
148 RenderLayerBacking::~RenderLayerBacking()
149 {
150     updateAncestorClippingLayer(false);
151     updateDescendantClippingLayer(false);
152     updateOverflowControlsLayers(false, false, false);
153     updateForegroundLayer(false);
154     updateBackgroundLayer(false);
155     updateMaskLayer(false);
156     updateScrollingLayers(false);
157     detachFromScrollingCoordinator();
158     destroyGraphicsLayers();
159 }
160
161 void RenderLayerBacking::willDestroyLayer(const GraphicsLayer* layer)
162 {
163     if (layer && layer->usingTiledBacking())
164         compositor().layerTiledBackingUsageChanged(layer, false);
165 }
166
167 std::unique_ptr<GraphicsLayer> RenderLayerBacking::createGraphicsLayer(const String& name)
168 {
169     GraphicsLayerFactory* graphicsLayerFactory = 0;
170     if (Page* page = renderer().frame().page())
171         graphicsLayerFactory = page->chrome().client().graphicsLayerFactory();
172
173     std::unique_ptr<GraphicsLayer> graphicsLayer = GraphicsLayer::create(graphicsLayerFactory, this);
174
175 #ifndef NDEBUG
176     graphicsLayer->setName(name);
177 #else
178     UNUSED_PARAM(name);
179 #endif
180     graphicsLayer->setMaintainsPixelAlignment(compositor().keepLayersPixelAligned());
181
182 #if PLATFORM(MAC) && USE(CA)
183     graphicsLayer->setAcceleratesDrawing(compositor().acceleratedDrawingEnabled());
184 #endif    
185     
186     return graphicsLayer;
187 }
188
189 bool RenderLayerBacking::shouldUseTiledBacking(const GraphicsLayer*) const
190 {
191     return m_usingTiledCacheLayer && m_creatingPrimaryGraphicsLayer;
192 }
193
194 void RenderLayerBacking::tiledBackingUsageChanged(const GraphicsLayer* layer, bool usingTiledBacking)
195 {
196     compositor().layerTiledBackingUsageChanged(layer, usingTiledBacking);
197 }
198
199 TiledBacking* RenderLayerBacking::tiledBacking() const
200 {
201     return m_graphicsLayer->tiledBacking();
202 }
203
204 static TiledBacking::TileCoverage computeTileCoverage(RenderLayerBacking* backing)
205 {
206     // FIXME: When we use TiledBacking for overflow, this should look at RenderView scrollability.
207     FrameView& frameView = backing->owningLayer().renderer().view().frameView();
208
209     TiledBacking::TileCoverage tileCoverage = TiledBacking::CoverageForVisibleArea;
210     bool useMinimalTilesDuringLiveResize = frameView.inLiveResize();
211     if (frameView.speculativeTilingEnabled() && !useMinimalTilesDuringLiveResize) {
212         bool clipsToExposedRect = !frameView.exposedRect().isInfinite();
213         if (frameView.horizontalScrollbarMode() != ScrollbarAlwaysOff || clipsToExposedRect)
214             tileCoverage |= TiledBacking::CoverageForHorizontalScrolling;
215
216         if (frameView.verticalScrollbarMode() != ScrollbarAlwaysOff || clipsToExposedRect)
217             tileCoverage |= TiledBacking::CoverageForVerticalScrolling;
218     }
219     return tileCoverage;
220 }
221
222 void RenderLayerBacking::adjustTiledBackingCoverage()
223 {
224     if (!m_usingTiledCacheLayer)
225         return;
226
227     TiledBacking::TileCoverage tileCoverage = computeTileCoverage(this);
228     tiledBacking()->setTileCoverage(tileCoverage);
229 }
230
231 void RenderLayerBacking::setTiledBackingHasMargins(bool hasExtendedBackgroundRect)
232 {
233     if (!m_usingTiledCacheLayer)
234         return;
235
236     int marginLeftAndRightSize = hasExtendedBackgroundRect ? defaultTileWidth : 0;
237     int marginTopAndBottomSize = hasExtendedBackgroundRect ? defaultTileHeight : 0;
238     tiledBacking()->setTileMargins(marginTopAndBottomSize, marginTopAndBottomSize, marginLeftAndRightSize, marginLeftAndRightSize);
239 }
240
241 void RenderLayerBacking::updateDebugIndicators(bool showBorder, bool showRepaintCounter)
242 {
243     m_graphicsLayer->setShowDebugBorder(showBorder);
244     m_graphicsLayer->setShowRepaintCounter(showRepaintCounter);
245     
246     if (m_ancestorClippingLayer)
247         m_ancestorClippingLayer->setShowDebugBorder(showBorder);
248
249     if (m_foregroundLayer) {
250         m_foregroundLayer->setShowDebugBorder(showBorder);
251         m_foregroundLayer->setShowRepaintCounter(showRepaintCounter);
252     }
253     
254     if (m_contentsContainmentLayer)
255         m_contentsContainmentLayer->setShowDebugBorder(showBorder);
256     
257     if (m_backgroundLayer) {
258         m_backgroundLayer->setShowDebugBorder(showBorder);
259         m_backgroundLayer->setShowRepaintCounter(showRepaintCounter);
260     }
261
262     if (m_maskLayer) {
263         m_maskLayer->setShowDebugBorder(showBorder);
264         m_maskLayer->setShowRepaintCounter(showRepaintCounter);
265     }
266
267     if (m_layerForHorizontalScrollbar)
268         m_layerForHorizontalScrollbar->setShowDebugBorder(showBorder);
269
270     if (m_layerForVerticalScrollbar)
271         m_layerForVerticalScrollbar->setShowDebugBorder(showBorder);
272
273     if (m_layerForScrollCorner)
274         m_layerForScrollCorner->setShowDebugBorder(showBorder);
275
276     if (m_scrollingLayer)
277         m_scrollingLayer->setShowDebugBorder(showBorder);
278
279     if (m_scrollingContentsLayer) {
280         m_scrollingContentsLayer->setShowDebugBorder(showBorder);
281         m_scrollingContentsLayer->setShowRepaintCounter(showRepaintCounter);
282     }
283 }
284
285 void RenderLayerBacking::createPrimaryGraphicsLayer()
286 {
287     String layerName;
288 #ifndef NDEBUG
289     layerName = m_owningLayer.name();
290 #endif
291     
292     // The call to createGraphicsLayer ends calling back into here as
293     // a GraphicsLayerClient to ask if it shouldUseTiledBacking(). We only want
294     // the tile cache on our main layer. This is pretty ugly, but saves us from
295     // exposing the API to all clients.
296
297     m_creatingPrimaryGraphicsLayer = true;
298     m_graphicsLayer = createGraphicsLayer(layerName);
299     m_creatingPrimaryGraphicsLayer = false;
300
301     if (m_usingTiledCacheLayer)
302         m_childContainmentLayer = createGraphicsLayer("TiledBacking Flattening Layer");
303
304     if (m_isMainFrameRenderViewLayer) {
305 #if !PLATFORM(IOS)
306         // Page scale is applied above the RenderView on iOS.
307         m_graphicsLayer->setContentsOpaque(true);
308         m_graphicsLayer->setAppliesPageScale();
309 #endif
310     }
311
312 #if PLATFORM(MAC) && USE(CA)
313     if (!compositor().acceleratedDrawingEnabled() && renderer().isCanvas()) {
314         const HTMLCanvasElement* canvas = toHTMLCanvasElement(renderer().element());
315         if (canvas->shouldAccelerate(canvas->size()))
316             m_graphicsLayer->setAcceleratesDrawing(true);
317     }
318 #endif    
319     
320     updateOpacity(&renderer().style());
321     updateTransform(&renderer().style());
322 #if ENABLE(CSS_FILTERS)
323     updateFilters(&renderer().style());
324 #endif
325 #if ENABLE(CSS_COMPOSITING)
326     updateBlendMode(&renderer().style());
327 #endif
328 }
329
330 #if PLATFORM(IOS)
331 void RenderLayerBacking::layerWillBeDestroyed()
332 {
333     RenderObject& renderer = this->renderer();
334     if (renderer.isEmbeddedObject() && toRenderEmbeddedObject(renderer).allowsAcceleratedCompositing()) {
335         PluginViewBase* pluginViewBase = toPluginViewBase(toRenderWidget(renderer).widget());
336         if (pluginViewBase && m_graphicsLayer->contentsLayerForMedia())
337             pluginViewBase->detachPluginLayer();
338     }
339 }
340 #endif
341
342 void RenderLayerBacking::destroyGraphicsLayers()
343 {
344     if (m_graphicsLayer) {
345         willDestroyLayer(m_graphicsLayer.get());
346         m_graphicsLayer->removeFromParent();
347     }
348
349     m_ancestorClippingLayer = nullptr;
350     m_contentsContainmentLayer = nullptr;
351     m_graphicsLayer = nullptr;
352     m_foregroundLayer = nullptr;
353     m_backgroundLayer = nullptr;
354     m_childContainmentLayer = nullptr;
355     m_maskLayer = nullptr;
356
357     m_scrollingLayer = nullptr;
358     m_scrollingContentsLayer = nullptr;
359 }
360
361 void RenderLayerBacking::updateOpacity(const RenderStyle* style)
362 {
363     m_graphicsLayer->setOpacity(compositingOpacity(style->opacity()));
364 }
365
366 void RenderLayerBacking::updateTransform(const RenderStyle* style)
367 {
368     // FIXME: This could use m_owningLayer.transform(), but that currently has transform-origin
369     // baked into it, and we don't want that.
370     TransformationMatrix t;
371     if (m_owningLayer.hasTransform()) {
372         style->applyTransform(t, toRenderBox(renderer()).pixelSnappedBorderBoxRect().size(), RenderStyle::ExcludeTransformOrigin);
373         makeMatrixRenderable(t, compositor().canRender3DTransforms());
374     }
375     
376     if (m_contentsContainmentLayer) {
377         m_contentsContainmentLayer->setTransform(t);
378         m_graphicsLayer->setTransform(TransformationMatrix());
379     } else
380         m_graphicsLayer->setTransform(t);
381 }
382
383 #if ENABLE(CSS_FILTERS)
384 void RenderLayerBacking::updateFilters(const RenderStyle* style)
385 {
386     m_canCompositeFilters = m_graphicsLayer->setFilters(style->filter());
387 }
388 #endif
389
390 #if ENABLE(CSS_COMPOSITING)
391 void RenderLayerBacking::updateBlendMode(const RenderStyle* style)
392 {
393     if (m_ancestorClippingLayer)
394         m_ancestorClippingLayer->setBlendMode(style->blendMode());
395     else
396         m_graphicsLayer->setBlendMode(style->blendMode());
397 }
398 #endif
399
400 static bool hasNonZeroTransformOrigin(const RenderObject& renderer)
401 {
402     const RenderStyle& style = renderer.style();
403     return (style.transformOriginX().type() == Fixed && style.transformOriginX().value())
404         || (style.transformOriginY().type() == Fixed && style.transformOriginY().value());
405 }
406
407 #if PLATFORM(IOS)
408 // FIXME: We should merge the concept of RenderLayer::{hasAcceleratedTouchScrolling, needsCompositedScrolling}()
409 // so that we can remove this iOS-specific variant.
410 static bool layerOrAncestorIsTransformedOrScrolling(RenderLayer& layer)
411 {
412     for (RenderLayer* curr = &layer; curr; curr = curr->parent()) {
413         if (curr->hasTransform() || curr->hasAcceleratedTouchScrolling())
414             return true;
415     }
416
417     return false;
418 }
419 #else
420 static bool layerOrAncestorIsTransformedOrUsingCompositedScrolling(RenderLayer& layer)
421 {
422     for (RenderLayer* curr = &layer; curr; curr = curr->parent()) {
423         if (curr->hasTransform() || curr->needsCompositedScrolling())
424             return true;
425     }
426
427     return false;
428 }
429 #endif
430     
431 bool RenderLayerBacking::shouldClipCompositedBounds() const
432 {
433 #if !PLATFORM(IOS)
434     // Scrollbar layers use this layer for relative positioning, so don't clip.
435     if (layerForHorizontalScrollbar() || layerForVerticalScrollbar())
436         return false;
437 #endif
438
439     if (m_usingTiledCacheLayer)
440         return false;
441
442 #if !PLATFORM(IOS)
443     if (layerOrAncestorIsTransformedOrUsingCompositedScrolling(m_owningLayer))
444         return false;
445 #else
446     if (layerOrAncestorIsTransformedOrScrolling(m_owningLayer))
447         return false;
448 #endif
449
450     if (m_owningLayer.isFlowThreadCollectingGraphicsLayersUnderRegions())
451         return false;
452
453     return true;
454 }
455
456 void RenderLayerBacking::updateCompositedBounds()
457 {
458     LayoutRect layerBounds = compositor().calculateCompositedBounds(m_owningLayer, m_owningLayer);
459
460     // Clip to the size of the document or enclosing overflow-scroll layer.
461     // If this or an ancestor is transformed, we can't currently compute the correct rect to intersect with.
462     // We'd need RenderObject::convertContainerToLocalQuad(), which doesn't yet exist.
463     if (shouldClipCompositedBounds()) {
464         RenderView& view = m_owningLayer.renderer().view();
465         RenderLayer* rootLayer = view.layer();
466
467         LayoutRect clippingBounds;
468         if (renderer().style().position() == FixedPosition && renderer().container() == &view)
469             clippingBounds = view.frameView().viewportConstrainedExtentRect();
470         else
471             clippingBounds = view.unscaledDocumentRect();
472
473         if (&m_owningLayer != rootLayer)
474             clippingBounds.intersect(m_owningLayer.backgroundClipRect(RenderLayer::ClipRectsContext(rootLayer, 0, AbsoluteClipRects)).rect()); // FIXME: Incorrect for CSS regions.
475
476         LayoutPoint delta;
477         m_owningLayer.convertToLayerCoords(rootLayer, delta, RenderLayer::AdjustForColumns);
478         clippingBounds.move(-delta.x(), -delta.y());
479
480         layerBounds.intersect(clippingBounds);
481     }
482     
483     // If the element has a transform-origin that has fixed lengths, and the renderer has zero size,
484     // then we need to ensure that the compositing layer has non-zero size so that we can apply
485     // the transform-origin via the GraphicsLayer anchorPoint (which is expressed as a fractional value).
486     if (layerBounds.isEmpty() && hasNonZeroTransformOrigin(renderer())) {
487         layerBounds.setWidth(1);
488         layerBounds.setHeight(1);
489         m_artificiallyInflatedBounds = true;
490     } else
491         m_artificiallyInflatedBounds = false;
492
493     setCompositedBounds(layerBounds);
494 }
495
496 void RenderLayerBacking::updateAfterWidgetResize()
497 {
498     if (!renderer().isWidget())
499         return;
500     if (RenderLayerCompositor* innerCompositor = RenderLayerCompositor::frameContentsCompositor(toRenderWidget(&renderer()))) {
501         innerCompositor->frameViewDidChangeSize();
502         innerCompositor->frameViewDidChangeLocation(flooredIntPoint(contentsBox().location()));
503     }
504 }
505
506 void RenderLayerBacking::updateAfterLayout(UpdateAfterLayoutFlags flags)
507 {
508     if (!compositor().compositingLayersNeedRebuild()) {
509         // Calling updateGraphicsLayerGeometry() here gives incorrect results, because the
510         // position of this layer's GraphicsLayer depends on the position of our compositing
511         // ancestor's GraphicsLayer. That cannot be determined until all the descendant 
512         // RenderLayers of that ancestor have been processed via updateLayerPositions().
513         //
514         // The solution is to update compositing children of this layer here,
515         // via updateCompositingChildrenGeometry().
516         updateCompositedBounds();
517         compositor().updateCompositingDescendantGeometry(m_owningLayer, m_owningLayer, flags & CompositingChildrenOnly);
518         
519         if (flags & IsUpdateRoot) {
520             updateGraphicsLayerGeometry();
521             compositor().updateRootLayerPosition();
522             RenderLayer* stackingContainer = m_owningLayer.enclosingStackingContainer();
523             if (!compositor().compositingLayersNeedRebuild() && stackingContainer && (stackingContainer != &m_owningLayer))
524                 compositor().updateCompositingDescendantGeometry(*stackingContainer, *stackingContainer, flags & CompositingChildrenOnly);
525         }
526     }
527     
528     if (flags & NeedsFullRepaint && !paintsIntoWindow() && !paintsIntoCompositedAncestor())
529         setContentsNeedDisplay();
530 }
531
532 bool RenderLayerBacking::updateGraphicsLayerConfiguration()
533 {
534     m_owningLayer.updateDescendantDependentFlags();
535     m_owningLayer.updateZOrderLists();
536
537     bool layerConfigChanged = false;
538     setBackgroundLayerPaintsFixedRootBackground(compositor().needsFixedRootBackgroundLayer(m_owningLayer));
539     
540     // The background layer is currently only used for fixed root backgrounds.
541     if (updateBackgroundLayer(m_backgroundLayerPaintsFixedRootBackground))
542         layerConfigChanged = true;
543
544     if (updateForegroundLayer(compositor().needsContentsCompositingLayer(m_owningLayer)))
545         layerConfigChanged = true;
546     
547     bool needsDescendentsClippingLayer = compositor().clipsCompositingDescendants(m_owningLayer);
548
549 #if PLATFORM(IOS)
550     // Our scrolling layer will clip.
551     if (m_owningLayer.hasAcceleratedTouchScrolling())
552         needsDescendentsClippingLayer = false;
553 #else
554     // Our scrolling layer will clip.
555     if (m_owningLayer.needsCompositedScrolling())
556         needsDescendentsClippingLayer = false;
557 #endif // PLATFORM(IOS)
558
559     if (updateAncestorClippingLayer(compositor().clippedByAncestor(m_owningLayer)))
560         layerConfigChanged = true;
561
562     if (updateDescendantClippingLayer(needsDescendentsClippingLayer))
563         layerConfigChanged = true;
564
565     if (updateOverflowControlsLayers(requiresHorizontalScrollbarLayer(), requiresVerticalScrollbarLayer(), requiresScrollCornerLayer()))
566         layerConfigChanged = true;
567
568 #if PLATFORM(IOS)
569     if (updateScrollingLayers(m_owningLayer.hasAcceleratedTouchScrolling()))
570         layerConfigChanged = true;
571 #else
572     if (updateScrollingLayers(m_owningLayer.needsCompositedScrolling()))
573         layerConfigChanged = true;
574 #endif // PLATFORM(IOS)
575
576     if (layerConfigChanged)
577         updateInternalHierarchy();
578
579     if (GraphicsLayer* flatteningLayer = tileCacheFlatteningLayer()) {
580         if (layerConfigChanged || flatteningLayer->parent() != m_graphicsLayer.get())
581             m_graphicsLayer->addChild(flatteningLayer);
582     }
583
584     if (updateMaskLayer(renderer().hasMask()))
585         m_graphicsLayer->setMaskLayer(m_maskLayer.get());
586
587     if (m_owningLayer.hasReflection()) {
588         if (m_owningLayer.reflectionLayer()->backing()) {
589             GraphicsLayer* reflectionLayer = m_owningLayer.reflectionLayer()->backing()->graphicsLayer();
590             m_graphicsLayer->setReplicatedByLayer(reflectionLayer);
591         }
592     } else
593         m_graphicsLayer->setReplicatedByLayer(0);
594
595     bool isSimpleContainer = isSimpleContainerCompositingLayer();
596     bool didUpdateContentsRect = false;
597     updateDirectlyCompositedContents(isSimpleContainer, didUpdateContentsRect);
598
599     updateRootLayerConfiguration();
600     
601     if (isDirectlyCompositedImage())
602         updateImageContents();
603
604     if (renderer().isEmbeddedObject() && toRenderEmbeddedObject(&renderer())->allowsAcceleratedCompositing()) {
605         PluginViewBase* pluginViewBase = toPluginViewBase(toRenderWidget(&renderer())->widget());
606 #if PLATFORM(IOS)
607         if (pluginViewBase && !m_graphicsLayer->contentsLayerForMedia()) {
608             pluginViewBase->detachPluginLayer();
609             pluginViewBase->attachPluginLayer();
610         }
611 #else
612         if (!pluginViewBase->shouldNotAddLayer())
613             m_graphicsLayer->setContentsToMedia(pluginViewBase->platformLayer());
614 #endif
615     }
616 #if ENABLE(VIDEO)
617     else if (renderer().isVideo()) {
618         HTMLMediaElement* mediaElement = toHTMLMediaElement(renderer().element());
619         m_graphicsLayer->setContentsToMedia(mediaElement->platformLayer());
620     }
621 #endif
622 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
623     else if (renderer().isCanvas() && canvasCompositingStrategy(renderer()) == CanvasAsLayerContents) {
624         const HTMLCanvasElement* canvas = toHTMLCanvasElement(renderer().element());
625         if (CanvasRenderingContext* context = canvas->renderingContext())
626             m_graphicsLayer->setContentsToCanvas(context->platformLayer());
627         layerConfigChanged = true;
628     }
629 #endif
630     if (renderer().isWidget())
631         layerConfigChanged = RenderLayerCompositor::parentFrameContentLayers(toRenderWidget(&renderer()));
632
633     return layerConfigChanged;
634 }
635
636 static IntRect clipBox(RenderBox& renderer)
637 {
638     LayoutRect result = LayoutRect::infiniteRect();
639     if (renderer.hasOverflowClip())
640         result = renderer.overflowClipRect(LayoutPoint(), 0); // FIXME: Incorrect for CSS regions.
641
642     if (renderer.hasClip())
643         result.intersect(renderer.clipRect(LayoutPoint(), 0)); // FIXME: Incorrect for CSS regions.
644
645     return pixelSnappedIntRect(result);
646 }
647
648 void RenderLayerBacking::updateGraphicsLayerGeometry()
649 {
650     // If we haven't built z-order lists yet, wait until later.
651     if (m_owningLayer.isStackingContainer() && m_owningLayer.m_zOrderListsDirty)
652         return;
653
654     // Set transform property, if it is not animating. We have to do this here because the transform
655     // is affected by the layer dimensions.
656     if (!renderer().animation().isRunningAcceleratedAnimationOnRenderer(&renderer(), CSSPropertyWebkitTransform))
657         updateTransform(&renderer().style());
658
659     // Set opacity, if it is not animating.
660     if (!renderer().animation().isRunningAcceleratedAnimationOnRenderer(&renderer(), CSSPropertyOpacity))
661         updateOpacity(&renderer().style());
662         
663 #if ENABLE(CSS_FILTERS)
664     updateFilters(&renderer().style());
665 #endif
666
667 #if ENABLE(CSS_COMPOSITING)
668     updateBlendMode(&renderer().style());
669 #endif
670
671     bool isSimpleContainer = isSimpleContainerCompositingLayer();
672     
673     m_owningLayer.updateDescendantDependentFlags();
674
675     // m_graphicsLayer is the corresponding GraphicsLayer for this RenderLayer and its non-compositing
676     // descendants. So, the visibility flag for m_graphicsLayer should be true if there are any
677     // non-compositing visible layers.
678     m_graphicsLayer->setContentsVisible(m_owningLayer.hasVisibleContent() || hasVisibleNonCompositingDescendantLayers());
679
680     const RenderStyle& style = renderer().style();
681     // FIXME: reflections should force transform-style to be flat in the style: https://bugs.webkit.org/show_bug.cgi?id=106959
682     bool preserves3D = style.transformStyle3D() == TransformStyle3DPreserve3D && !renderer().hasReflection();
683     m_graphicsLayer->setPreserves3D(preserves3D);
684     m_graphicsLayer->setBackfaceVisibility(style.backfaceVisibility() == BackfaceVisibilityVisible);
685
686     RenderLayer* compAncestor = m_owningLayer.ancestorCompositingLayer();
687     
688     // We compute everything relative to the enclosing compositing layer.
689     IntRect ancestorCompositingBounds;
690     if (compAncestor) {
691         ASSERT(compAncestor->backing());
692         ancestorCompositingBounds = pixelSnappedIntRect(compAncestor->backing()->compositedBounds());
693     }
694
695     LayoutRect localRawCompositingBounds = compositedBounds();
696     LayoutPoint rawDelta;
697     m_owningLayer.convertToLayerCoords(compAncestor, rawDelta, RenderLayer::AdjustForColumns);
698     IntPoint delta = flooredIntPoint(rawDelta);
699     m_subpixelAccumulation = toLayoutSize(rawDelta.fraction());
700     // Move the bounds by the subpixel accumulation so that it pixel-snaps relative to absolute pixels instead of local coordinates.
701     localRawCompositingBounds.move(m_subpixelAccumulation);
702
703     IntRect localCompositingBounds = pixelSnappedIntRect(localRawCompositingBounds);
704     IntRect relativeCompositingBounds(localCompositingBounds);
705     relativeCompositingBounds.moveBy(delta);
706
707     adjustAncestorCompositingBoundsForFlowThread(ancestorCompositingBounds, compAncestor);
708
709     IntPoint graphicsLayerParentLocation;
710     if (compAncestor && compAncestor->backing()->hasClippingLayer()) {
711         // If the compositing ancestor has a layer to clip children, we parent in that, and therefore
712         // position relative to it.
713         IntRect clippingBox = clipBox(toRenderBox(compAncestor->renderer()));
714         graphicsLayerParentLocation = clippingBox.location();
715     } else if (compAncestor)
716         graphicsLayerParentLocation = ancestorCompositingBounds.location();
717     else
718         graphicsLayerParentLocation = renderer().view().documentRect().location();
719
720 #if PLATFORM(IOS)
721     if (compAncestor && compAncestor->hasAcceleratedTouchScrolling()) {
722         RenderBox* renderBox = toRenderBox(&compAncestor->renderer());
723         IntRect paddingBox(renderBox->borderLeft(), renderBox->borderTop(),
724             renderBox->width() - renderBox->borderLeft() - renderBox->borderRight(),
725             renderBox->height() - renderBox->borderTop() - renderBox->borderBottom());
726
727         IntSize scrollOffset = compAncestor->scrolledContentOffset();
728         graphicsLayerParentLocation = paddingBox.location() - scrollOffset;
729     }
730 #endif
731
732     if (compAncestor && compAncestor->needsCompositedScrolling()) {
733         RenderBox& renderBox = toRenderBox(compAncestor->renderer());
734         IntSize scrollOffset = compAncestor->scrolledContentOffset();
735         IntPoint scrollOrigin(renderBox.borderLeft(), renderBox.borderTop());
736         graphicsLayerParentLocation = scrollOrigin - scrollOffset;
737     }
738     
739     if (compAncestor && m_ancestorClippingLayer) {
740         // Call calculateRects to get the backgroundRect which is what is used to clip the contents of this
741         // layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects
742         // for a compositing layer, rootLayer is the layer itself.
743         RenderLayer::ClipRectsContext clipRectsContext(compAncestor, 0, TemporaryClipRects, IgnoreOverlayScrollbarSize, IgnoreOverflowClip);
744         IntRect parentClipRect = pixelSnappedIntRect(m_owningLayer.backgroundClipRect(clipRectsContext).rect()); // FIXME: Incorrect for CSS regions.
745         ASSERT(parentClipRect != IntRect::infiniteRect());
746         m_ancestorClippingLayer->setPosition(FloatPoint(parentClipRect.location() - graphicsLayerParentLocation));
747         m_ancestorClippingLayer->setSize(parentClipRect.size());
748
749         // backgroundRect is relative to compAncestor, so subtract deltaX/deltaY to get back to local coords.
750         m_ancestorClippingLayer->setOffsetFromRenderer(parentClipRect.location() - delta);
751
752         // The primary layer is then parented in, and positioned relative to this clipping layer.
753         graphicsLayerParentLocation = parentClipRect.location();
754     }
755
756     FloatSize contentsSize = relativeCompositingBounds.size();
757     
758     if (m_contentsContainmentLayer) {
759         m_contentsContainmentLayer->setPreserves3D(preserves3D);
760         m_contentsContainmentLayer->setPosition(FloatPoint(relativeCompositingBounds.location() - graphicsLayerParentLocation));
761         // Use the same size as m_graphicsLayer so transforms behave correctly.
762         m_contentsContainmentLayer->setSize(contentsSize);
763         graphicsLayerParentLocation = relativeCompositingBounds.location();
764     }
765
766     m_graphicsLayer->setPosition(FloatPoint(relativeCompositingBounds.location() - graphicsLayerParentLocation));
767     m_graphicsLayer->setSize(contentsSize);
768     IntSize offsetFromRenderer = toIntSize(localCompositingBounds.location());
769     if (offsetFromRenderer != m_graphicsLayer->offsetFromRenderer()) {
770         m_graphicsLayer->setOffsetFromRenderer(toIntSize(localCompositingBounds.location()));
771         positionOverflowControlsLayers();
772     }
773
774     if (!m_isMainFrameRenderViewLayer) {
775         // For non-root layers, background is always painted by the primary graphics layer.
776         ASSERT(!m_backgroundLayer);
777         bool hadSubpixelRounding = LayoutSize(relativeCompositingBounds.size()) != localRawCompositingBounds.size();
778         m_graphicsLayer->setContentsOpaque(!hadSubpixelRounding && m_owningLayer.backgroundIsKnownToBeOpaqueInRect(localCompositingBounds));
779     }
780
781     // If we have a layer that clips children, position it.
782     IntRect clippingBox;
783     if (GraphicsLayer* clipLayer = clippingLayer()) {
784         clippingBox = clipBox(toRenderBox(renderer()));
785         clipLayer->setPosition(FloatPoint(clippingBox.location() - localCompositingBounds.location()));
786         clipLayer->setSize(clippingBox.size());
787         clipLayer->setOffsetFromRenderer(toIntSize(clippingBox.location()));
788     }
789     
790     if (m_maskLayer) {
791         m_maskLayer->setSize(m_graphicsLayer->size());
792         m_maskLayer->setPosition(FloatPoint());
793         m_maskLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
794     }
795     
796     if (m_owningLayer.hasTransform()) {
797         const IntRect borderBox = toRenderBox(renderer()).pixelSnappedBorderBoxRect();
798
799         // Get layout bounds in the coords of compAncestor to match relativeCompositingBounds.
800         IntRect layerBounds(delta, borderBox.size());
801
802         // Update properties that depend on layer dimensions
803         FloatPoint3D transformOrigin = computeTransformOrigin(borderBox);
804         // Compute the anchor point, which is in the center of the renderer box unless transform-origin is set.
805         FloatPoint3D anchor(relativeCompositingBounds.width()  != 0.0f ? ((layerBounds.x() - relativeCompositingBounds.x()) + transformOrigin.x()) / relativeCompositingBounds.width()  : 0.5f,
806                             relativeCompositingBounds.height() != 0.0f ? ((layerBounds.y() - relativeCompositingBounds.y()) + transformOrigin.y()) / relativeCompositingBounds.height() : 0.5f,
807                             transformOrigin.z());
808         if (m_contentsContainmentLayer)
809             m_contentsContainmentLayer->setAnchorPoint(anchor);
810         else
811             m_graphicsLayer->setAnchorPoint(anchor);
812
813         const RenderStyle& style = renderer().style();
814         GraphicsLayer* clipLayer = clippingLayer();
815         if (style.hasPerspective()) {
816             TransformationMatrix t = owningLayer().perspectiveTransform();
817             
818             if (clipLayer) {
819                 clipLayer->setChildrenTransform(t);
820                 m_graphicsLayer->setChildrenTransform(TransformationMatrix());
821             }
822             else
823                 m_graphicsLayer->setChildrenTransform(t);
824         } else {
825             if (clipLayer)
826                 clipLayer->setChildrenTransform(TransformationMatrix());
827             else
828                 m_graphicsLayer->setChildrenTransform(TransformationMatrix());
829         }
830     } else {
831         m_graphicsLayer->setAnchorPoint(FloatPoint3D(0.5f, 0.5f, 0));
832         if (m_contentsContainmentLayer)
833             m_contentsContainmentLayer->setAnchorPoint(FloatPoint3D(0.5f, 0.5f, 0));
834     }
835
836     if (m_foregroundLayer) {
837         FloatPoint foregroundPosition;
838         FloatSize foregroundSize = contentsSize;
839         IntSize foregroundOffset = m_graphicsLayer->offsetFromRenderer();
840         if (hasClippingLayer()) {
841             // If we have a clipping layer (which clips descendants), then the foreground layer is a child of it,
842             // so that it gets correctly sorted with children. In that case, position relative to the clipping layer.
843             foregroundSize = FloatSize(clippingBox.size());
844             foregroundOffset = toIntSize(clippingBox.location());
845         }
846
847         m_foregroundLayer->setPosition(foregroundPosition);
848         m_foregroundLayer->setSize(foregroundSize);
849         m_foregroundLayer->setOffsetFromRenderer(foregroundOffset);
850     }
851
852     if (m_backgroundLayer) {
853         FloatPoint backgroundPosition;
854         FloatSize backgroundSize = contentsSize;
855         if (backgroundLayerPaintsFixedRootBackground()) {
856             const FrameView& frameView = renderer().view().frameView();
857             backgroundPosition = IntPoint(frameView.scrollOffsetForFixedPosition());
858             backgroundSize = frameView.visibleContentRect().size();
859         }
860         m_backgroundLayer->setPosition(backgroundPosition);
861         m_backgroundLayer->setSize(backgroundSize);
862         m_backgroundLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
863     }
864
865     if (m_owningLayer.reflectionLayer() && m_owningLayer.reflectionLayer()->isComposited()) {
866         RenderLayerBacking* reflectionBacking = m_owningLayer.reflectionLayer()->backing();
867         reflectionBacking->updateGraphicsLayerGeometry();
868         
869         // The reflection layer has the bounds of m_owningLayer.reflectionLayer(),
870         // but the reflected layer is the bounds of this layer, so we need to position it appropriately.
871         FloatRect layerBounds = compositedBounds();
872         FloatRect reflectionLayerBounds = reflectionBacking->compositedBounds();
873         reflectionBacking->graphicsLayer()->setReplicatedLayerPosition(FloatPoint(layerBounds.location() - reflectionLayerBounds.location()));
874     }
875
876     if (m_scrollingLayer) {
877         ASSERT(m_scrollingContentsLayer);
878         RenderBox& renderBox = toRenderBox(renderer());
879         IntRect paddingBox(renderBox.borderLeft(), renderBox.borderTop(), renderBox.width() - renderBox.borderLeft() - renderBox.borderRight(), renderBox.height() - renderBox.borderTop() - renderBox.borderBottom());
880         IntSize scrollOffset = m_owningLayer.scrollOffset();
881
882         m_scrollingLayer->setPosition(FloatPoint(paddingBox.location() - localCompositingBounds.location()));
883
884         m_scrollingLayer->setSize(paddingBox.size());
885 #if PLATFORM(IOS)
886         IntSize oldScrollingLayerOffset = m_scrollingLayer->offsetFromRenderer();
887         m_scrollingLayer->setOffsetFromRenderer(IntPoint() - paddingBox.location());
888         bool paddingBoxOffsetChanged = oldScrollingLayerOffset != m_scrollingLayer->offsetFromRenderer();
889
890         if (m_owningLayer.isInUserScroll()) {
891             // If scrolling is happening externally, we don't want to touch the layer bounds origin here because that will cause
892             // jitter. Set a flag to ensure that we sync up later.
893             m_owningLayer.setRequiresScrollBoundsOriginUpdate(true);
894         } else {
895             // Note that we implement the contents offset via the bounds origin on this layer, rather than a position on the sublayer.
896             m_scrollingLayer->setBoundsOrigin(FloatPoint(scrollOffset.width(), scrollOffset.height()));
897             m_owningLayer.setRequiresScrollBoundsOriginUpdate(false);
898         }
899         
900         IntSize scrollSize(m_owningLayer.scrollWidth(), m_owningLayer.scrollHeight());
901
902         m_scrollingContentsLayer->setPosition(FloatPoint());
903         
904         if (scrollSize != m_scrollingContentsLayer->size() || paddingBoxOffsetChanged)
905             m_scrollingContentsLayer->setNeedsDisplay();
906
907         m_scrollingContentsLayer->setSize(scrollSize);
908         // Scrolling the content layer does not need to trigger a repaint. The offset will be compensated away during painting.
909         // FIXME: The paint offset and the scroll offset should really be separate concepts.
910         m_scrollingContentsLayer->setOffsetFromRenderer(paddingBox.location() - IntPoint() - scrollOffset, GraphicsLayer::DontSetNeedsDisplay);
911         
912         compositor().scrollingLayerAddedOrUpdated(&m_owningLayer);
913 #else
914         m_scrollingContentsLayer->setPosition(FloatPoint(-scrollOffset.width(), -scrollOffset.height()));
915
916         IntSize oldScrollingLayerOffset = m_scrollingLayer->offsetFromRenderer();
917         m_scrollingLayer->setOffsetFromRenderer(-toIntSize(paddingBox.location()));
918
919         bool paddingBoxOffsetChanged = oldScrollingLayerOffset != m_scrollingLayer->offsetFromRenderer();
920
921         IntSize scrollSize(m_owningLayer.scrollWidth(), m_owningLayer.scrollHeight());
922         if (scrollSize != m_scrollingContentsLayer->size() || paddingBoxOffsetChanged)
923             m_scrollingContentsLayer->setNeedsDisplay();
924
925         IntSize scrollingContentsOffset = toIntSize(paddingBox.location() - scrollOffset);
926         if (scrollingContentsOffset != m_scrollingContentsLayer->offsetFromRenderer() || scrollSize != m_scrollingContentsLayer->size())
927             compositor().scrollingLayerDidChange(m_owningLayer);
928
929         m_scrollingContentsLayer->setSize(scrollSize);
930         // FIXME: The paint offset and the scroll offset should really be separate concepts.
931         m_scrollingContentsLayer->setOffsetFromRenderer(scrollingContentsOffset, GraphicsLayer::DontSetNeedsDisplay);
932 #endif
933
934         if (m_foregroundLayer) {
935             m_foregroundLayer->setSize(m_scrollingContentsLayer->size());
936             m_foregroundLayer->setOffsetFromRenderer(m_scrollingContentsLayer->offsetFromRenderer());
937         }
938     }
939
940     // If this layer was created just for clipping or to apply perspective, it doesn't need its own backing store.
941     setRequiresOwnBackingStore(compositor().requiresOwnBackingStore(m_owningLayer, compAncestor, relativeCompositingBounds, ancestorCompositingBounds));
942
943     bool didUpdateContentsRect = false;
944     updateDirectlyCompositedContents(isSimpleContainer, didUpdateContentsRect);
945     if (!didUpdateContentsRect && m_graphicsLayer->hasContentsLayer())
946         resetContentsRect();
947
948     updateDrawsContent(isSimpleContainer);
949     updateAfterWidgetResize();
950
951     compositor().updateViewportConstraintStatus(m_owningLayer);
952 }
953
954 void RenderLayerBacking::adjustAncestorCompositingBoundsForFlowThread(IntRect& ancestorCompositingBounds, const RenderLayer* compositingAncestor) const
955 {
956     if (!m_owningLayer.isInsideFlowThread())
957         return;
958
959     RenderLayer* flowThreadLayer = m_owningLayer.isInsideOutOfFlowThread() ? m_owningLayer.stackingContainer() : m_owningLayer.enclosingFlowThreadAncestor();
960     if (flowThreadLayer && flowThreadLayer->isRenderFlowThread()) {
961         if (m_owningLayer.isFlowThreadCollectingGraphicsLayersUnderRegions()) {
962             // The RenderNamedFlowThread is not composited, as we need it to paint the 
963             // background layer of the regions. We need to compensate for that by manually
964             // subtracting the position of the flow-thread.
965             IntPoint flowPosition;
966             flowThreadLayer->convertToPixelSnappedLayerCoords(compositingAncestor, flowPosition);
967             ancestorCompositingBounds.moveBy(flowPosition);
968         }
969
970         // Move the ancestor position at the top of the region where the composited layer is going to display.
971         RenderFlowThread& flowThread = toRenderFlowThread(flowThreadLayer->renderer());
972         RenderNamedFlowFragment* parentRegion = flowThread.cachedRegionForCompositedLayer(m_owningLayer);
973         if (!parentRegion)
974             return;
975
976         IntPoint flowDelta;
977         m_owningLayer.convertToPixelSnappedLayerCoords(flowThreadLayer, flowDelta);
978         parentRegion->adjustRegionBoundsFromFlowThreadPortionRect(flowDelta, ancestorCompositingBounds);
979         RenderBoxModelObject& layerOwner = toRenderBoxModelObject(parentRegion->layerOwner());
980         RenderLayerBacking* layerOwnerBacking = layerOwner.layer()->backing();
981         if (!layerOwnerBacking)
982             return;
983
984         // Make sure that the region propagates its borders, paddings, outlines or box-shadows to layers inside it.
985         // Note that the composited bounds of the RenderRegion are already calculated because
986         // RenderLayerCompositor::rebuildCompositingLayerTree will only iterate on the content of the region after the
987         // region itself is computed.
988         ancestorCompositingBounds.moveBy(roundedIntPoint(layerOwnerBacking->compositedBounds().location()));
989         ancestorCompositingBounds.move(-layerOwner.borderAndPaddingStart(), -layerOwner.borderAndPaddingBefore());
990
991         // If there's a clipping GraphicsLayer on the hierarchy (region graphics layer -> clipping graphics layer ->
992         // composited content graphics layer), substract the offset of the clipping layer, since it's its parent
993         // that positions us (the graphics layer of the region).
994         if (layerOwnerBacking->clippingLayer())
995             ancestorCompositingBounds.moveBy(roundedIntPoint(layerOwnerBacking->clippingLayer()->position()));
996     }
997 }
998
999 void RenderLayerBacking::updateDirectlyCompositedContents(bool isSimpleContainer, bool& didUpdateContentsRect)
1000 {
1001     if (!m_owningLayer.hasVisibleContent())
1002         return;
1003
1004     // The order of operations here matters, since the last valid type of contents needs
1005     // to also update the contentsRect.
1006     updateDirectlyCompositedBackgroundColor(isSimpleContainer, didUpdateContentsRect);
1007     updateDirectlyCompositedBackgroundImage(isSimpleContainer, didUpdateContentsRect);
1008 }
1009
1010 void RenderLayerBacking::updateInternalHierarchy()
1011 {
1012     // m_foregroundLayer has to be inserted in the correct order with child layers,
1013     // so it's not inserted here.
1014     if (m_ancestorClippingLayer)
1015         m_ancestorClippingLayer->removeAllChildren();
1016     
1017     if (m_contentsContainmentLayer) {
1018         m_contentsContainmentLayer->removeAllChildren();
1019         if (m_ancestorClippingLayer)
1020             m_ancestorClippingLayer->addChild(m_contentsContainmentLayer.get());
1021     }
1022     
1023     if (m_backgroundLayer)
1024         m_contentsContainmentLayer->addChild(m_backgroundLayer.get());
1025
1026     if (m_contentsContainmentLayer)
1027         m_contentsContainmentLayer->addChild(m_graphicsLayer.get());
1028     else if (m_ancestorClippingLayer)
1029         m_ancestorClippingLayer->addChild(m_graphicsLayer.get());
1030
1031     if (m_childContainmentLayer) {
1032         m_childContainmentLayer->removeFromParent();
1033         m_graphicsLayer->addChild(m_childContainmentLayer.get());
1034     }
1035
1036     if (m_scrollingLayer) {
1037         GraphicsLayer* superlayer = m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsLayer.get();
1038         m_scrollingLayer->removeFromParent();
1039         superlayer->addChild(m_scrollingLayer.get());
1040     }
1041
1042     // The clip for child layers does not include space for overflow controls, so they exist as
1043     // siblings of the clipping layer if we have one. Normal children of this layer are set as
1044     // children of the clipping layer.
1045     if (m_layerForHorizontalScrollbar) {
1046         m_layerForHorizontalScrollbar->removeFromParent();
1047         m_graphicsLayer->addChild(m_layerForHorizontalScrollbar.get());
1048     }
1049     if (m_layerForVerticalScrollbar) {
1050         m_layerForVerticalScrollbar->removeFromParent();
1051         m_graphicsLayer->addChild(m_layerForVerticalScrollbar.get());
1052     }
1053     if (m_layerForScrollCorner) {
1054         m_layerForScrollCorner->removeFromParent();
1055         m_graphicsLayer->addChild(m_layerForScrollCorner.get());
1056     }
1057 }
1058
1059 void RenderLayerBacking::resetContentsRect()
1060 {
1061     m_graphicsLayer->setContentsRect(pixelSnappedIntRect(contentsBox()));
1062     
1063     LayoutRect contentsClippingRect;
1064     if (renderer().isBox())
1065         contentsClippingRect = toRenderBox(renderer()).contentBoxRect();
1066
1067     contentsClippingRect.move(contentOffsetInCompostingLayer());
1068     m_graphicsLayer->setContentsClippingRect(pixelSnappedIntRect(contentsClippingRect));
1069
1070     m_graphicsLayer->setContentsTileSize(IntSize());
1071     m_graphicsLayer->setContentsTilePhase(IntPoint());
1072 }
1073
1074 void RenderLayerBacking::updateDrawsContent()
1075 {
1076     updateDrawsContent(isSimpleContainerCompositingLayer());
1077 }
1078
1079 void RenderLayerBacking::updateDrawsContent(bool isSimpleContainer)
1080 {
1081     if (m_scrollingLayer) {
1082         // We don't have to consider overflow controls, because we know that the scrollbars are drawn elsewhere.
1083         // m_graphicsLayer only needs backing store if the non-scrolling parts (background, outlines, borders, shadows etc) need to paint.
1084         // m_scrollingLayer never has backing store.
1085         // m_scrollingContentsLayer only needs backing store if the scrolled contents need to paint.
1086         bool hasNonScrollingPaintedContent = m_owningLayer.hasVisibleContent() && m_owningLayer.hasBoxDecorationsOrBackground();
1087         m_graphicsLayer->setDrawsContent(hasNonScrollingPaintedContent);
1088
1089         bool hasScrollingPaintedContent = m_owningLayer.hasVisibleContent() && (renderer().hasBackground() || paintsChildren());
1090         m_scrollingContentsLayer->setDrawsContent(hasScrollingPaintedContent);
1091         return;
1092     }
1093
1094     bool hasPaintedContent = containsPaintedContent(isSimpleContainer);
1095
1096     // FIXME: we could refine this to only allocate backing for one of these layers if possible.
1097     m_graphicsLayer->setDrawsContent(hasPaintedContent);
1098     if (m_foregroundLayer)
1099         m_foregroundLayer->setDrawsContent(hasPaintedContent);
1100
1101     if (m_backgroundLayer)
1102         m_backgroundLayer->setDrawsContent(hasPaintedContent);
1103 }
1104
1105 // Return true if the layer changed.
1106 bool RenderLayerBacking::updateAncestorClippingLayer(bool needsAncestorClip)
1107 {
1108     bool layersChanged = false;
1109
1110     if (needsAncestorClip) {
1111         if (!m_ancestorClippingLayer) {
1112             m_ancestorClippingLayer = createGraphicsLayer("Ancestor clipping Layer");
1113             m_ancestorClippingLayer->setMasksToBounds(true);
1114             layersChanged = true;
1115         }
1116     } else if (hasAncestorClippingLayer()) {
1117         willDestroyLayer(m_ancestorClippingLayer.get());
1118         m_ancestorClippingLayer->removeFromParent();
1119         m_ancestorClippingLayer = nullptr;
1120         layersChanged = true;
1121     }
1122     
1123     return layersChanged;
1124 }
1125
1126 // Return true if the layer changed.
1127 bool RenderLayerBacking::updateDescendantClippingLayer(bool needsDescendantClip)
1128 {
1129     bool layersChanged = false;
1130
1131     if (needsDescendantClip) {
1132         if (!m_childContainmentLayer && !m_usingTiledCacheLayer) {
1133             m_childContainmentLayer = createGraphicsLayer("Child clipping Layer");
1134             m_childContainmentLayer->setMasksToBounds(true);
1135             layersChanged = true;
1136         }
1137     } else if (hasClippingLayer()) {
1138         willDestroyLayer(m_childContainmentLayer.get());
1139         m_childContainmentLayer->removeFromParent();
1140         m_childContainmentLayer = nullptr;
1141         layersChanged = true;
1142     }
1143     
1144     return layersChanged;
1145 }
1146
1147 void RenderLayerBacking::setBackgroundLayerPaintsFixedRootBackground(bool backgroundLayerPaintsFixedRootBackground)
1148 {
1149     m_backgroundLayerPaintsFixedRootBackground = backgroundLayerPaintsFixedRootBackground;
1150 }
1151
1152 bool RenderLayerBacking::requiresHorizontalScrollbarLayer() const
1153 {
1154     if (!m_owningLayer.hasOverlayScrollbars() && !m_owningLayer.needsCompositedScrolling())
1155         return false;
1156     return m_owningLayer.horizontalScrollbar();
1157 }
1158
1159 bool RenderLayerBacking::requiresVerticalScrollbarLayer() const
1160 {
1161     if (!m_owningLayer.hasOverlayScrollbars() && !m_owningLayer.needsCompositedScrolling())
1162         return false;
1163     return m_owningLayer.verticalScrollbar();
1164 }
1165
1166 bool RenderLayerBacking::requiresScrollCornerLayer() const
1167 {
1168     if (!m_owningLayer.hasOverlayScrollbars() && !m_owningLayer.needsCompositedScrolling())
1169         return false;
1170     return !m_owningLayer.scrollCornerAndResizerRect().isEmpty();
1171 }
1172
1173 bool RenderLayerBacking::updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer)
1174 {
1175     bool horizontalScrollbarLayerChanged = false;
1176     if (needsHorizontalScrollbarLayer) {
1177         if (!m_layerForHorizontalScrollbar) {
1178             m_layerForHorizontalScrollbar = createGraphicsLayer("horizontal scrollbar");
1179             horizontalScrollbarLayerChanged = true;
1180         }
1181     } else if (m_layerForHorizontalScrollbar) {
1182         willDestroyLayer(m_layerForHorizontalScrollbar.get());
1183         m_layerForHorizontalScrollbar = nullptr;
1184         horizontalScrollbarLayerChanged = true;
1185     }
1186
1187     bool verticalScrollbarLayerChanged = false;
1188     if (needsVerticalScrollbarLayer) {
1189         if (!m_layerForVerticalScrollbar) {
1190             m_layerForVerticalScrollbar = createGraphicsLayer("vertical scrollbar");
1191             verticalScrollbarLayerChanged = true;
1192         }
1193     } else if (m_layerForVerticalScrollbar) {
1194         willDestroyLayer(m_layerForVerticalScrollbar.get());
1195         m_layerForVerticalScrollbar = nullptr;
1196         verticalScrollbarLayerChanged = true;
1197     }
1198
1199     bool scrollCornerLayerChanged = false;
1200     if (needsScrollCornerLayer) {
1201         if (!m_layerForScrollCorner) {
1202             m_layerForScrollCorner = createGraphicsLayer("scroll corner");
1203             scrollCornerLayerChanged = true;
1204         }
1205     } else if (m_layerForScrollCorner) {
1206         willDestroyLayer(m_layerForScrollCorner.get());
1207         m_layerForScrollCorner = nullptr;
1208         scrollCornerLayerChanged = true;
1209     }
1210
1211     if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer)) {
1212         if (horizontalScrollbarLayerChanged)
1213             scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(&m_owningLayer, HorizontalScrollbar);
1214         if (verticalScrollbarLayerChanged)
1215             scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(&m_owningLayer, VerticalScrollbar);
1216     }
1217
1218     return horizontalScrollbarLayerChanged || verticalScrollbarLayerChanged || scrollCornerLayerChanged;
1219 }
1220
1221 void RenderLayerBacking::positionOverflowControlsLayers()
1222 {
1223     if (!m_owningLayer.hasScrollbars())
1224         return;
1225
1226     const IntRect borderBox = toRenderBox(renderer()).pixelSnappedBorderBoxRect();
1227
1228     IntSize offsetFromRenderer = m_graphicsLayer->offsetFromRenderer();
1229     if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
1230         IntRect hBarRect = m_owningLayer.rectForHorizontalScrollbar(borderBox);
1231         layer->setPosition(hBarRect.location() - offsetFromRenderer);
1232         layer->setSize(hBarRect.size());
1233         if (layer->hasContentsLayer()) {
1234             IntRect barRect = IntRect(IntPoint(), hBarRect.size());
1235             layer->setContentsRect(barRect);
1236             layer->setContentsClippingRect(barRect);
1237         }
1238         layer->setDrawsContent(m_owningLayer.horizontalScrollbar() && !layer->hasContentsLayer());
1239     }
1240     
1241     if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
1242         IntRect vBarRect = m_owningLayer.rectForVerticalScrollbar(borderBox);
1243         layer->setPosition(vBarRect.location() - offsetFromRenderer);
1244         layer->setSize(vBarRect.size());
1245         if (layer->hasContentsLayer()) {
1246             IntRect barRect = IntRect(IntPoint(), vBarRect.size());
1247             layer->setContentsRect(barRect);
1248             layer->setContentsClippingRect(barRect);
1249         }
1250         layer->setDrawsContent(m_owningLayer.verticalScrollbar() && !layer->hasContentsLayer());
1251     }
1252
1253     if (GraphicsLayer* layer = layerForScrollCorner()) {
1254         const LayoutRect& scrollCornerAndResizer = m_owningLayer.scrollCornerAndResizerRect();
1255         layer->setPosition(scrollCornerAndResizer.location() - offsetFromRenderer);
1256         layer->setSize(scrollCornerAndResizer.size());
1257         layer->setDrawsContent(!scrollCornerAndResizer.isEmpty());
1258     }
1259 }
1260
1261 bool RenderLayerBacking::hasUnpositionedOverflowControlsLayers() const
1262 {
1263     if (GraphicsLayer* layer = layerForHorizontalScrollbar())
1264         if (!layer->drawsContent())
1265             return true;
1266
1267     if (GraphicsLayer* layer = layerForVerticalScrollbar())
1268         if (!layer->drawsContent())
1269             return true;
1270
1271     if (GraphicsLayer* layer = layerForScrollCorner())
1272         if (!layer->drawsContent())
1273             return true;
1274
1275     return false;
1276 }
1277
1278 bool RenderLayerBacking::updateForegroundLayer(bool needsForegroundLayer)
1279 {
1280     bool layerChanged = false;
1281     if (needsForegroundLayer) {
1282         if (!m_foregroundLayer) {
1283             String layerName;
1284 #ifndef NDEBUG
1285             layerName = m_owningLayer.name() + " (foreground)";
1286 #endif
1287             m_foregroundLayer = createGraphicsLayer(layerName);
1288             m_foregroundLayer->setDrawsContent(true);
1289             m_foregroundLayer->setPaintingPhase(GraphicsLayerPaintForeground);
1290             layerChanged = true;
1291         }
1292     } else if (m_foregroundLayer) {
1293         willDestroyLayer(m_foregroundLayer.get());
1294         m_foregroundLayer->removeFromParent();
1295         m_foregroundLayer = nullptr;
1296         layerChanged = true;
1297     }
1298
1299     if (layerChanged) {
1300         m_graphicsLayer->setNeedsDisplay();
1301         m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
1302     }
1303
1304     return layerChanged;
1305 }
1306
1307 bool RenderLayerBacking::updateBackgroundLayer(bool needsBackgroundLayer)
1308 {
1309     bool layerChanged = false;
1310     if (needsBackgroundLayer) {
1311         if (!m_backgroundLayer) {
1312             String layerName;
1313 #ifndef NDEBUG
1314             layerName = m_owningLayer.name() + " (background)";
1315 #endif
1316             m_backgroundLayer = createGraphicsLayer(layerName);
1317             m_backgroundLayer->setDrawsContent(true);
1318             m_backgroundLayer->setAnchorPoint(FloatPoint3D());
1319             m_backgroundLayer->setPaintingPhase(GraphicsLayerPaintBackground);
1320             layerChanged = true;
1321         }
1322         
1323         if (!m_contentsContainmentLayer) {
1324             String layerName;
1325 #ifndef NDEBUG
1326             layerName = m_owningLayer.name() + " (contents containment)";
1327 #endif
1328             m_contentsContainmentLayer = createGraphicsLayer(layerName);
1329             m_contentsContainmentLayer->setAppliesPageScale(true);
1330             m_graphicsLayer->setAppliesPageScale(false);
1331             layerChanged = true;
1332         }
1333     } else {
1334         if (m_backgroundLayer) {
1335             willDestroyLayer(m_backgroundLayer.get());
1336             m_backgroundLayer->removeFromParent();
1337             m_backgroundLayer = nullptr;
1338             layerChanged = true;
1339         }
1340         if (m_contentsContainmentLayer) {
1341             willDestroyLayer(m_contentsContainmentLayer.get());
1342             m_contentsContainmentLayer->removeFromParent();
1343             m_contentsContainmentLayer = nullptr;
1344             layerChanged = true;
1345             m_graphicsLayer->setAppliesPageScale(true);
1346         }
1347     }
1348     
1349     if (layerChanged) {
1350         m_graphicsLayer->setNeedsDisplay();
1351         // This assumes that the background layer is only used for fixed backgrounds, which is currently a correct assumption.
1352         compositor().fixedRootBackgroundLayerChanged();
1353     }
1354     
1355     return layerChanged;
1356 }
1357
1358 bool RenderLayerBacking::updateMaskLayer(bool needsMaskLayer)
1359 {
1360     bool layerChanged = false;
1361     if (needsMaskLayer) {
1362         if (!m_maskLayer) {
1363             m_maskLayer = createGraphicsLayer("Mask");
1364             m_maskLayer->setDrawsContent(true);
1365             m_maskLayer->setPaintingPhase(GraphicsLayerPaintMask);
1366             layerChanged = true;
1367         }
1368     } else if (m_maskLayer) {
1369         willDestroyLayer(m_maskLayer.get());
1370         m_maskLayer = nullptr;
1371         layerChanged = true;
1372     }
1373
1374     if (layerChanged)
1375         m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
1376
1377     return layerChanged;
1378 }
1379
1380 bool RenderLayerBacking::updateScrollingLayers(bool needsScrollingLayers)
1381 {
1382     ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
1383
1384     bool layerChanged = false;
1385     if (needsScrollingLayers) {
1386         if (!m_scrollingLayer) {
1387             // Outer layer which corresponds with the scroll view.
1388             m_scrollingLayer = createGraphicsLayer("Scrolling container");
1389             m_scrollingLayer->setDrawsContent(false);
1390             m_scrollingLayer->setMasksToBounds(true);
1391
1392             // Inner layer which renders the content that scrolls.
1393             m_scrollingContentsLayer = createGraphicsLayer("Scrolled Contents");
1394             m_scrollingContentsLayer->setDrawsContent(true);
1395             GraphicsLayerPaintingPhase paintPhase = GraphicsLayerPaintOverflowContents | GraphicsLayerPaintCompositedScroll;
1396             if (!m_foregroundLayer)
1397                 paintPhase |= GraphicsLayerPaintForeground;
1398             m_scrollingContentsLayer->setPaintingPhase(paintPhase);
1399             m_scrollingLayer->addChild(m_scrollingContentsLayer.get());
1400
1401             layerChanged = true;
1402             if (scrollingCoordinator)
1403                 scrollingCoordinator->scrollableAreaScrollLayerDidChange(&m_owningLayer);
1404 #if PLATFORM(IOS)
1405             if (m_owningLayer.parent())
1406                 compositor().scrollingLayerAddedOrUpdated(&m_owningLayer);
1407 #endif
1408         }
1409     } else if (m_scrollingLayer) {
1410 #if PLATFORM(IOS)
1411         if (!renderer().documentBeingDestroyed())
1412             compositor().scrollingLayerRemoved(&m_owningLayer, m_scrollingLayer->platformLayer(), m_scrollingContentsLayer->platformLayer());
1413 #endif
1414         willDestroyLayer(m_scrollingLayer.get());
1415         willDestroyLayer(m_scrollingContentsLayer.get());
1416         m_scrollingLayer = nullptr;
1417         m_scrollingContentsLayer = nullptr;
1418         layerChanged = true;
1419         if (scrollingCoordinator)
1420             scrollingCoordinator->scrollableAreaScrollLayerDidChange(&m_owningLayer);
1421     }
1422
1423     if (layerChanged) {
1424         updateInternalHierarchy();
1425         m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
1426 #if !PLATFORM(IOS)
1427         m_graphicsLayer->setNeedsDisplay();
1428         compositor().scrollingLayerDidChange(m_owningLayer);
1429 #endif
1430     }
1431
1432     return layerChanged;
1433 }
1434
1435 void RenderLayerBacking::attachToScrollingCoordinatorWithParent(RenderLayerBacking* parent)
1436 {
1437     ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
1438     if (!scrollingCoordinator)
1439         return;
1440
1441     // FIXME: When we support overflow areas, we will have to refine this for overflow areas that are also
1442     // positon:fixed.
1443     ScrollingNodeType nodeType;
1444     if (renderer().style().position() == FixedPosition)
1445         nodeType = FixedNode;
1446     else if (renderer().style().position() == StickyPosition)
1447         nodeType = StickyNode;
1448     else
1449         nodeType = ScrollingNode;
1450
1451     ScrollingNodeID parentID = parent ? parent->scrollLayerID() : 0;
1452     m_scrollLayerID = scrollingCoordinator->attachToStateTree(nodeType, m_scrollLayerID ? m_scrollLayerID : scrollingCoordinator->uniqueScrollLayerID(), parentID);
1453 }
1454
1455 void RenderLayerBacking::detachFromScrollingCoordinator()
1456 {
1457     // If m_scrollLayerID is 0, then this backing is not attached to the ScrollingCoordinator.
1458     if (!m_scrollLayerID)
1459         return;
1460
1461     ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
1462     if (!scrollingCoordinator)
1463         return;
1464
1465     scrollingCoordinator->detachFromStateTree(m_scrollLayerID);
1466     m_scrollLayerID = 0;
1467 }
1468
1469 GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() const
1470 {
1471     unsigned phase = 0;
1472     if (!m_backgroundLayer)
1473         phase |= GraphicsLayerPaintBackground;
1474     if (!m_foregroundLayer)
1475         phase |= GraphicsLayerPaintForeground;
1476     if (!m_maskLayer)
1477         phase |= GraphicsLayerPaintMask;
1478
1479     if (m_scrollingContentsLayer) {
1480         phase &= ~GraphicsLayerPaintForeground;
1481         phase |= GraphicsLayerPaintCompositedScroll;
1482     }
1483
1484     return static_cast<GraphicsLayerPaintingPhase>(phase);
1485 }
1486
1487 float RenderLayerBacking::compositingOpacity(float rendererOpacity) const
1488 {
1489     float finalOpacity = rendererOpacity;
1490     
1491     for (RenderLayer* curr = m_owningLayer.parent(); curr; curr = curr->parent()) {
1492         // We only care about parents that are stacking contexts.
1493         // Recall that opacity creates stacking context.
1494         if (!curr->isStackingContainer())
1495             continue;
1496         
1497         // If we found a compositing layer, we want to compute opacity
1498         // relative to it. So we can break here.
1499         if (curr->isComposited())
1500             break;
1501         
1502         finalOpacity *= curr->renderer().opacity();
1503     }
1504
1505     return finalOpacity;
1506 }
1507
1508 static bool hasBoxDecorations(const RenderStyle* style)
1509 {
1510     return style->hasBorder() || style->hasBorderRadius() || style->hasOutline() || style->hasAppearance() || style->boxShadow() || style->hasFilter();
1511 }
1512
1513 static bool canCreateTiledImage(const RenderStyle*);
1514
1515 static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle* style)
1516 {
1517     if (hasBoxDecorations(style))
1518         return true;
1519
1520     if (!style->hasBackgroundImage())
1521         return false;
1522
1523     return !GraphicsLayer::supportsContentsTiling() || !canCreateTiledImage(style);
1524 }
1525
1526 static bool hasPerspectiveOrPreserves3D(const RenderStyle* style)
1527 {
1528     return style->hasPerspective() || style->preserves3D();
1529 }
1530
1531 Color RenderLayerBacking::rendererBackgroundColor() const
1532 {
1533     const auto& backgroundRenderer = renderer().isRoot() ? renderer().rendererForRootBackground() : renderer();
1534     return backgroundRenderer.style().visitedDependentColor(CSSPropertyBackgroundColor);
1535 }
1536
1537 void RenderLayerBacking::updateDirectlyCompositedBackgroundColor(bool isSimpleContainer, bool& didUpdateContentsRect)
1538 {
1539     if (!isSimpleContainer) {
1540         m_graphicsLayer->setContentsToSolidColor(Color());
1541         return;
1542     }
1543
1544     Color backgroundColor = rendererBackgroundColor();
1545
1546     // An unset (invalid) color will remove the solid color.
1547     m_graphicsLayer->setContentsToSolidColor(backgroundColor);
1548     IntRect contentsRect = backgroundBox();
1549     m_graphicsLayer->setContentsRect(contentsRect);
1550     m_graphicsLayer->setContentsClippingRect(contentsRect);
1551     didUpdateContentsRect = true;
1552 }
1553
1554 bool canCreateTiledImage(const RenderStyle* style)
1555 {
1556     const FillLayer* fillLayer = style->backgroundLayers();
1557     if (fillLayer->next())
1558         return false;
1559
1560     if (!fillLayer->imagesAreLoaded())
1561         return false;
1562
1563     if (fillLayer->attachment() != ScrollBackgroundAttachment)
1564         return false;
1565
1566     Color color = style->visitedDependentColor(CSSPropertyBackgroundColor);
1567
1568     // FIXME: Allow color+image compositing when it makes sense.
1569     // For now bailing out.
1570     if (color.isValid() && color.alpha())
1571         return false;
1572
1573     StyleImage* styleImage = fillLayer->image();
1574
1575     // FIXME: support gradients with isGeneratedImage.
1576     if (!styleImage->isCachedImage())
1577         return false;
1578
1579     Image* image = styleImage->cachedImage()->image();
1580     if (!image->isBitmapImage())
1581         return false;
1582
1583     return true;
1584 }
1585
1586 void RenderLayerBacking::updateDirectlyCompositedBackgroundImage(bool isSimpleContainer, bool& didUpdateContentsRect)
1587 {
1588     if (!GraphicsLayer::supportsContentsTiling())
1589         return;
1590
1591     if (isDirectlyCompositedImage())
1592         return;
1593
1594     const RenderStyle& style = renderer().style();
1595
1596     if (!isSimpleContainer || !style.hasBackgroundImage()) {
1597         m_graphicsLayer->setContentsToImage(0);
1598         return;
1599     }
1600
1601     IntRect destRect = backgroundBox();
1602     IntPoint phase;
1603     IntSize tileSize;
1604
1605     RefPtr<Image> image = style.backgroundLayers()->image()->cachedImage()->image();
1606     toRenderBox(renderer()).getGeometryForBackgroundImage(&m_owningLayer.renderer(), destRect, phase, tileSize);
1607     m_graphicsLayer->setContentsTileSize(tileSize);
1608     m_graphicsLayer->setContentsTilePhase(phase);
1609     m_graphicsLayer->setContentsRect(destRect);
1610     m_graphicsLayer->setContentsClippingRect(destRect);
1611     m_graphicsLayer->setContentsToImage(image.get());
1612     didUpdateContentsRect = true;
1613 }
1614
1615 void RenderLayerBacking::updateRootLayerConfiguration()
1616 {
1617     if (!m_usingTiledCacheLayer)
1618         return;
1619
1620     Color backgroundColor;
1621     bool viewIsTransparent = compositor().viewHasTransparentBackground(&backgroundColor);
1622
1623     if (m_backgroundLayerPaintsFixedRootBackground && m_backgroundLayer) {
1624         m_backgroundLayer->setBackgroundColor(backgroundColor);
1625         m_backgroundLayer->setContentsOpaque(!viewIsTransparent);
1626
1627         m_graphicsLayer->setBackgroundColor(Color());
1628         m_graphicsLayer->setContentsOpaque(false);
1629     } else {
1630         m_graphicsLayer->setBackgroundColor(backgroundColor);
1631         m_graphicsLayer->setContentsOpaque(!viewIsTransparent);
1632     }
1633 }
1634
1635 static bool supportsDirectBoxDecorationsComposition(const RenderLayerModelObject& renderer)
1636 {
1637     if (!GraphicsLayer::supportsBackgroundColorContent())
1638         return false;
1639
1640     if (renderer.hasClip())
1641         return false;
1642
1643     if (hasBoxDecorationsOrBackgroundImage(&renderer.style()))
1644         return false;
1645
1646     // FIXME: We can't create a directly composited background if this
1647     // layer will have children that intersect with the background layer.
1648     // A better solution might be to introduce a flattening layer if
1649     // we do direct box decoration composition.
1650     // https://bugs.webkit.org/show_bug.cgi?id=119461
1651     if (hasPerspectiveOrPreserves3D(&renderer.style()))
1652         return false;
1653
1654     // FIXME: we should be able to allow backgroundComposite; However since this is not a common use case it has been deferred for now.
1655     if (renderer.style().backgroundComposite() != CompositeSourceOver)
1656         return false;
1657
1658     if (renderer.style().backgroundClip() == TextFillBox)
1659         return false;
1660
1661     return true;
1662 }
1663
1664 bool RenderLayerBacking::paintsBoxDecorations() const
1665 {
1666     if (!m_owningLayer.hasVisibleBoxDecorations())
1667         return false;
1668
1669     if (!supportsDirectBoxDecorationsComposition(renderer()))
1670         return true;
1671
1672     return false;
1673 }
1674
1675 bool RenderLayerBacking::paintsChildren() const
1676 {
1677     if (m_owningLayer.hasVisibleContent() && m_owningLayer.hasNonEmptyChildRenderers())
1678         return true;
1679
1680     if (hasVisibleNonCompositingDescendantLayers())
1681         return true;
1682
1683     return false;
1684 }
1685
1686 static bool isRestartedPlugin(RenderObject* renderer)
1687 {
1688     if (!renderer->isEmbeddedObject())
1689         return false;
1690
1691     Element* element = toElement(renderer->node());
1692     if (!element || !element->isPluginElement())
1693         return false;
1694
1695     return toHTMLPlugInElement(element)->isRestartedPlugin();
1696 }
1697
1698 static bool isCompositedPlugin(RenderObject* renderer)
1699 {
1700     return renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing();
1701 }
1702
1703 // A "simple container layer" is a RenderLayer which has no visible content to render.
1704 // It may have no children, or all its children may be themselves composited.
1705 // This is a useful optimization, because it allows us to avoid allocating backing store.
1706 bool RenderLayerBacking::isSimpleContainerCompositingLayer() const
1707 {
1708     if (renderer().hasMask()) // masks require special treatment
1709         return false;
1710
1711     if (renderer().isReplaced() && (!isCompositedPlugin(&renderer()) || isRestartedPlugin(&renderer())))
1712         return false;
1713
1714     if (paintsBoxDecorations() || paintsChildren())
1715         return false;
1716
1717     if (renderer().isRenderNamedFlowFragmentContainer())
1718         return false;
1719
1720     if (renderer().isRenderView()) {
1721         // Look to see if the root object has a non-simple background
1722         RenderObject* rootObject = renderer().document().documentElement() ? renderer().document().documentElement()->renderer() : 0;
1723         if (!rootObject)
1724             return false;
1725         
1726         RenderStyle* style = &rootObject->style();
1727         
1728         // Reject anything that has a border, a border-radius or outline,
1729         // or is not a simple background (no background, or solid color).
1730         if (hasBoxDecorationsOrBackgroundImage(style))
1731             return false;
1732         
1733         // Now look at the body's renderer.
1734         HTMLElement* body = renderer().document().body();
1735         RenderObject* bodyObject = (body && body->hasLocalName(bodyTag)) ? body->renderer() : 0;
1736         if (!bodyObject)
1737             return false;
1738         
1739         style = &bodyObject->style();
1740         
1741         if (hasBoxDecorationsOrBackgroundImage(style))
1742             return false;
1743     }
1744
1745     return true;
1746 }
1747
1748 static bool hasVisibleNonCompositingDescendant(RenderLayer& parent)
1749 {
1750     // FIXME: We shouldn't be called with a stale z-order lists. See bug 85512.
1751     parent.updateLayerListsIfNeeded();
1752
1753 #if !ASSERT_DISABLED
1754     LayerListMutationDetector mutationChecker(&parent);
1755 #endif
1756
1757     if (Vector<RenderLayer*>* normalFlowList = parent.normalFlowList()) {
1758         size_t listSize = normalFlowList->size();
1759         for (size_t i = 0; i < listSize; ++i) {
1760             RenderLayer* curLayer = normalFlowList->at(i);
1761             if (!curLayer->isComposited()
1762                 && (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(*curLayer)))
1763                 return true;
1764         }
1765     }
1766
1767     if (parent.isStackingContainer()) {
1768         if (!parent.hasVisibleDescendant())
1769             return false;
1770
1771         // Use the m_hasCompositingDescendant bit to optimize?
1772         if (Vector<RenderLayer*>* negZOrderList = parent.negZOrderList()) {
1773             size_t listSize = negZOrderList->size();
1774             for (size_t i = 0; i < listSize; ++i) {
1775                 RenderLayer* curLayer = negZOrderList->at(i);
1776                 if (!curLayer->isComposited()
1777                     && (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(*curLayer)))
1778                     return true;
1779             }
1780         }
1781
1782         if (Vector<RenderLayer*>* posZOrderList = parent.posZOrderList()) {
1783             size_t listSize = posZOrderList->size();
1784             for (size_t i = 0; i < listSize; ++i) {
1785                 RenderLayer* curLayer = posZOrderList->at(i);
1786                 if (!curLayer->isComposited()
1787                     && (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(*curLayer)))
1788                     return true;
1789             }
1790         }
1791     }
1792
1793     return false;
1794 }
1795
1796 // Conservative test for having no rendered children.
1797 bool RenderLayerBacking::hasVisibleNonCompositingDescendantLayers() const
1798 {
1799     return hasVisibleNonCompositingDescendant(m_owningLayer);
1800 }
1801
1802 bool RenderLayerBacking::containsPaintedContent(bool isSimpleContainer) const
1803 {
1804     if (isSimpleContainer || paintsIntoWindow() || paintsIntoCompositedAncestor() || m_artificiallyInflatedBounds || m_owningLayer.isReflection())
1805         return false;
1806
1807     if (isDirectlyCompositedImage())
1808         return false;
1809
1810     // FIXME: we could optimize cases where the image, video or canvas is known to fill the border box entirely,
1811     // and set background color on the layer in that case, instead of allocating backing store and painting.
1812 #if ENABLE(VIDEO)
1813     if (renderer().isVideo() && toRenderVideo(renderer()).shouldDisplayVideo())
1814         return m_owningLayer.hasBoxDecorationsOrBackground();
1815 #endif
1816
1817 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
1818     if (renderer().isCanvas() && canvasCompositingStrategy(renderer()) == CanvasAsLayerContents)
1819         return m_owningLayer.hasBoxDecorationsOrBackground();
1820 #endif
1821
1822     return true;
1823 }
1824
1825 // An image can be directly compositing if it's the sole content of the layer, and has no box decorations
1826 // that require painting. Direct compositing saves backing store.
1827 bool RenderLayerBacking::isDirectlyCompositedImage() const
1828 {
1829     if (!renderer().isRenderImage() || m_owningLayer.hasBoxDecorationsOrBackground() || renderer().hasClip())
1830         return false;
1831
1832     RenderImage& imageRenderer = toRenderImage(renderer());
1833     if (CachedImage* cachedImage = imageRenderer.cachedImage()) {
1834         if (!cachedImage->hasImage())
1835             return false;
1836
1837         Image* image = cachedImage->imageForRenderer(&imageRenderer);
1838         if (!image->isBitmapImage())
1839             return false;
1840
1841         if (image->orientationForCurrentFrame() != DefaultImageOrientation)
1842             return false;
1843
1844         return m_graphicsLayer->shouldDirectlyCompositeImage(image);
1845     }
1846
1847     return false;
1848 }
1849
1850 void RenderLayerBacking::contentChanged(ContentChangeType changeType)
1851 {
1852     if ((changeType == ImageChanged) && isDirectlyCompositedImage()) {
1853         updateImageContents();
1854         return;
1855     }
1856
1857     if ((changeType == BackgroundImageChanged) && canCreateTiledImage(&renderer().style()))
1858         updateGraphicsLayerGeometry();
1859
1860     if ((changeType == MaskImageChanged) && m_maskLayer) {
1861         // The composited layer bounds relies on box->maskClipRect(), which changes
1862         // when the mask image becomes available.
1863         updateAfterLayout(CompositingChildrenOnly | IsUpdateRoot);
1864     }
1865
1866 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
1867     if ((changeType == CanvasChanged || changeType == CanvasPixelsChanged) && renderer().isCanvas() && canvasCompositingStrategy(renderer()) == CanvasAsLayerContents) {
1868         m_graphicsLayer->setContentsNeedsDisplay();
1869         return;
1870     }
1871 #endif
1872 }
1873
1874 void RenderLayerBacking::updateImageContents()
1875 {
1876     ASSERT(renderer().isRenderImage());
1877     RenderImage& imageRenderer = toRenderImage(renderer());
1878
1879     CachedImage* cachedImage = imageRenderer.cachedImage();
1880     if (!cachedImage)
1881         return;
1882
1883     Image* image = cachedImage->imageForRenderer(&imageRenderer);
1884     if (!image)
1885         return;
1886
1887     // We have to wait until the image is fully loaded before setting it on the layer.
1888     if (!cachedImage->isLoaded())
1889         return;
1890
1891     // This is a no-op if the layer doesn't have an inner layer for the image.
1892     m_graphicsLayer->setContentsRect(pixelSnappedIntRect(contentsBox()));
1893
1894     LayoutRect contentsClippingRect = imageRenderer.contentBoxRect();
1895     contentsClippingRect.move(contentOffsetInCompostingLayer());
1896     m_graphicsLayer->setContentsClippingRect(pixelSnappedIntRect(contentsClippingRect));
1897
1898     m_graphicsLayer->setContentsToImage(image);
1899     bool isSimpleContainer = false;
1900     updateDrawsContent(isSimpleContainer);
1901     
1902     // Image animation is "lazy", in that it automatically stops unless someone is drawing
1903     // the image. So we have to kick the animation each time; this has the downside that the
1904     // image will keep animating, even if its layer is not visible.
1905     image->startAnimation();
1906 }
1907
1908 FloatPoint3D RenderLayerBacking::computeTransformOrigin(const IntRect& borderBox) const
1909 {
1910     const RenderStyle& style = renderer().style();
1911
1912     FloatPoint3D origin;
1913     origin.setX(floatValueForLength(style.transformOriginX(), borderBox.width()));
1914     origin.setY(floatValueForLength(style.transformOriginY(), borderBox.height()));
1915     origin.setZ(style.transformOriginZ());
1916
1917     return origin;
1918 }
1919
1920 FloatPoint RenderLayerBacking::computePerspectiveOrigin(const IntRect& borderBox) const
1921 {
1922     const RenderStyle& style = renderer().style();
1923
1924     float boxWidth = borderBox.width();
1925     float boxHeight = borderBox.height();
1926
1927     FloatPoint origin;
1928     origin.setX(floatValueForLength(style.perspectiveOriginX(), boxWidth));
1929     origin.setY(floatValueForLength(style.perspectiveOriginY(), boxHeight));
1930
1931     return origin;
1932 }
1933
1934 // Return the offset from the top-left of this compositing layer at which the renderer's contents are painted.
1935 LayoutSize RenderLayerBacking::contentOffsetInCompostingLayer() const
1936 {
1937     return LayoutSize(-m_compositedBounds.x(), -m_compositedBounds.y());
1938 }
1939
1940 LayoutRect RenderLayerBacking::contentsBox() const
1941 {
1942     if (!renderer().isBox())
1943         return LayoutRect();
1944
1945     RenderBox& renderBox = toRenderBox(renderer());
1946     LayoutRect contentsRect;
1947 #if ENABLE(VIDEO)
1948     if (renderBox.isVideo())
1949         contentsRect = toRenderVideo(renderBox).videoBox();
1950     else
1951 #endif
1952     if (renderBox.isRenderReplaced()) {
1953         RenderReplaced& renderReplaced = *toRenderReplaced(&renderBox);
1954         contentsRect = renderReplaced.replacedContentRect(renderBox.intrinsicSize());
1955     } else
1956         contentsRect = renderBox.contentBoxRect();
1957
1958     contentsRect.move(contentOffsetInCompostingLayer());
1959     return contentsRect;
1960 }
1961
1962 static LayoutRect backgroundRectForBox(const RenderBox& box)
1963 {
1964     switch (box.style().backgroundClip()) {
1965     case BorderFillBox:
1966         return box.borderBoxRect();
1967     case PaddingFillBox:
1968         return box.paddingBoxRect();
1969     case ContentFillBox:
1970         return box.contentBoxRect();
1971     case TextFillBox:
1972         break;
1973     }
1974
1975     ASSERT_NOT_REACHED();
1976     return LayoutRect();
1977 }
1978
1979 IntRect RenderLayerBacking::backgroundBox() const
1980 {
1981     if (!renderer().isBox())
1982         return IntRect();
1983
1984     LayoutRect backgroundBox = backgroundRectForBox(toRenderBox(renderer()));
1985     backgroundBox.move(contentOffsetInCompostingLayer());
1986     return pixelSnappedIntRect(backgroundBox);
1987 }
1988
1989 GraphicsLayer* RenderLayerBacking::parentForSublayers() const
1990 {
1991     if (m_scrollingContentsLayer)
1992         return m_scrollingContentsLayer.get();
1993
1994 #if PLATFORM(IOS)
1995     // FIXME: Can we remove this iOS-specific code path?
1996     if (GraphicsLayer* clippingLayer = this->clippingLayer())
1997         return clippingLayer;
1998     return m_graphicsLayer.get();
1999 #else
2000     return m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsLayer.get();
2001 #endif
2002 }
2003
2004 GraphicsLayer* RenderLayerBacking::childForSuperlayers() const
2005 {
2006     if (m_ancestorClippingLayer)
2007         return m_ancestorClippingLayer.get();
2008
2009     if (m_contentsContainmentLayer)
2010         return m_contentsContainmentLayer.get();
2011     
2012     return m_graphicsLayer.get();
2013 }
2014
2015 bool RenderLayerBacking::paintsIntoWindow() const
2016 {
2017     if (m_usingTiledCacheLayer)
2018         return false;
2019
2020     if (m_owningLayer.isRootLayer()) {
2021 #if PLATFORM(IOS) || USE(COORDINATED_GRAPHICS)
2022         if (compositor().inForcedCompositingMode())
2023             return false;
2024 #endif
2025
2026         return compositor().rootLayerAttachment() != RenderLayerCompositor::RootLayerAttachedViaEnclosingFrame;
2027     }
2028     
2029     return false;
2030 }
2031
2032 void RenderLayerBacking::setRequiresOwnBackingStore(bool requiresOwnBacking)
2033 {
2034     if (requiresOwnBacking == m_requiresOwnBackingStore)
2035         return;
2036     
2037     m_requiresOwnBackingStore = requiresOwnBacking;
2038
2039     // This affects the answer to paintsIntoCompositedAncestor(), which in turn affects
2040     // cached clip rects, so when it changes we have to clear clip rects on descendants.
2041     m_owningLayer.clearClipRectsIncludingDescendants(PaintingClipRects);
2042     m_owningLayer.computeRepaintRectsIncludingDescendants();
2043     
2044     compositor().repaintInCompositedAncestor(m_owningLayer, compositedBounds());
2045 }
2046
2047 #if ENABLE(CSS_COMPOSITING)
2048 void RenderLayerBacking::setBlendMode(BlendMode blendMode)
2049 {
2050     m_graphicsLayer->setBlendMode(blendMode);
2051 }
2052 #endif
2053
2054 void RenderLayerBacking::setContentsNeedDisplay(GraphicsLayer::ShouldClipToLayer shouldClip)
2055 {
2056     ASSERT(!paintsIntoCompositedAncestor());
2057
2058     FrameView& frameView = owningLayer().renderer().view().frameView();
2059     if (m_isMainFrameRenderViewLayer && frameView.isTrackingRepaints())
2060         frameView.addTrackedRepaintRect(owningLayer().absoluteBoundingBox());
2061     
2062     if (m_graphicsLayer && m_graphicsLayer->drawsContent()) {
2063         // By default, setNeedsDisplay will clip to the size of the GraphicsLayer, which does not include margin tiles.
2064         // So if the TiledBacking has a margin that needs to be invalidated, we need to send in a rect to setNeedsDisplayInRect
2065         // that is large enough to include the margin. TiledBacking::bounds() includes the margin.
2066         TiledBacking* tiledBacking = this->tiledBacking();
2067         FloatRect rectToRepaint = tiledBacking ? tiledBacking->bounds() : FloatRect(FloatPoint(0, 0), m_graphicsLayer->size());
2068         m_graphicsLayer->setNeedsDisplayInRect(rectToRepaint, shouldClip);
2069     }
2070     
2071     if (m_foregroundLayer && m_foregroundLayer->drawsContent())
2072         m_foregroundLayer->setNeedsDisplay();
2073
2074     if (m_backgroundLayer && m_backgroundLayer->drawsContent())
2075         m_backgroundLayer->setNeedsDisplay();
2076
2077     if (m_maskLayer && m_maskLayer->drawsContent())
2078         m_maskLayer->setNeedsDisplay();
2079
2080     if (m_scrollingContentsLayer && m_scrollingContentsLayer->drawsContent())
2081         m_scrollingContentsLayer->setNeedsDisplay();
2082 }
2083
2084 // r is in the coordinate space of the layer's render object
2085 void RenderLayerBacking::setContentsNeedDisplayInRect(const IntRect& r, GraphicsLayer::ShouldClipToLayer shouldClip)
2086 {
2087     ASSERT(!paintsIntoCompositedAncestor());
2088
2089     FrameView& frameView = owningLayer().renderer().view().frameView();
2090     if (m_isMainFrameRenderViewLayer && frameView.isTrackingRepaints())
2091         frameView.addTrackedRepaintRect(pixelSnappedIntRect(r));
2092
2093     if (m_graphicsLayer && m_graphicsLayer->drawsContent()) {
2094         IntRect layerDirtyRect = r;
2095         layerDirtyRect.move(-m_graphicsLayer->offsetFromRenderer());
2096         m_graphicsLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2097     }
2098
2099     if (m_foregroundLayer && m_foregroundLayer->drawsContent()) {
2100         IntRect layerDirtyRect = r;
2101         layerDirtyRect.move(-m_foregroundLayer->offsetFromRenderer());
2102         m_foregroundLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2103     }
2104
2105     // FIXME: need to split out repaints for the background.
2106     if (m_backgroundLayer && m_backgroundLayer->drawsContent()) {
2107         IntRect layerDirtyRect = r;
2108         layerDirtyRect.move(-m_backgroundLayer->offsetFromRenderer());
2109         m_backgroundLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2110     }
2111
2112     if (m_maskLayer && m_maskLayer->drawsContent()) {
2113         IntRect layerDirtyRect = r;
2114         layerDirtyRect.move(-m_maskLayer->offsetFromRenderer());
2115         m_maskLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2116     }
2117
2118     if (m_scrollingContentsLayer && m_scrollingContentsLayer->drawsContent()) {
2119         IntRect layerDirtyRect = r;
2120         layerDirtyRect.move(-m_scrollingContentsLayer->offsetFromRenderer());
2121 #if PLATFORM(IOS)
2122         // Account for the fact that RenderLayerBacking::updateGraphicsLayerGeometry() bakes scrollOffset into offsetFromRenderer on iOS.
2123         layerDirtyRect.move(-m_owningLayer.scrollOffset());
2124 #endif
2125         m_scrollingContentsLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2126     }
2127 }
2128
2129 void RenderLayerBacking::paintIntoLayer(const GraphicsLayer* graphicsLayer, GraphicsContext* context,
2130                     const IntRect& paintDirtyRect, // In the coords of rootLayer.
2131                     PaintBehavior paintBehavior, GraphicsLayerPaintingPhase paintingPhase)
2132 {
2133     if (paintsIntoWindow() || paintsIntoCompositedAncestor()) {
2134 #if !PLATFORM(IOS)
2135         // FIXME: Looks like the CALayer tree is out of sync with the GraphicsLayer heirarchy
2136         // when pages are restored from the PageCache.
2137         // <rdar://problem/8712587> ASSERT: When Going Back to Page with Plugins in PageCache
2138         ASSERT_NOT_REACHED();
2139 #endif
2140         return;
2141     }
2142
2143     FontCachePurgePreventer fontCachePurgePreventer;
2144     
2145     RenderLayer::PaintLayerFlags paintFlags = 0;
2146     if (paintingPhase & GraphicsLayerPaintBackground)
2147         paintFlags |= RenderLayer::PaintLayerPaintingCompositingBackgroundPhase;
2148     if (paintingPhase & GraphicsLayerPaintForeground)
2149         paintFlags |= RenderLayer::PaintLayerPaintingCompositingForegroundPhase;
2150     if (paintingPhase & GraphicsLayerPaintMask)
2151         paintFlags |= RenderLayer::PaintLayerPaintingCompositingMaskPhase;
2152     if (paintingPhase & GraphicsLayerPaintOverflowContents)
2153         paintFlags |= RenderLayer::PaintLayerPaintingOverflowContents;
2154     if (paintingPhase & GraphicsLayerPaintCompositedScroll)
2155         paintFlags |= RenderLayer::PaintLayerPaintingCompositingScrollingPhase;
2156
2157     if (graphicsLayer == m_backgroundLayer.get())
2158         paintFlags |= (RenderLayer::PaintLayerPaintingRootBackgroundOnly | RenderLayer::PaintLayerPaintingCompositingForegroundPhase); // Need PaintLayerPaintingCompositingForegroundPhase to walk child layers.
2159     else if (compositor().fixedRootBackgroundLayer())
2160         paintFlags |= RenderLayer::PaintLayerPaintingSkipRootBackground;
2161     
2162     // FIXME: GraphicsLayers need a way to split for RenderRegions.
2163     RenderLayer::LayerPaintingInfo paintingInfo(&m_owningLayer, paintDirtyRect, paintBehavior, m_subpixelAccumulation);
2164     m_owningLayer.paintLayerContents(context, paintingInfo, paintFlags);
2165
2166     if (m_owningLayer.containsDirtyOverlayScrollbars())
2167         m_owningLayer.paintLayerContents(context, paintingInfo, paintFlags | RenderLayer::PaintLayerPaintingOverlayScrollbars);
2168
2169     compositor().didPaintBacking(this);
2170
2171     ASSERT(!m_owningLayer.m_usedTransparency);
2172 }
2173
2174 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
2175 {
2176     if (!scrollbar)
2177         return;
2178
2179     context.save();
2180     const IntRect& scrollbarRect = scrollbar->frameRect();
2181     context.translate(-scrollbarRect.x(), -scrollbarRect.y());
2182     IntRect transformedClip = clip;
2183     transformedClip.moveBy(scrollbarRect.location());
2184     scrollbar->paint(&context, transformedClip);
2185     context.restore();
2186 }
2187
2188 // Up-call from compositing layer drawing callback.
2189 void RenderLayerBacking::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase paintingPhase, const IntRect& clip)
2190 {
2191 #ifndef NDEBUG
2192     if (Page* page = renderer().frame().page())
2193         page->setIsPainting(true);
2194 #endif
2195
2196     if (graphicsLayer == m_graphicsLayer.get()
2197         || graphicsLayer == m_foregroundLayer.get()
2198         || graphicsLayer == m_backgroundLayer.get()
2199         || graphicsLayer == m_maskLayer.get()
2200         || graphicsLayer == m_scrollingContentsLayer.get()) {
2201         InspectorInstrumentation::willPaint(&renderer());
2202
2203         // The dirtyRect is in the coords of the painting root.
2204         IntRect dirtyRect = clip;
2205         if (!(paintingPhase & GraphicsLayerPaintOverflowContents))
2206             dirtyRect.intersect(enclosingIntRect(compositedBoundsIncludingMargin()));
2207
2208         // We have to use the same root as for hit testing, because both methods can compute and cache clipRects.
2209         paintIntoLayer(graphicsLayer, &context, dirtyRect, PaintBehaviorNormal, paintingPhase);
2210
2211         InspectorInstrumentation::didPaint(&renderer(), &context, clip);
2212     } else if (graphicsLayer == layerForHorizontalScrollbar()) {
2213         paintScrollbar(m_owningLayer.horizontalScrollbar(), context, clip);
2214     } else if (graphicsLayer == layerForVerticalScrollbar()) {
2215         paintScrollbar(m_owningLayer.verticalScrollbar(), context, clip);
2216     } else if (graphicsLayer == layerForScrollCorner()) {
2217         const LayoutRect& scrollCornerAndResizer = m_owningLayer.scrollCornerAndResizerRect();
2218         context.save();
2219         context.translate(-scrollCornerAndResizer.x(), -scrollCornerAndResizer.y());
2220         LayoutRect transformedClip = clip;
2221         transformedClip.moveBy(scrollCornerAndResizer.location());
2222         m_owningLayer.paintScrollCorner(&context, IntPoint(), pixelSnappedIntRect(transformedClip));
2223         m_owningLayer.paintResizer(&context, IntPoint(), transformedClip);
2224         context.restore();
2225     }
2226 #ifndef NDEBUG
2227     if (Page* page = renderer().frame().page())
2228         page->setIsPainting(false);
2229 #endif
2230 }
2231
2232 float RenderLayerBacking::pageScaleFactor() const
2233 {
2234     return compositor().pageScaleFactor();
2235 }
2236
2237 float RenderLayerBacking::deviceScaleFactor() const
2238 {
2239     return compositor().deviceScaleFactor();
2240 }
2241
2242 float RenderLayerBacking::contentsScaleMultiplierForNewTiles(const GraphicsLayer* layer) const
2243 {
2244     return compositor().contentsScaleMultiplierForNewTiles(layer);
2245 }
2246
2247 void RenderLayerBacking::didCommitChangesForLayer(const GraphicsLayer* layer) const
2248 {
2249     compositor().didFlushChangesForLayer(m_owningLayer, layer);
2250 }
2251
2252 bool RenderLayerBacking::getCurrentTransform(const GraphicsLayer* graphicsLayer, TransformationMatrix& transform) const
2253 {
2254     GraphicsLayer* transformedLayer = m_contentsContainmentLayer.get() ? m_contentsContainmentLayer.get() : m_graphicsLayer.get();
2255     if (graphicsLayer != transformedLayer)
2256         return false;
2257
2258     if (m_owningLayer.hasTransform()) {
2259         transform = m_owningLayer.currentTransform(RenderStyle::ExcludeTransformOrigin);
2260         return true;
2261     }
2262     return false;
2263 }
2264
2265 bool RenderLayerBacking::isTrackingRepaints() const
2266 {
2267     return static_cast<GraphicsLayerClient&>(compositor()).isTrackingRepaints();
2268 }
2269
2270 bool RenderLayerBacking::shouldSkipLayerInDump(const GraphicsLayer* layer) const
2271 {
2272     // Skip the root tile cache's flattening layer.
2273     return m_isMainFrameRenderViewLayer && layer && layer == m_childContainmentLayer.get();
2274 }
2275
2276 bool RenderLayerBacking::shouldDumpPropertyForLayer(const GraphicsLayer* layer, const char* propertyName) const
2277 {
2278     // For backwards compatibility with WebKit1 and other platforms,
2279     // skip some properties on the root tile cache.
2280     if (m_isMainFrameRenderViewLayer && layer == m_graphicsLayer.get()) {
2281         if (!strcmp(propertyName, "drawsContent"))
2282             return false;
2283
2284         // Background color could be of interest to tests or other dumpers if it's non-white.
2285         if (!strcmp(propertyName, "backgroundColor") && layer->backgroundColor() == Color::white)
2286             return false;
2287
2288         // The root tile cache's repaints will show up at the top with FrameView's,
2289         // so don't dump them twice.
2290         if (!strcmp(propertyName, "repaintRects"))
2291             return false;
2292     }
2293
2294     return true;
2295 }
2296
2297 #ifndef NDEBUG
2298 void RenderLayerBacking::verifyNotPainting()
2299 {
2300     ASSERT(!renderer().frame().page() || !renderer().frame().page()->isPainting());
2301 }
2302 #endif
2303
2304 bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim, const KeyframeList& keyframes)
2305 {
2306     bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity);
2307     bool hasTransform = renderer().isBox() && keyframes.containsProperty(CSSPropertyWebkitTransform);
2308 #if ENABLE(CSS_FILTERS)
2309     bool hasFilter = keyframes.containsProperty(CSSPropertyWebkitFilter);
2310 #else
2311     bool hasFilter = false;
2312 #endif
2313
2314     if (!hasOpacity && !hasTransform && !hasFilter)
2315         return false;
2316     
2317     KeyframeValueList transformVector(AnimatedPropertyWebkitTransform);
2318     KeyframeValueList opacityVector(AnimatedPropertyOpacity);
2319 #if ENABLE(CSS_FILTERS)
2320     KeyframeValueList filterVector(AnimatedPropertyWebkitFilter);
2321 #endif
2322
2323     size_t numKeyframes = keyframes.size();
2324     for (size_t i = 0; i < numKeyframes; ++i) {
2325         const KeyframeValue& currentKeyframe = keyframes[i];
2326         const RenderStyle* keyframeStyle = currentKeyframe.style();
2327         double key = currentKeyframe.key();
2328
2329         if (!keyframeStyle)
2330             continue;
2331             
2332         // Get timing function.
2333         RefPtr<TimingFunction> tf = keyframeStyle->hasAnimations() ? (*keyframeStyle->animations()).animation(0).timingFunction() : 0;
2334         
2335         bool isFirstOrLastKeyframe = key == 0 || key == 1;
2336         if ((hasTransform && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitTransform))
2337             transformVector.insert(TransformAnimationValue::create(key, keyframeStyle->transform(), tf));
2338
2339         if ((hasOpacity && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyOpacity))
2340             opacityVector.insert(FloatAnimationValue::create(key, keyframeStyle->opacity(), tf));
2341
2342 #if ENABLE(CSS_FILTERS)
2343         if ((hasFilter && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitFilter))
2344             filterVector.insert(FilterAnimationValue::create(key, keyframeStyle->filter(), tf));
2345 #endif
2346     }
2347
2348     if (renderer().frame().page() && !renderer().frame().page()->settings().acceleratedCompositedAnimationsEnabled())
2349         return false;
2350
2351     bool didAnimate = false;
2352
2353     if (hasTransform && m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer()).pixelSnappedBorderBoxRect().size(), anim, keyframes.animationName(), timeOffset))
2354         didAnimate = true;
2355
2356     if (hasOpacity && m_graphicsLayer->addAnimation(opacityVector, IntSize(), anim, keyframes.animationName(), timeOffset))
2357         didAnimate = true;
2358
2359 #if ENABLE(CSS_FILTERS)
2360     if (hasFilter && m_graphicsLayer->addAnimation(filterVector, IntSize(), anim, keyframes.animationName(), timeOffset))
2361         didAnimate = true;
2362 #endif
2363
2364     return didAnimate;
2365 }
2366
2367 void RenderLayerBacking::animationPaused(double timeOffset, const String& animationName)
2368 {
2369     m_graphicsLayer->pauseAnimation(animationName, timeOffset);
2370 }
2371
2372 void RenderLayerBacking::animationFinished(const String& animationName)
2373 {
2374     m_graphicsLayer->removeAnimation(animationName);
2375 }
2376
2377 bool RenderLayerBacking::startTransition(double timeOffset, CSSPropertyID property, const RenderStyle* fromStyle, const RenderStyle* toStyle)
2378 {
2379     bool didAnimate = false;
2380
2381     ASSERT(property != CSSPropertyInvalid);
2382
2383     if (property == CSSPropertyOpacity) {
2384         const Animation* opacityAnim = toStyle->transitionForProperty(CSSPropertyOpacity);
2385         if (opacityAnim && !opacityAnim->isEmptyOrZeroDuration()) {
2386             KeyframeValueList opacityVector(AnimatedPropertyOpacity);
2387             opacityVector.insert(FloatAnimationValue::create(0, compositingOpacity(fromStyle->opacity())));
2388             opacityVector.insert(FloatAnimationValue::create(1, compositingOpacity(toStyle->opacity())));
2389             // The boxSize param is only used for transform animations (which can only run on RenderBoxes), so we pass an empty size here.
2390             if (m_graphicsLayer->addAnimation(opacityVector, IntSize(), opacityAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyOpacity), timeOffset)) {
2391                 // To ensure that the correct opacity is visible when the animation ends, also set the final opacity.
2392                 updateOpacity(toStyle);
2393                 didAnimate = true;
2394             }
2395         }
2396     }
2397
2398     if (property == CSSPropertyWebkitTransform && m_owningLayer.hasTransform()) {
2399         const Animation* transformAnim = toStyle->transitionForProperty(CSSPropertyWebkitTransform);
2400         if (transformAnim && !transformAnim->isEmptyOrZeroDuration()) {
2401             KeyframeValueList transformVector(AnimatedPropertyWebkitTransform);
2402             transformVector.insert(TransformAnimationValue::create(0, fromStyle->transform()));
2403             transformVector.insert(TransformAnimationValue::create(1, toStyle->transform()));
2404             if (m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer()).pixelSnappedBorderBoxRect().size(), transformAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitTransform), timeOffset)) {
2405                 // To ensure that the correct transform is visible when the animation ends, also set the final transform.
2406                 updateTransform(toStyle);
2407                 didAnimate = true;
2408             }
2409         }
2410     }
2411
2412 #if ENABLE(CSS_FILTERS)
2413     if (property == CSSPropertyWebkitFilter && m_owningLayer.hasFilter()) {
2414         const Animation* filterAnim = toStyle->transitionForProperty(CSSPropertyWebkitFilter);
2415         if (filterAnim && !filterAnim->isEmptyOrZeroDuration()) {
2416             KeyframeValueList filterVector(AnimatedPropertyWebkitFilter);
2417             filterVector.insert(FilterAnimationValue::create(0, fromStyle->filter()));
2418             filterVector.insert(FilterAnimationValue::create(1, toStyle->filter()));
2419             if (m_graphicsLayer->addAnimation(filterVector, IntSize(), filterAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitFilter), timeOffset)) {
2420                 // To ensure that the correct filter is visible when the animation ends, also set the final filter.
2421                 updateFilters(toStyle);
2422                 didAnimate = true;
2423             }
2424         }
2425     }
2426 #endif
2427
2428     return didAnimate;
2429 }
2430
2431 void RenderLayerBacking::transitionPaused(double timeOffset, CSSPropertyID property)
2432 {
2433     AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
2434     if (animatedProperty != AnimatedPropertyInvalid)
2435         m_graphicsLayer->pauseAnimation(GraphicsLayer::animationNameForTransition(animatedProperty), timeOffset);
2436 }
2437
2438 void RenderLayerBacking::transitionFinished(CSSPropertyID property)
2439 {
2440     AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
2441     if (animatedProperty != AnimatedPropertyInvalid)
2442         m_graphicsLayer->removeAnimation(GraphicsLayer::animationNameForTransition(animatedProperty));
2443 }
2444
2445 void RenderLayerBacking::notifyAnimationStarted(const GraphicsLayer*, double time)
2446 {
2447     renderer().animation().notifyAnimationStarted(&renderer(), time);
2448 }
2449
2450 void RenderLayerBacking::notifyFlushRequired(const GraphicsLayer* layer)
2451 {
2452     if (renderer().documentBeingDestroyed())
2453         return;
2454     compositor().scheduleLayerFlush(layer->canThrottleLayerFlush());
2455 }
2456
2457 void RenderLayerBacking::notifyFlushBeforeDisplayRefresh(const GraphicsLayer* layer)
2458 {
2459     compositor().notifyFlushBeforeDisplayRefresh(layer);
2460 }
2461
2462 // This is used for the 'freeze' API, for testing only.
2463 void RenderLayerBacking::suspendAnimations(double time)
2464 {
2465     m_graphicsLayer->suspendAnimations(time);
2466 }
2467
2468 void RenderLayerBacking::resumeAnimations()
2469 {
2470     m_graphicsLayer->resumeAnimations();
2471 }
2472
2473 LayoutRect RenderLayerBacking::compositedBounds() const
2474 {
2475     return m_compositedBounds;
2476 }
2477
2478 void RenderLayerBacking::setCompositedBounds(const LayoutRect& bounds)
2479 {
2480     m_compositedBounds = bounds;
2481 }
2482
2483 LayoutRect RenderLayerBacking::compositedBoundsIncludingMargin() const
2484 {
2485     TiledBacking* tiledBacking = this->tiledBacking();
2486     if (!tiledBacking || !tiledBacking->hasMargins())
2487         return compositedBounds();
2488
2489     LayoutRect boundsIncludingMargin = compositedBounds();
2490     LayoutUnit leftMarginWidth = tiledBacking->leftMarginWidth();
2491     LayoutUnit topMarginHeight = tiledBacking->topMarginHeight();
2492
2493     boundsIncludingMargin.moveBy(IntPoint(-leftMarginWidth, -topMarginHeight));
2494     boundsIncludingMargin.expand(leftMarginWidth + (LayoutUnit)tiledBacking->rightMarginWidth(), topMarginHeight + (LayoutUnit)tiledBacking->bottomMarginHeight());
2495
2496     return boundsIncludingMargin;
2497 }
2498
2499 CSSPropertyID RenderLayerBacking::graphicsLayerToCSSProperty(AnimatedPropertyID property)
2500 {
2501     CSSPropertyID cssProperty = CSSPropertyInvalid;
2502     switch (property) {
2503         case AnimatedPropertyWebkitTransform:
2504             cssProperty = CSSPropertyWebkitTransform;
2505             break;
2506         case AnimatedPropertyOpacity:
2507             cssProperty = CSSPropertyOpacity;
2508             break;
2509         case AnimatedPropertyBackgroundColor:
2510             cssProperty = CSSPropertyBackgroundColor;
2511             break;
2512         case AnimatedPropertyWebkitFilter:
2513 #if ENABLE(CSS_FILTERS)
2514             cssProperty = CSSPropertyWebkitFilter;
2515 #else
2516             ASSERT_NOT_REACHED();
2517 #endif
2518             break;
2519         case AnimatedPropertyInvalid:
2520             ASSERT_NOT_REACHED();
2521     }
2522     return cssProperty;
2523 }
2524
2525 AnimatedPropertyID RenderLayerBacking::cssToGraphicsLayerProperty(CSSPropertyID cssProperty)
2526 {
2527     switch (cssProperty) {
2528         case CSSPropertyWebkitTransform:
2529             return AnimatedPropertyWebkitTransform;
2530         case CSSPropertyOpacity:
2531             return AnimatedPropertyOpacity;
2532         case CSSPropertyBackgroundColor:
2533             return AnimatedPropertyBackgroundColor;
2534 #if ENABLE(CSS_FILTERS)
2535         case CSSPropertyWebkitFilter:
2536             return AnimatedPropertyWebkitFilter;
2537 #endif
2538         default:
2539             // It's fine if we see other css properties here; they are just not accelerated.
2540             break;
2541     }
2542     return AnimatedPropertyInvalid;
2543 }
2544
2545 CompositingLayerType RenderLayerBacking::compositingLayerType() const
2546 {
2547     if (m_graphicsLayer->hasContentsLayer())
2548         return MediaCompositingLayer;
2549
2550     if (m_graphicsLayer->drawsContent())
2551         return m_graphicsLayer->usingTiledBacking() ? TiledCompositingLayer : NormalCompositingLayer;
2552     
2553     return ContainerCompositingLayer;
2554 }
2555
2556 double RenderLayerBacking::backingStoreMemoryEstimate() const
2557 {
2558     double backingMemory;
2559     
2560     // m_ancestorClippingLayer, m_contentsContainmentLayer and m_childContainmentLayer are just used for masking or containment, so have no backing.
2561     backingMemory = m_graphicsLayer->backingStoreMemoryEstimate();
2562     if (m_foregroundLayer)
2563         backingMemory += m_foregroundLayer->backingStoreMemoryEstimate();
2564     if (m_backgroundLayer)
2565         backingMemory += m_backgroundLayer->backingStoreMemoryEstimate();
2566     if (m_maskLayer)
2567         backingMemory += m_maskLayer->backingStoreMemoryEstimate();
2568
2569     if (m_scrollingContentsLayer)
2570         backingMemory += m_scrollingContentsLayer->backingStoreMemoryEstimate();
2571
2572     if (m_layerForHorizontalScrollbar)
2573         backingMemory += m_layerForHorizontalScrollbar->backingStoreMemoryEstimate();
2574
2575     if (m_layerForVerticalScrollbar)
2576         backingMemory += m_layerForVerticalScrollbar->backingStoreMemoryEstimate();
2577
2578     if (m_layerForScrollCorner)
2579         backingMemory += m_layerForScrollCorner->backingStoreMemoryEstimate();
2580     
2581     return backingMemory;
2582 }
2583
2584 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
2585 bool RenderLayerBacking::mediaLayerMustBeUpdatedOnMainThread() const
2586 {
2587     return renderer().frame().page() && renderer().frame().page()->settings().isVideoPluginProxyEnabled();
2588 }
2589 #endif
2590
2591 } // namespace WebCore