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