Replace OptionSet |= and -= operators with add() and remove() functions
[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 "FilterEffectRenderer.h"
38 #include "Frame.h"
39 #include "FrameView.h"
40 #include "GraphicsContext.h"
41 #include "GraphicsLayer.h"
42 #include "HTMLBodyElement.h"
43 #include "HTMLCanvasElement.h"
44 #include "HTMLIFrameElement.h"
45 #include "HTMLMediaElement.h"
46 #include "HTMLNames.h"
47 #include "HTMLPlugInElement.h"
48 #include "InspectorInstrumentation.h"
49 #include "KeyframeList.h"
50 #include "Logging.h"
51 #include "Page.h"
52 #include "PerformanceLoggingClient.h"
53 #include "PluginViewBase.h"
54 #include "ProgressTracker.h"
55 #include "RenderFragmentContainer.h"
56 #include "RenderFragmentedFlow.h"
57 #include "RenderHTMLCanvas.h"
58 #include "RenderIFrame.h"
59 #include "RenderImage.h"
60 #include "RenderLayerCompositor.h"
61 #include "RenderEmbeddedObject.h"
62 #include "RenderMedia.h"
63 #include "RenderVideo.h"
64 #include "RenderView.h"
65 #include "RuntimeEnabledFeatures.h"
66 #include "ScrollingCoordinator.h"
67 #include "Settings.h"
68 #include "StyleResolver.h"
69 #include "TiledBacking.h"
70 #include <wtf/text/TextStream.h>
71
72 #if PLATFORM(IOS)
73 #include "RuntimeApplicationChecks.h"
74 #endif
75
76 #if PLATFORM(MAC)
77 #include "LocalDefaultSystemAppearance.h"
78 #endif
79
80 namespace WebCore {
81
82 using namespace HTMLNames;
83
84 CanvasCompositingStrategy canvasCompositingStrategy(const RenderObject& renderer)
85 {
86     ASSERT(renderer.isCanvas());
87     
88     const HTMLCanvasElement* canvas = downcast<HTMLCanvasElement>(renderer.node());
89     auto* context = canvas->renderingContext();
90     if (!context || !context->isAccelerated())
91         return UnacceleratedCanvas;
92     
93     if (context->isGPUBased())
94         return CanvasAsLayerContents;
95
96 #if ENABLE(ACCELERATED_2D_CANVAS)
97     return CanvasAsLayerContents;
98 #else
99     return CanvasPaintedToLayer; // On Mac and iOS we paint accelerated canvases into their layers.
100 #endif
101 }
102
103 // This acts as a cache of what we know about what is painting into this RenderLayerBacking.
104 class PaintedContentsInfo {
105 public:
106     enum class ContentsTypeDetermination {
107         Unknown,
108         SimpleContainer,
109         DirectlyCompositedImage,
110         Painted
111     };
112
113     PaintedContentsInfo(RenderLayerBacking& inBacking)
114         : m_backing(inBacking)
115     {
116     }
117     
118     void setWantsSubpixelAntialiasedTextState(bool wantsSubpixelAntialiasedTextState)
119     {
120         m_subpixelAntialiasedText = wantsSubpixelAntialiasedTextState ? RequestState::Unknown : RequestState::DontCare;
121     }
122
123     RequestState paintsBoxDecorationsDetermination();
124     bool paintsBoxDecorations()
125     {
126         RequestState state = paintsBoxDecorationsDetermination();
127         return state == RequestState::True || state == RequestState::Undetermined;
128     }
129
130     RequestState paintsContentDetermination();
131     bool paintsContent()
132     {
133         RequestState state = paintsContentDetermination();
134         return state == RequestState::True || state == RequestState::Undetermined;
135     }
136
137     RequestState paintsSubpixelAntialiasedTextDetermination();
138     bool paintsSubpixelAntialiasedText()
139     {
140         RequestState state = paintsSubpixelAntialiasedTextDetermination();
141         return state == RequestState::True || state == RequestState::Undetermined;
142     }
143
144     ContentsTypeDetermination contentsTypeDetermination();
145     bool isSimpleContainer()
146     {
147         return contentsTypeDetermination() == ContentsTypeDetermination::SimpleContainer;
148     }
149
150     bool isDirectlyCompositedImage()
151     {
152         return contentsTypeDetermination() == ContentsTypeDetermination::DirectlyCompositedImage;
153     }
154
155     RenderLayerBacking& m_backing;
156     RequestState m_boxDecorations { RequestState::Unknown };
157     RequestState m_content { RequestState::Unknown };
158     RequestState m_subpixelAntialiasedText { RequestState::DontCare };
159
160     ContentsTypeDetermination m_contentsType { ContentsTypeDetermination::Unknown };
161 };
162
163 RequestState PaintedContentsInfo::paintsBoxDecorationsDetermination()
164 {
165     if (m_boxDecorations != RequestState::Unknown)
166         return m_boxDecorations;
167
168     m_boxDecorations = m_backing.paintsBoxDecorations() ? RequestState::True : RequestState::False;
169     return m_boxDecorations;
170 }
171
172 RequestState PaintedContentsInfo::paintsContentDetermination()
173 {
174     if (m_content != RequestState::Unknown && m_subpixelAntialiasedText != RequestState::Unknown)
175         return m_content;
176
177     RenderLayer::PaintedContentRequest contentRequest;
178     if (m_subpixelAntialiasedText == RequestState::Unknown)
179         contentRequest.hasSubpixelAntialiasedText = RequestState::Unknown;
180
181     m_content = m_backing.paintsContent(contentRequest) ? RequestState::True : RequestState::False;
182
183     if (m_subpixelAntialiasedText == RequestState::Unknown)
184         m_subpixelAntialiasedText = contentRequest.hasSubpixelAntialiasedText;
185
186     return m_content;
187 }
188
189 RequestState PaintedContentsInfo::paintsSubpixelAntialiasedTextDetermination()
190 {
191     if (m_subpixelAntialiasedText != RequestState::Unknown)
192         return m_subpixelAntialiasedText;
193
194     paintsContentDetermination();
195
196     return m_subpixelAntialiasedText;
197 }
198
199 PaintedContentsInfo::ContentsTypeDetermination PaintedContentsInfo::contentsTypeDetermination()
200 {
201     if (m_contentsType != ContentsTypeDetermination::Unknown)
202         return m_contentsType;
203
204     if (m_backing.isSimpleContainerCompositingLayer(*this))
205         m_contentsType = ContentsTypeDetermination::SimpleContainer;
206     else if (m_backing.isDirectlyCompositedImage())
207         m_contentsType = ContentsTypeDetermination::DirectlyCompositedImage;
208     else
209         m_contentsType = ContentsTypeDetermination::Painted;
210
211     return m_contentsType;
212 }
213
214
215 RenderLayerBacking::RenderLayerBacking(RenderLayer& layer)
216     : m_owningLayer(layer)
217 {
218     if (layer.isRenderViewLayer()) {
219         m_isMainFrameRenderViewLayer = renderer().frame().isMainFrame();
220         m_isFrameLayerWithTiledBacking = renderer().page().chrome().client().shouldUseTiledBackingForFrameView(renderer().view().frameView());
221     }
222     
223     createPrimaryGraphicsLayer();
224 #if ENABLE(FULLSCREEN_API)
225     setRequiresBackgroundLayer(layer.renderer().isRenderFullScreen());
226 #endif
227
228     if (auto* tiledBacking = this->tiledBacking()) {
229         tiledBacking->setIsInWindow(renderer().page().isInWindow());
230
231         if (m_isFrameLayerWithTiledBacking) {
232             tiledBacking->setScrollingPerformanceLoggingEnabled(renderer().settings().scrollingPerformanceLoggingEnabled());
233             adjustTiledBackingCoverage();
234         }
235     }
236 }
237
238 RenderLayerBacking::~RenderLayerBacking()
239 {
240     updateAncestorClippingLayer(false);
241     updateChildClippingStrategy(false);
242     updateDescendantClippingLayer(false);
243     updateOverflowControlsLayers(false, false, false);
244     updateForegroundLayer(false);
245     updateBackgroundLayer(false);
246     updateMaskingLayer(false, false);
247     updateScrollingLayers(false);
248     detachFromScrollingCoordinator({ Scrolling, ViewportConstrained });
249     destroyGraphicsLayers();
250 }
251
252 void RenderLayerBacking::willDestroyLayer(const GraphicsLayer* layer)
253 {
254     if (layer && layer->type() == GraphicsLayer::Type::Normal && layer->tiledBacking())
255         compositor().layerTiledBackingUsageChanged(layer, false);
256 }
257
258 std::unique_ptr<GraphicsLayer> RenderLayerBacking::createGraphicsLayer(const String& name, GraphicsLayer::Type layerType)
259 {
260     auto* graphicsLayerFactory = renderer().page().chrome().client().graphicsLayerFactory();
261
262     std::unique_ptr<GraphicsLayer> graphicsLayer = GraphicsLayer::create(graphicsLayerFactory, *this, layerType);
263
264     graphicsLayer->setName(name);
265
266 #if PLATFORM(COCOA) && USE(CA)
267     graphicsLayer->setAcceleratesDrawing(compositor().acceleratedDrawingEnabled());
268     graphicsLayer->setUsesDisplayListDrawing(compositor().displayListDrawingEnabled());
269 #endif
270     
271     return graphicsLayer;
272 }
273
274 void RenderLayerBacking::setUsesDisplayListDrawing(bool usesDisplayListDrawing)
275 {
276     // Note that this only affects the primary layer.
277     if (usesDisplayListDrawing == m_graphicsLayer->usesDisplayListDrawing())
278         return;
279
280     m_graphicsLayer->setUsesDisplayListDrawing(usesDisplayListDrawing);
281     if (m_graphicsLayer->drawsContent())
282         m_graphicsLayer->setNeedsDisplay();
283 }
284
285 String RenderLayerBacking::displayListAsText(DisplayList::AsTextFlags flags) const
286 {
287     return m_graphicsLayer->displayListAsText(flags);
288 }
289
290 void RenderLayerBacking::setIsTrackingDisplayListReplay(bool isTrackingReplay)
291 {
292     m_graphicsLayer->setIsTrackingDisplayListReplay(isTrackingReplay);
293 }
294
295 String RenderLayerBacking::replayDisplayListAsText(DisplayList::AsTextFlags flags) const
296 {
297     return m_graphicsLayer->replayDisplayListAsText(flags);
298 }
299
300 void RenderLayerBacking::tiledBackingUsageChanged(const GraphicsLayer* layer, bool usingTiledBacking)
301 {
302     compositor().layerTiledBackingUsageChanged(layer, usingTiledBacking);
303 }
304
305 TiledBacking* RenderLayerBacking::tiledBacking() const
306 {
307     return m_graphicsLayer->tiledBacking();
308 }
309
310 static TiledBacking::TileCoverage computePageTiledBackingCoverage(RenderLayerBacking* backing)
311 {
312     // FIXME: When we use TiledBacking for overflow, this should look at RenderView scrollability.
313     auto& frameView = backing->owningLayer().renderer().view().frameView();
314
315     // If the page is non-visible, don't incur the cost of keeping extra tiles for scrolling.
316     if (!backing->owningLayer().page().isVisible())
317         return TiledBacking::CoverageForVisibleArea;
318
319     TiledBacking::TileCoverage tileCoverage = TiledBacking::CoverageForVisibleArea;
320     bool useMinimalTilesDuringLiveResize = frameView.inLiveResize();
321     if (frameView.speculativeTilingEnabled() && !useMinimalTilesDuringLiveResize) {
322         bool clipsToExposedRect = static_cast<bool>(frameView.viewExposedRect());
323         if (frameView.horizontalScrollbarMode() != ScrollbarAlwaysOff || clipsToExposedRect)
324             tileCoverage |= TiledBacking::CoverageForHorizontalScrolling;
325
326         if (frameView.verticalScrollbarMode() != ScrollbarAlwaysOff || clipsToExposedRect)
327             tileCoverage |= TiledBacking::CoverageForVerticalScrolling;
328     }
329     return tileCoverage;
330 }
331
332 void RenderLayerBacking::adjustTiledBackingCoverage()
333 {
334     if (!m_isFrameLayerWithTiledBacking)
335         return;
336
337     TiledBacking::TileCoverage tileCoverage = computePageTiledBackingCoverage(this);
338     tiledBacking()->setTileCoverage(tileCoverage);
339 }
340
341 void RenderLayerBacking::setTiledBackingHasMargins(bool hasExtendedBackgroundOnLeftAndRight, bool hasExtendedBackgroundOnTopAndBottom)
342 {
343     if (!m_isFrameLayerWithTiledBacking)
344         return;
345
346     tiledBacking()->setHasMargins(hasExtendedBackgroundOnTopAndBottom, hasExtendedBackgroundOnTopAndBottom, hasExtendedBackgroundOnLeftAndRight, hasExtendedBackgroundOnLeftAndRight);
347 }
348
349 void RenderLayerBacking::updateDebugIndicators(bool showBorder, bool showRepaintCounter)
350 {
351     m_graphicsLayer->setShowDebugBorder(showBorder);
352     m_graphicsLayer->setShowRepaintCounter(showRepaintCounter);
353     
354     if (m_ancestorClippingLayer)
355         m_ancestorClippingLayer->setShowDebugBorder(showBorder);
356
357     if (m_foregroundLayer) {
358         m_foregroundLayer->setShowDebugBorder(showBorder);
359         m_foregroundLayer->setShowRepaintCounter(showRepaintCounter);
360     }
361     
362     if (m_contentsContainmentLayer)
363         m_contentsContainmentLayer->setShowDebugBorder(showBorder);
364     
365     if (m_backgroundLayer) {
366         m_backgroundLayer->setShowDebugBorder(showBorder);
367         m_backgroundLayer->setShowRepaintCounter(showRepaintCounter);
368     }
369
370     if (m_maskLayer) {
371         m_maskLayer->setShowDebugBorder(showBorder);
372         m_maskLayer->setShowRepaintCounter(showRepaintCounter);
373     }
374
375     if (m_layerForHorizontalScrollbar)
376         m_layerForHorizontalScrollbar->setShowDebugBorder(showBorder);
377
378     if (m_layerForVerticalScrollbar)
379         m_layerForVerticalScrollbar->setShowDebugBorder(showBorder);
380
381     if (m_layerForScrollCorner)
382         m_layerForScrollCorner->setShowDebugBorder(showBorder);
383
384     if (m_scrollingLayer)
385         m_scrollingLayer->setShowDebugBorder(showBorder);
386
387     if (m_scrollingContentsLayer) {
388         m_scrollingContentsLayer->setShowDebugBorder(showBorder);
389         m_scrollingContentsLayer->setShowRepaintCounter(showRepaintCounter);
390     }
391 }
392
393 void RenderLayerBacking::createPrimaryGraphicsLayer()
394 {
395     String layerName = m_owningLayer.name();
396     const unsigned maxLayerNameLength = 100;
397     if (layerName.length() > maxLayerNameLength) {
398         layerName.truncate(maxLayerNameLength);
399         layerName.append("...");
400     }
401     m_graphicsLayer = createGraphicsLayer(layerName, m_isFrameLayerWithTiledBacking ? GraphicsLayer::Type::PageTiledBacking : GraphicsLayer::Type::Normal);
402
403     if (m_isFrameLayerWithTiledBacking) {
404         m_childContainmentLayer = createGraphicsLayer("Page TiledBacking containment");
405         m_graphicsLayer->addChild(m_childContainmentLayer.get());
406     }
407
408 #if !PLATFORM(IOS)
409     if (m_isMainFrameRenderViewLayer) {
410         // Page scale is applied above the RenderView on iOS.
411         m_graphicsLayer->setContentsOpaque(!compositor().viewHasTransparentBackground());
412         m_graphicsLayer->setAppliesPageScale();
413     }
414 #endif
415
416 #if PLATFORM(COCOA) && USE(CA)
417     if (!compositor().acceleratedDrawingEnabled() && renderer().isCanvas()) {
418         const HTMLCanvasElement* canvas = downcast<HTMLCanvasElement>(renderer().element());
419         if (canvas->shouldAccelerate(canvas->size()))
420             m_graphicsLayer->setAcceleratesDrawing(true);
421     }
422 #endif    
423     
424     updateOpacity(renderer().style());
425     updateTransform(renderer().style());
426     updateFilters(renderer().style());
427 #if ENABLE(FILTERS_LEVEL_2)
428     updateBackdropFilters(renderer().style());
429 #endif
430 #if ENABLE(CSS_COMPOSITING)
431     updateBlendMode(renderer().style());
432 #endif
433     updateCustomAppearance(renderer().style());
434 }
435
436 #if PLATFORM(IOS)
437 void RenderLayerBacking::layerWillBeDestroyed()
438 {
439     auto& renderer = this->renderer();
440     if (is<RenderEmbeddedObject>(renderer) && downcast<RenderEmbeddedObject>(renderer).allowsAcceleratedCompositing()) {
441         auto* pluginViewBase = downcast<PluginViewBase>(downcast<RenderWidget>(renderer).widget());
442         if (pluginViewBase && m_graphicsLayer->contentsLayerForMedia())
443             pluginViewBase->detachPluginLayer();
444     }
445 }
446
447 bool RenderLayerBacking::needsIOSDumpRenderTreeMainFrameRenderViewLayerIsAlwaysOpaqueHack(const GraphicsLayer& layer) const
448 {
449     if (m_isMainFrameRenderViewLayer && IOSApplication::isDumpRenderTree()) {
450         // In iOS WebKit1 the main frame's RenderView layer is always transparent. We lie that it is opaque so that
451         // internals.layerTreeAsText() tests succeed.
452         ASSERT_UNUSED(layer, !layer.contentsOpaque());
453         return true;
454     }
455     return false;
456 }
457 #endif
458
459 void RenderLayerBacking::destroyGraphicsLayers()
460 {
461     if (m_graphicsLayer) {
462         willDestroyLayer(m_graphicsLayer.get());
463         m_graphicsLayer->removeFromParent();
464     }
465
466     m_ancestorClippingLayer = nullptr;
467     m_contentsContainmentLayer = nullptr;
468     m_graphicsLayer = nullptr;
469     m_foregroundLayer = nullptr;
470     m_backgroundLayer = nullptr;
471     m_childContainmentLayer = nullptr;
472     m_maskLayer = nullptr;
473     m_childClippingMaskLayer = nullptr;
474
475     m_scrollingLayer = nullptr;
476     m_scrollingContentsLayer = nullptr;
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.get());
1307     }
1308     
1309     if (m_backgroundLayer)
1310         m_contentsContainmentLayer->addChild(m_backgroundLayer.get());
1311
1312     if (m_contentsContainmentLayer)
1313         m_contentsContainmentLayer->addChild(m_graphicsLayer.get());
1314     else if (m_ancestorClippingLayer)
1315         m_ancestorClippingLayer->addChild(m_graphicsLayer.get());
1316
1317     if (m_childContainmentLayer) {
1318         m_childContainmentLayer->removeFromParent();
1319         m_graphicsLayer->addChild(m_childContainmentLayer.get());
1320     }
1321
1322     if (m_scrollingLayer) {
1323         auto* superlayer = m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsLayer.get();
1324         m_scrollingLayer->removeFromParent();
1325         superlayer->addChild(m_scrollingLayer.get());
1326     }
1327
1328     // The clip for child layers does not include space for overflow controls, so they exist as
1329     // siblings of the clipping layer if we have one. Normal children of this layer are set as
1330     // children of the clipping layer.
1331     if (m_layerForHorizontalScrollbar) {
1332         m_layerForHorizontalScrollbar->removeFromParent();
1333         m_graphicsLayer->addChild(m_layerForHorizontalScrollbar.get());
1334     }
1335     if (m_layerForVerticalScrollbar) {
1336         m_layerForVerticalScrollbar->removeFromParent();
1337         m_graphicsLayer->addChild(m_layerForVerticalScrollbar.get());
1338     }
1339     if (m_layerForScrollCorner) {
1340         m_layerForScrollCorner->removeFromParent();
1341         m_graphicsLayer->addChild(m_layerForScrollCorner.get());
1342     }
1343 }
1344
1345 void RenderLayerBacking::resetContentsRect()
1346 {
1347     m_graphicsLayer->setContentsRect(snapRectToDevicePixels(contentsBox(), deviceScaleFactor()));
1348     
1349     if (is<RenderBox>(renderer())) {
1350         LayoutRect boxRect(LayoutPoint(), downcast<RenderBox>(renderer()).size());
1351         boxRect.move(contentOffsetInCompostingLayer());
1352         FloatRoundedRect contentsClippingRect = renderer().style().getRoundedInnerBorderFor(boxRect).pixelSnappedRoundedRectForPainting(deviceScaleFactor());
1353         m_graphicsLayer->setContentsClippingRect(contentsClippingRect);
1354     }
1355
1356     m_graphicsLayer->setContentsTileSize(IntSize());
1357     m_graphicsLayer->setContentsTilePhase(IntSize());
1358 }
1359
1360 void RenderLayerBacking::updateDrawsContent()
1361 {
1362     PaintedContentsInfo contentsInfo(*this);
1363     contentsInfo.setWantsSubpixelAntialiasedTextState(GraphicsLayer::supportsSubpixelAntialiasedLayerText());
1364
1365     updateDrawsContent(contentsInfo);
1366 }
1367
1368 void RenderLayerBacking::updateDrawsContent(PaintedContentsInfo& contentsInfo)
1369 {
1370     if (m_scrollingLayer) {
1371         // We don't have to consider overflow controls, because we know that the scrollbars are drawn elsewhere.
1372         // m_graphicsLayer only needs backing store if the non-scrolling parts (background, outlines, borders, shadows etc) need to paint.
1373         // m_scrollingLayer never has backing store.
1374         // m_scrollingContentsLayer only needs backing store if the scrolled contents need to paint.
1375         bool hasNonScrollingPaintedContent = m_owningLayer.hasVisibleContent() && m_owningLayer.hasVisibleBoxDecorationsOrBackground();
1376         m_graphicsLayer->setDrawsContent(hasNonScrollingPaintedContent);
1377
1378         bool hasScrollingPaintedContent = m_owningLayer.hasVisibleContent() && (renderer().hasBackground() || contentsInfo.paintsContent());
1379         m_scrollingContentsLayer->setDrawsContent(hasScrollingPaintedContent);
1380         return;
1381     }
1382
1383     bool hasPaintedContent = containsPaintedContent(contentsInfo);
1384
1385     m_paintsSubpixelAntialiasedText = renderer().settings().subpixelAntialiasedLayerTextEnabled() && contentsInfo.paintsSubpixelAntialiasedText();
1386
1387     // FIXME: we could refine this to only allocate backing for one of these layers if possible.
1388     m_graphicsLayer->setDrawsContent(hasPaintedContent);
1389     if (m_foregroundLayer) {
1390         m_foregroundLayer->setDrawsContent(hasPaintedContent);
1391         m_foregroundLayer->setSupportsSubpixelAntialiasedText(m_paintsSubpixelAntialiasedText);
1392         // The text content is painted into the foreground layer.
1393         // FIXME: this ignores SVG background images which may contain text.
1394         m_graphicsLayer->setSupportsSubpixelAntialiasedText(false);
1395     } else
1396         m_graphicsLayer->setSupportsSubpixelAntialiasedText(m_paintsSubpixelAntialiasedText);
1397
1398     if (m_backgroundLayer)
1399         m_backgroundLayer->setDrawsContent(m_backgroundLayerPaintsFixedRootBackground ? hasPaintedContent : contentsInfo.paintsBoxDecorations());
1400 }
1401
1402 // Return true if the layer changed.
1403 bool RenderLayerBacking::updateAncestorClippingLayer(bool needsAncestorClip)
1404 {
1405     bool layersChanged = false;
1406
1407     if (needsAncestorClip) {
1408         if (!m_ancestorClippingLayer) {
1409             m_ancestorClippingLayer = createGraphicsLayer("ancestor clipping");
1410             m_ancestorClippingLayer->setMasksToBounds(true);
1411             layersChanged = true;
1412         }
1413     } else if (hasAncestorClippingLayer()) {
1414         willDestroyLayer(m_ancestorClippingLayer.get());
1415         m_ancestorClippingLayer->removeFromParent();
1416         m_ancestorClippingLayer = nullptr;
1417         layersChanged = true;
1418     }
1419     
1420     return layersChanged;
1421 }
1422
1423 // Return true if the layer changed.
1424 bool RenderLayerBacking::updateDescendantClippingLayer(bool needsDescendantClip)
1425 {
1426     bool layersChanged = false;
1427
1428     if (needsDescendantClip) {
1429         if (!m_childContainmentLayer && !m_isFrameLayerWithTiledBacking) {
1430             m_childContainmentLayer = createGraphicsLayer("child clipping");
1431             m_childContainmentLayer->setMasksToBounds(true);
1432             layersChanged = true;
1433         }
1434     } else if (hasClippingLayer()) {
1435         willDestroyLayer(m_childContainmentLayer.get());
1436         m_childContainmentLayer->removeFromParent();
1437         m_childContainmentLayer = nullptr;
1438         layersChanged = true;
1439     }
1440     
1441     return layersChanged;
1442 }
1443
1444 void RenderLayerBacking::setBackgroundLayerPaintsFixedRootBackground(bool backgroundLayerPaintsFixedRootBackground)
1445 {
1446     if (backgroundLayerPaintsFixedRootBackground == m_backgroundLayerPaintsFixedRootBackground)
1447         return;
1448
1449     m_backgroundLayerPaintsFixedRootBackground = backgroundLayerPaintsFixedRootBackground;
1450
1451     if (m_backgroundLayerPaintsFixedRootBackground) {
1452         ASSERT(m_isFrameLayerWithTiledBacking);
1453         renderer().view().frameView().removeSlowRepaintObject(*renderer().view().rendererForRootBackground());
1454     }
1455 }
1456
1457 void RenderLayerBacking::setRequiresBackgroundLayer(bool requiresBackgroundLayer)
1458 {
1459     m_requiresBackgroundLayer = requiresBackgroundLayer;
1460 }
1461
1462 bool RenderLayerBacking::requiresHorizontalScrollbarLayer() const
1463 {
1464     if (!m_owningLayer.hasOverlayScrollbars() && !m_owningLayer.needsCompositedScrolling())
1465         return false;
1466     return m_owningLayer.horizontalScrollbar();
1467 }
1468
1469 bool RenderLayerBacking::requiresVerticalScrollbarLayer() const
1470 {
1471     if (!m_owningLayer.hasOverlayScrollbars() && !m_owningLayer.needsCompositedScrolling())
1472         return false;
1473     return m_owningLayer.verticalScrollbar();
1474 }
1475
1476 bool RenderLayerBacking::requiresScrollCornerLayer() const
1477 {
1478     if (!m_owningLayer.hasOverlayScrollbars() && !m_owningLayer.needsCompositedScrolling())
1479         return false;
1480     return !m_owningLayer.scrollCornerAndResizerRect().isEmpty();
1481 }
1482
1483 bool RenderLayerBacking::updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer)
1484 {
1485     bool horizontalScrollbarLayerChanged = false;
1486     if (needsHorizontalScrollbarLayer) {
1487         if (!m_layerForHorizontalScrollbar) {
1488             m_layerForHorizontalScrollbar = createGraphicsLayer("horizontal scrollbar");
1489             m_layerForHorizontalScrollbar->setCanDetachBackingStore(false);
1490             horizontalScrollbarLayerChanged = true;
1491         }
1492     } else if (m_layerForHorizontalScrollbar) {
1493         willDestroyLayer(m_layerForHorizontalScrollbar.get());
1494         m_layerForHorizontalScrollbar = nullptr;
1495         horizontalScrollbarLayerChanged = true;
1496     }
1497
1498     bool verticalScrollbarLayerChanged = false;
1499     if (needsVerticalScrollbarLayer) {
1500         if (!m_layerForVerticalScrollbar) {
1501             m_layerForVerticalScrollbar = createGraphicsLayer("vertical scrollbar");
1502             m_layerForVerticalScrollbar->setCanDetachBackingStore(false);
1503             verticalScrollbarLayerChanged = true;
1504         }
1505     } else if (m_layerForVerticalScrollbar) {
1506         willDestroyLayer(m_layerForVerticalScrollbar.get());
1507         m_layerForVerticalScrollbar = nullptr;
1508         verticalScrollbarLayerChanged = true;
1509     }
1510
1511     bool scrollCornerLayerChanged = false;
1512     if (needsScrollCornerLayer) {
1513         if (!m_layerForScrollCorner) {
1514             m_layerForScrollCorner = createGraphicsLayer("scroll corner");
1515             m_layerForScrollCorner->setCanDetachBackingStore(false);
1516             scrollCornerLayerChanged = true;
1517         }
1518     } else if (m_layerForScrollCorner) {
1519         willDestroyLayer(m_layerForScrollCorner.get());
1520         m_layerForScrollCorner = nullptr;
1521         scrollCornerLayerChanged = true;
1522     }
1523
1524     if (auto* scrollingCoordinator = m_owningLayer.page().scrollingCoordinator()) {
1525         if (horizontalScrollbarLayerChanged)
1526             scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_owningLayer, HorizontalScrollbar);
1527         if (verticalScrollbarLayerChanged)
1528             scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_owningLayer, VerticalScrollbar);
1529     }
1530
1531     return horizontalScrollbarLayerChanged || verticalScrollbarLayerChanged || scrollCornerLayerChanged;
1532 }
1533
1534 void RenderLayerBacking::positionOverflowControlsLayers()
1535 {
1536     if (!m_owningLayer.hasScrollbars())
1537         return;
1538
1539     const IntRect borderBox = snappedIntRect(renderBox()->borderBoxRect());
1540
1541     FloatSize offsetFromRenderer = m_graphicsLayer->offsetFromRenderer();
1542     if (auto* layer = layerForHorizontalScrollbar()) {
1543         IntRect hBarRect = m_owningLayer.rectForHorizontalScrollbar(borderBox);
1544         layer->setPosition(hBarRect.location() - offsetFromRenderer);
1545         layer->setSize(hBarRect.size());
1546         if (layer->usesContentsLayer()) {
1547             IntRect barRect = IntRect(IntPoint(), hBarRect.size());
1548             layer->setContentsRect(barRect);
1549             layer->setContentsClippingRect(FloatRoundedRect(barRect));
1550         }
1551         layer->setDrawsContent(m_owningLayer.horizontalScrollbar() && !layer->usesContentsLayer());
1552     }
1553     
1554     if (auto* layer = layerForVerticalScrollbar()) {
1555         IntRect vBarRect = m_owningLayer.rectForVerticalScrollbar(borderBox);
1556         layer->setPosition(vBarRect.location() - offsetFromRenderer);
1557         layer->setSize(vBarRect.size());
1558         if (layer->usesContentsLayer()) {
1559             IntRect barRect = IntRect(IntPoint(), vBarRect.size());
1560             layer->setContentsRect(barRect);
1561             layer->setContentsClippingRect(FloatRoundedRect(barRect));
1562         }
1563         layer->setDrawsContent(m_owningLayer.verticalScrollbar() && !layer->usesContentsLayer());
1564     }
1565
1566     if (auto* layer = layerForScrollCorner()) {
1567         const LayoutRect& scrollCornerAndResizer = m_owningLayer.scrollCornerAndResizerRect();
1568         layer->setPosition(scrollCornerAndResizer.location() - offsetFromRenderer);
1569         layer->setSize(scrollCornerAndResizer.size());
1570         layer->setDrawsContent(!scrollCornerAndResizer.isEmpty());
1571     }
1572 }
1573
1574 bool RenderLayerBacking::hasUnpositionedOverflowControlsLayers() const
1575 {
1576     if (auto* layer = layerForHorizontalScrollbar()) {
1577         if (!layer->drawsContent())
1578             return true;
1579     }
1580
1581     if (auto* layer = layerForVerticalScrollbar()) {
1582         if (!layer->drawsContent())
1583             return true;
1584     }
1585
1586     if (auto* layer = layerForScrollCorner()) {
1587         if (!layer->drawsContent())
1588             return true;
1589     }
1590
1591     return false;
1592 }
1593
1594 bool RenderLayerBacking::updateForegroundLayer(bool needsForegroundLayer)
1595 {
1596     bool layerChanged = false;
1597     if (needsForegroundLayer) {
1598         if (!m_foregroundLayer) {
1599             String layerName = m_owningLayer.name() + " (foreground)";
1600             m_foregroundLayer = createGraphicsLayer(layerName);
1601             m_foregroundLayer->setDrawsContent(true);
1602             m_foregroundLayer->setPaintingPhase(GraphicsLayerPaintForeground);
1603             layerChanged = true;
1604         }
1605     } else if (m_foregroundLayer) {
1606         willDestroyLayer(m_foregroundLayer.get());
1607         m_foregroundLayer->removeFromParent();
1608         m_foregroundLayer = nullptr;
1609         layerChanged = true;
1610     }
1611
1612     if (layerChanged) {
1613         m_graphicsLayer->setNeedsDisplay();
1614         m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
1615     }
1616
1617     return layerChanged;
1618 }
1619
1620 bool RenderLayerBacking::updateBackgroundLayer(bool needsBackgroundLayer)
1621 {
1622     bool layerChanged = false;
1623     if (needsBackgroundLayer) {
1624         if (!m_backgroundLayer) {
1625             String layerName = m_owningLayer.name() + " (background)";
1626             m_backgroundLayer = createGraphicsLayer(layerName);
1627             m_backgroundLayer->setDrawsContent(true);
1628             m_backgroundLayer->setAnchorPoint(FloatPoint3D());
1629             m_backgroundLayer->setPaintingPhase(GraphicsLayerPaintBackground);
1630             layerChanged = true;
1631         }
1632         
1633         if (!m_contentsContainmentLayer) {
1634             String layerName = m_owningLayer.name() + " (contents containment)";
1635             m_contentsContainmentLayer = createGraphicsLayer(layerName);
1636             m_contentsContainmentLayer->setAppliesPageScale(true);
1637             m_graphicsLayer->setAppliesPageScale(false);
1638             layerChanged = true;
1639         }
1640     } else {
1641         if (m_backgroundLayer) {
1642             willDestroyLayer(m_backgroundLayer.get());
1643             m_backgroundLayer->removeFromParent();
1644             m_backgroundLayer = nullptr;
1645             layerChanged = true;
1646         }
1647         if (m_contentsContainmentLayer) {
1648             willDestroyLayer(m_contentsContainmentLayer.get());
1649             m_contentsContainmentLayer->removeFromParent();
1650             m_contentsContainmentLayer = nullptr;
1651             layerChanged = true;
1652             m_graphicsLayer->setAppliesPageScale(true);
1653         }
1654     }
1655     
1656     if (layerChanged) {
1657         m_graphicsLayer->setNeedsDisplay();
1658
1659         if (m_backgroundLayerPaintsFixedRootBackground)
1660             compositor().fixedRootBackgroundLayerChanged();
1661     }
1662     
1663     return layerChanged;
1664 }
1665
1666 // Masking layer is used for masks or clip-path.
1667 void RenderLayerBacking::updateMaskingLayer(bool hasMask, bool hasClipPath)
1668 {
1669     bool layerChanged = false;
1670     if (hasMask || hasClipPath) {
1671         GraphicsLayerPaintingPhase maskPhases = 0;
1672         if (hasMask)
1673             maskPhases = GraphicsLayerPaintMask;
1674         
1675         if (hasClipPath) {
1676             // If we have a mask, we need to paint the combined clip-path and mask into the mask layer.
1677             if (hasMask || renderer().style().clipPath()->type() == ClipPathOperation::Reference || !GraphicsLayer::supportsLayerType(GraphicsLayer::Type::Shape))
1678                 maskPhases |= GraphicsLayerPaintClipPath;
1679         }
1680
1681         bool paintsContent = maskPhases;
1682         GraphicsLayer::Type requiredLayerType = paintsContent ? GraphicsLayer::Type::Normal : GraphicsLayer::Type::Shape;
1683         if (m_maskLayer && m_maskLayer->type() != requiredLayerType) {
1684             m_graphicsLayer->setMaskLayer(nullptr);
1685             willDestroyLayer(m_maskLayer.get());
1686             m_maskLayer = nullptr;
1687         }
1688
1689         if (!m_maskLayer) {
1690             m_maskLayer = createGraphicsLayer("mask", requiredLayerType);
1691             m_maskLayer->setDrawsContent(paintsContent);
1692             m_maskLayer->setPaintingPhase(maskPhases);
1693             layerChanged = true;
1694             m_graphicsLayer->setMaskLayer(m_maskLayer.get());
1695         }
1696     } else if (m_maskLayer) {
1697         m_graphicsLayer->setMaskLayer(nullptr);
1698         willDestroyLayer(m_maskLayer.get());
1699         m_maskLayer = nullptr;
1700         layerChanged = true;
1701     }
1702
1703     if (layerChanged)
1704         m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
1705 }
1706
1707 void RenderLayerBacking::updateChildClippingStrategy(bool needsDescendantsClippingLayer)
1708 {
1709     if (hasClippingLayer() && needsDescendantsClippingLayer) {
1710         if (is<RenderBox>(renderer()) && (renderer().style().clipPath() || renderer().style().hasBorderRadius())) {
1711             // FIXME: we shouldn't get geometry here as layout may not have been udpated.
1712             LayoutRect boxRect(LayoutPoint(), downcast<RenderBox>(renderer()).size());
1713             boxRect.move(contentOffsetInCompostingLayer());
1714             FloatRoundedRect contentsClippingRect = renderer().style().getRoundedInnerBorderFor(boxRect).pixelSnappedRoundedRectForPainting(deviceScaleFactor());
1715             if (clippingLayer()->setMasksToBoundsRect(contentsClippingRect)) {
1716                 if (m_childClippingMaskLayer) 
1717                     m_childClippingMaskLayer = nullptr;
1718                 return;
1719             }
1720
1721             if (!m_childClippingMaskLayer) {
1722                 m_childClippingMaskLayer = createGraphicsLayer("child clipping mask");
1723                 m_childClippingMaskLayer->setDrawsContent(true);
1724                 m_childClippingMaskLayer->setPaintingPhase(GraphicsLayerPaintChildClippingMask);
1725                 clippingLayer()->setMaskLayer(m_childClippingMaskLayer.get());
1726             }
1727         }
1728     } else {
1729         if (m_childClippingMaskLayer) {
1730             if (hasClippingLayer())
1731                 clippingLayer()->setMaskLayer(nullptr);
1732             m_childClippingMaskLayer = nullptr;
1733         } else 
1734             if (hasClippingLayer())
1735                 clippingLayer()->setMasksToBoundsRect(FloatRoundedRect(FloatRect(FloatPoint(), clippingLayer()->size())));
1736     }
1737 }
1738
1739 bool RenderLayerBacking::updateScrollingLayers(bool needsScrollingLayers)
1740 {
1741     if (needsScrollingLayers == !!m_scrollingLayer)
1742         return false;
1743
1744     if (!m_scrollingLayer) {
1745         // Outer layer which corresponds with the scroll view.
1746         m_scrollingLayer = createGraphicsLayer("scrolling container", GraphicsLayer::Type::Scrolling);
1747         m_scrollingLayer->setDrawsContent(false);
1748         m_scrollingLayer->setMasksToBounds(true);
1749
1750         // Inner layer which renders the content that scrolls.
1751         m_scrollingContentsLayer = createGraphicsLayer("scrolled Contents");
1752         m_scrollingContentsLayer->setDrawsContent(true);
1753
1754         GraphicsLayerPaintingPhase paintPhase = GraphicsLayerPaintOverflowContents | GraphicsLayerPaintCompositedScroll;
1755         if (!m_foregroundLayer)
1756             paintPhase |= GraphicsLayerPaintForeground;
1757         m_scrollingContentsLayer->setPaintingPhase(paintPhase);
1758         m_scrollingLayer->addChild(m_scrollingContentsLayer.get());
1759     } else {
1760         compositor().willRemoveScrollingLayerWithBacking(m_owningLayer, *this);
1761
1762         willDestroyLayer(m_scrollingLayer.get());
1763         willDestroyLayer(m_scrollingContentsLayer.get());
1764         m_scrollingLayer = nullptr;
1765         m_scrollingContentsLayer = nullptr;
1766     }
1767
1768     m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
1769     m_graphicsLayer->setNeedsDisplay(); // Because painting phases changed.
1770
1771     if (m_scrollingLayer)
1772         compositor().didAddScrollingLayer(m_owningLayer);
1773     
1774     return true;
1775 }
1776
1777 void RenderLayerBacking::detachFromScrollingCoordinator(OptionSet<LayerScrollCoordinationRole> roles)
1778 {
1779     if (!m_scrollingNodeID && !m_viewportConstrainedNodeID)
1780         return;
1781
1782     auto* scrollingCoordinator = m_owningLayer.page().scrollingCoordinator();
1783     if (!scrollingCoordinator)
1784         return;
1785
1786     if ((roles & Scrolling) && m_scrollingNodeID) {
1787         LOG(Compositing, "Detaching Scrolling node %" PRIu64, m_scrollingNodeID);
1788         scrollingCoordinator->detachFromStateTree(m_scrollingNodeID);
1789         m_scrollingNodeID = 0;
1790     }
1791     
1792     if ((roles & ViewportConstrained) && m_viewportConstrainedNodeID) {
1793         LOG(Compositing, "Detaching ViewportConstrained node %" PRIu64, m_viewportConstrainedNodeID);
1794         scrollingCoordinator->detachFromStateTree(m_viewportConstrainedNodeID);
1795         m_viewportConstrainedNodeID = 0;
1796     }
1797 }
1798
1799 void RenderLayerBacking::setIsScrollCoordinatedWithViewportConstrainedRole(bool viewportCoordinated)
1800 {
1801     m_graphicsLayer->setIsViewportConstrained(viewportCoordinated);
1802 }
1803
1804 GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() const
1805 {
1806     unsigned phase = 0;
1807     if (!m_backgroundLayer)
1808         phase |= GraphicsLayerPaintBackground;
1809     if (!m_foregroundLayer)
1810         phase |= GraphicsLayerPaintForeground;
1811
1812     if (m_scrollingContentsLayer) {
1813         phase &= ~GraphicsLayerPaintForeground;
1814         phase |= GraphicsLayerPaintCompositedScroll;
1815     }
1816
1817     return static_cast<GraphicsLayerPaintingPhase>(phase);
1818 }
1819
1820 float RenderLayerBacking::compositingOpacity(float rendererOpacity) const
1821 {
1822     float finalOpacity = rendererOpacity;
1823     
1824     for (auto* curr = m_owningLayer.parent(); curr; curr = curr->parent()) {
1825         // We only care about parents that are stacking contexts.
1826         // Recall that opacity creates stacking context.
1827         if (!curr->isStackingContainer())
1828             continue;
1829         
1830         // If we found a compositing layer, we want to compute opacity
1831         // relative to it. So we can break here.
1832         if (curr->isComposited())
1833             break;
1834         
1835         finalOpacity *= curr->renderer().opacity();
1836     }
1837
1838     return finalOpacity;
1839 }
1840
1841 // FIXME: Code is duplicated in RenderLayer. Also, we should probably not consider filters a box decoration here.
1842 static inline bool hasVisibleBoxDecorations(const RenderStyle& style)
1843 {
1844     return style.hasVisibleBorder() || style.hasBorderRadius() || style.hasOutline() || style.hasAppearance() || style.boxShadow() || style.hasFilter();
1845 }
1846
1847 static bool canDirectlyCompositeBackgroundBackgroundImage(const RenderStyle& style)
1848 {
1849     if (!GraphicsLayer::supportsContentsTiling())
1850         return false;
1851
1852     auto& fillLayer = style.backgroundLayers();
1853     if (fillLayer.next())
1854         return false;
1855
1856     if (!fillLayer.imagesAreLoaded())
1857         return false;
1858
1859     if (fillLayer.attachment() != FillAttachment::ScrollBackground)
1860         return false;
1861
1862     // FIXME: Allow color+image compositing when it makes sense.
1863     // For now bailing out.
1864     if (style.visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor).isVisible())
1865         return false;
1866
1867     // FIXME: support gradients with isGeneratedImage.
1868     auto* styleImage = fillLayer.image();
1869     if (!styleImage->isCachedImage())
1870         return false;
1871
1872     auto* image = styleImage->cachedImage()->image();
1873     if (!image->isBitmapImage())
1874         return false;
1875
1876     return true;
1877 }
1878
1879 static bool hasPaintedBoxDecorationsOrBackgroundImage(const RenderStyle& style)
1880 {
1881     if (hasVisibleBoxDecorations(style))
1882         return true;
1883
1884     if (!style.hasBackgroundImage())
1885         return false;
1886
1887     return !canDirectlyCompositeBackgroundBackgroundImage(style);
1888 }
1889
1890 static inline bool hasPerspectiveOrPreserves3D(const RenderStyle& style)
1891 {
1892     return style.hasPerspective() || style.preserves3D();
1893 }
1894
1895 Color RenderLayerBacking::rendererBackgroundColor() const
1896 {
1897     RenderElement* backgroundRenderer = nullptr;
1898     if (renderer().isDocumentElementRenderer())
1899         backgroundRenderer = renderer().view().rendererForRootBackground();
1900     
1901     if (!backgroundRenderer)
1902         backgroundRenderer = &renderer();
1903
1904     return backgroundRenderer->style().visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
1905 }
1906
1907 void RenderLayerBacking::updateDirectlyCompositedBackgroundColor(PaintedContentsInfo& contentsInfo, bool& didUpdateContentsRect)
1908 {
1909     if (m_backgroundLayer && !m_backgroundLayerPaintsFixedRootBackground && !contentsInfo.paintsBoxDecorations()) {
1910         m_graphicsLayer->setContentsToSolidColor(Color());
1911         m_backgroundLayer->setContentsToSolidColor(rendererBackgroundColor());
1912
1913         FloatRect contentsRect = backgroundBoxForSimpleContainerPainting();
1914         // NOTE: This is currently only used by RenderFullScreen, which we want to be
1915         // big enough to hide overflow areas of the root.
1916         contentsRect.inflate(contentsRect.size());
1917         m_backgroundLayer->setContentsRect(contentsRect);
1918         m_backgroundLayer->setContentsClippingRect(FloatRoundedRect(contentsRect));
1919         return;
1920     }
1921
1922     if (!contentsInfo.isSimpleContainer() || (is<RenderBox>(renderer()) && !downcast<RenderBox>(renderer()).paintsOwnBackground())) {
1923         m_graphicsLayer->setContentsToSolidColor(Color());
1924         return;
1925     }
1926
1927     Color backgroundColor = rendererBackgroundColor();
1928
1929     // An unset (invalid) color will remove the solid color.
1930     m_graphicsLayer->setContentsToSolidColor(backgroundColor);
1931     FloatRect contentsRect = backgroundBoxForSimpleContainerPainting();
1932     m_graphicsLayer->setContentsRect(contentsRect);
1933     m_graphicsLayer->setContentsClippingRect(FloatRoundedRect(contentsRect));
1934     didUpdateContentsRect = true;
1935 }
1936
1937 void RenderLayerBacking::updateDirectlyCompositedBackgroundImage(PaintedContentsInfo& contentsInfo, bool& didUpdateContentsRect)
1938 {
1939     if (!GraphicsLayer::supportsContentsTiling())
1940         return;
1941
1942     if (contentsInfo.isDirectlyCompositedImage())
1943         return;
1944
1945     auto& style = renderer().style();
1946     if (!contentsInfo.isSimpleContainer() || !style.hasBackgroundImage()) {
1947         m_graphicsLayer->setContentsToImage(0);
1948         return;
1949     }
1950
1951     auto destRect = backgroundBoxForSimpleContainerPainting();
1952     FloatSize phase;
1953     FloatSize tileSize;
1954     // FIXME: Absolute paint location is required here.
1955     downcast<RenderBox>(renderer()).getGeometryForBackgroundImage(&renderer(), LayoutPoint(), destRect, phase, tileSize);
1956
1957     m_graphicsLayer->setContentsTileSize(tileSize);
1958     m_graphicsLayer->setContentsTilePhase(phase);
1959     m_graphicsLayer->setContentsRect(destRect);
1960     m_graphicsLayer->setContentsClippingRect(FloatRoundedRect(destRect));
1961     m_graphicsLayer->setContentsToImage(style.backgroundLayers().image()->cachedImage()->image());
1962
1963     didUpdateContentsRect = true;
1964 }
1965
1966 void RenderLayerBacking::updateRootLayerConfiguration()
1967 {
1968     if (!m_isFrameLayerWithTiledBacking)
1969         return;
1970
1971     Color backgroundColor;
1972     bool viewIsTransparent = compositor().viewHasTransparentBackground(&backgroundColor);
1973
1974     if (m_backgroundLayerPaintsFixedRootBackground && m_backgroundLayer) {
1975         if (m_isMainFrameRenderViewLayer) {
1976             m_backgroundLayer->setBackgroundColor(backgroundColor);
1977             m_backgroundLayer->setContentsOpaque(!viewIsTransparent);
1978         }
1979
1980         m_graphicsLayer->setBackgroundColor(Color());
1981         m_graphicsLayer->setContentsOpaque(false);
1982     } else if (m_isMainFrameRenderViewLayer) {
1983         m_graphicsLayer->setBackgroundColor(backgroundColor);
1984         m_graphicsLayer->setContentsOpaque(!viewIsTransparent);
1985     }
1986 }
1987
1988 static bool supportsDirectlyCompositedBoxDecorations(const RenderLayerModelObject& renderer)
1989 {
1990     if (!GraphicsLayer::supportsBackgroundColorContent())
1991         return false;
1992
1993     const RenderStyle& style = renderer.style();
1994     if (renderer.hasClip())
1995         return false;
1996
1997     if (hasPaintedBoxDecorationsOrBackgroundImage(style))
1998         return false;
1999
2000     // FIXME: We can't create a directly composited background if this
2001     // layer will have children that intersect with the background layer.
2002     // A better solution might be to introduce a flattening layer if
2003     // we do direct box decoration composition.
2004     // https://bugs.webkit.org/show_bug.cgi?id=119461
2005     if (hasPerspectiveOrPreserves3D(style))
2006         return false;
2007
2008     // FIXME: we should be able to allow backgroundComposite; However since this is not a common use case it has been deferred for now.
2009     if (style.backgroundComposite() != CompositeSourceOver)
2010         return false;
2011
2012     return true;
2013 }
2014
2015 bool RenderLayerBacking::paintsBoxDecorations() const
2016 {
2017     if (!m_owningLayer.hasVisibleBoxDecorations())
2018         return false;
2019
2020     return !supportsDirectlyCompositedBoxDecorations(renderer());
2021 }
2022
2023 bool RenderLayerBacking::paintsContent(RenderLayer::PaintedContentRequest& request) const
2024 {
2025     bool paintsContent = false;
2026
2027     if (m_owningLayer.hasVisibleContent() && m_owningLayer.hasNonEmptyChildRenderers(request))
2028         paintsContent = true;
2029
2030     if (request.isSatisfied())
2031         return paintsContent;
2032
2033     if (isPaintDestinationForDescendantLayers(request))
2034         paintsContent = true;
2035
2036     if (request.isSatisfied())
2037         return paintsContent;
2038
2039     if (request.hasPaintedContent == RequestState::Unknown)
2040         request.hasPaintedContent = RequestState::False;
2041
2042     if (request.hasSubpixelAntialiasedText == RequestState::Unknown)
2043         request.hasSubpixelAntialiasedText = RequestState::False;
2044
2045     return paintsContent;
2046 }
2047
2048 static bool isRestartedPlugin(RenderObject& renderer)
2049 {
2050     if (!is<RenderEmbeddedObject>(renderer))
2051         return false;
2052
2053     auto& element = downcast<RenderEmbeddedObject>(renderer).frameOwnerElement();
2054     if (!is<HTMLPlugInElement>(element))
2055         return false;
2056
2057     return downcast<HTMLPlugInElement>(element).isRestartedPlugin();
2058 }
2059
2060 static bool isCompositedPlugin(RenderObject& renderer)
2061 {
2062     return is<RenderEmbeddedObject>(renderer) && downcast<RenderEmbeddedObject>(renderer).allowsAcceleratedCompositing();
2063 }
2064
2065 // A "simple container layer" is a RenderLayer which has no visible content to render.
2066 // It may have no children, or all its children may be themselves composited.
2067 // This is a useful optimization, because it allows us to avoid allocating backing store.
2068 bool RenderLayerBacking::isSimpleContainerCompositingLayer(PaintedContentsInfo& contentsInfo) const
2069 {
2070     if (renderer().isRenderReplaced() && (!isCompositedPlugin(renderer()) || isRestartedPlugin(renderer())))
2071         return false;
2072
2073     if (renderer().isTextControl())
2074         return false;
2075
2076     if (contentsInfo.paintsBoxDecorations() || contentsInfo.paintsContent())
2077         return false;
2078
2079     if (renderer().style().backgroundClip() == FillBox::Text)
2080         return false;
2081     
2082     if (renderer().isDocumentElementRenderer() && m_owningLayer.isolatesCompositedBlending())
2083         return false;
2084
2085     if (renderer().isRenderView()) {
2086         // Look to see if the root object has a non-simple background
2087         auto* rootObject = renderer().document().documentElement() ? renderer().document().documentElement()->renderer() : nullptr;
2088         if (!rootObject)
2089             return false;
2090         
2091         // Reject anything that has a border, a border-radius or outline,
2092         // or is not a simple background (no background, or solid color).
2093         if (hasPaintedBoxDecorationsOrBackgroundImage(rootObject->style()))
2094             return false;
2095         
2096         // Now look at the body's renderer.
2097         auto* body = renderer().document().body();
2098         if (!body)
2099             return false;
2100         auto* bodyRenderer = body->renderer();
2101         if (!bodyRenderer)
2102             return false;
2103         
2104         if (hasPaintedBoxDecorationsOrBackgroundImage(bodyRenderer->style()))
2105             return false;
2106     }
2107
2108     return true;
2109 }
2110
2111 // Returning true stops the traversal.
2112 enum class LayerTraversal { Continue, Stop };
2113
2114 static LayerTraversal traverseVisibleNonCompositedDescendantLayers(RenderLayer& parent, const WTF::Function<LayerTraversal (const RenderLayer&)>& layerFunc)
2115 {
2116     // FIXME: We shouldn't be called with a stale z-order lists. See bug 85512.
2117     parent.updateLayerListsIfNeeded();
2118
2119 #if !ASSERT_DISABLED
2120     LayerListMutationDetector mutationChecker(&parent);
2121 #endif
2122
2123     if (auto* normalFlowList = parent.normalFlowList()) {
2124         for (auto* childLayer : *normalFlowList) {
2125             if (compositedWithOwnBackingStore(*childLayer))
2126                 continue;
2127
2128             if (layerFunc(*childLayer) == LayerTraversal::Stop)
2129                 return LayerTraversal::Stop;
2130             
2131             if (traverseVisibleNonCompositedDescendantLayers(*childLayer, layerFunc) == LayerTraversal::Stop)
2132                 return LayerTraversal::Stop;
2133         }
2134     }
2135
2136     if (parent.isStackingContainer() && !parent.hasVisibleDescendant())
2137         return LayerTraversal::Continue;
2138
2139     // Use the m_hasCompositingDescendant bit to optimize?
2140     if (auto* negZOrderList = parent.negZOrderList()) {
2141         for (auto* childLayer : *negZOrderList) {
2142             if (compositedWithOwnBackingStore(*childLayer))
2143                 continue;
2144
2145             if (layerFunc(*childLayer) == LayerTraversal::Stop)
2146                 return LayerTraversal::Stop;
2147
2148             if (traverseVisibleNonCompositedDescendantLayers(*childLayer, layerFunc) == LayerTraversal::Stop)
2149                 return LayerTraversal::Stop;
2150         }
2151     }
2152
2153     if (auto* posZOrderList = parent.posZOrderList()) {
2154         for (auto* childLayer : *posZOrderList) {
2155             if (compositedWithOwnBackingStore(*childLayer))
2156                 continue;
2157
2158             if (layerFunc(*childLayer) == LayerTraversal::Stop)
2159                 return LayerTraversal::Stop;
2160
2161             if (traverseVisibleNonCompositedDescendantLayers(*childLayer, layerFunc) == LayerTraversal::Stop)
2162                 return LayerTraversal::Stop;
2163         }
2164     }
2165
2166     return LayerTraversal::Continue;
2167 }
2168
2169 // Conservative test for having no rendered children.
2170 bool RenderLayerBacking::isPaintDestinationForDescendantLayers(RenderLayer::PaintedContentRequest& request) const
2171 {
2172     bool hasPaintingDescendant = false;
2173     traverseVisibleNonCompositedDescendantLayers(m_owningLayer, [&hasPaintingDescendant, &request](const RenderLayer& layer) {
2174         hasPaintingDescendant |= layer.isVisuallyNonEmpty(&request);
2175         return (hasPaintingDescendant && request.isSatisfied()) ? LayerTraversal::Stop : LayerTraversal::Continue;
2176     });
2177
2178     return hasPaintingDescendant;
2179 }
2180
2181 bool RenderLayerBacking::hasVisibleNonCompositedDescendants() const
2182 {
2183     bool hasVisibleDescendant = false;
2184     traverseVisibleNonCompositedDescendantLayers(m_owningLayer, [&hasVisibleDescendant](const RenderLayer& layer) {
2185         hasVisibleDescendant |= layer.hasVisibleContent();
2186         return hasVisibleDescendant ? LayerTraversal::Stop : LayerTraversal::Continue;
2187     });
2188
2189     return hasVisibleDescendant;
2190 }
2191
2192 bool RenderLayerBacking::containsPaintedContent(PaintedContentsInfo& contentsInfo) const
2193 {
2194     if (contentsInfo.isSimpleContainer() || paintsIntoWindow() || paintsIntoCompositedAncestor() || m_artificiallyInflatedBounds || m_owningLayer.isReflection())
2195         return false;
2196
2197     if (contentsInfo.isDirectlyCompositedImage())
2198         return false;
2199
2200     // FIXME: we could optimize cases where the image, video or canvas is known to fill the border box entirely,
2201     // and set background color on the layer in that case, instead of allocating backing store and painting.
2202 #if ENABLE(VIDEO)
2203     if (is<RenderVideo>(renderer()) && downcast<RenderVideo>(renderer()).shouldDisplayVideo())
2204         return m_owningLayer.hasVisibleBoxDecorationsOrBackground() || (!(downcast<RenderVideo>(renderer()).supportsAcceleratedRendering()) && m_requiresOwnBackingStore);
2205 #endif
2206
2207 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
2208     if (is<RenderHTMLCanvas>(renderer()) && canvasCompositingStrategy(renderer()) == CanvasAsLayerContents)
2209         return m_owningLayer.hasVisibleBoxDecorationsOrBackground();
2210 #endif
2211
2212     return true;
2213 }
2214
2215 // An image can be directly compositing if it's the sole content of the layer, and has no box decorations
2216 // that require painting. Direct compositing saves backing store.
2217 bool RenderLayerBacking::isDirectlyCompositedImage() const
2218 {
2219     if (!is<RenderImage>(renderer()) || m_owningLayer.hasVisibleBoxDecorationsOrBackground() || m_owningLayer.paintsWithFilters() || renderer().hasClip())
2220         return false;
2221
2222 #if ENABLE(VIDEO)
2223     if (is<RenderMedia>(renderer()))
2224         return false;
2225 #endif
2226
2227     auto& imageRenderer = downcast<RenderImage>(renderer());
2228     if (auto* cachedImage = imageRenderer.cachedImage()) {
2229         if (!cachedImage->hasImage())
2230             return false;
2231
2232         auto* image = cachedImage->imageForRenderer(&imageRenderer);
2233         if (!is<BitmapImage>(image))
2234             return false;
2235
2236         if (downcast<BitmapImage>(*image).orientationForCurrentFrame() != DefaultImageOrientation)
2237             return false;
2238
2239 #if (PLATFORM(GTK) || PLATFORM(WPE))
2240         // GTK and WPE ports don't support rounded rect clipping at TextureMapper level, so they cannot
2241         // directly composite images that have border-radius propery. Draw them as non directly composited
2242         // content instead. See https://bugs.webkit.org/show_bug.cgi?id=174157.
2243         if (imageRenderer.style().hasBorderRadius())
2244             return false;
2245 #endif
2246
2247         return m_graphicsLayer->shouldDirectlyCompositeImage(image);
2248     }
2249
2250     return false;
2251 }
2252
2253 void RenderLayerBacking::contentChanged(ContentChangeType changeType)
2254 {
2255     PaintedContentsInfo contentsInfo(*this);
2256     if ((changeType == ImageChanged) && contentsInfo.isDirectlyCompositedImage()) {
2257         updateImageContents(contentsInfo);
2258         return;
2259     }
2260
2261     if ((changeType == BackgroundImageChanged) && canDirectlyCompositeBackgroundBackgroundImage(renderer().style()))
2262         updateGeometry();
2263
2264     if ((changeType == MaskImageChanged) && m_maskLayer) {
2265         // The composited layer bounds relies on box->maskClipRect(), which changes
2266         // when the mask image becomes available.
2267         updateAfterLayout(UpdateAfterLayoutFlags::IsUpdateRoot);
2268     }
2269
2270 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
2271     if ((changeType == CanvasChanged || changeType == CanvasPixelsChanged) && renderer().isCanvas() && canvasCompositingStrategy(renderer()) == CanvasAsLayerContents) {
2272         m_graphicsLayer->setContentsNeedsDisplay();
2273         return;
2274     }
2275 #endif
2276 }
2277
2278 void RenderLayerBacking::updateImageContents(PaintedContentsInfo& contentsInfo)
2279 {
2280     auto& imageRenderer = downcast<RenderImage>(renderer());
2281
2282     auto* cachedImage = imageRenderer.cachedImage();
2283     if (!cachedImage)
2284         return;
2285
2286     auto* image = cachedImage->imageForRenderer(&imageRenderer);
2287     if (!image)
2288         return;
2289
2290     // We have to wait until the image is fully loaded before setting it on the layer.
2291     if (!cachedImage->isLoaded())
2292         return;
2293
2294     // This is a no-op if the layer doesn't have an inner layer for the image.
2295     m_graphicsLayer->setContentsRect(snapRectToDevicePixels(contentsBox(), deviceScaleFactor()));
2296
2297     LayoutRect boxRect(LayoutPoint(), imageRenderer.size());
2298     boxRect.move(contentOffsetInCompostingLayer());
2299     FloatRoundedRect contentsClippingRect = renderer().style().getRoundedInnerBorderFor(boxRect).pixelSnappedRoundedRectForPainting(deviceScaleFactor());
2300     m_graphicsLayer->setContentsClippingRect(contentsClippingRect);
2301
2302     m_graphicsLayer->setContentsToImage(image);
2303     
2304     updateDrawsContent(contentsInfo);
2305     
2306     // Image animation is "lazy", in that it automatically stops unless someone is drawing
2307     // the image. So we have to kick the animation each time; this has the downside that the
2308     // image will keep animating, even if its layer is not visible.
2309     image->startAnimation();
2310 }
2311
2312 FloatPoint3D RenderLayerBacking::computeTransformOriginForPainting(const LayoutRect& borderBox) const
2313 {
2314     const RenderStyle& style = renderer().style();
2315     float deviceScaleFactor = this->deviceScaleFactor();
2316
2317     FloatPoint3D origin;
2318     origin.setX(roundToDevicePixel(floatValueForLength(style.transformOriginX(), borderBox.width()), deviceScaleFactor));
2319     origin.setY(roundToDevicePixel(floatValueForLength(style.transformOriginY(), borderBox.height()), deviceScaleFactor));
2320     origin.setZ(style.transformOriginZ());
2321
2322     return origin;
2323 }
2324
2325 // Return the offset from the top-left of this compositing layer at which the renderer's contents are painted.
2326 LayoutSize RenderLayerBacking::contentOffsetInCompostingLayer() const
2327 {
2328     return LayoutSize(-m_compositedBounds.x() + m_compositedBoundsOffsetFromGraphicsLayer.width(), -m_compositedBounds.y() + m_compositedBoundsOffsetFromGraphicsLayer.height());
2329 }
2330
2331 LayoutRect RenderLayerBacking::contentsBox() const
2332 {
2333     if (!is<RenderBox>(renderer()))
2334         return LayoutRect();
2335
2336     auto& renderBox = downcast<RenderBox>(renderer());
2337     LayoutRect contentsRect;
2338 #if ENABLE(VIDEO)
2339     if (is<RenderVideo>(renderBox))
2340         contentsRect = downcast<RenderVideo>(renderBox).videoBox();
2341     else
2342 #endif
2343     if (is<RenderReplaced>(renderBox)) {
2344         RenderReplaced& renderReplaced = downcast<RenderReplaced>(renderBox);
2345         contentsRect = renderReplaced.replacedContentRect();
2346     } else
2347         contentsRect = renderBox.contentBoxRect();
2348
2349     contentsRect.move(contentOffsetInCompostingLayer());
2350     return contentsRect;
2351 }
2352
2353 static LayoutRect backgroundRectForBox(const RenderBox& box)
2354 {
2355     switch (box.style().backgroundClip()) {
2356     case FillBox::Border:
2357         return box.borderBoxRect();
2358     case FillBox::Padding:
2359         return box.paddingBoxRect();
2360     case FillBox::Content:
2361         return box.contentBoxRect();
2362     default:
2363         break;
2364     }
2365
2366     ASSERT_NOT_REACHED();
2367     return LayoutRect();
2368 }
2369
2370 FloatRect RenderLayerBacking::backgroundBoxForSimpleContainerPainting() const
2371 {
2372     if (!is<RenderBox>(renderer()))
2373         return FloatRect();
2374
2375     LayoutRect backgroundBox = backgroundRectForBox(downcast<RenderBox>(renderer()));
2376     backgroundBox.move(contentOffsetInCompostingLayer());
2377     return snapRectToDevicePixels(backgroundBox, deviceScaleFactor());
2378 }
2379
2380 GraphicsLayer* RenderLayerBacking::parentForSublayers() const
2381 {
2382     if (m_scrollingContentsLayer)
2383         return m_scrollingContentsLayer.get();
2384
2385     return m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsLayer.get();
2386 }
2387
2388 GraphicsLayer* RenderLayerBacking::childForSuperlayers() const
2389 {
2390     if (m_ancestorClippingLayer)
2391         return m_ancestorClippingLayer.get();
2392
2393     if (m_contentsContainmentLayer)
2394         return m_contentsContainmentLayer.get();
2395     
2396     return m_graphicsLayer.get();
2397 }
2398
2399 bool RenderLayerBacking::paintsIntoWindow() const
2400 {
2401 #if USE(COORDINATED_GRAPHICS_THREADED)
2402         return false;
2403 #endif
2404
2405     if (m_isFrameLayerWithTiledBacking)
2406         return false;
2407
2408     if (m_owningLayer.isRenderViewLayer()) {
2409 #if PLATFORM(IOS) || USE(COORDINATED_GRAPHICS)
2410         if (compositor().inForcedCompositingMode())
2411             return false;
2412 #endif
2413
2414         return compositor().rootLayerAttachment() != RenderLayerCompositor::RootLayerAttachedViaEnclosingFrame;
2415     }
2416     
2417     return false;
2418 }
2419
2420 void RenderLayerBacking::setRequiresOwnBackingStore(bool requiresOwnBacking)
2421 {
2422     if (requiresOwnBacking == m_requiresOwnBackingStore)
2423         return;
2424     
2425     m_requiresOwnBackingStore = requiresOwnBacking;
2426
2427     // This affects the answer to paintsIntoCompositedAncestor(), which in turn affects
2428     // cached clip rects, so when it changes we have to clear clip rects on descendants.
2429     m_owningLayer.clearClipRectsIncludingDescendants(PaintingClipRects);
2430     m_owningLayer.computeRepaintRectsIncludingDescendants();
2431     
2432     compositor().repaintInCompositedAncestor(m_owningLayer, compositedBounds());
2433 }
2434
2435 void RenderLayerBacking::setContentsNeedDisplay(GraphicsLayer::ShouldClipToLayer shouldClip)
2436 {
2437     ASSERT(!paintsIntoCompositedAncestor());
2438
2439     auto& frameView = renderer().view().frameView();
2440     if (m_isMainFrameRenderViewLayer && frameView.isTrackingRepaints())
2441         frameView.addTrackedRepaintRect(owningLayer().absoluteBoundingBoxForPainting());
2442     
2443     if (m_graphicsLayer && m_graphicsLayer->drawsContent()) {
2444         // By default, setNeedsDisplay will clip to the size of the GraphicsLayer, which does not include margin tiles.
2445         // So if the TiledBacking has a margin that needs to be invalidated, we need to send in a rect to setNeedsDisplayInRect
2446         // that is large enough to include the margin. TiledBacking::bounds() includes the margin.
2447         auto* tiledBacking = this->tiledBacking();
2448         FloatRect rectToRepaint = tiledBacking ? tiledBacking->bounds() : FloatRect(FloatPoint(0, 0), m_graphicsLayer->size());
2449         m_graphicsLayer->setNeedsDisplayInRect(rectToRepaint, shouldClip);
2450     }
2451     
2452     if (m_foregroundLayer && m_foregroundLayer->drawsContent())
2453         m_foregroundLayer->setNeedsDisplay();
2454
2455     if (m_backgroundLayer && m_backgroundLayer->drawsContent())
2456         m_backgroundLayer->setNeedsDisplay();
2457
2458     if (m_maskLayer && m_maskLayer->drawsContent())
2459         m_maskLayer->setNeedsDisplay();
2460
2461     if (m_childClippingMaskLayer && m_childClippingMaskLayer->drawsContent())
2462         m_childClippingMaskLayer->setNeedsDisplay();
2463
2464     if (m_scrollingContentsLayer && m_scrollingContentsLayer->drawsContent())
2465         m_scrollingContentsLayer->setNeedsDisplay();
2466 }
2467
2468 // r is in the coordinate space of the layer's render object
2469 void RenderLayerBacking::setContentsNeedDisplayInRect(const LayoutRect& r, GraphicsLayer::ShouldClipToLayer shouldClip)
2470 {
2471     ASSERT(!paintsIntoCompositedAncestor());
2472
2473     FloatRect pixelSnappedRectForPainting = snapRectToDevicePixels(r, deviceScaleFactor());
2474     auto& frameView = renderer().view().frameView();
2475     if (m_isMainFrameRenderViewLayer && frameView.isTrackingRepaints())
2476         frameView.addTrackedRepaintRect(pixelSnappedRectForPainting);
2477
2478     if (m_graphicsLayer && m_graphicsLayer->drawsContent()) {
2479         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
2480         layerDirtyRect.move(-m_graphicsLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
2481         m_graphicsLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2482     }
2483
2484     if (m_foregroundLayer && m_foregroundLayer->drawsContent()) {
2485         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
2486         layerDirtyRect.move(-m_foregroundLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
2487         m_foregroundLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2488     }
2489
2490     // FIXME: need to split out repaints for the background.
2491     if (m_backgroundLayer && m_backgroundLayer->drawsContent()) {
2492         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
2493         layerDirtyRect.move(-m_backgroundLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
2494         m_backgroundLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2495     }
2496
2497     if (m_maskLayer && m_maskLayer->drawsContent()) {
2498         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
2499         layerDirtyRect.move(-m_maskLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
2500         m_maskLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2501     }
2502
2503     if (m_childClippingMaskLayer && m_childClippingMaskLayer->drawsContent()) {
2504         FloatRect layerDirtyRect = r;
2505         layerDirtyRect.move(-m_childClippingMaskLayer->offsetFromRenderer());
2506         m_childClippingMaskLayer->setNeedsDisplayInRect(layerDirtyRect);
2507     }
2508
2509     if (m_scrollingContentsLayer && m_scrollingContentsLayer->drawsContent()) {
2510         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
2511         layerDirtyRect.move(-m_scrollingContentsLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
2512 #if PLATFORM(IOS)
2513         // Account for the fact that RenderLayerBacking::updateGeometry() bakes scrollOffset into offsetFromRenderer on iOS,
2514         // but the repaint rect is computed without taking the scroll position into account (see shouldApplyClipAndScrollPositionForRepaint()).
2515         layerDirtyRect.moveBy(-m_owningLayer.scrollPosition());
2516 #endif
2517         m_scrollingContentsLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2518     }
2519 }
2520
2521 void RenderLayerBacking::paintIntoLayer(const GraphicsLayer* graphicsLayer, GraphicsContext& context,
2522     const IntRect& paintDirtyRect, // In the coords of rootLayer.
2523     OptionSet<PaintBehavior> paintBehavior, GraphicsLayerPaintingPhase paintingPhase)
2524 {
2525     if ((paintsIntoWindow() || paintsIntoCompositedAncestor()) && paintingPhase != GraphicsLayerPaintChildClippingMask) {
2526 #if !PLATFORM(IOS) && !OS(WINDOWS)
2527         // FIXME: Looks like the CALayer tree is out of sync with the GraphicsLayer heirarchy
2528         // when pages are restored from the PageCache.
2529         // <rdar://problem/8712587> ASSERT: When Going Back to Page with Plugins in PageCache
2530         ASSERT_NOT_REACHED();
2531 #endif
2532         return;
2533     }
2534
2535     OptionSet<RenderLayer::PaintLayerFlag> paintFlags;
2536     if (paintingPhase & GraphicsLayerPaintBackground)
2537         paintFlags.add(RenderLayer::PaintLayerPaintingCompositingBackgroundPhase);
2538     if (paintingPhase & GraphicsLayerPaintForeground)
2539         paintFlags.add(RenderLayer::PaintLayerPaintingCompositingForegroundPhase);
2540     if (paintingPhase & GraphicsLayerPaintMask)
2541         paintFlags.add(RenderLayer::PaintLayerPaintingCompositingMaskPhase);
2542     if (paintingPhase & GraphicsLayerPaintClipPath)
2543         paintFlags.add(RenderLayer::PaintLayerPaintingCompositingClipPathPhase);
2544     if (paintingPhase & GraphicsLayerPaintChildClippingMask)
2545         paintFlags.add(RenderLayer::PaintLayerPaintingChildClippingMaskPhase);
2546     if (paintingPhase & GraphicsLayerPaintOverflowContents)
2547         paintFlags.add(RenderLayer::PaintLayerPaintingOverflowContents);
2548     if (paintingPhase & GraphicsLayerPaintCompositedScroll)
2549         paintFlags.add(RenderLayer::PaintLayerPaintingCompositingScrollingPhase);
2550
2551     if (graphicsLayer == m_backgroundLayer.get() && m_backgroundLayerPaintsFixedRootBackground)
2552         paintFlags.add({ RenderLayer::PaintLayerPaintingRootBackgroundOnly, RenderLayer::PaintLayerPaintingCompositingForegroundPhase }); // Need PaintLayerPaintingCompositingForegroundPhase to walk child layers.
2553     else if (compositor().fixedRootBackgroundLayer())
2554         paintFlags.add(RenderLayer::PaintLayerPaintingSkipRootBackground);
2555
2556 #ifndef NDEBUG
2557     RenderElement::SetLayoutNeededForbiddenScope forbidSetNeedsLayout(&renderer());
2558 #endif
2559
2560     FrameView::PaintingState paintingState;
2561     if (m_owningLayer.isRenderViewLayer())
2562         renderer().view().frameView().willPaintContents(context, paintDirtyRect, paintingState);
2563
2564     // FIXME: GraphicsLayers need a way to split for RenderFragmentContainers.
2565     RenderLayer::LayerPaintingInfo paintingInfo(&m_owningLayer, paintDirtyRect, paintBehavior, -m_subpixelOffsetFromRenderer);
2566     m_owningLayer.paintLayerContents(context, paintingInfo, paintFlags);
2567
2568     if (m_owningLayer.containsDirtyOverlayScrollbars())
2569         m_owningLayer.paintLayerContents(context, paintingInfo, paintFlags | RenderLayer::PaintLayerPaintingOverlayScrollbars);
2570
2571     if (m_owningLayer.isRenderViewLayer())
2572         renderer().view().frameView().didPaintContents(context, paintDirtyRect, paintingState);
2573
2574     compositor().didPaintBacking(this);
2575
2576     ASSERT(!m_owningLayer.m_usedTransparency);
2577 }
2578
2579 // Up-call from compositing layer drawing callback.
2580 void RenderLayerBacking::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase paintingPhase, const FloatRect& clip, GraphicsLayerPaintBehavior layerPaintBehavior)
2581 {
2582 #ifndef NDEBUG
2583     renderer().page().setIsPainting(true);
2584 #endif
2585
2586 #if PLATFORM(MAC)
2587     LocalDefaultSystemAppearance localAppearance(renderer().page().useSystemAppearance(), renderer().page().useDarkAppearance());
2588 #endif
2589
2590     // The dirtyRect is in the coords of the painting root.
2591     FloatRect adjustedClipRect = clip;
2592     adjustedClipRect.move(m_subpixelOffsetFromRenderer);
2593     IntRect dirtyRect = enclosingIntRect(adjustedClipRect);
2594
2595     if (!graphicsLayer->repaintCount())
2596         layerPaintBehavior |= GraphicsLayerPaintFirstTilePaint;
2597
2598     if (graphicsLayer == m_graphicsLayer.get()
2599         || graphicsLayer == m_foregroundLayer.get()
2600         || graphicsLayer == m_backgroundLayer.get()
2601         || graphicsLayer == m_maskLayer.get()
2602         || graphicsLayer == m_childClippingMaskLayer.get()
2603         || graphicsLayer == m_scrollingContentsLayer.get()) {
2604         InspectorInstrumentation::willPaint(renderer());
2605
2606         if (!(paintingPhase & GraphicsLayerPaintOverflowContents))
2607             dirtyRect.intersect(enclosingIntRect(compositedBoundsIncludingMargin()));
2608
2609         // We have to use the same root as for hit testing, because both methods can compute and cache clipRects.
2610         OptionSet<PaintBehavior> behavior = PaintBehavior::Normal;
2611         if (layerPaintBehavior == GraphicsLayerPaintSnapshotting)
2612             behavior.add(PaintBehavior::Snapshotting);
2613         
2614         if (layerPaintBehavior == GraphicsLayerPaintFirstTilePaint)
2615             behavior.add(PaintBehavior::TileFirstPaint);
2616
2617         paintIntoLayer(graphicsLayer, context, dirtyRect, behavior, paintingPhase);
2618
2619         InspectorInstrumentation::didPaint(renderer(), dirtyRect);
2620     } else if (graphicsLayer == layerForHorizontalScrollbar()) {
2621         paintScrollbar(m_owningLayer.horizontalScrollbar(), context, dirtyRect);
2622     } else if (graphicsLayer == layerForVerticalScrollbar()) {
2623         paintScrollbar(m_owningLayer.verticalScrollbar(), context, dirtyRect);
2624     } else if (graphicsLayer == layerForScrollCorner()) {
2625         const LayoutRect& scrollCornerAndResizer = m_owningLayer.scrollCornerAndResizerRect();
2626         context.save();
2627         context.translate(-scrollCornerAndResizer.location());
2628         LayoutRect transformedClip = LayoutRect(clip);
2629         transformedClip.moveBy(scrollCornerAndResizer.location());
2630         m_owningLayer.paintScrollCorner(context, IntPoint(), snappedIntRect(transformedClip));
2631         m_owningLayer.paintResizer(context, IntPoint(), transformedClip);
2632         context.restore();
2633     }
2634 #ifndef NDEBUG
2635     renderer().page().setIsPainting(false);
2636 #endif
2637 }
2638
2639 float RenderLayerBacking::pageScaleFactor() const
2640 {
2641     return compositor().pageScaleFactor();
2642 }
2643
2644 float RenderLayerBacking::zoomedOutPageScaleFactor() const
2645 {
2646     return compositor().zoomedOutPageScaleFactor();
2647 }
2648
2649 float RenderLayerBacking::deviceScaleFactor() const
2650 {
2651     return compositor().deviceScaleFactor();
2652 }
2653
2654 float RenderLayerBacking::contentsScaleMultiplierForNewTiles(const GraphicsLayer* layer) const
2655 {
2656     return compositor().contentsScaleMultiplierForNewTiles(layer);
2657 }
2658
2659 bool RenderLayerBacking::paintsOpaquelyAtNonIntegralScales(const GraphicsLayer*) const
2660 {
2661     return m_isMainFrameRenderViewLayer;
2662 }
2663
2664 void RenderLayerBacking::didCommitChangesForLayer(const GraphicsLayer* layer) const
2665 {
2666     compositor().didFlushChangesForLayer(m_owningLayer, layer);
2667 }
2668
2669 bool RenderLayerBacking::getCurrentTransform(const GraphicsLayer* graphicsLayer, TransformationMatrix& transform) const
2670 {
2671     auto* transformedLayer = m_contentsContainmentLayer.get() ? m_contentsContainmentLayer.get() : m_graphicsLayer.get();
2672     if (graphicsLayer != transformedLayer)
2673         return false;
2674
2675     if (m_owningLayer.hasTransform()) {
2676         transform = m_owningLayer.currentTransform(RenderStyle::ExcludeTransformOrigin);
2677         return true;
2678     }
2679     return false;
2680 }
2681
2682 bool RenderLayerBacking::isTrackingRepaints() const
2683 {
2684     return static_cast<GraphicsLayerClient&>(compositor()).isTrackingRepaints();
2685 }
2686
2687 bool RenderLayerBacking::shouldSkipLayerInDump(const GraphicsLayer* layer, LayerTreeAsTextBehavior behavior) const
2688 {
2689     if (behavior & LayerTreeAsTextDebug)
2690         return false;
2691
2692     // Skip the root tile cache's flattening layer.
2693     return m_isMainFrameRenderViewLayer && layer && layer == m_childContainmentLayer.get();
2694 }
2695
2696 bool RenderLayerBacking::shouldDumpPropertyForLayer(const GraphicsLayer* layer, const char* propertyName) const
2697 {
2698     // For backwards compatibility with WebKit1 and other platforms,
2699     // skip some properties on the root tile cache.
2700     if (m_isMainFrameRenderViewLayer && layer == m_graphicsLayer.get()) {
2701         if (!strcmp(propertyName, "drawsContent"))
2702             return false;
2703
2704         // Background color could be of interest to tests or other dumpers if it's non-white.
2705         if (!strcmp(propertyName, "backgroundColor") && layer->backgroundColor() == Color::white)
2706             return false;
2707
2708         // The root tile cache's repaints will show up at the top with FrameView's,
2709         // so don't dump them twice.
2710         if (!strcmp(propertyName, "repaintRects"))
2711             return false;
2712     }
2713
2714     return true;
2715 }
2716
2717 bool RenderLayerBacking::shouldAggressivelyRetainTiles(const GraphicsLayer*) const
2718 {
2719     // Only the main frame TileController has enough information about in-window state to
2720     // correctly implement aggressive tile retention.
2721     if (!m_isMainFrameRenderViewLayer)
2722         return false;
2723
2724     return renderer().settings().aggressiveTileRetentionEnabled();
2725 }
2726
2727 bool RenderLayerBacking::shouldTemporarilyRetainTileCohorts(const GraphicsLayer*) const
2728 {
2729     return renderer().settings().temporaryTileCohortRetentionEnabled();
2730 }
2731
2732 bool RenderLayerBacking::useGiantTiles() const
2733 {
2734     return renderer().settings().useGiantTiles();
2735 }
2736
2737 void RenderLayerBacking::logFilledVisibleFreshTile(unsigned blankPixelCount)
2738 {
2739     if (auto* loggingClient = renderer().page().performanceLoggingClient())
2740         loggingClient->logScrollingEvent(PerformanceLoggingClient::ScrollingEvent::FilledTile, MonotonicTime::now(), blankPixelCount);
2741 }
2742
2743 #ifndef NDEBUG
2744 void RenderLayerBacking::verifyNotPainting()
2745 {
2746     ASSERT(!renderer().page().isPainting());
2747 }
2748 #endif
2749
2750 bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim, const KeyframeList& keyframes)
2751 {
2752     bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity);
2753     bool hasTransform = renderer().isBox() && keyframes.containsProperty(CSSPropertyTransform);
2754     bool hasFilter = keyframes.containsProperty(CSSPropertyFilter);
2755
2756     bool hasBackdropFilter = false;
2757 #if ENABLE(FILTERS_LEVEL_2)
2758     hasBackdropFilter = keyframes.containsProperty(CSSPropertyWebkitBackdropFilter);
2759 #endif
2760
2761     if (!hasOpacity && !hasTransform && !hasFilter && !hasBackdropFilter)
2762         return false;
2763
2764     KeyframeValueList transformVector(AnimatedPropertyTransform);
2765     KeyframeValueList opacityVector(AnimatedPropertyOpacity);
2766     KeyframeValueList filterVector(AnimatedPropertyFilter);
2767 #if ENABLE(FILTERS_LEVEL_2)
2768     KeyframeValueList backdropFilterVector(AnimatedPropertyWebkitBackdropFilter);
2769 #endif
2770
2771     size_t numKeyframes = keyframes.size();
2772     for (size_t i = 0; i < numKeyframes; ++i) {
2773         const KeyframeValue& currentKeyframe = keyframes[i];
2774         const RenderStyle* keyframeStyle = currentKeyframe.style();
2775         double key = currentKeyframe.key();
2776
2777         if (!keyframeStyle)
2778             continue;
2779             
2780         auto* tf = currentKeyframe.timingFunction();
2781         
2782         bool isFirstOrLastKeyframe = key == 0 || key == 1;
2783         if ((hasTransform && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyTransform))
2784             transformVector.insert(std::make_unique<TransformAnimationValue>(key, keyframeStyle->transform(), tf));
2785
2786         if ((hasOpacity && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyOpacity))
2787             opacityVector.insert(std::make_unique<FloatAnimationValue>(key, keyframeStyle->opacity(), tf));
2788
2789         if ((hasFilter && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyFilter))
2790             filterVector.insert(std::make_unique<FilterAnimationValue>(key, keyframeStyle->filter(), tf));
2791
2792 #if ENABLE(FILTERS_LEVEL_2)
2793         if ((hasBackdropFilter && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitBackdropFilter))
2794             backdropFilterVector.insert(std::make_unique<FilterAnimationValue>(key, keyframeStyle->backdropFilter(), tf));
2795 #endif
2796     }
2797
2798     if (!renderer().settings().acceleratedCompositedAnimationsEnabled())
2799         return false;
2800
2801     bool didAnimate = false;
2802
2803     if (hasTransform && m_graphicsLayer->addAnimation(transformVector, snappedIntRect(renderBox()->borderBoxRect()).size(), anim, keyframes.animationName(), timeOffset))
2804         didAnimate = true;
2805
2806     if (hasOpacity && m_graphicsLayer->addAnimation(opacityVector, IntSize(), anim, keyframes.animationName(), timeOffset))
2807         didAnimate = true;
2808
2809     if (hasFilter && m_graphicsLayer->addAnimation(filterVector, IntSize(), anim, keyframes.animationName(), timeOffset))
2810         didAnimate = true;
2811
2812 #if ENABLE(FILTERS_LEVEL_2)
2813     if (hasBackdropFilter && m_graphicsLayer->addAnimation(backdropFilterVector, IntSize(), anim, keyframes.animationName(), timeOffset))
2814         didAnimate = true;
2815 #endif
2816
2817     return didAnimate;
2818 }
2819
2820 void RenderLayerBacking::animationPaused(double timeOffset, const String& animationName)
2821 {
2822     m_graphicsLayer->pauseAnimation(animationName, timeOffset);
2823 }
2824
2825 void RenderLayerBacking::animationSeeked(double timeOffset, const String& animationName)
2826 {
2827     m_graphicsLayer->seekAnimation(animationName, timeOffset);
2828 }
2829
2830 void RenderLayerBacking::animationFinished(const String& animationName)
2831 {
2832     m_graphicsLayer->removeAnimation(animationName);
2833 }
2834
2835 bool RenderLayerBacking::startTransition(double timeOffset, CSSPropertyID property, const RenderStyle* fromStyle, const RenderStyle* toStyle)
2836 {
2837     bool didAnimate = false;
2838
2839     ASSERT(property != CSSPropertyInvalid);
2840
2841     if (property == CSSPropertyOpacity) {
2842         const Animation* opacityAnim = toStyle->transitionForProperty(CSSPropertyOpacity);
2843         if (opacityAnim && !opacityAnim->isEmptyOrZeroDuration()) {
2844             KeyframeValueList opacityVector(AnimatedPropertyOpacity);
2845             opacityVector.insert(std::make_unique<FloatAnimationValue>(0, compositingOpacity(fromStyle->opacity())));
2846             opacityVector.insert(std::make_unique<FloatAnimationValue>(1, compositingOpacity(toStyle->opacity())));
2847             // The boxSize param is only used for transform animations (which can only run on RenderBoxes), so we pass an empty size here.
2848             if (m_graphicsLayer->addAnimation(opacityVector, FloatSize(), opacityAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyOpacity), timeOffset)) {
2849                 // To ensure that the correct opacity is visible when the animation ends, also set the final opacity.
2850                 updateOpacity(*toStyle);
2851                 didAnimate = true;
2852             }
2853         }
2854     }
2855
2856     if (property == CSSPropertyTransform && m_owningLayer.hasTransform()) {
2857         const Animation* transformAnim = toStyle->transitionForProperty(CSSPropertyTransform);
2858         if (transformAnim && !transformAnim->isEmptyOrZeroDuration()) {
2859             KeyframeValueList transformVector(AnimatedPropertyTransform);
2860             transformVector.insert(std::make_unique<TransformAnimationValue>(0, fromStyle->transform()));
2861             transformVector.insert(std::make_unique<TransformAnimationValue>(1, toStyle->transform()));
2862             if (m_graphicsLayer->addAnimation(transformVector, snappedIntRect(renderBox()->borderBoxRect()).size(), transformAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyTransform), timeOffset)) {
2863                 // To ensure that the correct transform is visible when the animation ends, also set the final transform.
2864                 updateTransform(*toStyle);
2865                 didAnimate = true;
2866             }
2867         }
2868     }
2869
2870     if (property == CSSPropertyFilter && m_owningLayer.hasFilter()) {
2871         const Animation* filterAnim = toStyle->transitionForProperty(CSSPropertyFilter);
2872         if (filterAnim && !filterAnim->isEmptyOrZeroDuration()) {
2873             KeyframeValueList filterVector(AnimatedPropertyFilter);
2874             filterVector.insert(std::make_unique<FilterAnimationValue>(0, fromStyle->filter()));
2875             filterVector.insert(std::make_unique<FilterAnimationValue>(1, toStyle->filter()));
2876             if (m_graphicsLayer->addAnimation(filterVector, FloatSize(), filterAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyFilter), timeOffset)) {
2877                 // To ensure that the correct filter is visible when the animation ends, also set the final filter.
2878                 updateFilters(*toStyle);
2879                 didAnimate = true;
2880             }
2881         }
2882     }
2883
2884 #if ENABLE(FILTERS_LEVEL_2)
2885     if (property == CSSPropertyWebkitBackdropFilter && m_owningLayer.hasBackdropFilter()) {
2886         const Animation* backdropFilterAnim = toStyle->transitionForProperty(CSSPropertyWebkitBackdropFilter);
2887         if (backdropFilterAnim && !backdropFilterAnim->isEmptyOrZeroDuration()) {
2888             KeyframeValueList backdropFilterVector(AnimatedPropertyWebkitBackdropFilter);
2889             backdropFilterVector.insert(std::make_unique<FilterAnimationValue>(0, fromStyle->backdropFilter()));
2890             backdropFilterVector.insert(std::make_unique<FilterAnimationValue>(1, toStyle->backdropFilter()));
2891             if (m_graphicsLayer->addAnimation(backdropFilterVector, FloatSize(), backdropFilterAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitBackdropFilter), timeOffset)) {
2892                 // To ensure that the correct backdrop filter is visible when the animation ends, also set the final backdrop filter.
2893                 updateBackdropFilters(*toStyle);
2894                 didAnimate = true;
2895             }
2896         }
2897     }
2898 #endif
2899
2900     return didAnimate;
2901 }
2902
2903 void RenderLayerBacking::transitionPaused(double timeOffset, CSSPropertyID property)
2904 {
2905     AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
2906     if (animatedProperty != AnimatedPropertyInvalid)
2907         m_graphicsLayer->pauseAnimation(GraphicsLayer::animationNameForTransition(animatedProperty), timeOffset);
2908 }
2909
2910 void RenderLayerBacking::transitionFinished(CSSPropertyID property)
2911 {
2912     AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
2913     if (animatedProperty != AnimatedPropertyInvalid)
2914         m_graphicsLayer->removeAnimation(GraphicsLayer::animationNameForTransition(animatedProperty));
2915 }
2916
2917 void RenderLayerBacking::notifyAnimationStarted(const GraphicsLayer*, const String&, MonotonicTime time)
2918 {
2919     renderer().animation().notifyAnimationStarted(renderer(), time);
2920 }
2921
2922 void RenderLayerBacking::notifyFlushRequired(const GraphicsLayer* layer)
2923 {
2924     if (renderer().renderTreeBeingDestroyed())
2925         return;
2926     compositor().scheduleLayerFlush(layer->canThrottleLayerFlush());
2927 }
2928
2929 void RenderLayerBacking::notifyFlushBeforeDisplayRefresh(const GraphicsLayer* layer)
2930 {
2931     compositor().notifyFlushBeforeDisplayRefresh(layer);
2932 }
2933
2934 // This is used for the 'freeze' API, for testing only.
2935 void RenderLayerBacking::suspendAnimations(MonotonicTime time)
2936 {
2937     m_graphicsLayer->suspendAnimations(time);
2938 }
2939
2940 void RenderLayerBacking::resumeAnimations()
2941 {
2942     m_graphicsLayer->resumeAnimations();
2943 }
2944
2945 LayoutRect RenderLayerBacking::compositedBounds() const
2946 {
2947     return m_compositedBounds;
2948 }
2949
2950 void RenderLayerBacking::setCompositedBounds(const LayoutRect& bounds)
2951 {
2952     m_compositedBounds = bounds;
2953 }
2954
2955 LayoutRect RenderLayerBacking::compositedBoundsIncludingMargin() const
2956 {
2957     auto* tiledBacking = this->tiledBacking();
2958     if (!tiledBacking || !tiledBacking->hasMargins())
2959         return compositedBounds();
2960
2961     LayoutRect boundsIncludingMargin = compositedBounds();
2962     LayoutUnit leftMarginWidth = tiledBacking->leftMarginWidth();
2963     LayoutUnit topMarginHeight = tiledBacking->topMarginHeight();
2964
2965     boundsIncludingMargin.moveBy(LayoutPoint(-leftMarginWidth, -topMarginHeight));
2966     boundsIncludingMargin.expand(leftMarginWidth + tiledBacking->rightMarginWidth(), topMarginHeight + tiledBacking->bottomMarginHeight());
2967
2968     return boundsIncludingMargin;
2969 }
2970
2971 CSSPropertyID RenderLayerBacking::graphicsLayerToCSSProperty(AnimatedPropertyID property)
2972 {
2973     CSSPropertyID cssProperty = CSSPropertyInvalid;
2974     switch (property) {
2975     case AnimatedPropertyTransform:
2976         cssProperty = CSSPropertyTransform;
2977         break;
2978     case AnimatedPropertyOpacity:
2979         cssProperty = CSSPropertyOpacity;
2980         break;
2981     case AnimatedPropertyBackgroundColor:
2982         cssProperty = CSSPropertyBackgroundColor;
2983         break;
2984     case AnimatedPropertyFilter:
2985         cssProperty = CSSPropertyFilter;
2986         break;
2987 #if ENABLE(FILTERS_LEVEL_2)
2988     case AnimatedPropertyWebkitBackdropFilter:
2989         cssProperty = CSSPropertyWebkitBackdropFilter;
2990         break;
2991 #endif
2992     case AnimatedPropertyInvalid:
2993         ASSERT_NOT_REACHED();
2994     }
2995     return cssProperty;
2996 }
2997
2998 AnimatedPropertyID RenderLayerBacking::cssToGraphicsLayerProperty(CSSPropertyID cssProperty)
2999 {
3000     switch (cssProperty) {
3001     case CSSPropertyTransform:
3002         return AnimatedPropertyTransform;
3003     case CSSPropertyOpacity:
3004         return AnimatedPropertyOpacity;
3005     case CSSPropertyBackgroundColor:
3006         return AnimatedPropertyBackgroundColor;
3007     case CSSPropertyFilter:
3008         return AnimatedPropertyFilter;
3009 #if ENABLE(FILTERS_LEVEL_2)
3010     case CSSPropertyWebkitBackdropFilter:
3011         return AnimatedPropertyWebkitBackdropFilter;
3012 #endif
3013     default:
3014         // It's fine if we see other css properties here; they are just not accelerated.
3015         break;
3016     }
3017     return AnimatedPropertyInvalid;
3018 }
3019
3020 CompositingLayerType RenderLayerBacking::compositingLayerType() const
3021 {
3022     if (m_graphicsLayer->usesContentsLayer())
3023         return MediaCompositingLayer;
3024
3025     if (m_graphicsLayer->drawsContent())
3026         return m_graphicsLayer->tiledBacking() ? TiledCompositingLayer : NormalCompositingLayer;
3027     
3028     return ContainerCompositingLayer;
3029 }
3030
3031 double RenderLayerBacking::backingStoreMemoryEstimate() const
3032 {
3033     double backingMemory;
3034     
3035     // m_ancestorClippingLayer, m_contentsContainmentLayer and m_childContainmentLayer are just used for masking or containment, so have no backing.
3036     backingMemory = m_graphicsLayer->backingStoreMemoryEstimate();
3037     if (m_foregroundLayer)
3038         backingMemory += m_foregroundLayer->backingStoreMemoryEstimate();
3039     if (m_backgroundLayer)
3040         backingMemory += m_backgroundLayer->backingStoreMemoryEstimate();
3041     if (m_maskLayer)
3042         backingMemory += m_maskLayer->backingStoreMemoryEstimate();
3043     if (m_childClippingMaskLayer)
3044         backingMemory += m_childClippingMaskLayer->backingStoreMemoryEstimate();
3045
3046     if (m_scrollingContentsLayer)
3047         backingMemory += m_scrollingContentsLayer->backingStoreMemoryEstimate();
3048
3049     if (m_layerForHorizontalScrollbar)
3050         backingMemory += m_layerForHorizontalScrollbar->backingStoreMemoryEstimate();
3051
3052     if (m_layerForVerticalScrollbar)
3053         backingMemory += m_layerForVerticalScrollbar->backingStoreMemoryEstimate();
3054
3055     if (m_layerForScrollCorner)
3056         backingMemory += m_layerForScrollCorner->backingStoreMemoryEstimate();
3057     
3058     return backingMemory;
3059 }
3060
3061 TextStream& operator<<(TextStream& ts, const RenderLayerBacking& backing)
3062 {
3063     ts << "RenderLayerBacking " << &backing << " bounds " << backing.compositedBounds();
3064
3065     if (backing.isFrameLayerWithTiledBacking())
3066         ts << " frame layer tiled backing";
3067     if (backing.paintsIntoWindow())
3068         ts << " paintsIntoWindow";
3069     if (backing.paintsIntoCompositedAncestor())
3070         ts << " paintsIntoCompositedAncestor";
3071
3072     ts << " primary layer ID " << backing.graphicsLayer()->primaryLayerID();
3073     if (auto nodeID = backing.scrollingNodeIDForRole(ViewportConstrained))
3074         ts << " viewport constrained scrolling node " << nodeID;
3075     if (auto nodeID = backing.scrollingNodeIDForRole(Scrolling))
3076         ts << " scrolling node " << nodeID;
3077     return ts;
3078 }
3079
3080 } // namespace WebCore