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