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