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