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