Unreviewed, rolling out r121572.
[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 "Chrome.h"
36 #include "FontCache.h"
37 #include "FrameView.h"
38 #include "GraphicsContext.h"
39 #include "GraphicsLayer.h"
40 #include "HTMLCanvasElement.h"
41 #include "HTMLIFrameElement.h"
42 #include "HTMLMediaElement.h"
43 #include "HTMLNames.h"
44 #include "InspectorInstrumentation.h"
45 #include "KeyframeList.h"
46 #include "PluginViewBase.h"
47 #include "RenderApplet.h"
48 #include "RenderIFrame.h"
49 #include "RenderImage.h"
50 #include "RenderLayerCompositor.h"
51 #include "RenderEmbeddedObject.h"
52 #include "RenderVideo.h"
53 #include "RenderView.h"
54 #include "ScrollingCoordinator.h"
55 #include "StyleResolver.h"
56 #include "TiledBacking.h"
57
58 #include <wtf/CurrentTime.h>
59
60 #if ENABLE(CSS_FILTERS)
61 #include "FilterEffectRenderer.h"
62 #endif
63
64 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
65 #include "GraphicsContext3D.h"
66 #endif
67
68 using namespace std;
69
70 namespace WebCore {
71
72 using namespace HTMLNames;
73
74 static bool hasBoxDecorations(const RenderStyle*);
75 static bool hasBoxDecorationsOrBackground(const RenderObject*);
76 static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle*);
77 static IntRect clipBox(RenderBox* renderer);
78
79 static inline bool isAcceleratedCanvas(RenderObject* renderer)
80 {
81 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
82     if (renderer->isCanvas()) {
83         HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
84         if (CanvasRenderingContext* context = canvas->renderingContext())
85             return context->isAccelerated();
86     }
87 #else
88     UNUSED_PARAM(renderer);
89 #endif
90     return false;
91 }
92
93 RenderLayerBacking::RenderLayerBacking(RenderLayer* layer)
94     : m_owningLayer(layer)
95     , m_artificiallyInflatedBounds(false)
96     , m_isMainFrameRenderViewLayer(false)
97     , m_usingTiledCacheLayer(false)
98     , m_requiresOwnBackingStore(true)
99 #if ENABLE(CSS_FILTERS)
100     , m_canCompositeFilters(false)
101 #endif
102 {
103     if (renderer()->isRenderView()) {
104         Frame* frame = toRenderView(renderer())->frameView()->frame();
105         Page* page = frame ? frame->page() : 0;
106         if (page && frame && page->mainFrame() == frame) {
107             m_isMainFrameRenderViewLayer = true;
108
109 #if PLATFORM(MAC)
110             // FIXME: It's a little weird that we base this decision on whether there's a scrolling coordinator or not.
111             if (page->scrollingCoordinator())
112                 m_usingTiledCacheLayer = true;
113 #endif
114         }
115     }
116     
117     createPrimaryGraphicsLayer();
118
119     if (m_usingTiledCacheLayer) {
120         if (Page* page = renderer()->frame()->page()) {
121             if (TiledBacking* tiledBacking = m_graphicsLayer->tiledBacking()) {
122                 tiledBacking->setIsInWindow(page->isOnscreen());
123                 tiledBacking->setCanHaveScrollbars(renderer()->frame()->view()->canHaveScrollbars());
124             }
125         }
126     }
127 }
128
129 RenderLayerBacking::~RenderLayerBacking()
130 {
131     updateClippingLayers(false, false);
132     updateOverflowControlsLayers(false, false, false);
133     updateForegroundLayer(false);
134     updateMaskLayer(false);
135     destroyGraphicsLayers();
136 }
137
138 PassOwnPtr<GraphicsLayer> RenderLayerBacking::createGraphicsLayer(const String& name)
139 {
140     OwnPtr<GraphicsLayer> graphicsLayer = GraphicsLayer::create(this);
141 #ifndef NDEBUG
142     graphicsLayer->setName(name);
143 #else
144     UNUSED_PARAM(name);
145 #endif
146     graphicsLayer->setMaintainsPixelAlignment(compositor()->keepLayersPixelAligned());
147
148 #if PLATFORM(MAC) && USE(CA)
149     graphicsLayer->setAcceleratesDrawing(compositor()->acceleratedDrawingEnabled());
150 #endif    
151     
152     return graphicsLayer.release();
153 }
154
155 bool RenderLayerBacking::shouldUseTileCache(const GraphicsLayer*) const
156 {
157     return m_usingTiledCacheLayer;
158 }
159
160 void RenderLayerBacking::createPrimaryGraphicsLayer()
161 {
162     String layerName;
163 #ifndef NDEBUG
164     layerName = nameForLayer();
165 #endif
166     m_graphicsLayer = createGraphicsLayer(layerName);
167
168     if (m_isMainFrameRenderViewLayer) {
169         bool isTransparent = false;
170         if (FrameView* frameView = toRenderView(renderer())->frameView())
171             isTransparent = frameView->isTransparent();
172
173         m_graphicsLayer->setContentsOpaque(!isTransparent);
174         m_graphicsLayer->setAppliesPageScale();
175     }
176
177 #if PLATFORM(MAC) && USE(CA)
178     if (!compositor()->acceleratedDrawingEnabled() && renderer()->isCanvas()) {
179         HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer()->node());
180         if (canvas->shouldAccelerate(canvas->size()))
181             m_graphicsLayer->setAcceleratesDrawing(true);
182     }
183 #endif    
184     
185     updateLayerOpacity(renderer()->style());
186     updateLayerTransform(renderer()->style());
187 #if ENABLE(CSS_FILTERS)
188     updateLayerFilters(renderer()->style());
189 #endif
190 }
191
192 void RenderLayerBacking::destroyGraphicsLayers()
193 {
194     if (m_graphicsLayer)
195         m_graphicsLayer->removeFromParent();
196
197     m_graphicsLayer = nullptr;
198     m_foregroundLayer = nullptr;
199     m_clippingLayer = nullptr;
200     m_maskLayer = nullptr;
201 }
202
203 void RenderLayerBacking::updateLayerOpacity(const RenderStyle* style)
204 {
205     m_graphicsLayer->setOpacity(compositingOpacity(style->opacity()));
206 }
207
208 void RenderLayerBacking::updateLayerTransform(const RenderStyle* style)
209 {
210     // FIXME: This could use m_owningLayer->transform(), but that currently has transform-origin
211     // baked into it, and we don't want that.
212     TransformationMatrix t;
213     if (m_owningLayer->hasTransform()) {
214         style->applyTransform(t, toRenderBox(renderer())->borderBoxRect().size(), RenderStyle::ExcludeTransformOrigin);
215         makeMatrixRenderable(t, compositor()->canRender3DTransforms());
216     }
217     
218     m_graphicsLayer->setTransform(t);
219 }
220
221 #if ENABLE(CSS_FILTERS)
222 void RenderLayerBacking::updateLayerFilters(const RenderStyle* style)
223 {
224     m_canCompositeFilters = m_graphicsLayer->setFilters(style->filter());
225 }
226 #endif
227
228 static bool hasNonZeroTransformOrigin(const RenderObject* renderer)
229 {
230     RenderStyle* style = renderer->style();
231     return (style->transformOriginX().type() == Fixed && style->transformOriginX().value())
232         || (style->transformOriginY().type() == Fixed && style->transformOriginY().value());
233 }
234
235 static bool layerOrAncestorIsTransformed(RenderLayer* layer)
236 {
237     for (RenderLayer* curr = layer; curr; curr = curr->parent()) {
238         if (curr->hasTransform())
239             return true;
240     }
241     
242     return false;
243 }
244
245 bool RenderLayerBacking::shouldClipCompositedBounds() const
246 {
247     // Scrollbar layers use this layer for relative positioning, so don't clip.
248     if (layerForHorizontalScrollbar() || layerForVerticalScrollbar())
249         return false;
250
251     if (m_usingTiledCacheLayer)
252         return true;
253
254     if (!compositor()->compositingConsultsOverlap())
255         return false;
256
257     if (layerOrAncestorIsTransformed(m_owningLayer))
258         return false;
259
260     return true;
261 }
262
263
264 void RenderLayerBacking::updateCompositedBounds()
265 {
266     IntRect layerBounds = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer);
267
268     // Clip to the size of the document or enclosing overflow-scroll layer.
269     // If this or an ancestor is transformed, we can't currently compute the correct rect to intersect with.
270     // We'd need RenderObject::convertContainerToLocalQuad(), which doesn't yet exist.
271     if (shouldClipCompositedBounds()) {
272         RenderView* view = m_owningLayer->renderer()->view();
273         RenderLayer* rootLayer = view->layer();
274
275         // Start by clipping to the view's bounds.
276         LayoutRect clippingBounds = view->unscaledDocumentRect();
277
278         if (m_owningLayer != rootLayer)
279             clippingBounds.intersect(m_owningLayer->backgroundClipRect(rootLayer, 0, AbsoluteClipRects).rect()); // FIXME: Incorrect for CSS regions.
280
281         LayoutPoint delta;
282         m_owningLayer->convertToLayerCoords(rootLayer, delta);
283         clippingBounds.move(-delta.x(), -delta.y());
284
285         layerBounds.intersect(pixelSnappedIntRect(clippingBounds));
286     }
287     
288     // If the element has a transform-origin that has fixed lengths, and the renderer has zero size,
289     // then we need to ensure that the compositing layer has non-zero size so that we can apply
290     // the transform-origin via the GraphicsLayer anchorPoint (which is expressed as a fractional value).
291     if (layerBounds.isEmpty() && hasNonZeroTransformOrigin(renderer())) {
292         layerBounds.setWidth(1);
293         layerBounds.setHeight(1);
294         m_artificiallyInflatedBounds = true;
295     } else
296         m_artificiallyInflatedBounds = false;
297
298     setCompositedBounds(layerBounds);
299 }
300
301 void RenderLayerBacking::updateAfterWidgetResize()
302 {
303     if (renderer()->isRenderPart()) {
304         if (RenderLayerCompositor* innerCompositor = RenderLayerCompositor::frameContentsCompositor(toRenderPart(renderer()))) {
305             innerCompositor->frameViewDidChangeSize();
306             innerCompositor->frameViewDidChangeLocation(contentsBox().location());
307         }
308     }
309 }
310
311 void RenderLayerBacking::updateAfterLayout(UpdateDepth updateDepth, bool isUpdateRoot)
312 {
313     RenderLayerCompositor* layerCompositor = compositor();
314     if (!layerCompositor->compositingLayersNeedRebuild()) {
315         // Calling updateGraphicsLayerGeometry() here gives incorrect results, because the
316         // position of this layer's GraphicsLayer depends on the position of our compositing
317         // ancestor's GraphicsLayer. That cannot be determined until all the descendant 
318         // RenderLayers of that ancestor have been processed via updateLayerPositions().
319         //
320         // The solution is to update compositing children of this layer here,
321         // via updateCompositingChildrenGeometry().
322         updateCompositedBounds();
323         layerCompositor->updateCompositingDescendantGeometry(m_owningLayer, m_owningLayer, updateDepth);
324         
325         if (isUpdateRoot) {
326             updateGraphicsLayerGeometry();
327             layerCompositor->updateRootLayerPosition();
328         }
329     }
330 }
331
332 bool RenderLayerBacking::updateGraphicsLayerConfiguration()
333 {
334     RenderLayerCompositor* compositor = this->compositor();
335     RenderObject* renderer = this->renderer();
336
337     m_owningLayer->updateZOrderLists();
338
339     bool layerConfigChanged = false;
340     if (updateForegroundLayer(compositor->needsContentsCompositingLayer(m_owningLayer)))
341         layerConfigChanged = true;
342     
343     if (updateClippingLayers(compositor->clippedByAncestor(m_owningLayer), compositor->clipsCompositingDescendants(m_owningLayer)))
344         layerConfigChanged = true;
345
346     if (updateOverflowControlsLayers(requiresHorizontalScrollbarLayer(), requiresVerticalScrollbarLayer(), requiresScrollCornerLayer()))
347         layerConfigChanged = true;
348
349     if (layerConfigChanged)
350         updateInternalHierarchy();
351
352     if (updateMaskLayer(renderer->hasMask()))
353         m_graphicsLayer->setMaskLayer(m_maskLayer.get());
354
355     if (m_owningLayer->hasReflection()) {
356         if (m_owningLayer->reflectionLayer()->backing()) {
357             GraphicsLayer* reflectionLayer = m_owningLayer->reflectionLayer()->backing()->graphicsLayer();
358             m_graphicsLayer->setReplicatedByLayer(reflectionLayer);
359         }
360     } else
361         m_graphicsLayer->setReplicatedByLayer(0);
362
363     if (isDirectlyCompositedImage())
364         updateImageContents();
365
366     if ((renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing())
367         || (renderer->isApplet() && toRenderApplet(renderer)->allowsAcceleratedCompositing())) {
368         PluginViewBase* pluginViewBase = static_cast<PluginViewBase*>(toRenderWidget(renderer)->widget());
369         m_graphicsLayer->setContentsToMedia(pluginViewBase->platformLayer());
370     }
371 #if ENABLE(VIDEO)
372     else if (renderer->isVideo()) {
373         HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(renderer->node());
374         m_graphicsLayer->setContentsToMedia(mediaElement->platformLayer());
375     }
376 #endif
377 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
378     else if (isAcceleratedCanvas(renderer)) {
379         HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
380         if (CanvasRenderingContext* context = canvas->renderingContext())
381             m_graphicsLayer->setContentsToCanvas(context->platformLayer());
382         layerConfigChanged = true;
383     }
384 #endif
385 #if ENABLE(FULLSCREEN_API)
386     else if (renderer->isRenderFullScreen()) {
387         // RenderFullScreen renderers have no content, and only a solid
388         // background color.  They also can be large enough to trigger the
389         // creation of a tiled-layer, which can cause flashing problems
390         // during repainting.  Special case the RenderFullScreen case because
391         // we know its style does not come from CSS and it is therefore will
392         // not contain paintable content (e.g. background images, gradients,
393         // etc), so safe to set the layer's background color to the renderer's 
394         // style's background color.
395         updateBackgroundColor();
396     }
397 #endif
398     if (renderer->isRenderPart())
399         layerConfigChanged = RenderLayerCompositor::parentFrameContentLayers(toRenderPart(renderer));
400
401     return layerConfigChanged;
402 }
403
404 static IntRect clipBox(RenderBox* renderer)
405 {
406     LayoutRect result = PaintInfo::infiniteRect();
407     if (renderer->hasOverflowClip())
408         result = renderer->overflowClipRect(LayoutPoint(), 0); // FIXME: Incorrect for CSS regions.
409
410     if (renderer->hasClip())
411         result.intersect(renderer->clipRect(LayoutPoint(), 0)); // FIXME: Incorrect for CSS regions.
412
413     return pixelSnappedIntRect(result);
414 }
415
416 void RenderLayerBacking::updateGraphicsLayerGeometry()
417 {
418     // If we haven't built z-order lists yet, wait until later.
419     if (m_owningLayer->isStackingContext() && m_owningLayer->m_zOrderListsDirty)
420         return;
421
422     // Set transform property, if it is not animating. We have to do this here because the transform
423     // is affected by the layer dimensions.
424     if (!renderer()->animation()->isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyWebkitTransform))
425         updateLayerTransform(renderer()->style());
426
427     // Set opacity, if it is not animating.
428     if (!renderer()->animation()->isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyOpacity))
429         updateLayerOpacity(renderer()->style());
430         
431 #if ENABLE(CSS_FILTERS)
432     updateLayerFilters(renderer()->style());
433 #endif
434     
435     m_owningLayer->updateDescendantDependentFlags();
436
437     // m_graphicsLayer is the corresponding GraphicsLayer for this RenderLayer and its non-compositing
438     // descendants. So, the visibility flag for m_graphicsLayer should be true if there are any
439     // non-compositing visible layers.
440     m_graphicsLayer->setContentsVisible(m_owningLayer->hasVisibleContent() || hasVisibleNonCompositingDescendantLayers());
441
442     RenderStyle* style = renderer()->style();
443     m_graphicsLayer->setPreserves3D(style->transformStyle3D() == TransformStyle3DPreserve3D && !renderer()->hasReflection());
444     m_graphicsLayer->setBackfaceVisibility(style->backfaceVisibility() == BackfaceVisibilityVisible);
445
446     // Register fixed position layers and their containers with the scrolling coordinator.
447     if (Page* page = renderer()->frame()->page()) {
448         if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator()) {
449             if (style->position() == FixedPosition || compositor()->fixedPositionedByAncestor(m_owningLayer))
450                 scrollingCoordinator->setLayerIsFixedToContainerLayer(childForSuperlayers(), true);
451             else {
452                 if (m_ancestorClippingLayer)
453                     scrollingCoordinator->setLayerIsFixedToContainerLayer(m_ancestorClippingLayer.get(), false);
454                 scrollingCoordinator->setLayerIsFixedToContainerLayer(m_graphicsLayer.get(), false);
455             }
456             bool isContainer = m_owningLayer->hasTransform();
457             scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(childForSuperlayers(), isContainer);
458         }
459     }
460     RenderLayer* compAncestor = m_owningLayer->ancestorCompositingLayer();
461     
462     // We compute everything relative to the enclosing compositing layer.
463     IntRect ancestorCompositingBounds;
464     if (compAncestor) {
465         ASSERT(compAncestor->backing());
466         ancestorCompositingBounds = pixelSnappedIntRect(compAncestor->backing()->compositedBounds());
467     }
468
469     IntRect localCompositingBounds = pixelSnappedIntRect(compositedBounds());
470
471     IntRect relativeCompositingBounds(localCompositingBounds);
472     IntPoint delta;
473     m_owningLayer->convertToPixelSnappedLayerCoords(compAncestor, delta);
474     relativeCompositingBounds.moveBy(delta);
475
476     IntPoint graphicsLayerParentLocation;
477     if (compAncestor && compAncestor->backing()->hasClippingLayer()) {
478         // If the compositing ancestor has a layer to clip children, we parent in that, and therefore
479         // position relative to it.
480         IntRect clippingBox = clipBox(toRenderBox(compAncestor->renderer()));
481         graphicsLayerParentLocation = clippingBox.location();
482     } else if (compAncestor)
483         graphicsLayerParentLocation = ancestorCompositingBounds.location();
484     else
485         graphicsLayerParentLocation = renderer()->view()->documentRect().location();
486     
487     if (compAncestor && m_ancestorClippingLayer) {
488         // Call calculateRects to get the backgroundRect which is what is used to clip the contents of this
489         // layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects
490         // for a compositing layer, rootLayer is the layer itself.
491         IntRect parentClipRect = pixelSnappedIntRect(m_owningLayer->backgroundClipRect(compAncestor, 0, TemporaryClipRects).rect()); // FIXME: Incorrect for CSS regions.
492         ASSERT(parentClipRect != PaintInfo::infiniteRect());
493         m_ancestorClippingLayer->setPosition(FloatPoint() + (parentClipRect.location() - graphicsLayerParentLocation));
494         m_ancestorClippingLayer->setSize(parentClipRect.size());
495
496         // backgroundRect is relative to compAncestor, so subtract deltaX/deltaY to get back to local coords.
497         m_ancestorClippingLayer->setOffsetFromRenderer(parentClipRect.location() - delta);
498
499         // The primary layer is then parented in, and positioned relative to this clipping layer.
500         graphicsLayerParentLocation = parentClipRect.location();
501     }
502
503     m_graphicsLayer->setPosition(FloatPoint() + (relativeCompositingBounds.location() - graphicsLayerParentLocation));
504     m_graphicsLayer->setOffsetFromRenderer(localCompositingBounds.location() - IntPoint());
505     
506     FloatSize oldSize = m_graphicsLayer->size();
507     FloatSize newSize = relativeCompositingBounds.size();
508     if (oldSize != newSize) {
509         m_graphicsLayer->setSize(newSize);
510         // A bounds change will almost always require redisplay. Usually that redisplay
511         // will happen because of a repaint elsewhere, but not always:
512         // e.g. see RenderView::setMaximalOutlineSize()
513         m_graphicsLayer->setNeedsDisplay();
514     }
515
516     // If we have a layer that clips children, position it.
517     IntRect clippingBox;
518     if (m_clippingLayer) {
519         clippingBox = clipBox(toRenderBox(renderer()));
520         m_clippingLayer->setPosition(FloatPoint() + (clippingBox.location() - localCompositingBounds.location()));
521         m_clippingLayer->setSize(clippingBox.size());
522         m_clippingLayer->setOffsetFromRenderer(clippingBox.location() - IntPoint());
523     }
524     
525     if (m_maskLayer) {
526         if (m_maskLayer->size() != m_graphicsLayer->size()) {
527             m_maskLayer->setSize(m_graphicsLayer->size());
528             m_maskLayer->setNeedsDisplay();
529         }
530         m_maskLayer->setPosition(FloatPoint());
531         m_maskLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
532     }
533     
534     if (m_owningLayer->hasTransform()) {
535         const IntRect borderBox = toRenderBox(renderer())->pixelSnappedBorderBoxRect();
536
537         // Get layout bounds in the coords of compAncestor to match relativeCompositingBounds.
538         IntRect layerBounds = IntRect(delta, borderBox.size());
539
540         // Update properties that depend on layer dimensions
541         FloatPoint3D transformOrigin = computeTransformOrigin(borderBox);
542         // Compute the anchor point, which is in the center of the renderer box unless transform-origin is set.
543         FloatPoint3D anchor(relativeCompositingBounds.width()  != 0.0f ? ((layerBounds.x() - relativeCompositingBounds.x()) + transformOrigin.x()) / relativeCompositingBounds.width()  : 0.5f,
544                             relativeCompositingBounds.height() != 0.0f ? ((layerBounds.y() - relativeCompositingBounds.y()) + transformOrigin.y()) / relativeCompositingBounds.height() : 0.5f,
545                             transformOrigin.z());
546         m_graphicsLayer->setAnchorPoint(anchor);
547
548         RenderStyle* style = renderer()->style();
549         if (style->hasPerspective()) {
550             TransformationMatrix t = owningLayer()->perspectiveTransform();
551             
552             if (m_clippingLayer) {
553                 m_clippingLayer->setChildrenTransform(t);
554                 m_graphicsLayer->setChildrenTransform(TransformationMatrix());
555             }
556             else
557                 m_graphicsLayer->setChildrenTransform(t);
558         } else {
559             if (m_clippingLayer)
560                 m_clippingLayer->setChildrenTransform(TransformationMatrix());
561             else
562                 m_graphicsLayer->setChildrenTransform(TransformationMatrix());
563         }
564     } else {
565         m_graphicsLayer->setAnchorPoint(FloatPoint3D(0.5f, 0.5f, 0));
566     }
567
568     if (m_foregroundLayer) {
569         FloatPoint foregroundPosition;
570         FloatSize foregroundSize = newSize;
571         IntSize foregroundOffset = m_graphicsLayer->offsetFromRenderer();
572         if (m_clippingLayer) {
573             // If we have a clipping layer (which clips descendants), then the foreground layer is a child of it,
574             // so that it gets correctly sorted with children. In that case, position relative to the clipping layer.
575             foregroundSize = FloatSize(clippingBox.size());
576             foregroundOffset = clippingBox.location() - IntPoint();
577         }
578
579         m_foregroundLayer->setPosition(foregroundPosition);
580         m_foregroundLayer->setSize(foregroundSize);
581         m_foregroundLayer->setOffsetFromRenderer(foregroundOffset);
582     }
583
584     if (m_owningLayer->reflectionLayer() && m_owningLayer->reflectionLayer()->isComposited()) {
585         RenderLayerBacking* reflectionBacking = m_owningLayer->reflectionLayer()->backing();
586         reflectionBacking->updateGraphicsLayerGeometry();
587         
588         // The reflection layer has the bounds of m_owningLayer->reflectionLayer(),
589         // but the reflected layer is the bounds of this layer, so we need to position it appropriately.
590         FloatRect layerBounds = compositedBounds();
591         FloatRect reflectionLayerBounds = reflectionBacking->compositedBounds();
592         reflectionBacking->graphicsLayer()->setReplicatedLayerPosition(FloatPoint() + (layerBounds.location() - reflectionLayerBounds.location()));
593     }
594
595     m_graphicsLayer->setContentsRect(contentsBox());
596
597     // If this layer was created just for clipping or to apply perspective, it doesn't need its own backing store.
598     setRequiresOwnBackingStore(compositor()->requiresOwnBackingStore(m_owningLayer, compAncestor));
599
600     updateDrawsContent();
601     updateAfterWidgetResize();
602 }
603
604 void RenderLayerBacking::updateInternalHierarchy()
605 {
606     // m_foregroundLayer has to be inserted in the correct order with child layers,
607     // so it's not inserted here.
608     if (m_ancestorClippingLayer) {
609         m_ancestorClippingLayer->removeAllChildren();
610         m_graphicsLayer->removeFromParent();
611         m_ancestorClippingLayer->addChild(m_graphicsLayer.get());
612     }
613
614     if (m_clippingLayer) {
615         m_clippingLayer->removeFromParent();
616         m_graphicsLayer->addChild(m_clippingLayer.get());
617     }
618
619     // The clip for child layers does not include space for overflow controls, so they exist as
620     // siblings of the clipping layer if we have one. Normal children of this layer are set as
621     // children of the clipping layer.
622     if (m_layerForHorizontalScrollbar) {
623         m_layerForHorizontalScrollbar->removeFromParent();
624         m_graphicsLayer->addChild(m_layerForHorizontalScrollbar.get());
625     }
626     if (m_layerForVerticalScrollbar) {
627         m_layerForVerticalScrollbar->removeFromParent();
628         m_graphicsLayer->addChild(m_layerForVerticalScrollbar.get());
629     }
630     if (m_layerForScrollCorner) {
631         m_layerForScrollCorner->removeFromParent();
632         m_graphicsLayer->addChild(m_layerForScrollCorner.get());
633     }
634 }
635
636 void RenderLayerBacking::updateDrawsContent()
637 {
638     bool hasPaintedContent = containsPaintedContent();
639
640     // FIXME: we could refine this to only allocate backing for one of these layers if possible.
641     m_graphicsLayer->setDrawsContent(hasPaintedContent);
642     if (m_foregroundLayer)
643         m_foregroundLayer->setDrawsContent(hasPaintedContent);
644 }
645
646 // Return true if the layers changed.
647 bool RenderLayerBacking::updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip)
648 {
649     bool layersChanged = false;
650
651     if (needsAncestorClip) {
652         if (!m_ancestorClippingLayer) {
653             m_ancestorClippingLayer = createGraphicsLayer("Ancestor clipping Layer");
654             m_ancestorClippingLayer->setMasksToBounds(true);
655             layersChanged = true;
656         }
657     } else if (m_ancestorClippingLayer) {
658         m_ancestorClippingLayer->removeFromParent();
659         m_ancestorClippingLayer = nullptr;
660         layersChanged = true;
661     }
662     
663     if (needsDescendantClip) {
664         if (!m_clippingLayer) {
665             m_clippingLayer = createGraphicsLayer("Child clipping Layer");
666             m_clippingLayer->setMasksToBounds(true);
667             layersChanged = true;
668         }
669     } else if (m_clippingLayer) {
670         m_clippingLayer->removeFromParent();
671         m_clippingLayer = nullptr;
672         layersChanged = true;
673     }
674     
675     return layersChanged;
676 }
677
678 bool RenderLayerBacking::requiresHorizontalScrollbarLayer() const
679 {
680 #if !PLATFORM(CHROMIUM)
681     if (!m_owningLayer->hasOverlayScrollbars())
682         return false;
683 #endif
684     return m_owningLayer->horizontalScrollbar();
685 }
686
687 bool RenderLayerBacking::requiresVerticalScrollbarLayer() const
688 {
689 #if !PLATFORM(CHROMIUM)
690     if (!m_owningLayer->hasOverlayScrollbars())
691         return false;
692 #endif
693     return m_owningLayer->verticalScrollbar();
694 }
695
696 bool RenderLayerBacking::requiresScrollCornerLayer() const
697 {
698 #if !PLATFORM(CHROMIUM)
699     if (!m_owningLayer->hasOverlayScrollbars())
700         return false;
701 #endif
702     return !m_owningLayer->scrollCornerAndResizerRect().isEmpty();
703 }
704
705 bool RenderLayerBacking::updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer)
706 {
707     bool layersChanged = false;
708     if (needsHorizontalScrollbarLayer) {
709         if (!m_layerForHorizontalScrollbar) {
710             m_layerForHorizontalScrollbar = createGraphicsLayer("horizontal scrollbar");
711             layersChanged = true;
712         }
713     } else if (m_layerForHorizontalScrollbar) {
714         m_layerForHorizontalScrollbar.clear();
715         layersChanged = true;
716     }
717
718     if (needsVerticalScrollbarLayer) {
719         if (!m_layerForVerticalScrollbar) {
720             m_layerForVerticalScrollbar = createGraphicsLayer("vertical scrollbar");
721             layersChanged = true;
722         }
723     } else if (m_layerForVerticalScrollbar) {
724         m_layerForVerticalScrollbar.clear();
725         layersChanged = true;
726     }
727
728     if (needsScrollCornerLayer) {
729         if (!m_layerForScrollCorner) {
730             m_layerForScrollCorner = createGraphicsLayer("scroll corner");
731             layersChanged = true;
732         }
733     } else if (m_layerForScrollCorner) {
734         m_layerForScrollCorner.clear();
735         layersChanged = true;
736     }
737
738     return layersChanged;
739 }
740
741 bool RenderLayerBacking::updateForegroundLayer(bool needsForegroundLayer)
742 {
743     bool layerChanged = false;
744     if (needsForegroundLayer) {
745         if (!m_foregroundLayer) {
746             String layerName;
747 #ifndef NDEBUG
748             layerName = nameForLayer() + " (foreground)";
749 #endif
750             m_foregroundLayer = createGraphicsLayer(layerName);
751             m_foregroundLayer->setDrawsContent(true);
752             m_foregroundLayer->setPaintingPhase(GraphicsLayerPaintForeground);
753             layerChanged = true;
754         }
755     } else if (m_foregroundLayer) {
756         m_foregroundLayer->removeFromParent();
757         m_foregroundLayer = nullptr;
758         layerChanged = true;
759     }
760
761     if (layerChanged)
762         m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
763
764     return layerChanged;
765 }
766
767 bool RenderLayerBacking::updateMaskLayer(bool needsMaskLayer)
768 {
769     bool layerChanged = false;
770     if (needsMaskLayer) {
771         if (!m_maskLayer) {
772             m_maskLayer = createGraphicsLayer("Mask");
773             m_maskLayer->setDrawsContent(true);
774             m_maskLayer->setPaintingPhase(GraphicsLayerPaintMask);
775             layerChanged = true;
776         }
777     } else if (m_maskLayer) {
778         m_maskLayer = nullptr;
779         layerChanged = true;
780     }
781
782     if (layerChanged)
783         m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
784
785     return layerChanged;
786 }
787
788 GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() const
789 {
790     unsigned phase = GraphicsLayerPaintBackground;
791     if (!m_foregroundLayer)
792         phase |= GraphicsLayerPaintForeground;
793     if (!m_maskLayer)
794         phase |= GraphicsLayerPaintMask;
795
796     return static_cast<GraphicsLayerPaintingPhase>(phase);
797 }
798
799 float RenderLayerBacking::compositingOpacity(float rendererOpacity) const
800 {
801     float finalOpacity = rendererOpacity;
802     
803     for (RenderLayer* curr = m_owningLayer->parent(); curr; curr = curr->parent()) {
804         // We only care about parents that are stacking contexts.
805         // Recall that opacity creates stacking context.
806         if (!curr->isStackingContext())
807             continue;
808         
809         // If we found a compositing layer, we want to compute opacity
810         // relative to it. So we can break here.
811         if (curr->isComposited())
812             break;
813         
814         finalOpacity *= curr->renderer()->opacity();
815     }
816
817     return finalOpacity;
818 }
819
820 static bool hasBoxDecorations(const RenderStyle* style)
821 {
822     return style->hasBorder() || style->hasBorderRadius() || style->hasOutline() || style->hasAppearance() || style->boxShadow() || style->hasFilter();
823 }
824
825 static bool hasBoxDecorationsOrBackground(const RenderObject* renderer)
826 {
827     return hasBoxDecorations(renderer->style()) || renderer->hasBackground();
828 }
829
830 static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle* style)
831 {
832     return hasBoxDecorations(style) || style->hasBackgroundImage();
833 }
834
835 Color RenderLayerBacking::rendererBackgroundColor() const
836 {
837     RenderObject* backgroundRenderer = renderer();
838     if (backgroundRenderer->isRoot())
839         backgroundRenderer = backgroundRenderer->rendererForRootBackground();
840
841     return backgroundRenderer->style()->visitedDependentColor(CSSPropertyBackgroundColor);
842 }
843
844 void RenderLayerBacking::updateBackgroundColor()
845 {
846     m_graphicsLayer->setContentsToBackgroundColor(rendererBackgroundColor());
847 }
848
849 bool RenderLayerBacking::paintsBoxDecorations() const
850 {
851     if (!m_owningLayer->hasVisibleContent())
852         return false;
853
854     if (hasBoxDecorationsOrBackground(renderer()))
855         return true;
856
857     if (m_owningLayer->hasOverflowControls())
858         return true;
859
860     return false;
861 }
862
863 bool RenderLayerBacking::paintsChildren() const
864 {
865     if (m_owningLayer->hasVisibleContent() && containsNonEmptyRenderers())
866         return true;
867         
868     if (hasVisibleNonCompositingDescendantLayers())
869         return true;
870
871     return false;
872 }
873
874 // A "simple container layer" is a RenderLayer which has no visible content to render.
875 // It may have no children, or all its children may be themselves composited.
876 // This is a useful optimization, because it allows us to avoid allocating backing store.
877 bool RenderLayerBacking::isSimpleContainerCompositingLayer() const
878 {
879     RenderObject* renderObject = renderer();
880     if (renderObject->isReplaced() ||       // replaced objects are not containers
881         renderObject->hasMask())            // masks require special treatment
882         return false;
883
884     if (paintsBoxDecorations() || paintsChildren())
885         return false;
886     
887     if (renderObject->node() && renderObject->node()->isDocumentNode()) {
888         // Look to see if the root object has a non-simple background
889         RenderObject* rootObject = renderObject->document()->documentElement() ? renderObject->document()->documentElement()->renderer() : 0;
890         if (!rootObject)
891             return false;
892         
893         RenderStyle* style = rootObject->style();
894         
895         // Reject anything that has a border, a border-radius or outline,
896         // or is not a simple background (no background, or solid color).
897         if (hasBoxDecorationsOrBackgroundImage(style))
898             return false;
899         
900         // Now look at the body's renderer.
901         HTMLElement* body = renderObject->document()->body();
902         RenderObject* bodyObject = (body && body->hasLocalName(bodyTag)) ? body->renderer() : 0;
903         if (!bodyObject)
904             return false;
905         
906         style = bodyObject->style();
907         
908         if (hasBoxDecorationsOrBackgroundImage(style))
909             return false;
910     }
911
912     return true;
913 }
914
915 bool RenderLayerBacking::containsNonEmptyRenderers() const
916 {
917     // Some HTML can cause whitespace text nodes to have renderers, like:
918     // <div>
919     // <img src=...>
920     // </div>
921     // so test for 0x0 RenderTexts here
922     for (RenderObject* child = renderer()->firstChild(); child; child = child->nextSibling()) {
923         if (!child->hasLayer()) {
924             if (child->isRenderInline() || !child->isBox())
925                 return true;
926             
927             if (toRenderBox(child)->width() > 0 || toRenderBox(child)->height() > 0)
928                 return true;
929         }
930     }
931     return false;
932 }
933
934 // Conservative test for having no rendered children.
935 bool RenderLayerBacking::hasVisibleNonCompositingDescendantLayers() const
936 {
937     // FIXME: We shouldn't be called with a stale z-order lists. See bug 85512.
938     m_owningLayer->updateLayerListsIfNeeded();
939
940 #if !ASSERT_DISABLED
941     LayerListMutationDetector mutationChecker(m_owningLayer);
942 #endif
943
944     if (Vector<RenderLayer*>* normalFlowList = m_owningLayer->normalFlowList()) {
945         size_t listSize = normalFlowList->size();
946         for (size_t i = 0; i < listSize; ++i) {
947             RenderLayer* curLayer = normalFlowList->at(i);
948             if (!curLayer->isComposited() && curLayer->hasVisibleContent())
949                 return true;
950         }
951     }
952
953     if (m_owningLayer->isStackingContext()) {
954         if (!m_owningLayer->hasVisibleDescendant())
955             return false;
956
957         // Use the m_hasCompositingDescendant bit to optimize?
958         if (Vector<RenderLayer*>* negZOrderList = m_owningLayer->negZOrderList()) {
959             size_t listSize = negZOrderList->size();
960             for (size_t i = 0; i < listSize; ++i) {
961                 RenderLayer* curLayer = negZOrderList->at(i);
962                 if (!curLayer->isComposited() && curLayer->hasVisibleContent())
963                     return true;
964             }
965         }
966
967         if (Vector<RenderLayer*>* posZOrderList = m_owningLayer->posZOrderList()) {
968             size_t listSize = posZOrderList->size();
969             for (size_t i = 0; i < listSize; ++i) {
970                 RenderLayer* curLayer = posZOrderList->at(i);
971                 if (!curLayer->isComposited() && curLayer->hasVisibleContent())
972                     return true;
973             }
974         }
975     }
976
977     return false;
978 }
979
980 bool RenderLayerBacking::containsPaintedContent() const
981 {
982     if (isSimpleContainerCompositingLayer() || paintsIntoWindow() || paintsIntoCompositedAncestor() || m_artificiallyInflatedBounds || m_owningLayer->isReflection())
983         return false;
984
985     if (isDirectlyCompositedImage())
986         return false;
987
988     // FIXME: we could optimize cases where the image, video or canvas is known to fill the border box entirely,
989     // and set background color on the layer in that case, instead of allocating backing store and painting.
990 #if ENABLE(VIDEO)
991     if (renderer()->isVideo() && toRenderVideo(renderer())->shouldDisplayVideo())
992         return hasBoxDecorationsOrBackground(renderer());
993 #endif
994 #if PLATFORM(MAC) && USE(CA) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
995 #elif ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
996     if (isAcceleratedCanvas(renderer()))
997         return hasBoxDecorationsOrBackground(renderer());
998 #endif
999
1000     return true;
1001 }
1002
1003 // An image can be directly compositing if it's the sole content of the layer, and has no box decorations
1004 // that require painting. Direct compositing saves backing store.
1005 bool RenderLayerBacking::isDirectlyCompositedImage() const
1006 {
1007     RenderObject* renderObject = renderer();
1008     
1009     if (!renderObject->isImage() || hasBoxDecorationsOrBackground(renderObject) || renderObject->hasClip())
1010         return false;
1011
1012     RenderImage* imageRenderer = toRenderImage(renderObject);
1013     if (CachedImage* cachedImage = imageRenderer->cachedImage()) {
1014         if (cachedImage->hasImage())
1015             return cachedImage->imageForRenderer(imageRenderer)->isBitmapImage();
1016     }
1017
1018     return false;
1019 }
1020
1021 void RenderLayerBacking::contentChanged(ContentChangeType changeType)
1022 {
1023     if ((changeType == ImageChanged) && isDirectlyCompositedImage()) {
1024         updateImageContents();
1025         return;
1026     }
1027     
1028     if ((changeType == MaskImageChanged) && m_maskLayer) {
1029         // The composited layer bounds relies on box->maskClipRect(), which changes
1030         // when the mask image becomes available.
1031         bool isUpdateRoot = true;
1032         updateAfterLayout(CompositingChildren, isUpdateRoot);
1033     }
1034
1035 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
1036     if ((changeType == CanvasChanged) && isAcceleratedCanvas(renderer())) {
1037         m_graphicsLayer->setContentsNeedsDisplay();
1038         return;
1039     }
1040 #endif
1041 }
1042
1043 void RenderLayerBacking::updateImageContents()
1044 {
1045     ASSERT(renderer()->isImage());
1046     RenderImage* imageRenderer = toRenderImage(renderer());
1047
1048     CachedImage* cachedImage = imageRenderer->cachedImage();
1049     if (!cachedImage)
1050         return;
1051
1052     Image* image = cachedImage->imageForRenderer(imageRenderer);
1053     if (!image)
1054         return;
1055
1056     // We have to wait until the image is fully loaded before setting it on the layer.
1057     if (!cachedImage->isLoaded())
1058         return;
1059
1060     // This is a no-op if the layer doesn't have an inner layer for the image.
1061     m_graphicsLayer->setContentsToImage(image);
1062     updateDrawsContent();
1063     
1064     // Image animation is "lazy", in that it automatically stops unless someone is drawing
1065     // the image. So we have to kick the animation each time; this has the downside that the
1066     // image will keep animating, even if its layer is not visible.
1067     image->startAnimation();
1068 }
1069
1070 FloatPoint3D RenderLayerBacking::computeTransformOrigin(const IntRect& borderBox) const
1071 {
1072     RenderStyle* style = renderer()->style();
1073
1074     FloatPoint3D origin;
1075     origin.setX(floatValueForLength(style->transformOriginX(), borderBox.width()));
1076     origin.setY(floatValueForLength(style->transformOriginY(), borderBox.height()));
1077     origin.setZ(style->transformOriginZ());
1078
1079     return origin;
1080 }
1081
1082 FloatPoint RenderLayerBacking::computePerspectiveOrigin(const IntRect& borderBox) const
1083 {
1084     RenderStyle* style = renderer()->style();
1085
1086     float boxWidth = borderBox.width();
1087     float boxHeight = borderBox.height();
1088
1089     FloatPoint origin;
1090     origin.setX(floatValueForLength(style->perspectiveOriginX(), boxWidth));
1091     origin.setY(floatValueForLength(style->perspectiveOriginY(), boxHeight));
1092
1093     return origin;
1094 }
1095
1096 // Return the offset from the top-left of this compositing layer at which the renderer's contents are painted.
1097 IntSize RenderLayerBacking::contentOffsetInCompostingLayer() const
1098 {
1099     return IntSize(-m_compositedBounds.x(), -m_compositedBounds.y());
1100 }
1101
1102 IntRect RenderLayerBacking::contentsBox() const
1103 {
1104     if (!renderer()->isBox())
1105         return IntRect();
1106
1107     IntRect contentsRect;
1108 #if ENABLE(VIDEO)
1109     if (renderer()->isVideo()) {
1110         RenderVideo* videoRenderer = toRenderVideo(renderer());
1111         contentsRect = videoRenderer->videoBox();
1112     } else
1113 #endif
1114         contentsRect = pixelSnappedIntRect(toRenderBox(renderer())->contentBoxRect());
1115
1116     IntSize contentOffset = contentOffsetInCompostingLayer();
1117     contentsRect.move(contentOffset);
1118     return contentsRect;
1119 }
1120
1121 bool RenderLayerBacking::paintsIntoWindow() const
1122 {
1123     if (m_usingTiledCacheLayer)
1124         return false;
1125
1126     if (m_owningLayer->isRootLayer()) {
1127 #if PLATFORM(BLACKBERRY)
1128         if (compositor()->inForcedCompositingMode())
1129             return false;
1130 #endif
1131
1132         return compositor()->rootLayerAttachment() != RenderLayerCompositor::RootLayerAttachedViaEnclosingFrame;
1133     }
1134     
1135     return false;
1136 }
1137
1138 void RenderLayerBacking::setRequiresOwnBackingStore(bool requiresOwnBacking)
1139 {
1140     if (requiresOwnBacking == m_requiresOwnBackingStore)
1141         return;
1142     
1143     // This affects the answer to paintsIntoCompositedAncestor(), which in turn affects
1144     // cached clip rects, so when it changes we have to clear clip rects on descendants.
1145     m_owningLayer->clearClipRectsIncludingDescendants(PaintingClipRects);
1146     m_requiresOwnBackingStore = requiresOwnBacking;
1147     
1148     compositor()->repaintInCompositedAncestor(m_owningLayer, compositedBounds());
1149 }
1150
1151 void RenderLayerBacking::setContentsNeedDisplay()
1152 {
1153     ASSERT(!paintsIntoCompositedAncestor());
1154     
1155     if (m_graphicsLayer && m_graphicsLayer->drawsContent())
1156         m_graphicsLayer->setNeedsDisplay();
1157     
1158     if (m_foregroundLayer && m_foregroundLayer->drawsContent())
1159         m_foregroundLayer->setNeedsDisplay();
1160
1161     if (m_maskLayer && m_maskLayer->drawsContent())
1162         m_maskLayer->setNeedsDisplay();
1163 }
1164
1165 // r is in the coordinate space of the layer's render object
1166 void RenderLayerBacking::setContentsNeedDisplayInRect(const IntRect& r)
1167 {
1168     ASSERT(!paintsIntoCompositedAncestor());
1169
1170     if (m_graphicsLayer && m_graphicsLayer->drawsContent()) {
1171         IntRect layerDirtyRect = r;
1172         layerDirtyRect.move(-m_graphicsLayer->offsetFromRenderer());
1173         m_graphicsLayer->setNeedsDisplayInRect(layerDirtyRect);
1174     }
1175
1176     if (m_foregroundLayer && m_foregroundLayer->drawsContent()) {
1177         IntRect layerDirtyRect = r;
1178         layerDirtyRect.move(-m_foregroundLayer->offsetFromRenderer());
1179         m_foregroundLayer->setNeedsDisplayInRect(layerDirtyRect);
1180     }
1181
1182     if (m_maskLayer && m_maskLayer->drawsContent()) {
1183         IntRect layerDirtyRect = r;
1184         layerDirtyRect.move(-m_maskLayer->offsetFromRenderer());
1185         m_maskLayer->setNeedsDisplayInRect(layerDirtyRect);
1186     }
1187 }
1188
1189 void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* context,
1190                     const IntRect& paintDirtyRect, // In the coords of rootLayer.
1191                     PaintBehavior paintBehavior, GraphicsLayerPaintingPhase paintingPhase,
1192                     RenderObject* paintingRoot)
1193 {
1194     if (paintsIntoWindow() || paintsIntoCompositedAncestor()) {
1195         ASSERT_NOT_REACHED();
1196         return;
1197     }
1198
1199     FontCachePurgePreventer fontCachePurgePreventer;
1200     
1201     RenderLayer::PaintLayerFlags paintFlags = 0;
1202     if (paintingPhase & GraphicsLayerPaintBackground)
1203         paintFlags |= RenderLayer::PaintLayerPaintingCompositingBackgroundPhase;
1204     if (paintingPhase & GraphicsLayerPaintForeground)
1205         paintFlags |= RenderLayer::PaintLayerPaintingCompositingForegroundPhase;
1206     if (paintingPhase & GraphicsLayerPaintMask)
1207         paintFlags |= RenderLayer::PaintLayerPaintingCompositingMaskPhase;
1208         
1209     // FIXME: GraphicsLayers need a way to split for RenderRegions.
1210     m_owningLayer->paintLayerContents(rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, 0, 0, paintFlags);
1211
1212     if (m_owningLayer->containsDirtyOverlayScrollbars())
1213         m_owningLayer->paintOverlayScrollbars(context, paintDirtyRect, paintBehavior, paintingRoot);
1214
1215     ASSERT(!m_owningLayer->m_usedTransparency);
1216 }
1217
1218 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
1219 {
1220     if (!scrollbar)
1221         return;
1222
1223     context.save();
1224     const IntRect& scrollbarRect = scrollbar->frameRect();
1225     context.translate(-scrollbarRect.x(), -scrollbarRect.y());
1226     IntRect transformedClip = clip;
1227     transformedClip.moveBy(scrollbarRect.location());
1228     scrollbar->paint(&context, transformedClip);
1229     context.restore();
1230 }
1231
1232 // Up-call from compositing layer drawing callback.
1233 void RenderLayerBacking::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase paintingPhase, const IntRect& clip)
1234 {
1235 #ifndef NDEBUG
1236     if (Page* page = renderer()->frame()->page())
1237         page->setIsPainting(true);
1238 #endif
1239     if (graphicsLayer == m_graphicsLayer.get() || graphicsLayer == m_foregroundLayer.get() || graphicsLayer == m_maskLayer.get()) {
1240         InspectorInstrumentationCookie cookie = InspectorInstrumentation::willPaint(m_owningLayer->renderer()->frame(), &context, clip);
1241
1242         // The dirtyRect is in the coords of the painting root.
1243         IntRect dirtyRect = compositedBounds();
1244         dirtyRect.intersect(clip);
1245
1246         // We have to use the same root as for hit testing, because both methods can compute and cache clipRects.
1247         paintIntoLayer(m_owningLayer, &context, dirtyRect, PaintBehaviorNormal, paintingPhase, renderer());
1248
1249         if (m_usingTiledCacheLayer)
1250             m_owningLayer->renderer()->frame()->view()->setLastPaintTime(currentTime());
1251
1252         InspectorInstrumentation::didPaint(cookie);
1253     } else if (graphicsLayer == layerForHorizontalScrollbar()) {
1254         paintScrollbar(m_owningLayer->horizontalScrollbar(), context, clip);
1255     } else if (graphicsLayer == layerForVerticalScrollbar()) {
1256         paintScrollbar(m_owningLayer->verticalScrollbar(), context, clip);
1257     } else if (graphicsLayer == layerForScrollCorner()) {
1258         const IntRect& scrollCornerAndResizer = m_owningLayer->scrollCornerAndResizerRect();
1259         context.save();
1260         context.translate(-scrollCornerAndResizer.x(), -scrollCornerAndResizer.y());
1261         IntRect transformedClip = clip;
1262         transformedClip.moveBy(scrollCornerAndResizer.location());
1263         m_owningLayer->paintScrollCorner(&context, IntPoint(), transformedClip);
1264         m_owningLayer->paintResizer(&context, IntPoint(), transformedClip);
1265         context.restore();
1266     }
1267 #ifndef NDEBUG
1268     if (Page* page = renderer()->frame()->page())
1269         page->setIsPainting(false);
1270 #endif
1271 }
1272
1273 float RenderLayerBacking::pageScaleFactor() const
1274 {
1275     return compositor()->pageScaleFactor();
1276 }
1277
1278 float RenderLayerBacking::deviceScaleFactor() const
1279 {
1280     return compositor()->deviceScaleFactor();
1281 }
1282
1283 void RenderLayerBacking::didCommitChangesForLayer(const GraphicsLayer*) const
1284 {
1285     compositor()->didFlushChangesForLayer(m_owningLayer);
1286 }
1287
1288 bool RenderLayerBacking::showDebugBorders(const GraphicsLayer*) const
1289 {
1290     return compositor() ? compositor()->compositorShowDebugBorders() : false;
1291 }
1292
1293 bool RenderLayerBacking::showRepaintCounter(const GraphicsLayer*) const
1294 {
1295     return compositor() ? compositor()->compositorShowRepaintCounter() : false;
1296 }
1297
1298 #ifndef NDEBUG
1299 void RenderLayerBacking::verifyNotPainting()
1300 {
1301     ASSERT(!renderer()->frame()->page() || !renderer()->frame()->page()->isPainting());
1302 }
1303 #endif
1304
1305 bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim, const KeyframeList& keyframes)
1306 {
1307     bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity);
1308     bool hasTransform = renderer()->isBox() && keyframes.containsProperty(CSSPropertyWebkitTransform);
1309 #if ENABLE(CSS_FILTERS)
1310     bool hasFilter = keyframes.containsProperty(CSSPropertyWebkitFilter);
1311 #else
1312     bool hasFilter = false;
1313 #endif
1314
1315     if (!hasOpacity && !hasTransform && !hasFilter)
1316         return false;
1317     
1318     KeyframeValueList transformVector(AnimatedPropertyWebkitTransform);
1319     KeyframeValueList opacityVector(AnimatedPropertyOpacity);
1320 #if ENABLE(CSS_FILTERS)
1321     KeyframeValueList filterVector(AnimatedPropertyWebkitFilter);
1322 #endif
1323
1324     size_t numKeyframes = keyframes.size();
1325     for (size_t i = 0; i < numKeyframes; ++i) {
1326         const KeyframeValue& currentKeyframe = keyframes[i];
1327         const RenderStyle* keyframeStyle = currentKeyframe.style();
1328         float key = currentKeyframe.key();
1329
1330         if (!keyframeStyle)
1331             continue;
1332             
1333         // Get timing function.
1334         RefPtr<TimingFunction> tf = keyframeStyle->hasAnimations() ? (*keyframeStyle->animations()).animation(0)->timingFunction() : 0;
1335         
1336         bool isFirstOrLastKeyframe = key == 0 || key == 1;
1337         if ((hasTransform && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitTransform))
1338             transformVector.insert(new TransformAnimationValue(key, &(keyframeStyle->transform()), tf));
1339         
1340         if ((hasOpacity && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyOpacity))
1341             opacityVector.insert(new FloatAnimationValue(key, keyframeStyle->opacity(), tf));
1342
1343 #if ENABLE(CSS_FILTERS)
1344         if ((hasFilter && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitFilter))
1345             filterVector.insert(new FilterAnimationValue(key, &(keyframeStyle->filter()), tf));
1346 #endif
1347     }
1348
1349     bool didAnimateTransform = false;
1350     bool didAnimateOpacity = false;
1351 #if ENABLE(CSS_FILTERS)
1352     bool didAnimateFilter = false;
1353 #endif
1354     
1355     if (hasTransform && m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->pixelSnappedBorderBoxRect().size(), anim, keyframes.animationName(), timeOffset))
1356         didAnimateTransform = true;
1357
1358     if (hasOpacity && m_graphicsLayer->addAnimation(opacityVector, IntSize(), anim, keyframes.animationName(), timeOffset))
1359         didAnimateOpacity = true;
1360
1361 #if ENABLE(CSS_FILTERS)
1362     if (hasFilter && m_graphicsLayer->addAnimation(filterVector, IntSize(), anim, keyframes.animationName(), timeOffset))
1363         didAnimateFilter = true;
1364 #endif
1365
1366 #if ENABLE(CSS_FILTERS)
1367     return didAnimateTransform || didAnimateOpacity || didAnimateFilter;
1368 #else
1369     return didAnimateTransform || didAnimateOpacity;
1370 #endif
1371 }
1372
1373 void RenderLayerBacking::animationPaused(double timeOffset, const String& animationName)
1374 {
1375     m_graphicsLayer->pauseAnimation(animationName, timeOffset);
1376 }
1377
1378 void RenderLayerBacking::animationFinished(const String& animationName)
1379 {
1380     m_graphicsLayer->removeAnimation(animationName);
1381 }
1382
1383 bool RenderLayerBacking::startTransition(double timeOffset, CSSPropertyID property, const RenderStyle* fromStyle, const RenderStyle* toStyle)
1384 {
1385     bool didAnimateOpacity = false;
1386     bool didAnimateTransform = false;
1387 #if ENABLE(CSS_FILTERS)
1388     bool didAnimateFilter = false;
1389 #endif
1390
1391     ASSERT(property != CSSPropertyInvalid);
1392
1393     if (property == CSSPropertyOpacity) {
1394         const Animation* opacityAnim = toStyle->transitionForProperty(CSSPropertyOpacity);
1395         if (opacityAnim && !opacityAnim->isEmptyOrZeroDuration()) {
1396             KeyframeValueList opacityVector(AnimatedPropertyOpacity);
1397             opacityVector.insert(new FloatAnimationValue(0, compositingOpacity(fromStyle->opacity())));
1398             opacityVector.insert(new FloatAnimationValue(1, compositingOpacity(toStyle->opacity())));
1399             // The boxSize param is only used for transform animations (which can only run on RenderBoxes), so we pass an empty size here.
1400             if (m_graphicsLayer->addAnimation(opacityVector, IntSize(), opacityAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyOpacity), timeOffset)) {
1401                 // To ensure that the correct opacity is visible when the animation ends, also set the final opacity.
1402                 updateLayerOpacity(toStyle);
1403                 didAnimateOpacity = true;
1404             }
1405         }
1406     }
1407
1408     if (property == CSSPropertyWebkitTransform && m_owningLayer->hasTransform()) {
1409         const Animation* transformAnim = toStyle->transitionForProperty(CSSPropertyWebkitTransform);
1410         if (transformAnim && !transformAnim->isEmptyOrZeroDuration()) {
1411             KeyframeValueList transformVector(AnimatedPropertyWebkitTransform);
1412             transformVector.insert(new TransformAnimationValue(0, &fromStyle->transform()));
1413             transformVector.insert(new TransformAnimationValue(1, &toStyle->transform()));
1414             if (m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->pixelSnappedBorderBoxRect().size(), transformAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitTransform), timeOffset)) {
1415                 // To ensure that the correct transform is visible when the animation ends, also set the final transform.
1416                 updateLayerTransform(toStyle);
1417                 didAnimateTransform = true;
1418             }
1419         }
1420     }
1421
1422 #if ENABLE(CSS_FILTERS)
1423     if (property == CSSPropertyWebkitFilter && m_owningLayer->hasFilter()) {
1424         const Animation* filterAnim = toStyle->transitionForProperty(CSSPropertyWebkitFilter);
1425         if (filterAnim && !filterAnim->isEmptyOrZeroDuration()) {
1426             KeyframeValueList filterVector(AnimatedPropertyWebkitFilter);
1427             filterVector.insert(new FilterAnimationValue(0, &fromStyle->filter()));
1428             filterVector.insert(new FilterAnimationValue(1, &toStyle->filter()));
1429             if (m_graphicsLayer->addAnimation(filterVector, IntSize(), filterAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitFilter), timeOffset)) {
1430                 // To ensure that the correct filter is visible when the animation ends, also set the final filter.
1431                 updateLayerFilters(toStyle);
1432                 didAnimateFilter = true;
1433             }
1434         }
1435     }
1436 #endif
1437
1438 #if ENABLE(CSS_FILTERS)
1439     return didAnimateOpacity || didAnimateTransform || didAnimateFilter;
1440 #else
1441     return didAnimateOpacity || didAnimateTransform;
1442 #endif
1443 }
1444
1445 void RenderLayerBacking::transitionPaused(double timeOffset, CSSPropertyID property)
1446 {
1447     AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
1448     if (animatedProperty != AnimatedPropertyInvalid)
1449         m_graphicsLayer->pauseAnimation(GraphicsLayer::animationNameForTransition(animatedProperty), timeOffset);
1450 }
1451
1452 void RenderLayerBacking::transitionFinished(CSSPropertyID property)
1453 {
1454     AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
1455     if (animatedProperty != AnimatedPropertyInvalid)
1456         m_graphicsLayer->removeAnimation(GraphicsLayer::animationNameForTransition(animatedProperty));
1457 }
1458
1459 void RenderLayerBacking::notifyAnimationStarted(const GraphicsLayer*, double time)
1460 {
1461     renderer()->animation()->notifyAnimationStarted(renderer(), time);
1462 }
1463
1464 void RenderLayerBacking::notifySyncRequired(const GraphicsLayer*)
1465 {
1466     if (!renderer()->documentBeingDestroyed())
1467         compositor()->scheduleLayerFlush();
1468 }
1469
1470 // This is used for the 'freeze' API, for testing only.
1471 void RenderLayerBacking::suspendAnimations(double time)
1472 {
1473     m_graphicsLayer->suspendAnimations(time);
1474 }
1475
1476 void RenderLayerBacking::resumeAnimations()
1477 {
1478     m_graphicsLayer->resumeAnimations();
1479 }
1480
1481 IntRect RenderLayerBacking::compositedBounds() const
1482 {
1483     return m_compositedBounds;
1484 }
1485
1486 void RenderLayerBacking::setCompositedBounds(const IntRect& bounds)
1487 {
1488     m_compositedBounds = bounds;
1489 }
1490
1491 CSSPropertyID RenderLayerBacking::graphicsLayerToCSSProperty(AnimatedPropertyID property)
1492 {
1493     CSSPropertyID cssProperty = CSSPropertyInvalid;
1494     switch (property) {
1495         case AnimatedPropertyWebkitTransform:
1496             cssProperty = CSSPropertyWebkitTransform;
1497             break;
1498         case AnimatedPropertyOpacity:
1499             cssProperty = CSSPropertyOpacity;
1500             break;
1501         case AnimatedPropertyBackgroundColor:
1502             cssProperty = CSSPropertyBackgroundColor;
1503             break;
1504         case AnimatedPropertyWebkitFilter:
1505 #if ENABLE(CSS_FILTERS)
1506             cssProperty = CSSPropertyWebkitFilter;
1507 #else
1508             ASSERT_NOT_REACHED();
1509 #endif
1510             break;
1511         case AnimatedPropertyInvalid:
1512             ASSERT_NOT_REACHED();
1513     }
1514     return cssProperty;
1515 }
1516
1517 AnimatedPropertyID RenderLayerBacking::cssToGraphicsLayerProperty(CSSPropertyID cssProperty)
1518 {
1519     switch (cssProperty) {
1520         case CSSPropertyWebkitTransform:
1521             return AnimatedPropertyWebkitTransform;
1522         case CSSPropertyOpacity:
1523             return AnimatedPropertyOpacity;
1524         case CSSPropertyBackgroundColor:
1525             return AnimatedPropertyBackgroundColor;
1526 #if ENABLE(CSS_FILTERS)
1527         case CSSPropertyWebkitFilter:
1528             return AnimatedPropertyWebkitFilter;
1529 #endif
1530         default:
1531             // It's fine if we see other css properties here; they are just not accelerated.
1532             break;
1533     }
1534     return AnimatedPropertyInvalid;
1535 }
1536
1537 String RenderLayerBacking::nameForLayer() const
1538 {
1539     String name = renderer()->renderName();
1540     if (Node* node = renderer()->node()) {
1541         if (node->isElementNode())
1542             name += " " + static_cast<Element*>(node)->tagName();
1543         if (node->hasID())
1544             name += " id=\'" + static_cast<Element*>(node)->getIdAttribute() + "\'";
1545
1546         if (node->hasClass()) {
1547             StyledElement* styledElement = static_cast<StyledElement*>(node);
1548             String classes;
1549             for (size_t i = 0; i < styledElement->classNames().size(); ++i) {
1550                 if (i > 0)
1551                     classes += " ";
1552                 classes += styledElement->classNames()[i];
1553             }
1554             name += " class=\'" + classes + "\'";
1555         }
1556     }
1557
1558     if (m_owningLayer->isReflection())
1559         name += " (reflection)";
1560
1561     return name;
1562 }
1563
1564 CompositingLayerType RenderLayerBacking::compositingLayerType() const
1565 {
1566     if (m_graphicsLayer->hasContentsLayer())
1567         return MediaCompositingLayer;
1568
1569     if (m_graphicsLayer->drawsContent())
1570         return m_graphicsLayer->usingTiledLayer() ? TiledCompositingLayer : NormalCompositingLayer;
1571     
1572     return ContainerCompositingLayer;
1573 }
1574
1575 double RenderLayerBacking::backingStoreMemoryEstimate() const
1576 {
1577     double backingMemory;
1578     
1579     // m_ancestorClippingLayer and m_clippingLayer are just used for masking, so have no backing.
1580     backingMemory = m_graphicsLayer->backingStoreMemoryEstimate();
1581     if (m_foregroundLayer)
1582         backingMemory += m_foregroundLayer->backingStoreMemoryEstimate();
1583     if (m_maskLayer)
1584         backingMemory += m_maskLayer->backingStoreMemoryEstimate();
1585
1586     if (m_layerForHorizontalScrollbar)
1587         backingMemory += m_layerForHorizontalScrollbar->backingStoreMemoryEstimate();
1588
1589     if (m_layerForVerticalScrollbar)
1590         backingMemory += m_layerForVerticalScrollbar->backingStoreMemoryEstimate();
1591
1592     if (m_layerForScrollCorner)
1593         backingMemory += m_layerForScrollCorner->backingStoreMemoryEstimate();
1594     
1595     return backingMemory;
1596 }
1597
1598 } // namespace WebCore
1599
1600 #endif // USE(ACCELERATED_COMPOSITING)