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