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