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