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