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