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