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