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