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