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