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