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