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