Canvas and DOM go out of sync
[WebKit-https.git] / Source / WebCore / rendering / RenderLayerBacking.cpp
1 /*
2  * Copyright (C) 2009, 2010, 2011 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27
28 #if USE(ACCELERATED_COMPOSITING)
29
30 #include "RenderLayerBacking.h"
31
32 #include "AnimationController.h"
33 #include "CanvasRenderingContext.h"
34 #include "CSSPropertyNames.h"
35 #include "CachedImage.h"
36 #include "Chrome.h"
37 #include "FontCache.h"
38 #include "FrameView.h"
39 #include "GraphicsContext.h"
40 #include "GraphicsLayer.h"
41 #include "HTMLCanvasElement.h"
42 #include "HTMLIFrameElement.h"
43 #include "HTMLMediaElement.h"
44 #include "HTMLNames.h"
45 #include "InspectorInstrumentation.h"
46 #include "KeyframeList.h"
47 #include "PluginViewBase.h"
48 #include "RenderApplet.h"
49 #include "RenderIFrame.h"
50 #include "RenderImage.h"
51 #include "RenderLayerCompositor.h"
52 #include "RenderEmbeddedObject.h"
53 #include "RenderVideo.h"
54 #include "RenderView.h"
55 #include "ScrollingCoordinator.h"
56 #include "Settings.h"
57 #include "StyleResolver.h"
58 #include "TiledBacking.h"
59 #include "WebCoreMemoryInstrumentation.h"
60 #include <wtf/CurrentTime.h>
61 #include <wtf/text/StringBuilder.h>
62
63 #if ENABLE(CSS_FILTERS)
64 #include "FilterEffectRenderer.h"
65 #if ENABLE(CSS_SHADERS)
66 #include "CustomFilterOperation.h"
67 #endif
68 #endif
69
70 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
71 #include "GraphicsContext3D.h"
72 #endif
73
74 using namespace std;
75
76 namespace WebCore {
77
78 using namespace HTMLNames;
79
80 static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle*);
81 static IntRect clipBox(RenderBox* renderer);
82
83 static inline bool isAcceleratedCanvas(RenderObject* renderer)
84 {
85 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
86     if (renderer->isCanvas()) {
87         HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
88         if (CanvasRenderingContext* context = canvas->renderingContext())
89             return context->isAccelerated();
90     }
91 #else
92     UNUSED_PARAM(renderer);
93 #endif
94     return false;
95 }
96
97 // Get the scrolling coordinator in a way that works inside RenderLayerBacking's destructor.
98 static ScrollingCoordinator* scrollingCoordinatorFromLayer(RenderLayer* layer)
99 {
100     Page* page = layer->renderer()->frame()->page();
101     if (!page)
102         return 0;
103
104     return page->scrollingCoordinator();
105 }
106
107 bool RenderLayerBacking::m_creatingPrimaryGraphicsLayer = false;
108
109 RenderLayerBacking::RenderLayerBacking(RenderLayer* layer)
110     : m_owningLayer(layer)
111     , m_scrollLayerID(0)
112     , m_artificiallyInflatedBounds(false)
113     , m_boundsConstrainedByClipping(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     if (layer->isRootLayer()) {
123         Frame* frame = toRenderView(renderer())->frameView()->frame();
124         Page* page = frame ? frame->page() : 0;
125         if (page && frame && page->mainFrame() == frame) {
126             m_isMainFrameRenderViewLayer = true;
127
128 #if PLATFORM(MAC)
129             // FIXME: It's a little weird that we base this decision on whether there's a scrolling coordinator or not.
130             if (page->scrollingCoordinator())
131                 m_usingTiledCacheLayer = true;
132 #endif
133         }
134     }
135     
136     createPrimaryGraphicsLayer();
137
138     if (m_usingTiledCacheLayer) {
139         TiledBacking* tiledBacking = this->tiledBacking();
140         if (Page* page = renderer()->frame()->page()) {
141             Frame* frame = renderer()->frame();
142             tiledBacking->setIsInWindow(page->isInWindow());
143
144             if (m_isMainFrameRenderViewLayer)
145                 tiledBacking->setUnparentsOffscreenTiles(true);
146
147             tiledBacking->setScrollingPerformanceLoggingEnabled(frame->settings() && frame->settings()->scrollingPerformanceLoggingEnabled());
148             adjustTileCacheCoverage();
149         }
150     }
151 }
152
153 RenderLayerBacking::~RenderLayerBacking()
154 {
155     updateClippingLayers(false, false);
156     updateOverflowControlsLayers(false, false, false);
157     updateForegroundLayer(false);
158     updateBackgroundLayer(false);
159     updateMaskLayer(false);
160     updateScrollingLayers(false);
161     detachFromScrollingCoordinator();
162     destroyGraphicsLayers();
163 }
164
165 PassOwnPtr<GraphicsLayer> RenderLayerBacking::createGraphicsLayer(const String& name)
166 {
167     GraphicsLayerFactory* graphicsLayerFactory = 0;
168     if (Page* page = renderer()->frame()->page())
169         graphicsLayerFactory = page->chrome()->client()->graphicsLayerFactory();
170
171     OwnPtr<GraphicsLayer> graphicsLayer = GraphicsLayer::create(graphicsLayerFactory, this);
172
173 #ifndef NDEBUG
174     graphicsLayer->setName(name);
175 #else
176     UNUSED_PARAM(name);
177 #endif
178     graphicsLayer->setMaintainsPixelAlignment(compositor()->keepLayersPixelAligned());
179
180 #if PLATFORM(MAC) && USE(CA)
181     graphicsLayer->setAcceleratesDrawing(compositor()->acceleratedDrawingEnabled());
182 #endif    
183     
184     return graphicsLayer.release();
185 }
186
187 bool RenderLayerBacking::shouldUseTileCache(const GraphicsLayer*) const
188 {
189     return m_usingTiledCacheLayer && m_creatingPrimaryGraphicsLayer;
190 }
191
192 TiledBacking* RenderLayerBacking::tiledBacking() const
193 {
194     return m_graphicsLayer->tiledBacking();
195 }
196
197 void RenderLayerBacking::adjustTileCacheCoverage()
198 {
199     if (!m_usingTiledCacheLayer)
200         return;
201
202     TiledBacking::TileCoverage tileCoverage = TiledBacking::CoverageForVisibleArea;
203
204     // FIXME: When we use TiledBacking for overflow, this should look at RenderView scrollability.
205     Frame* frame = renderer()->frame();
206     if (frame) {
207         FrameView* frameView = frame->view();
208         if (frameView->horizontalScrollbarMode() != ScrollbarAlwaysOff)
209             tileCoverage |= TiledBacking::CoverageForHorizontalScrolling;
210
211         if (frameView->verticalScrollbarMode() != ScrollbarAlwaysOff)
212             tileCoverage |= TiledBacking::CoverageForVerticalScrolling;
213
214         if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer)) {
215             // Ask our TiledBacking for large tiles unless the only reason we're main-thread-scrolling
216             // is a page overlay (find-in-page, the Web Inspector highlight mechanism, etc.).
217             if (scrollingCoordinator->mainThreadScrollingReasons() & ~ScrollingCoordinator::ForcedOnMainThread)
218                 tileCoverage |= TiledBacking::CoverageForSlowScrolling;
219         }
220     }
221
222     tiledBacking()->setTileCoverage(tileCoverage);
223 }
224
225 void RenderLayerBacking::updateDebugIndicators(bool showBorder, bool showRepaintCounter)
226 {
227     m_graphicsLayer->setShowDebugBorder(showBorder);
228     m_graphicsLayer->setShowRepaintCounter(showRepaintCounter);
229     
230     if (m_ancestorClippingLayer)
231         m_ancestorClippingLayer->setShowDebugBorder(showBorder);
232
233     if (m_foregroundLayer) {
234         m_foregroundLayer->setShowDebugBorder(showBorder);
235         m_foregroundLayer->setShowRepaintCounter(showRepaintCounter);
236     }
237     
238     if (m_contentsContainmentLayer)
239         m_contentsContainmentLayer->setShowDebugBorder(showBorder);
240     
241     if (m_backgroundLayer) {
242         m_backgroundLayer->setShowDebugBorder(showBorder);
243         m_backgroundLayer->setShowRepaintCounter(showRepaintCounter);
244     }
245
246     if (m_maskLayer) {
247         m_maskLayer->setShowDebugBorder(showBorder);
248         m_maskLayer->setShowRepaintCounter(showRepaintCounter);
249     }
250
251     if (m_layerForHorizontalScrollbar)
252         m_layerForHorizontalScrollbar->setShowDebugBorder(showBorder);
253
254     if (m_layerForVerticalScrollbar)
255         m_layerForVerticalScrollbar->setShowDebugBorder(showBorder);
256
257     if (m_layerForScrollCorner)
258         m_layerForScrollCorner->setShowDebugBorder(showBorder);
259
260     if (m_scrollingLayer)
261         m_scrollingLayer->setShowDebugBorder(showBorder);
262
263     if (m_scrollingContentsLayer) {
264         m_scrollingContentsLayer->setShowDebugBorder(showBorder);
265         m_scrollingContentsLayer->setShowRepaintCounter(showRepaintCounter);
266     }
267 }
268
269 void RenderLayerBacking::createPrimaryGraphicsLayer()
270 {
271     String layerName;
272 #ifndef NDEBUG
273     layerName = m_owningLayer->name();
274 #endif
275     
276     // The call to createGraphicsLayer ends calling back into here as
277     // a GraphicsLayerClient to ask if it shouldUseTileCache(). We only want
278     // the tile cache on our main layer. This is pretty ugly, but saves us from
279     // exposing the API to all clients.
280
281     m_creatingPrimaryGraphicsLayer = true;
282     m_graphicsLayer = createGraphicsLayer(layerName);
283     m_creatingPrimaryGraphicsLayer = false;
284
285     if (m_usingTiledCacheLayer)
286         m_childContainmentLayer = createGraphicsLayer("TileCache Flattening Layer");
287
288     if (m_isMainFrameRenderViewLayer) {
289         m_graphicsLayer->setContentsOpaque(true);
290         m_graphicsLayer->setAppliesPageScale();
291     }
292
293 #if PLATFORM(MAC) && USE(CA)
294     if (!compositor()->acceleratedDrawingEnabled() && renderer()->isCanvas()) {
295         HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer()->node());
296         if (canvas->shouldAccelerate(canvas->size()))
297             m_graphicsLayer->setAcceleratesDrawing(true);
298     }
299 #endif    
300     
301     updateOpacity(renderer()->style());
302     updateTransform(renderer()->style());
303 #if ENABLE(CSS_FILTERS)
304     updateFilters(renderer()->style());
305 #endif
306 #if ENABLE(CSS_COMPOSITING)
307     updateLayerBlendMode(renderer()->style());
308 #endif
309 }
310
311 void RenderLayerBacking::destroyGraphicsLayers()
312 {
313     if (m_graphicsLayer)
314         m_graphicsLayer->removeFromParent();
315
316     m_ancestorClippingLayer = nullptr;
317     m_contentsContainmentLayer = nullptr;
318     m_graphicsLayer = nullptr;
319     m_foregroundLayer = nullptr;
320     m_backgroundLayer = nullptr;
321     m_childContainmentLayer = nullptr;
322     m_maskLayer = nullptr;
323
324     m_scrollingLayer = nullptr;
325     m_scrollingContentsLayer = nullptr;
326 }
327
328 void RenderLayerBacking::updateOpacity(const RenderStyle* style)
329 {
330     m_graphicsLayer->setOpacity(compositingOpacity(style->opacity()));
331 }
332
333 void RenderLayerBacking::updateTransform(const RenderStyle* style)
334 {
335     // FIXME: This could use m_owningLayer->transform(), but that currently has transform-origin
336     // baked into it, and we don't want that.
337     TransformationMatrix t;
338     if (m_owningLayer->hasTransform()) {
339         style->applyTransform(t, toRenderBox(renderer())->pixelSnappedBorderBoxRect().size(), RenderStyle::ExcludeTransformOrigin);
340         makeMatrixRenderable(t, compositor()->canRender3DTransforms());
341     }
342     
343     if (m_contentsContainmentLayer) {
344         m_contentsContainmentLayer->setTransform(t);
345         m_graphicsLayer->setTransform(TransformationMatrix());
346     } else
347         m_graphicsLayer->setTransform(t);
348 }
349
350 #if ENABLE(CSS_FILTERS)
351 void RenderLayerBacking::updateFilters(const RenderStyle* style)
352 {
353     m_canCompositeFilters = m_graphicsLayer->setFilters(owningLayer()->computeFilterOperations(style));
354 }
355 #endif
356
357 #if ENABLE(CSS_COMPOSITING)
358 void RenderLayerBacking::updateLayerBlendMode(const RenderStyle*)
359 {
360 }
361 #endif
362
363 static bool hasNonZeroTransformOrigin(const RenderObject* renderer)
364 {
365     RenderStyle* style = renderer->style();
366     return (style->transformOriginX().type() == Fixed && style->transformOriginX().value())
367         || (style->transformOriginY().type() == Fixed && style->transformOriginY().value());
368 }
369
370 static bool layerOrAncestorIsTransformedOrUsingCompositedScrolling(RenderLayer* layer)
371 {
372     for (RenderLayer* curr = layer; curr; curr = curr->parent()) {
373         if (curr->hasTransform() || curr->needsCompositedScrolling())
374             return true;
375     }
376     
377     return false;
378 }
379
380 bool RenderLayerBacking::shouldClipCompositedBounds() const
381 {
382     // Scrollbar layers use this layer for relative positioning, so don't clip.
383     if (layerForHorizontalScrollbar() || layerForVerticalScrollbar())
384         return false;
385
386     if (m_usingTiledCacheLayer)
387         return false;
388
389     if (!compositor()->compositingConsultsOverlap())
390         return false;
391
392     if (layerOrAncestorIsTransformedOrUsingCompositedScrolling(m_owningLayer))
393         return false;
394
395     return true;
396 }
397
398 void RenderLayerBacking::updateCompositedBounds()
399 {
400     IntRect layerBounds = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer);
401
402     // Clip to the size of the document or enclosing overflow-scroll layer.
403     // If this or an ancestor is transformed, we can't currently compute the correct rect to intersect with.
404     // We'd need RenderObject::convertContainerToLocalQuad(), which doesn't yet exist.
405     if (shouldClipCompositedBounds()) {
406         RenderView* view = m_owningLayer->renderer()->view();
407         RenderLayer* rootLayer = view->layer();
408
409         LayoutRect clippingBounds;
410         if (renderer()->style()->position() == FixedPosition && renderer()->container() == view)
411             clippingBounds = view->frameView()->viewportConstrainedVisibleContentRect();
412         else
413             clippingBounds = view->unscaledDocumentRect();
414
415         if (m_owningLayer != rootLayer)
416             clippingBounds.intersect(m_owningLayer->backgroundClipRect(RenderLayer::ClipRectsContext(rootLayer, 0, AbsoluteClipRects)).rect()); // FIXME: Incorrect for CSS regions.
417
418         LayoutPoint delta;
419         m_owningLayer->convertToLayerCoords(rootLayer, delta);
420         clippingBounds.move(-delta.x(), -delta.y());
421
422         layerBounds.intersect(pixelSnappedIntRect(clippingBounds));
423         m_boundsConstrainedByClipping = true;
424     } else
425         m_boundsConstrainedByClipping = false;
426     
427     // If the element has a transform-origin that has fixed lengths, and the renderer has zero size,
428     // then we need to ensure that the compositing layer has non-zero size so that we can apply
429     // the transform-origin via the GraphicsLayer anchorPoint (which is expressed as a fractional value).
430     if (layerBounds.isEmpty() && hasNonZeroTransformOrigin(renderer())) {
431         layerBounds.setWidth(1);
432         layerBounds.setHeight(1);
433         m_artificiallyInflatedBounds = true;
434     } else
435         m_artificiallyInflatedBounds = false;
436
437     setCompositedBounds(layerBounds);
438 }
439
440 void RenderLayerBacking::updateAfterWidgetResize()
441 {
442     if (renderer()->isRenderPart()) {
443         if (RenderLayerCompositor* innerCompositor = RenderLayerCompositor::frameContentsCompositor(toRenderPart(renderer()))) {
444             innerCompositor->frameViewDidChangeSize();
445             innerCompositor->frameViewDidChangeLocation(contentsBox().location());
446         }
447     }
448 }
449
450 void RenderLayerBacking::updateAfterLayout(UpdateAfterLayoutFlags flags)
451 {
452     RenderLayerCompositor* layerCompositor = compositor();
453     if (!layerCompositor->compositingLayersNeedRebuild()) {
454         // Calling updateGraphicsLayerGeometry() here gives incorrect results, because the
455         // position of this layer's GraphicsLayer depends on the position of our compositing
456         // ancestor's GraphicsLayer. That cannot be determined until all the descendant 
457         // RenderLayers of that ancestor have been processed via updateLayerPositions().
458         //
459         // The solution is to update compositing children of this layer here,
460         // via updateCompositingChildrenGeometry().
461         updateCompositedBounds();
462         layerCompositor->updateCompositingDescendantGeometry(m_owningLayer, m_owningLayer, flags & CompositingChildrenOnly);
463         
464         if (flags & IsUpdateRoot) {
465             updateGraphicsLayerGeometry();
466             layerCompositor->updateRootLayerPosition();
467             RenderLayer* stackingContainer = m_owningLayer->enclosingStackingContainer();
468             if (!layerCompositor->compositingLayersNeedRebuild() && stackingContainer && (stackingContainer != m_owningLayer))
469                 layerCompositor->updateCompositingDescendantGeometry(stackingContainer, stackingContainer, flags & CompositingChildrenOnly);
470         }
471     }
472     
473     if (flags & NeedsFullRepaint && !paintsIntoWindow() && !paintsIntoCompositedAncestor())
474         setContentsNeedDisplay();
475 }
476
477 bool RenderLayerBacking::updateGraphicsLayerConfiguration()
478 {
479     RenderLayerCompositor* compositor = this->compositor();
480     RenderObject* renderer = this->renderer();
481
482     m_owningLayer->updateDescendantDependentFlags();
483     m_owningLayer->updateZOrderLists();
484
485     bool layerConfigChanged = false;
486     setBackgroundLayerPaintsFixedRootBackground(compositor->needsFixedRootBackgroundLayer(m_owningLayer));
487     
488     // The background layer is currently only used for fixed root backgrounds.
489     if (updateBackgroundLayer(m_backgroundLayerPaintsFixedRootBackground))
490         layerConfigChanged = true;
491
492     if (updateForegroundLayer(compositor->needsContentsCompositingLayer(m_owningLayer)))
493         layerConfigChanged = true;
494     
495     bool needsDescendentsClippingLayer = compositor->clipsCompositingDescendants(m_owningLayer);
496
497     // Our scrolling layer will clip.
498     if (m_owningLayer->needsCompositedScrolling())
499         needsDescendentsClippingLayer = false;
500
501     if (updateClippingLayers(compositor->clippedByAncestor(m_owningLayer), needsDescendentsClippingLayer))
502         layerConfigChanged = true;
503
504     if (updateOverflowControlsLayers(requiresHorizontalScrollbarLayer(), requiresVerticalScrollbarLayer(), requiresScrollCornerLayer()))
505         layerConfigChanged = true;
506
507     if (updateScrollingLayers(m_owningLayer->needsCompositedScrolling()))
508         layerConfigChanged = true;
509
510     if (layerConfigChanged)
511         updateInternalHierarchy();
512
513     if (GraphicsLayer* flatteningLayer = tileCacheFlatteningLayer()) {
514         flatteningLayer->removeFromParent();
515         m_graphicsLayer->addChild(flatteningLayer);
516     }
517
518     if (updateMaskLayer(renderer->hasMask()))
519         m_graphicsLayer->setMaskLayer(m_maskLayer.get());
520
521     if (m_owningLayer->hasReflection()) {
522         if (m_owningLayer->reflectionLayer()->backing()) {
523             GraphicsLayer* reflectionLayer = m_owningLayer->reflectionLayer()->backing()->graphicsLayer();
524             m_graphicsLayer->setReplicatedByLayer(reflectionLayer);
525         }
526     } else
527         m_graphicsLayer->setReplicatedByLayer(0);
528
529     updateBackgroundColor(isSimpleContainerCompositingLayer());
530     updateRootLayerConfiguration();
531     
532     if (isDirectlyCompositedImage())
533         updateImageContents();
534
535     if (renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing()) {
536         PluginViewBase* pluginViewBase = static_cast<PluginViewBase*>(toRenderWidget(renderer)->widget());
537         m_graphicsLayer->setContentsToMedia(pluginViewBase->platformLayer());
538     }
539 #if ENABLE(VIDEO)
540     else if (renderer->isVideo()) {
541         HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(renderer->node());
542         m_graphicsLayer->setContentsToMedia(mediaElement->platformLayer());
543     }
544 #endif
545 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
546     else if (isAcceleratedCanvas(renderer)) {
547         HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
548         if (CanvasRenderingContext* context = canvas->renderingContext())
549             m_graphicsLayer->setContentsToCanvas(context->platformLayer());
550         layerConfigChanged = true;
551     }
552 #endif
553     if (renderer->isRenderPart())
554         layerConfigChanged = RenderLayerCompositor::parentFrameContentLayers(toRenderPart(renderer));
555
556     return layerConfigChanged;
557 }
558
559 static IntRect clipBox(RenderBox* renderer)
560 {
561     LayoutRect result = PaintInfo::infiniteRect();
562     if (renderer->hasOverflowClip())
563         result = renderer->overflowClipRect(LayoutPoint(), 0); // FIXME: Incorrect for CSS regions.
564
565     if (renderer->hasClip())
566         result.intersect(renderer->clipRect(LayoutPoint(), 0)); // FIXME: Incorrect for CSS regions.
567
568     return pixelSnappedIntRect(result);
569 }
570
571 void RenderLayerBacking::updateGraphicsLayerGeometry()
572 {
573     // If we haven't built z-order lists yet, wait until later.
574     if (m_owningLayer->isStackingContainer() && m_owningLayer->m_zOrderListsDirty)
575         return;
576
577     // Set transform property, if it is not animating. We have to do this here because the transform
578     // is affected by the layer dimensions.
579     if (!renderer()->animation()->isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyWebkitTransform))
580         updateTransform(renderer()->style());
581
582     // Set opacity, if it is not animating.
583     if (!renderer()->animation()->isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyOpacity))
584         updateOpacity(renderer()->style());
585         
586 #if ENABLE(CSS_FILTERS)
587     updateFilters(renderer()->style());
588 #endif
589
590 #if ENABLE(CSS_COMPOSITING)
591     updateLayerBlendMode(renderer()->style());
592 #endif
593
594     bool isSimpleContainer = isSimpleContainerCompositingLayer();
595     
596     m_owningLayer->updateDescendantDependentFlags();
597
598     // m_graphicsLayer is the corresponding GraphicsLayer for this RenderLayer and its non-compositing
599     // descendants. So, the visibility flag for m_graphicsLayer should be true if there are any
600     // non-compositing visible layers.
601     m_graphicsLayer->setContentsVisible(m_owningLayer->hasVisibleContent() || hasVisibleNonCompositingDescendantLayers());
602
603     RenderStyle* style = renderer()->style();
604     // FIXME: reflections should force transform-style to be flat in the style: https://bugs.webkit.org/show_bug.cgi?id=106959
605     bool preserves3D = style->transformStyle3D() == TransformStyle3DPreserve3D && !renderer()->hasReflection();
606     m_graphicsLayer->setPreserves3D(preserves3D);
607     m_graphicsLayer->setBackfaceVisibility(style->backfaceVisibility() == BackfaceVisibilityVisible);
608
609     RenderLayer* compAncestor = m_owningLayer->ancestorCompositingLayer();
610     
611     // We compute everything relative to the enclosing compositing layer.
612     IntRect ancestorCompositingBounds;
613     if (compAncestor) {
614         ASSERT(compAncestor->backing());
615         ancestorCompositingBounds = pixelSnappedIntRect(compAncestor->backing()->compositedBounds());
616     }
617
618     IntRect localCompositingBounds = pixelSnappedIntRect(compositedBounds());
619
620     IntRect relativeCompositingBounds(localCompositingBounds);
621     IntPoint delta;
622     m_owningLayer->convertToPixelSnappedLayerCoords(compAncestor, delta);
623     relativeCompositingBounds.moveBy(delta);
624
625     IntPoint graphicsLayerParentLocation;
626     if (compAncestor && compAncestor->backing()->hasClippingLayer()) {
627         // If the compositing ancestor has a layer to clip children, we parent in that, and therefore
628         // position relative to it.
629         IntRect clippingBox = clipBox(toRenderBox(compAncestor->renderer()));
630         graphicsLayerParentLocation = clippingBox.location();
631     } else if (compAncestor)
632         graphicsLayerParentLocation = ancestorCompositingBounds.location();
633     else
634         graphicsLayerParentLocation = renderer()->view()->documentRect().location();
635
636     if (compAncestor && compAncestor->needsCompositedScrolling()) {
637         RenderBox* renderBox = toRenderBox(compAncestor->renderer());
638         IntSize scrollOffset = compAncestor->scrolledContentOffset();
639         IntPoint scrollOrigin(renderBox->borderLeft(), renderBox->borderTop());
640         graphicsLayerParentLocation = scrollOrigin - scrollOffset;
641     }
642     
643     if (compAncestor && m_ancestorClippingLayer) {
644         // Call calculateRects to get the backgroundRect which is what is used to clip the contents of this
645         // layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects
646         // for a compositing layer, rootLayer is the layer itself.
647         RenderLayer::ClipRectsContext clipRectsContext(compAncestor, 0, TemporaryClipRects, IgnoreOverlayScrollbarSize, IgnoreOverflowClip);
648         IntRect parentClipRect = pixelSnappedIntRect(m_owningLayer->backgroundClipRect(clipRectsContext).rect()); // FIXME: Incorrect for CSS regions.
649         ASSERT(parentClipRect != PaintInfo::infiniteRect());
650         m_ancestorClippingLayer->setPosition(FloatPoint(parentClipRect.location() - graphicsLayerParentLocation));
651         m_ancestorClippingLayer->setSize(parentClipRect.size());
652
653         // backgroundRect is relative to compAncestor, so subtract deltaX/deltaY to get back to local coords.
654         m_ancestorClippingLayer->setOffsetFromRenderer(parentClipRect.location() - delta);
655
656         // The primary layer is then parented in, and positioned relative to this clipping layer.
657         graphicsLayerParentLocation = parentClipRect.location();
658     }
659
660     FloatSize contentsSize = relativeCompositingBounds.size();
661     
662     if (m_contentsContainmentLayer) {
663         m_contentsContainmentLayer->setPreserves3D(preserves3D);
664         m_contentsContainmentLayer->setPosition(FloatPoint(relativeCompositingBounds.location() - graphicsLayerParentLocation));
665         // Use the same size as m_graphicsLayer so transforms behave correctly.
666         m_contentsContainmentLayer->setSize(contentsSize);
667         graphicsLayerParentLocation = relativeCompositingBounds.location();
668     }
669
670     m_graphicsLayer->setPosition(FloatPoint(relativeCompositingBounds.location() - graphicsLayerParentLocation));
671     m_graphicsLayer->setOffsetFromRenderer(toIntSize(localCompositingBounds.location()));
672     
673     FloatSize oldSize = m_graphicsLayer->size();
674     if (oldSize != contentsSize) {
675         m_graphicsLayer->setSize(contentsSize);
676         // Usually invalidation will happen via layout etc, but if we've affected the layer
677         // size by constraining relative to a clipping ancestor or the viewport, we
678         // have to invalidate to avoid showing stretched content.
679         if (m_boundsConstrainedByClipping)
680             m_graphicsLayer->setNeedsDisplay();
681     }
682     if (!m_isMainFrameRenderViewLayer)
683         m_graphicsLayer->setContentsOpaque(m_owningLayer->contentsOpaqueInRect(localCompositingBounds));
684
685     // If we have a layer that clips children, position it.
686     IntRect clippingBox;
687     if (GraphicsLayer* clipLayer = clippingLayer()) {
688         clippingBox = clipBox(toRenderBox(renderer()));
689         clipLayer->setPosition(FloatPoint(clippingBox.location() - localCompositingBounds.location()));
690         clipLayer->setSize(clippingBox.size());
691         clipLayer->setOffsetFromRenderer(toIntSize(clippingBox.location()));
692     }
693     
694     if (m_maskLayer) {
695         if (m_maskLayer->size() != m_graphicsLayer->size()) {
696             m_maskLayer->setSize(m_graphicsLayer->size());
697             m_maskLayer->setNeedsDisplay();
698         }
699         m_maskLayer->setPosition(FloatPoint());
700         m_maskLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
701     }
702     
703     if (m_owningLayer->hasTransform()) {
704         const IntRect borderBox = toRenderBox(renderer())->pixelSnappedBorderBoxRect();
705
706         // Get layout bounds in the coords of compAncestor to match relativeCompositingBounds.
707         IntRect layerBounds = IntRect(delta, borderBox.size());
708
709         // Update properties that depend on layer dimensions
710         FloatPoint3D transformOrigin = computeTransformOrigin(borderBox);
711         // Compute the anchor point, which is in the center of the renderer box unless transform-origin is set.
712         FloatPoint3D anchor(relativeCompositingBounds.width()  != 0.0f ? ((layerBounds.x() - relativeCompositingBounds.x()) + transformOrigin.x()) / relativeCompositingBounds.width()  : 0.5f,
713                             relativeCompositingBounds.height() != 0.0f ? ((layerBounds.y() - relativeCompositingBounds.y()) + transformOrigin.y()) / relativeCompositingBounds.height() : 0.5f,
714                             transformOrigin.z());
715         if (m_contentsContainmentLayer)
716             m_contentsContainmentLayer->setAnchorPoint(anchor);
717         else
718             m_graphicsLayer->setAnchorPoint(anchor);
719
720         RenderStyle* style = renderer()->style();
721         GraphicsLayer* clipLayer = clippingLayer();
722         if (style->hasPerspective()) {
723             TransformationMatrix t = owningLayer()->perspectiveTransform();
724             
725             if (clipLayer) {
726                 clipLayer->setChildrenTransform(t);
727                 m_graphicsLayer->setChildrenTransform(TransformationMatrix());
728             }
729             else
730                 m_graphicsLayer->setChildrenTransform(t);
731         } else {
732             if (clipLayer)
733                 clipLayer->setChildrenTransform(TransformationMatrix());
734             else
735                 m_graphicsLayer->setChildrenTransform(TransformationMatrix());
736         }
737     } else {
738         m_graphicsLayer->setAnchorPoint(FloatPoint3D(0.5f, 0.5f, 0));
739         if (m_contentsContainmentLayer)
740             m_contentsContainmentLayer->setAnchorPoint(FloatPoint3D(0.5f, 0.5f, 0));
741     }
742
743     if (m_foregroundLayer) {
744         FloatPoint foregroundPosition;
745         FloatSize foregroundSize = contentsSize;
746         IntSize foregroundOffset = m_graphicsLayer->offsetFromRenderer();
747         if (hasClippingLayer()) {
748             // If we have a clipping layer (which clips descendants), then the foreground layer is a child of it,
749             // so that it gets correctly sorted with children. In that case, position relative to the clipping layer.
750             foregroundSize = FloatSize(clippingBox.size());
751             foregroundOffset = toIntSize(clippingBox.location());
752         }
753
754         m_foregroundLayer->setPosition(foregroundPosition);
755         if (foregroundSize != m_foregroundLayer->size()) {
756             m_foregroundLayer->setSize(foregroundSize);
757             m_foregroundLayer->setNeedsDisplay();
758         }
759         m_foregroundLayer->setOffsetFromRenderer(foregroundOffset);
760     }
761
762     if (m_backgroundLayer) {
763         FloatPoint backgroundPosition;
764         FloatSize backgroundSize = contentsSize;
765         if (backgroundLayerPaintsFixedRootBackground()) {
766             FrameView* frameView = toRenderView(renderer())->frameView();
767             backgroundPosition = IntPoint(frameView->scrollOffsetForFixedPosition());
768             backgroundSize = frameView->visibleContentRect().size();
769         }
770         m_backgroundLayer->setPosition(backgroundPosition);
771         if (backgroundSize != m_backgroundLayer->size()) {
772             m_backgroundLayer->setSize(backgroundSize);
773             m_backgroundLayer->setNeedsDisplay();
774         }
775         m_backgroundLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
776     }
777
778     if (m_owningLayer->reflectionLayer() && m_owningLayer->reflectionLayer()->isComposited()) {
779         RenderLayerBacking* reflectionBacking = m_owningLayer->reflectionLayer()->backing();
780         reflectionBacking->updateGraphicsLayerGeometry();
781         
782         // The reflection layer has the bounds of m_owningLayer->reflectionLayer(),
783         // but the reflected layer is the bounds of this layer, so we need to position it appropriately.
784         FloatRect layerBounds = compositedBounds();
785         FloatRect reflectionLayerBounds = reflectionBacking->compositedBounds();
786         reflectionBacking->graphicsLayer()->setReplicatedLayerPosition(FloatPoint(layerBounds.location() - reflectionLayerBounds.location()));
787     }
788
789     if (m_scrollingLayer) {
790         ASSERT(m_scrollingContentsLayer);
791         RenderBox* renderBox = toRenderBox(renderer());
792         IntRect paddingBox(renderBox->borderLeft(), renderBox->borderTop(), renderBox->width() - renderBox->borderLeft() - renderBox->borderRight(), renderBox->height() - renderBox->borderTop() - renderBox->borderBottom());
793         IntSize scrollOffset = m_owningLayer->scrolledContentOffset();
794
795         m_scrollingLayer->setPosition(FloatPoint(paddingBox.location() - localCompositingBounds.location()));
796
797         m_scrollingLayer->setSize(paddingBox.size());
798         m_scrollingContentsLayer->setPosition(FloatPoint(-scrollOffset.width(), -scrollOffset.height()));
799
800         IntSize oldScrollingLayerOffset = m_scrollingLayer->offsetFromRenderer();
801         m_scrollingLayer->setOffsetFromRenderer(-toIntSize(paddingBox.location()));
802
803         bool paddingBoxOffsetChanged = oldScrollingLayerOffset != m_scrollingLayer->offsetFromRenderer();
804
805         IntSize scrollSize(m_owningLayer->scrollWidth(), m_owningLayer->scrollHeight());
806         if (scrollSize != m_scrollingContentsLayer->size() || paddingBoxOffsetChanged)
807             m_scrollingContentsLayer->setNeedsDisplay();
808
809         IntSize scrollingContentsOffset = toIntSize(paddingBox.location() - scrollOffset);
810         if (scrollingContentsOffset != m_scrollingContentsLayer->offsetFromRenderer() || scrollSize != m_scrollingContentsLayer->size())
811             compositor()->scrollingLayerDidChange(m_owningLayer);
812
813         m_scrollingContentsLayer->setSize(scrollSize);
814         // FIXME: The paint offset and the scroll offset should really be separate concepts.
815         m_scrollingContentsLayer->setOffsetFromRenderer(scrollingContentsOffset, GraphicsLayer::DontSetNeedsDisplay);
816     }
817
818     // If this layer was created just for clipping or to apply perspective, it doesn't need its own backing store.
819     setRequiresOwnBackingStore(compositor()->requiresOwnBackingStore(m_owningLayer, compAncestor));
820
821     updateContentsRect(isSimpleContainer);
822     updateBackgroundColor(isSimpleContainer);
823     updateDrawsContent(isSimpleContainer);
824     updateAfterWidgetResize();
825     registerScrollingLayers();
826 }
827
828 void RenderLayerBacking::registerScrollingLayers()
829 {
830     // Register fixed position layers and their containers with the scrolling coordinator.
831     ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
832     if (!scrollingCoordinator)
833         return;
834
835     compositor()->updateViewportConstraintStatus(m_owningLayer);
836
837     // FIXME: it would be nice to avoid all this work if the platform doesn't implement setLayerIsFixedToContainerLayer().
838     if (renderer()->style()->position() == FixedPosition || compositor()->fixedPositionedByAncestor(m_owningLayer))
839         scrollingCoordinator->setLayerIsFixedToContainerLayer(childForSuperlayers(), true);
840     else {
841         if (m_ancestorClippingLayer)
842             scrollingCoordinator->setLayerIsFixedToContainerLayer(m_ancestorClippingLayer.get(), false);
843         scrollingCoordinator->setLayerIsFixedToContainerLayer(m_graphicsLayer.get(), false);
844     }
845     // Page scale is applied as a transform on the root render view layer. Because the scroll
846     // layer is further up in the hierarchy, we need to avoid marking the root render view
847     // layer as a container.
848     bool isContainer = m_owningLayer->hasTransform() && !m_owningLayer->isRootLayer();
849     scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(childForSuperlayers(), isContainer);
850 }
851
852 void RenderLayerBacking::updateInternalHierarchy()
853 {
854     // m_foregroundLayer has to be inserted in the correct order with child layers,
855     // so it's not inserted here.
856     if (m_ancestorClippingLayer)
857         m_ancestorClippingLayer->removeAllChildren();
858     
859     if (m_contentsContainmentLayer) {
860         m_contentsContainmentLayer->removeAllChildren();
861         if (m_ancestorClippingLayer)
862             m_ancestorClippingLayer->addChild(m_contentsContainmentLayer.get());
863     }
864     
865     if (m_backgroundLayer)
866         m_contentsContainmentLayer->addChild(m_backgroundLayer.get());
867
868     m_graphicsLayer->removeFromParent();
869     if (m_contentsContainmentLayer)
870         m_contentsContainmentLayer->addChild(m_graphicsLayer.get());
871     else if (m_ancestorClippingLayer)
872         m_ancestorClippingLayer->addChild(m_graphicsLayer.get());
873
874     if (m_childContainmentLayer) {
875         m_childContainmentLayer->removeFromParent();
876         m_graphicsLayer->addChild(m_childContainmentLayer.get());
877     }
878
879     if (m_scrollingLayer) {
880         GraphicsLayer* superlayer = m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsLayer.get();
881         m_scrollingLayer->removeFromParent();
882         superlayer->addChild(m_scrollingLayer.get());
883     }
884
885     // The clip for child layers does not include space for overflow controls, so they exist as
886     // siblings of the clipping layer if we have one. Normal children of this layer are set as
887     // children of the clipping layer.
888     if (m_layerForHorizontalScrollbar) {
889         m_layerForHorizontalScrollbar->removeFromParent();
890         m_graphicsLayer->addChild(m_layerForHorizontalScrollbar.get());
891     }
892     if (m_layerForVerticalScrollbar) {
893         m_layerForVerticalScrollbar->removeFromParent();
894         m_graphicsLayer->addChild(m_layerForVerticalScrollbar.get());
895     }
896     if (m_layerForScrollCorner) {
897         m_layerForScrollCorner->removeFromParent();
898         m_graphicsLayer->addChild(m_layerForScrollCorner.get());
899     }
900 }
901
902 void RenderLayerBacking::updateContentsRect(bool isSimpleContainer)
903 {
904     IntRect contentsRect;
905     if (isSimpleContainer && renderer()->hasBackground())
906         contentsRect = backgroundBox();
907     else
908         contentsRect = contentsBox();
909
910     m_graphicsLayer->setContentsRect(contentsRect);
911 }
912
913 void RenderLayerBacking::updateDrawsContent()
914 {
915     updateDrawsContent(isSimpleContainerCompositingLayer());
916 }
917
918 void RenderLayerBacking::updateDrawsContent(bool isSimpleContainer)
919 {
920     if (m_scrollingLayer) {
921         // We don't have to consider overflow controls, because we know that the scrollbars are drawn elsewhere.
922         // m_graphicsLayer only needs backing store if the non-scrolling parts (background, outlines, borders, shadows etc) need to paint.
923         // m_scrollingLayer never has backing store.
924         // m_scrollingContentsLayer only needs backing store if the scrolled contents need to paint.
925         bool hasNonScrollingPaintedContent = m_owningLayer->hasVisibleContent() && m_owningLayer->hasBoxDecorationsOrBackground();
926         m_graphicsLayer->setDrawsContent(hasNonScrollingPaintedContent);
927
928         bool hasScrollingPaintedContent = m_owningLayer->hasVisibleContent() && (renderer()->hasBackground() || paintsChildren());
929         m_scrollingContentsLayer->setDrawsContent(hasScrollingPaintedContent);
930         return;
931     }
932
933     bool hasPaintedContent = !isSimpleContainer && containsPaintedContent();
934
935     // FIXME: we could refine this to only allocate backing for one of these layers if possible.
936     m_graphicsLayer->setDrawsContent(hasPaintedContent);
937     if (m_foregroundLayer)
938         m_foregroundLayer->setDrawsContent(hasPaintedContent);
939
940     if (m_backgroundLayer)
941         m_backgroundLayer->setDrawsContent(hasPaintedContent);
942 }
943
944 // Return true if the layers changed.
945 bool RenderLayerBacking::updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip)
946 {
947     bool layersChanged = false;
948
949     if (needsAncestorClip) {
950         if (!m_ancestorClippingLayer) {
951             m_ancestorClippingLayer = createGraphicsLayer("Ancestor clipping Layer");
952             m_ancestorClippingLayer->setMasksToBounds(true);
953             layersChanged = true;
954         }
955     } else if (m_ancestorClippingLayer) {
956         m_ancestorClippingLayer->removeFromParent();
957         m_ancestorClippingLayer = nullptr;
958         layersChanged = true;
959     }
960     
961     if (needsDescendantClip) {
962         if (!m_childContainmentLayer && !m_usingTiledCacheLayer) {
963             m_childContainmentLayer = createGraphicsLayer("Child clipping Layer");
964             m_childContainmentLayer->setMasksToBounds(true);
965             layersChanged = true;
966         }
967     } else if (hasClippingLayer()) {
968         m_childContainmentLayer->removeFromParent();
969         m_childContainmentLayer = nullptr;
970         layersChanged = true;
971     }
972     
973     return layersChanged;
974 }
975
976 void RenderLayerBacking::setBackgroundLayerPaintsFixedRootBackground(bool backgroundLayerPaintsFixedRootBackground)
977 {
978     m_backgroundLayerPaintsFixedRootBackground = backgroundLayerPaintsFixedRootBackground;
979 }
980
981 bool RenderLayerBacking::requiresHorizontalScrollbarLayer() const
982 {
983 #if !PLATFORM(CHROMIUM)
984     if (!m_owningLayer->hasOverlayScrollbars() && !m_owningLayer->needsCompositedScrolling())
985         return false;
986 #endif
987     return m_owningLayer->horizontalScrollbar();
988 }
989
990 bool RenderLayerBacking::requiresVerticalScrollbarLayer() const
991 {
992 #if !PLATFORM(CHROMIUM)
993     if (!m_owningLayer->hasOverlayScrollbars() && !m_owningLayer->needsCompositedScrolling())
994         return false;
995 #endif
996     return m_owningLayer->verticalScrollbar();
997 }
998
999 bool RenderLayerBacking::requiresScrollCornerLayer() const
1000 {
1001 #if !PLATFORM(CHROMIUM)
1002     if (!m_owningLayer->hasOverlayScrollbars() && !m_owningLayer->needsCompositedScrolling())
1003         return false;
1004 #endif
1005     return !m_owningLayer->scrollCornerAndResizerRect().isEmpty();
1006 }
1007
1008 bool RenderLayerBacking::updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer)
1009 {
1010     bool horizontalScrollbarLayerChanged = false;
1011     if (needsHorizontalScrollbarLayer) {
1012         if (!m_layerForHorizontalScrollbar) {
1013             m_layerForHorizontalScrollbar = createGraphicsLayer("horizontal scrollbar");
1014             horizontalScrollbarLayerChanged = true;
1015         }
1016     } else if (m_layerForHorizontalScrollbar) {
1017         m_layerForHorizontalScrollbar.clear();
1018         horizontalScrollbarLayerChanged = true;
1019     }
1020
1021     bool verticalScrollbarLayerChanged = false;
1022     if (needsVerticalScrollbarLayer) {
1023         if (!m_layerForVerticalScrollbar) {
1024             m_layerForVerticalScrollbar = createGraphicsLayer("vertical scrollbar");
1025             verticalScrollbarLayerChanged = true;
1026         }
1027     } else if (m_layerForVerticalScrollbar) {
1028         m_layerForVerticalScrollbar.clear();
1029         verticalScrollbarLayerChanged = true;
1030     }
1031
1032     bool scrollCornerLayerChanged = false;
1033     if (needsScrollCornerLayer) {
1034         if (!m_layerForScrollCorner) {
1035             m_layerForScrollCorner = createGraphicsLayer("scroll corner");
1036             scrollCornerLayerChanged = true;
1037         }
1038     } else if (m_layerForScrollCorner) {
1039         m_layerForScrollCorner.clear();
1040         scrollCornerLayerChanged = true;
1041     }
1042
1043     if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer)) {
1044         if (horizontalScrollbarLayerChanged)
1045             scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_owningLayer, HorizontalScrollbar);
1046         if (verticalScrollbarLayerChanged)
1047             scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_owningLayer, VerticalScrollbar);
1048     }
1049
1050     return horizontalScrollbarLayerChanged || verticalScrollbarLayerChanged || scrollCornerLayerChanged;
1051 }
1052
1053 void RenderLayerBacking::positionOverflowControlsLayers(const IntSize& offsetFromRoot)
1054 {
1055     IntSize offsetFromRenderer = m_graphicsLayer->offsetFromRenderer();
1056     if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
1057         Scrollbar* hBar = m_owningLayer->horizontalScrollbar();
1058         if (hBar) {
1059             layer->setPosition(hBar->frameRect().location() - offsetFromRoot - offsetFromRenderer);
1060             layer->setSize(hBar->frameRect().size());
1061             if (layer->hasContentsLayer())
1062                 layer->setContentsRect(IntRect(IntPoint(), hBar->frameRect().size()));
1063         }
1064         layer->setDrawsContent(hBar && !layer->hasContentsLayer());
1065     }
1066     
1067     if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
1068         Scrollbar* vBar = m_owningLayer->verticalScrollbar();
1069         if (vBar) {
1070             layer->setPosition(vBar->frameRect().location() - offsetFromRoot - offsetFromRenderer);
1071             layer->setSize(vBar->frameRect().size());
1072             if (layer->hasContentsLayer())
1073                 layer->setContentsRect(IntRect(IntPoint(), vBar->frameRect().size()));
1074         }
1075         layer->setDrawsContent(vBar && !layer->hasContentsLayer());
1076     }
1077
1078     if (GraphicsLayer* layer = layerForScrollCorner()) {
1079         const LayoutRect& scrollCornerAndResizer = m_owningLayer->scrollCornerAndResizerRect();
1080         layer->setPosition(scrollCornerAndResizer.location() - offsetFromRenderer);
1081         layer->setSize(scrollCornerAndResizer.size());
1082         layer->setDrawsContent(!scrollCornerAndResizer.isEmpty());
1083     }
1084 }
1085
1086 bool RenderLayerBacking::hasUnpositionedOverflowControlsLayers() const
1087 {
1088     if (GraphicsLayer* layer = layerForHorizontalScrollbar())
1089         if (!layer->drawsContent())
1090             return true;
1091
1092     if (GraphicsLayer* layer = layerForVerticalScrollbar())
1093         if (!layer->drawsContent())
1094             return true;
1095
1096     if (GraphicsLayer* layer = layerForScrollCorner())
1097         if (!layer->drawsContent())
1098             return true;
1099
1100     return false;
1101 }
1102
1103 bool RenderLayerBacking::updateForegroundLayer(bool needsForegroundLayer)
1104 {
1105     bool layerChanged = false;
1106     if (needsForegroundLayer) {
1107         if (!m_foregroundLayer) {
1108             String layerName;
1109 #ifndef NDEBUG
1110             layerName = m_owningLayer->name() + " (foreground)";
1111 #endif
1112             m_foregroundLayer = createGraphicsLayer(layerName);
1113             m_foregroundLayer->setDrawsContent(true);
1114             m_foregroundLayer->setPaintingPhase(GraphicsLayerPaintForeground);
1115             layerChanged = true;
1116         }
1117     } else if (m_foregroundLayer) {
1118         m_foregroundLayer->removeFromParent();
1119         m_foregroundLayer = nullptr;
1120         layerChanged = true;
1121     }
1122
1123     if (layerChanged)
1124         m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
1125
1126     return layerChanged;
1127 }
1128
1129 bool RenderLayerBacking::updateBackgroundLayer(bool needsBackgroundLayer)
1130 {
1131     bool layerChanged = false;
1132     if (needsBackgroundLayer) {
1133         if (!m_backgroundLayer) {
1134             String layerName;
1135 #ifndef NDEBUG
1136             layerName = m_owningLayer->name() + " (background)";
1137 #endif
1138             m_backgroundLayer = createGraphicsLayer(layerName);
1139             m_backgroundLayer->setDrawsContent(true);
1140             m_backgroundLayer->setAnchorPoint(FloatPoint3D());
1141             m_backgroundLayer->setPaintingPhase(GraphicsLayerPaintBackground);
1142             layerChanged = true;
1143         }
1144         
1145         if (!m_contentsContainmentLayer) {
1146             String layerName;
1147 #ifndef NDEBUG
1148             layerName = m_owningLayer->name() + " (contents containment)";
1149 #endif
1150             m_contentsContainmentLayer = createGraphicsLayer(layerName);
1151             m_contentsContainmentLayer->setAppliesPageScale(true);
1152             m_graphicsLayer->setAppliesPageScale(false);
1153             layerChanged = true;
1154         }
1155     } else {
1156         if (m_backgroundLayer) {
1157             m_backgroundLayer->removeFromParent();
1158             m_backgroundLayer = nullptr;
1159             layerChanged = true;
1160         }
1161         if (m_contentsContainmentLayer) {
1162             m_contentsContainmentLayer->removeFromParent();
1163             m_contentsContainmentLayer = nullptr;
1164             layerChanged = true;
1165             m_graphicsLayer->setAppliesPageScale(true);
1166         }
1167     }
1168     
1169     if (layerChanged) {
1170         // This assumes that the background layer is only used for fixed backgrounds, which is currently a correct assumption.
1171         if (renderer()->view())
1172             compositor()->fixedRootBackgroundLayerChanged();
1173     }
1174     
1175     return layerChanged;
1176 }
1177
1178 bool RenderLayerBacking::updateMaskLayer(bool needsMaskLayer)
1179 {
1180     bool layerChanged = false;
1181     if (needsMaskLayer) {
1182         if (!m_maskLayer) {
1183             m_maskLayer = createGraphicsLayer("Mask");
1184             m_maskLayer->setDrawsContent(true);
1185             m_maskLayer->setPaintingPhase(GraphicsLayerPaintMask);
1186             layerChanged = true;
1187         }
1188     } else if (m_maskLayer) {
1189         m_maskLayer = nullptr;
1190         layerChanged = true;
1191     }
1192
1193     if (layerChanged)
1194         m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
1195
1196     return layerChanged;
1197 }
1198
1199 bool RenderLayerBacking::updateScrollingLayers(bool needsScrollingLayers)
1200 {
1201     ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
1202
1203     bool layerChanged = false;
1204     if (needsScrollingLayers) {
1205         if (!m_scrollingLayer) {
1206             // Outer layer which corresponds with the scroll view.
1207             m_scrollingLayer = createGraphicsLayer("Scrolling container");
1208             m_scrollingLayer->setDrawsContent(false);
1209             m_scrollingLayer->setMasksToBounds(true);
1210
1211             // Inner layer which renders the content that scrolls.
1212             m_scrollingContentsLayer = createGraphicsLayer("Scrolled Contents");
1213             m_scrollingContentsLayer->setDrawsContent(true);
1214             m_scrollingContentsLayer->setPaintingPhase(GraphicsLayerPaintForeground | GraphicsLayerPaintOverflowContents);
1215             m_scrollingLayer->addChild(m_scrollingContentsLayer.get());
1216
1217             layerChanged = true;
1218             if (scrollingCoordinator)
1219                 scrollingCoordinator->scrollableAreaScrollLayerDidChange(m_owningLayer);
1220         }
1221     } else if (m_scrollingLayer) {
1222         m_scrollingLayer = nullptr;
1223         m_scrollingContentsLayer = nullptr;
1224         layerChanged = true;
1225         if (scrollingCoordinator)
1226             scrollingCoordinator->scrollableAreaScrollLayerDidChange(m_owningLayer);
1227     }
1228
1229     if (layerChanged) {
1230         updateInternalHierarchy();
1231         m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
1232         m_graphicsLayer->setNeedsDisplay();
1233         if (renderer()->view())
1234             compositor()->scrollingLayerDidChange(m_owningLayer);
1235     }
1236
1237     return layerChanged;
1238 }
1239
1240 void RenderLayerBacking::attachToScrollingCoordinatorWithParent(RenderLayerBacking* parent)
1241 {
1242     ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
1243     if (!scrollingCoordinator)
1244         return;
1245
1246     // FIXME: When we support overflow areas, we will have to refine this for overflow areas that are also
1247     // positon:fixed.
1248     ScrollingNodeType nodeType;
1249     if (renderer()->style()->position() == FixedPosition)
1250         nodeType = FixedNode;
1251     else if (renderer()->style()->position() == StickyPosition)
1252         nodeType = StickyNode;
1253     else
1254         nodeType = ScrollingNode;
1255
1256     ScrollingNodeID parentID = parent ? parent->scrollLayerID() : 0;
1257     m_scrollLayerID = scrollingCoordinator->attachToStateTree(nodeType, m_scrollLayerID ? m_scrollLayerID : scrollingCoordinator->uniqueScrollLayerID(), parentID);
1258 }
1259
1260 void RenderLayerBacking::detachFromScrollingCoordinator()
1261 {
1262     // If m_scrollLayerID is 0, then this backing is not attached to the ScrollingCoordinator.
1263     if (!m_scrollLayerID)
1264         return;
1265
1266     ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
1267     if (!scrollingCoordinator)
1268         return;
1269
1270     scrollingCoordinator->detachFromStateTree(m_scrollLayerID);
1271     m_scrollLayerID = 0;
1272 }
1273
1274 GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() const
1275 {
1276     unsigned phase = 0;
1277     if (!m_backgroundLayer)
1278         phase |= GraphicsLayerPaintBackground;
1279     if (!m_foregroundLayer)
1280         phase |= GraphicsLayerPaintForeground;
1281     if (!m_maskLayer)
1282         phase |= GraphicsLayerPaintMask;
1283
1284     if (m_scrollingContentsLayer)
1285         phase &= ~GraphicsLayerPaintForeground;
1286
1287     return static_cast<GraphicsLayerPaintingPhase>(phase);
1288 }
1289
1290 float RenderLayerBacking::compositingOpacity(float rendererOpacity) const
1291 {
1292     float finalOpacity = rendererOpacity;
1293     
1294     for (RenderLayer* curr = m_owningLayer->parent(); curr; curr = curr->parent()) {
1295         // We only care about parents that are stacking contexts.
1296         // Recall that opacity creates stacking context.
1297         if (!curr->isStackingContainer())
1298             continue;
1299         
1300         // If we found a compositing layer, we want to compute opacity
1301         // relative to it. So we can break here.
1302         if (curr->isComposited())
1303             break;
1304         
1305         finalOpacity *= curr->renderer()->opacity();
1306     }
1307
1308     return finalOpacity;
1309 }
1310
1311 static bool hasBoxDecorations(const RenderStyle* style)
1312 {
1313     return style->hasBorder() || style->hasBorderRadius() || style->hasOutline() || style->hasAppearance() || style->boxShadow() || style->hasFilter();
1314 }
1315
1316 static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle* style)
1317 {
1318     return hasBoxDecorations(style) || style->hasBackgroundImage();
1319 }
1320
1321 Color RenderLayerBacking::rendererBackgroundColor() const
1322 {
1323     RenderObject* backgroundRenderer = renderer();
1324     if (backgroundRenderer->isRoot())
1325         backgroundRenderer = backgroundRenderer->rendererForRootBackground();
1326
1327     return backgroundRenderer->style()->visitedDependentColor(CSSPropertyBackgroundColor);
1328 }
1329
1330 void RenderLayerBacking::updateBackgroundColor(bool isSimpleContainer)
1331 {
1332     Color backgroundColor;
1333     if (isSimpleContainer)
1334         backgroundColor = rendererBackgroundColor();
1335
1336     // An unset (invalid) color will remove the solid color.
1337     m_graphicsLayer->setContentsToSolidColor(backgroundColor);
1338 }
1339
1340 void RenderLayerBacking::updateRootLayerConfiguration()
1341 {
1342     if (!m_usingTiledCacheLayer)
1343         return;
1344
1345     Color backgroundColor;
1346     bool viewIsTransparent = compositor()->viewHasTransparentBackground(&backgroundColor);
1347
1348     if (m_backgroundLayerPaintsFixedRootBackground && m_backgroundLayer) {
1349         m_backgroundLayer->setBackgroundColor(backgroundColor);
1350         m_backgroundLayer->setContentsOpaque(!viewIsTransparent);
1351
1352         m_graphicsLayer->setBackgroundColor(Color());
1353         m_graphicsLayer->setContentsOpaque(false);
1354     } else {
1355         m_graphicsLayer->setBackgroundColor(backgroundColor);
1356         m_graphicsLayer->setContentsOpaque(!viewIsTransparent);
1357     }
1358 }
1359
1360 static bool supportsDirectBoxDecorationsComposition(const RenderObject* renderer)
1361 {
1362     if (!GraphicsLayer::supportsBackgroundColorContent())
1363         return false;
1364
1365     if (renderer->hasClip())
1366         return false;
1367
1368     if (hasBoxDecorationsOrBackgroundImage(renderer->style()))
1369         return false;
1370
1371     // FIXME: we should be able to allow backgroundComposite; However since this is not a common use case it has been deferred for now.
1372     if (renderer->style()->backgroundComposite() != CompositeSourceOver)
1373         return false;
1374
1375     if (renderer->style()->backgroundClip() == TextFillBox)
1376         return false;
1377
1378     return true;
1379 }
1380
1381 bool RenderLayerBacking::paintsBoxDecorations() const
1382 {
1383     if (!m_owningLayer->hasVisibleBoxDecorations())
1384         return false;
1385
1386     if (!supportsDirectBoxDecorationsComposition(renderer()))
1387         return true;
1388
1389     return false;
1390 }
1391
1392 bool RenderLayerBacking::paintsChildren() const
1393 {
1394     if (m_owningLayer->hasVisibleContent() && m_owningLayer->hasNonEmptyChildRenderers())
1395         return true;
1396         
1397     if (hasVisibleNonCompositingDescendantLayers())
1398         return true;
1399
1400     return false;
1401 }
1402
1403 static bool isCompositedPlugin(RenderObject* renderer)
1404 {
1405     return renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing();
1406 }
1407
1408 // A "simple container layer" is a RenderLayer which has no visible content to render.
1409 // It may have no children, or all its children may be themselves composited.
1410 // This is a useful optimization, because it allows us to avoid allocating backing store.
1411 bool RenderLayerBacking::isSimpleContainerCompositingLayer() const
1412 {
1413     RenderObject* renderObject = renderer();
1414     if (renderObject->hasMask()) // masks require special treatment
1415         return false;
1416
1417     if (renderObject->isReplaced() && !isCompositedPlugin(renderObject))
1418         return false;
1419     
1420     if (paintsBoxDecorations() || paintsChildren())
1421         return false;
1422
1423     if (renderObject->isRenderRegion())
1424         return false;
1425
1426     if (renderObject->node() && renderObject->node()->isDocumentNode()) {
1427         // Look to see if the root object has a non-simple background
1428         RenderObject* rootObject = renderObject->document()->documentElement() ? renderObject->document()->documentElement()->renderer() : 0;
1429         if (!rootObject)
1430             return false;
1431         
1432         RenderStyle* style = rootObject->style();
1433         
1434         // Reject anything that has a border, a border-radius or outline,
1435         // or is not a simple background (no background, or solid color).
1436         if (hasBoxDecorationsOrBackgroundImage(style))
1437             return false;
1438         
1439         // Now look at the body's renderer.
1440         HTMLElement* body = renderObject->document()->body();
1441         RenderObject* bodyObject = (body && body->hasLocalName(bodyTag)) ? body->renderer() : 0;
1442         if (!bodyObject)
1443             return false;
1444         
1445         style = bodyObject->style();
1446         
1447         if (hasBoxDecorationsOrBackgroundImage(style))
1448             return false;
1449     }
1450
1451     return true;
1452 }
1453
1454 static bool hasVisibleNonCompositingDescendant(RenderLayer* parent)
1455 {
1456     // FIXME: We shouldn't be called with a stale z-order lists. See bug 85512.
1457     parent->updateLayerListsIfNeeded();
1458
1459 #if !ASSERT_DISABLED
1460     LayerListMutationDetector mutationChecker(parent);
1461 #endif
1462
1463     if (Vector<RenderLayer*>* normalFlowList = parent->normalFlowList()) {
1464         size_t listSize = normalFlowList->size();
1465         for (size_t i = 0; i < listSize; ++i) {
1466             RenderLayer* curLayer = normalFlowList->at(i);
1467             if (!curLayer->isComposited()
1468                 && (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(curLayer)))
1469                 return true;
1470         }
1471     }
1472
1473     if (parent->isStackingContainer()) {
1474         if (!parent->hasVisibleDescendant())
1475             return false;
1476
1477         // Use the m_hasCompositingDescendant bit to optimize?
1478         if (Vector<RenderLayer*>* negZOrderList = parent->negZOrderList()) {
1479             size_t listSize = negZOrderList->size();
1480             for (size_t i = 0; i < listSize; ++i) {
1481                 RenderLayer* curLayer = negZOrderList->at(i);
1482                 if (!curLayer->isComposited()
1483                     && (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(curLayer)))
1484                     return true;
1485             }
1486         }
1487
1488         if (Vector<RenderLayer*>* posZOrderList = parent->posZOrderList()) {
1489             size_t listSize = posZOrderList->size();
1490             for (size_t i = 0; i < listSize; ++i) {
1491                 RenderLayer* curLayer = posZOrderList->at(i);
1492                 if (!curLayer->isComposited()
1493                     && (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(curLayer)))
1494                     return true;
1495             }
1496         }
1497     }
1498
1499     return false;
1500 }
1501
1502 // Conservative test for having no rendered children.
1503 bool RenderLayerBacking::hasVisibleNonCompositingDescendantLayers() const
1504 {
1505     return hasVisibleNonCompositingDescendant(m_owningLayer);
1506 }
1507
1508 bool RenderLayerBacking::containsPaintedContent() const
1509 {
1510     if (isSimpleContainerCompositingLayer() || paintsIntoWindow() || paintsIntoCompositedAncestor() || m_artificiallyInflatedBounds || m_owningLayer->isReflection())
1511         return false;
1512
1513     if (isDirectlyCompositedImage())
1514         return false;
1515
1516     // FIXME: we could optimize cases where the image, video or canvas is known to fill the border box entirely,
1517     // and set background color on the layer in that case, instead of allocating backing store and painting.
1518 #if ENABLE(VIDEO)
1519     if (renderer()->isVideo() && toRenderVideo(renderer())->shouldDisplayVideo())
1520         return m_owningLayer->hasBoxDecorationsOrBackground();
1521 #endif
1522 #if PLATFORM(MAC) && USE(CA) && (PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)
1523 #elif ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
1524     if (isAcceleratedCanvas(renderer()))
1525         return m_owningLayer->hasBoxDecorationsOrBackground();
1526 #endif
1527
1528     return true;
1529 }
1530
1531 // An image can be directly compositing if it's the sole content of the layer, and has no box decorations
1532 // that require painting. Direct compositing saves backing store.
1533 bool RenderLayerBacking::isDirectlyCompositedImage() const
1534 {
1535     RenderObject* renderObject = renderer();
1536     
1537     if (!renderObject->isImage() || m_owningLayer->hasBoxDecorationsOrBackground() || renderObject->hasClip())
1538         return false;
1539
1540     RenderImage* imageRenderer = toRenderImage(renderObject);
1541     if (CachedImage* cachedImage = imageRenderer->cachedImage()) {
1542         if (!cachedImage->hasImage())
1543             return false;
1544
1545         Image* image = cachedImage->imageForRenderer(imageRenderer);
1546         if (!image->isBitmapImage())
1547             return false;
1548
1549         return m_graphicsLayer->shouldDirectlyCompositeImage(image);
1550     }
1551
1552     return false;
1553 }
1554
1555 void RenderLayerBacking::contentChanged(ContentChangeType changeType)
1556 {
1557     if ((changeType == ImageChanged) && isDirectlyCompositedImage()) {
1558         updateImageContents();
1559         return;
1560     }
1561
1562     if ((changeType == MaskImageChanged) && m_maskLayer) {
1563         // The composited layer bounds relies on box->maskClipRect(), which changes
1564         // when the mask image becomes available.
1565         updateAfterLayout(CompositingChildrenOnly | IsUpdateRoot);
1566     }
1567
1568 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
1569     if ((changeType == CanvasChanged || changeType == CanvasPixelsChanged) && isAcceleratedCanvas(renderer())) {
1570         m_graphicsLayer->setContentsNeedsDisplay();
1571         return;
1572     }
1573 #endif
1574 }
1575
1576 void RenderLayerBacking::updateImageContents()
1577 {
1578     ASSERT(renderer()->isImage());
1579     RenderImage* imageRenderer = toRenderImage(renderer());
1580
1581     CachedImage* cachedImage = imageRenderer->cachedImage();
1582     if (!cachedImage)
1583         return;
1584
1585     Image* image = cachedImage->imageForRenderer(imageRenderer);
1586     if (!image)
1587         return;
1588
1589     // We have to wait until the image is fully loaded before setting it on the layer.
1590     if (!cachedImage->isLoaded())
1591         return;
1592
1593     // This is a no-op if the layer doesn't have an inner layer for the image.
1594     m_graphicsLayer->setContentsToImage(image);
1595     bool isSimpleContainer = false;
1596     updateDrawsContent(isSimpleContainer);
1597     
1598     // Image animation is "lazy", in that it automatically stops unless someone is drawing
1599     // the image. So we have to kick the animation each time; this has the downside that the
1600     // image will keep animating, even if its layer is not visible.
1601     image->startAnimation();
1602 }
1603
1604 FloatPoint3D RenderLayerBacking::computeTransformOrigin(const IntRect& borderBox) const
1605 {
1606     RenderStyle* style = renderer()->style();
1607
1608     FloatPoint3D origin;
1609     origin.setX(floatValueForLength(style->transformOriginX(), borderBox.width()));
1610     origin.setY(floatValueForLength(style->transformOriginY(), borderBox.height()));
1611     origin.setZ(style->transformOriginZ());
1612
1613     return origin;
1614 }
1615
1616 FloatPoint RenderLayerBacking::computePerspectiveOrigin(const IntRect& borderBox) const
1617 {
1618     RenderStyle* style = renderer()->style();
1619
1620     float boxWidth = borderBox.width();
1621     float boxHeight = borderBox.height();
1622
1623     FloatPoint origin;
1624     origin.setX(floatValueForLength(style->perspectiveOriginX(), boxWidth));
1625     origin.setY(floatValueForLength(style->perspectiveOriginY(), boxHeight));
1626
1627     return origin;
1628 }
1629
1630 // Return the offset from the top-left of this compositing layer at which the renderer's contents are painted.
1631 IntSize RenderLayerBacking::contentOffsetInCompostingLayer() const
1632 {
1633     return IntSize(-m_compositedBounds.x(), -m_compositedBounds.y());
1634 }
1635
1636 IntRect RenderLayerBacking::contentsBox() const
1637 {
1638     if (!renderer()->isBox())
1639         return IntRect();
1640
1641     IntRect contentsRect;
1642 #if ENABLE(VIDEO)
1643     if (renderer()->isVideo()) {
1644         RenderVideo* videoRenderer = toRenderVideo(renderer());
1645         contentsRect = videoRenderer->videoBox();
1646     } else
1647 #endif
1648         contentsRect = pixelSnappedIntRect(toRenderBox(renderer())->contentBoxRect());
1649
1650     contentsRect.move(contentOffsetInCompostingLayer());
1651     return contentsRect;
1652 }
1653
1654 static LayoutRect backgroundRectForBox(const RenderBox* box)
1655 {
1656     EFillBox clip = box->style()->backgroundClip();
1657     switch (clip) {
1658     case BorderFillBox:
1659         return box->borderBoxRect();
1660     case PaddingFillBox:
1661         return box->paddingBoxRect();
1662     case ContentFillBox:
1663         return box->contentBoxRect();
1664     case TextFillBox:
1665         break;
1666     }
1667
1668     ASSERT_NOT_REACHED();
1669     return LayoutRect();
1670 }
1671
1672 IntRect RenderLayerBacking::backgroundBox() const
1673 {
1674     if (!renderer()->isBox())
1675         return IntRect();
1676
1677     IntRect pixelSnappedBackgroundBox = pixelSnappedIntRect(backgroundRectForBox(toRenderBox(renderer())));
1678     pixelSnappedBackgroundBox.move(contentOffsetInCompostingLayer());
1679     return pixelSnappedBackgroundBox;
1680 }
1681
1682 GraphicsLayer* RenderLayerBacking::parentForSublayers() const
1683 {
1684     if (m_scrollingContentsLayer)
1685         return m_scrollingContentsLayer.get();
1686
1687     return m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsLayer.get();
1688 }
1689
1690 GraphicsLayer* RenderLayerBacking::childForSuperlayers() const
1691 {
1692     if (m_ancestorClippingLayer)
1693         return m_ancestorClippingLayer.get();
1694
1695     if (m_contentsContainmentLayer)
1696         return m_contentsContainmentLayer.get();
1697     
1698     return m_graphicsLayer.get();
1699 }
1700
1701 bool RenderLayerBacking::paintsIntoWindow() const
1702 {
1703     if (m_usingTiledCacheLayer)
1704         return false;
1705
1706     if (m_owningLayer->isRootLayer()) {
1707 #if PLATFORM(BLACKBERRY)
1708         if (compositor()->inForcedCompositingMode())
1709             return false;
1710 #endif
1711
1712         return compositor()->rootLayerAttachment() != RenderLayerCompositor::RootLayerAttachedViaEnclosingFrame;
1713     }
1714     
1715     return false;
1716 }
1717
1718 void RenderLayerBacking::setRequiresOwnBackingStore(bool requiresOwnBacking)
1719 {
1720     if (requiresOwnBacking == m_requiresOwnBackingStore)
1721         return;
1722     
1723     m_requiresOwnBackingStore = requiresOwnBacking;
1724
1725     // This affects the answer to paintsIntoCompositedAncestor(), which in turn affects
1726     // cached clip rects, so when it changes we have to clear clip rects on descendants.
1727     m_owningLayer->clearClipRectsIncludingDescendants(PaintingClipRects);
1728     m_owningLayer->computeRepaintRectsIncludingDescendants();
1729     
1730     compositor()->repaintInCompositedAncestor(m_owningLayer, compositedBounds());
1731 }
1732
1733 #if ENABLE(CSS_COMPOSITING)
1734 void RenderLayerBacking::setBlendMode(BlendMode)
1735 {
1736 }
1737 #endif
1738
1739 void RenderLayerBacking::setContentsNeedDisplay()
1740 {
1741     ASSERT(!paintsIntoCompositedAncestor());
1742     
1743     if (m_graphicsLayer && m_graphicsLayer->drawsContent())
1744         m_graphicsLayer->setNeedsDisplay();
1745     
1746     if (m_foregroundLayer && m_foregroundLayer->drawsContent())
1747         m_foregroundLayer->setNeedsDisplay();
1748
1749     if (m_backgroundLayer && m_backgroundLayer->drawsContent())
1750         m_backgroundLayer->setNeedsDisplay();
1751
1752     if (m_maskLayer && m_maskLayer->drawsContent())
1753         m_maskLayer->setNeedsDisplay();
1754
1755     if (m_scrollingContentsLayer && m_scrollingContentsLayer->drawsContent())
1756         m_scrollingContentsLayer->setNeedsDisplay();
1757 }
1758
1759 // r is in the coordinate space of the layer's render object
1760 void RenderLayerBacking::setContentsNeedDisplayInRect(const IntRect& r)
1761 {
1762     ASSERT(!paintsIntoCompositedAncestor());
1763
1764     if (m_graphicsLayer && m_graphicsLayer->drawsContent()) {
1765         IntRect layerDirtyRect = r;
1766         layerDirtyRect.move(-m_graphicsLayer->offsetFromRenderer());
1767         m_graphicsLayer->setNeedsDisplayInRect(layerDirtyRect);
1768     }
1769
1770     if (m_foregroundLayer && m_foregroundLayer->drawsContent()) {
1771         IntRect layerDirtyRect = r;
1772         layerDirtyRect.move(-m_foregroundLayer->offsetFromRenderer());
1773         m_foregroundLayer->setNeedsDisplayInRect(layerDirtyRect);
1774     }
1775
1776     // FIXME: need to split out repaints for the background.
1777     if (m_backgroundLayer && m_backgroundLayer->drawsContent()) {
1778         IntRect layerDirtyRect = r;
1779         layerDirtyRect.move(-m_backgroundLayer->offsetFromRenderer());
1780         m_backgroundLayer->setNeedsDisplayInRect(layerDirtyRect);
1781     }
1782
1783     if (m_maskLayer && m_maskLayer->drawsContent()) {
1784         IntRect layerDirtyRect = r;
1785         layerDirtyRect.move(-m_maskLayer->offsetFromRenderer());
1786         m_maskLayer->setNeedsDisplayInRect(layerDirtyRect);
1787     }
1788
1789     if (m_scrollingContentsLayer && m_scrollingContentsLayer->drawsContent()) {
1790         IntRect layerDirtyRect = r;
1791         layerDirtyRect.move(-m_scrollingContentsLayer->offsetFromRenderer());
1792         m_scrollingContentsLayer->setNeedsDisplayInRect(layerDirtyRect);
1793     }
1794 }
1795
1796 void RenderLayerBacking::paintIntoLayer(const GraphicsLayer* graphicsLayer, GraphicsContext* context,
1797                     const IntRect& paintDirtyRect, // In the coords of rootLayer.
1798                     PaintBehavior paintBehavior, GraphicsLayerPaintingPhase paintingPhase)
1799 {
1800     if (paintsIntoWindow() || paintsIntoCompositedAncestor()) {
1801         ASSERT_NOT_REACHED();
1802         return;
1803     }
1804
1805     FontCachePurgePreventer fontCachePurgePreventer;
1806     
1807     RenderLayer::PaintLayerFlags paintFlags = 0;
1808     if (paintingPhase & GraphicsLayerPaintBackground)
1809         paintFlags |= RenderLayer::PaintLayerPaintingCompositingBackgroundPhase;
1810     if (paintingPhase & GraphicsLayerPaintForeground)
1811         paintFlags |= RenderLayer::PaintLayerPaintingCompositingForegroundPhase;
1812     if (paintingPhase & GraphicsLayerPaintMask)
1813         paintFlags |= RenderLayer::PaintLayerPaintingCompositingMaskPhase;
1814     if (paintingPhase & GraphicsLayerPaintOverflowContents)
1815         paintFlags |= RenderLayer::PaintLayerPaintingOverflowContents;
1816
1817     if (graphicsLayer == m_backgroundLayer)
1818         paintFlags |= (RenderLayer::PaintLayerPaintingRootBackgroundOnly | RenderLayer::PaintLayerPaintingCompositingForegroundPhase); // Need PaintLayerPaintingCompositingForegroundPhase to walk child layers.
1819     else if (m_backgroundLayer)
1820         paintFlags |= RenderLayer::PaintLayerPaintingSkipRootBackground;
1821     
1822     // FIXME: GraphicsLayers need a way to split for RenderRegions.
1823     RenderLayer::LayerPaintingInfo paintingInfo(m_owningLayer, paintDirtyRect, paintBehavior, LayoutSize());
1824     m_owningLayer->paintLayerContents(context, paintingInfo, paintFlags);
1825
1826     if (m_owningLayer->containsDirtyOverlayScrollbars())
1827         m_owningLayer->paintLayerContents(context, paintingInfo, paintFlags | RenderLayer::PaintLayerPaintingOverlayScrollbars);
1828
1829     ASSERT(!m_owningLayer->m_usedTransparency);
1830 }
1831
1832 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
1833 {
1834     if (!scrollbar)
1835         return;
1836
1837     context.save();
1838     const IntRect& scrollbarRect = scrollbar->frameRect();
1839     context.translate(-scrollbarRect.x(), -scrollbarRect.y());
1840     IntRect transformedClip = clip;
1841     transformedClip.moveBy(scrollbarRect.location());
1842     scrollbar->paint(&context, transformedClip);
1843     context.restore();
1844 }
1845
1846 // Up-call from compositing layer drawing callback.
1847 void RenderLayerBacking::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase paintingPhase, const IntRect& clip)
1848 {
1849 #ifndef NDEBUG
1850     if (Page* page = renderer()->frame()->page())
1851         page->setIsPainting(true);
1852 #endif
1853
1854     if (graphicsLayer == m_graphicsLayer.get()
1855         || graphicsLayer == m_foregroundLayer.get()
1856         || graphicsLayer == m_backgroundLayer.get()
1857         || graphicsLayer == m_maskLayer.get()
1858         || graphicsLayer == m_scrollingContentsLayer.get()) {
1859         InspectorInstrumentationCookie cookie = InspectorInstrumentation::willPaint(m_owningLayer->renderer()->frame());
1860
1861         // The dirtyRect is in the coords of the painting root.
1862         IntRect dirtyRect = clip;
1863         if (!(paintingPhase & GraphicsLayerPaintOverflowContents))
1864             dirtyRect.intersect(compositedBounds());
1865
1866         // We have to use the same root as for hit testing, because both methods can compute and cache clipRects.
1867         paintIntoLayer(graphicsLayer, &context, dirtyRect, PaintBehaviorNormal, paintingPhase);
1868
1869         if (m_usingTiledCacheLayer)
1870             m_owningLayer->renderer()->frame()->view()->setLastPaintTime(currentTime());
1871
1872         InspectorInstrumentation::didPaint(cookie, &context, clip);
1873     } else if (graphicsLayer == layerForHorizontalScrollbar()) {
1874         paintScrollbar(m_owningLayer->horizontalScrollbar(), context, clip);
1875     } else if (graphicsLayer == layerForVerticalScrollbar()) {
1876         paintScrollbar(m_owningLayer->verticalScrollbar(), context, clip);
1877     } else if (graphicsLayer == layerForScrollCorner()) {
1878         const IntRect& scrollCornerAndResizer = m_owningLayer->scrollCornerAndResizerRect();
1879         context.save();
1880         context.translate(-scrollCornerAndResizer.x(), -scrollCornerAndResizer.y());
1881         IntRect transformedClip = clip;
1882         transformedClip.moveBy(scrollCornerAndResizer.location());
1883         m_owningLayer->paintScrollCorner(&context, IntPoint(), transformedClip);
1884         m_owningLayer->paintResizer(&context, IntPoint(), transformedClip);
1885         context.restore();
1886     }
1887 #ifndef NDEBUG
1888     if (Page* page = renderer()->frame()->page())
1889         page->setIsPainting(false);
1890 #endif
1891 }
1892
1893 float RenderLayerBacking::pageScaleFactor() const
1894 {
1895     return compositor()->pageScaleFactor();
1896 }
1897
1898 float RenderLayerBacking::deviceScaleFactor() const
1899 {
1900     return compositor()->deviceScaleFactor();
1901 }
1902
1903 void RenderLayerBacking::didCommitChangesForLayer(const GraphicsLayer* layer) const
1904 {
1905     compositor()->didFlushChangesForLayer(m_owningLayer, layer);
1906 }
1907
1908 bool RenderLayerBacking::getCurrentTransform(const GraphicsLayer* graphicsLayer, TransformationMatrix& transform) const
1909 {
1910     GraphicsLayer* transformedLayer = m_contentsContainmentLayer.get() ? m_contentsContainmentLayer.get() : m_graphicsLayer.get();
1911     if (graphicsLayer != transformedLayer)
1912         return false;
1913
1914     if (m_owningLayer->hasTransform()) {
1915         transform = m_owningLayer->currentTransform(RenderStyle::ExcludeTransformOrigin);
1916         return true;
1917     }
1918     return false;
1919 }
1920
1921 bool RenderLayerBacking::isTrackingRepaints() const
1922 {
1923     GraphicsLayerClient* client = compositor();
1924     return client ? client->isTrackingRepaints() : false;
1925 }
1926
1927 #ifndef NDEBUG
1928 void RenderLayerBacking::verifyNotPainting()
1929 {
1930     ASSERT(!renderer()->frame()->page() || !renderer()->frame()->page()->isPainting());
1931 }
1932 #endif
1933
1934 bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim, const KeyframeList& keyframes)
1935 {
1936     bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity);
1937     bool hasTransform = renderer()->isBox() && keyframes.containsProperty(CSSPropertyWebkitTransform);
1938 #if ENABLE(CSS_FILTERS)
1939     bool hasFilter = keyframes.containsProperty(CSSPropertyWebkitFilter);
1940 #else
1941     bool hasFilter = false;
1942 #endif
1943
1944     if (!hasOpacity && !hasTransform && !hasFilter)
1945         return false;
1946     
1947     KeyframeValueList transformVector(AnimatedPropertyWebkitTransform);
1948     KeyframeValueList opacityVector(AnimatedPropertyOpacity);
1949 #if ENABLE(CSS_FILTERS)
1950     KeyframeValueList filterVector(AnimatedPropertyWebkitFilter);
1951 #endif
1952
1953     size_t numKeyframes = keyframes.size();
1954     for (size_t i = 0; i < numKeyframes; ++i) {
1955         const KeyframeValue& currentKeyframe = keyframes[i];
1956         const RenderStyle* keyframeStyle = currentKeyframe.style();
1957         float key = currentKeyframe.key();
1958
1959         if (!keyframeStyle)
1960             continue;
1961             
1962         // Get timing function.
1963         RefPtr<TimingFunction> tf = keyframeStyle->hasAnimations() ? (*keyframeStyle->animations()).animation(0)->timingFunction() : 0;
1964         
1965         bool isFirstOrLastKeyframe = key == 0 || key == 1;
1966         if ((hasTransform && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitTransform))
1967             transformVector.insert(new TransformAnimationValue(key, &(keyframeStyle->transform()), tf));
1968         
1969         if ((hasOpacity && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyOpacity))
1970             opacityVector.insert(new FloatAnimationValue(key, keyframeStyle->opacity(), tf));
1971
1972 #if ENABLE(CSS_FILTERS)
1973         if ((hasFilter && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitFilter))
1974             filterVector.insert(new FilterAnimationValue(key, &(keyframeStyle->filter()), tf));
1975 #endif
1976     }
1977
1978     bool didAnimateTransform = false;
1979     bool didAnimateOpacity = false;
1980 #if ENABLE(CSS_FILTERS)
1981     bool didAnimateFilter = false;
1982 #endif
1983     
1984     if (hasTransform && m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->pixelSnappedBorderBoxRect().size(), anim, keyframes.animationName(), timeOffset))
1985         didAnimateTransform = true;
1986
1987     if (hasOpacity && m_graphicsLayer->addAnimation(opacityVector, IntSize(), anim, keyframes.animationName(), timeOffset))
1988         didAnimateOpacity = true;
1989
1990 #if ENABLE(CSS_FILTERS)
1991     if (hasFilter && m_graphicsLayer->addAnimation(filterVector, IntSize(), anim, keyframes.animationName(), timeOffset))
1992         didAnimateFilter = true;
1993 #endif
1994
1995 #if ENABLE(CSS_FILTERS)
1996     return didAnimateTransform || didAnimateOpacity || didAnimateFilter;
1997 #else
1998     return didAnimateTransform || didAnimateOpacity;
1999 #endif
2000 }
2001
2002 void RenderLayerBacking::animationPaused(double timeOffset, const String& animationName)
2003 {
2004     m_graphicsLayer->pauseAnimation(animationName, timeOffset);
2005 }
2006
2007 void RenderLayerBacking::animationFinished(const String& animationName)
2008 {
2009     m_graphicsLayer->removeAnimation(animationName);
2010 }
2011
2012 bool RenderLayerBacking::startTransition(double timeOffset, CSSPropertyID property, const RenderStyle* fromStyle, const RenderStyle* toStyle)
2013 {
2014     bool didAnimateOpacity = false;
2015     bool didAnimateTransform = false;
2016 #if ENABLE(CSS_FILTERS)
2017     bool didAnimateFilter = false;
2018 #endif
2019
2020     ASSERT(property != CSSPropertyInvalid);
2021
2022     if (property == CSSPropertyOpacity) {
2023         const Animation* opacityAnim = toStyle->transitionForProperty(CSSPropertyOpacity);
2024         if (opacityAnim && !opacityAnim->isEmptyOrZeroDuration()) {
2025             KeyframeValueList opacityVector(AnimatedPropertyOpacity);
2026             opacityVector.insert(new FloatAnimationValue(0, compositingOpacity(fromStyle->opacity())));
2027             opacityVector.insert(new FloatAnimationValue(1, compositingOpacity(toStyle->opacity())));
2028             // The boxSize param is only used for transform animations (which can only run on RenderBoxes), so we pass an empty size here.
2029             if (m_graphicsLayer->addAnimation(opacityVector, IntSize(), opacityAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyOpacity), timeOffset)) {
2030                 // To ensure that the correct opacity is visible when the animation ends, also set the final opacity.
2031                 updateOpacity(toStyle);
2032                 didAnimateOpacity = true;
2033             }
2034         }
2035     }
2036
2037     if (property == CSSPropertyWebkitTransform && m_owningLayer->hasTransform()) {
2038         const Animation* transformAnim = toStyle->transitionForProperty(CSSPropertyWebkitTransform);
2039         if (transformAnim && !transformAnim->isEmptyOrZeroDuration()) {
2040             KeyframeValueList transformVector(AnimatedPropertyWebkitTransform);
2041             transformVector.insert(new TransformAnimationValue(0, &fromStyle->transform()));
2042             transformVector.insert(new TransformAnimationValue(1, &toStyle->transform()));
2043             if (m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->pixelSnappedBorderBoxRect().size(), transformAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitTransform), timeOffset)) {
2044                 // To ensure that the correct transform is visible when the animation ends, also set the final transform.
2045                 updateTransform(toStyle);
2046                 didAnimateTransform = true;
2047             }
2048         }
2049     }
2050
2051 #if ENABLE(CSS_FILTERS)
2052     if (property == CSSPropertyWebkitFilter && m_owningLayer->hasFilter()) {
2053         const Animation* filterAnim = toStyle->transitionForProperty(CSSPropertyWebkitFilter);
2054         if (filterAnim && !filterAnim->isEmptyOrZeroDuration()) {
2055             KeyframeValueList filterVector(AnimatedPropertyWebkitFilter);
2056             filterVector.insert(new FilterAnimationValue(0, &fromStyle->filter()));
2057             filterVector.insert(new FilterAnimationValue(1, &toStyle->filter()));
2058             if (m_graphicsLayer->addAnimation(filterVector, IntSize(), filterAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitFilter), timeOffset)) {
2059                 // To ensure that the correct filter is visible when the animation ends, also set the final filter.
2060                 updateFilters(toStyle);
2061                 didAnimateFilter = true;
2062             }
2063         }
2064     }
2065 #endif
2066
2067 #if ENABLE(CSS_FILTERS)
2068     return didAnimateOpacity || didAnimateTransform || didAnimateFilter;
2069 #else
2070     return didAnimateOpacity || didAnimateTransform;
2071 #endif
2072 }
2073
2074 void RenderLayerBacking::transitionPaused(double timeOffset, CSSPropertyID property)
2075 {
2076     AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
2077     if (animatedProperty != AnimatedPropertyInvalid)
2078         m_graphicsLayer->pauseAnimation(GraphicsLayer::animationNameForTransition(animatedProperty), timeOffset);
2079 }
2080
2081 void RenderLayerBacking::transitionFinished(CSSPropertyID property)
2082 {
2083     AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
2084     if (animatedProperty != AnimatedPropertyInvalid)
2085         m_graphicsLayer->removeAnimation(GraphicsLayer::animationNameForTransition(animatedProperty));
2086 }
2087
2088 void RenderLayerBacking::notifyAnimationStarted(const GraphicsLayer*, double time)
2089 {
2090     renderer()->animation()->notifyAnimationStarted(renderer(), time);
2091 }
2092
2093 void RenderLayerBacking::notifyFlushRequired(const GraphicsLayer*)
2094 {
2095     if (!renderer()->documentBeingDestroyed())
2096         compositor()->scheduleLayerFlush();
2097 }
2098
2099 void RenderLayerBacking::notifyFlushBeforeDisplayRefresh(const GraphicsLayer* layer)
2100 {
2101     compositor()->notifyFlushBeforeDisplayRefresh(layer);
2102 }
2103
2104 // This is used for the 'freeze' API, for testing only.
2105 void RenderLayerBacking::suspendAnimations(double time)
2106 {
2107     m_graphicsLayer->suspendAnimations(time);
2108 }
2109
2110 void RenderLayerBacking::resumeAnimations()
2111 {
2112     m_graphicsLayer->resumeAnimations();
2113 }
2114
2115 IntRect RenderLayerBacking::compositedBounds() const
2116 {
2117     return m_compositedBounds;
2118 }
2119
2120 void RenderLayerBacking::setCompositedBounds(const IntRect& bounds)
2121 {
2122     m_compositedBounds = bounds;
2123 }
2124
2125 CSSPropertyID RenderLayerBacking::graphicsLayerToCSSProperty(AnimatedPropertyID property)
2126 {
2127     CSSPropertyID cssProperty = CSSPropertyInvalid;
2128     switch (property) {
2129         case AnimatedPropertyWebkitTransform:
2130             cssProperty = CSSPropertyWebkitTransform;
2131             break;
2132         case AnimatedPropertyOpacity:
2133             cssProperty = CSSPropertyOpacity;
2134             break;
2135         case AnimatedPropertyBackgroundColor:
2136             cssProperty = CSSPropertyBackgroundColor;
2137             break;
2138         case AnimatedPropertyWebkitFilter:
2139 #if ENABLE(CSS_FILTERS)
2140             cssProperty = CSSPropertyWebkitFilter;
2141 #else
2142             ASSERT_NOT_REACHED();
2143 #endif
2144             break;
2145         case AnimatedPropertyInvalid:
2146             ASSERT_NOT_REACHED();
2147     }
2148     return cssProperty;
2149 }
2150
2151 AnimatedPropertyID RenderLayerBacking::cssToGraphicsLayerProperty(CSSPropertyID cssProperty)
2152 {
2153     switch (cssProperty) {
2154         case CSSPropertyWebkitTransform:
2155             return AnimatedPropertyWebkitTransform;
2156         case CSSPropertyOpacity:
2157             return AnimatedPropertyOpacity;
2158         case CSSPropertyBackgroundColor:
2159             return AnimatedPropertyBackgroundColor;
2160 #if ENABLE(CSS_FILTERS)
2161         case CSSPropertyWebkitFilter:
2162             return AnimatedPropertyWebkitFilter;
2163 #endif
2164         default:
2165             // It's fine if we see other css properties here; they are just not accelerated.
2166             break;
2167     }
2168     return AnimatedPropertyInvalid;
2169 }
2170
2171 CompositingLayerType RenderLayerBacking::compositingLayerType() const
2172 {
2173     if (m_graphicsLayer->hasContentsLayer())
2174         return MediaCompositingLayer;
2175
2176     if (m_graphicsLayer->drawsContent())
2177         return m_graphicsLayer->usingTiledLayer() ? TiledCompositingLayer : NormalCompositingLayer;
2178     
2179     return ContainerCompositingLayer;
2180 }
2181
2182 double RenderLayerBacking::backingStoreMemoryEstimate() const
2183 {
2184     double backingMemory;
2185     
2186     // m_ancestorClippingLayer, m_contentsContainmentLayer and m_childContainmentLayer are just used for masking or containment, so have no backing.
2187     backingMemory = m_graphicsLayer->backingStoreMemoryEstimate();
2188     if (m_foregroundLayer)
2189         backingMemory += m_foregroundLayer->backingStoreMemoryEstimate();
2190     if (m_backgroundLayer)
2191         backingMemory += m_backgroundLayer->backingStoreMemoryEstimate();
2192     if (m_maskLayer)
2193         backingMemory += m_maskLayer->backingStoreMemoryEstimate();
2194
2195     if (m_scrollingContentsLayer)
2196         backingMemory += m_scrollingContentsLayer->backingStoreMemoryEstimate();
2197
2198     if (m_layerForHorizontalScrollbar)
2199         backingMemory += m_layerForHorizontalScrollbar->backingStoreMemoryEstimate();
2200
2201     if (m_layerForVerticalScrollbar)
2202         backingMemory += m_layerForVerticalScrollbar->backingStoreMemoryEstimate();
2203
2204     if (m_layerForScrollCorner)
2205         backingMemory += m_layerForScrollCorner->backingStoreMemoryEstimate();
2206     
2207     return backingMemory;
2208 }
2209
2210 #if PLATFORM(BLACKBERRY)
2211 bool RenderLayerBacking::contentsVisible(const GraphicsLayer*, const IntRect& localContentRect) const
2212 {
2213     Frame* frame = renderer()->frame();
2214     FrameView* view = frame ? frame->view() : 0;
2215     if (!view)
2216         return false;
2217
2218     IntRect visibleContentRect(view->visibleContentRect());
2219     FloatQuad absoluteContentQuad = renderer()->localToAbsoluteQuad(FloatRect(localContentRect));
2220     return absoluteContentQuad.enclosingBoundingBox().intersects(visibleContentRect);
2221 }
2222 #endif
2223
2224 void RenderLayerBacking::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
2225 {
2226     MemoryClassInfo info(memoryObjectInfo, this, PlatformMemoryTypes::Rendering);
2227     info.addWeakPointer(m_owningLayer);
2228     info.addMember(m_ancestorClippingLayer, "ancestorClippingLayer");
2229     info.addMember(m_contentsContainmentLayer, "contentsContainmentLayer");
2230     info.addMember(m_graphicsLayer, "graphicsLayer");
2231     info.addMember(m_foregroundLayer, "foregroundLayer");
2232     info.addMember(m_backgroundLayer, "backgroundLayer");
2233     info.addMember(m_childContainmentLayer, "childContainmentLayer");
2234     info.addMember(m_maskLayer, "maskLayer");
2235     info.addMember(m_layerForHorizontalScrollbar, "layerForHorizontalScrollbar");
2236     info.addMember(m_layerForVerticalScrollbar, "layerForVerticalScrollbar");
2237     info.addMember(m_layerForScrollCorner, "layerForScrollCorner");
2238     info.addMember(m_scrollingLayer, "scrollingLayer");
2239     info.addMember(m_scrollingContentsLayer, "scrollingContentsLayer");
2240 }
2241
2242 } // namespace WebCore
2243
2244 #endif // USE(ACCELERATED_COMPOSITING)