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