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