Home | History | Annotate | Download | only in rendering
      1 /*
      2  * Copyright (C) 2009 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 
     28 #if USE(ACCELERATED_COMPOSITING)
     29 
     30 #include "RenderLayerBacking.h"
     31 
     32 #include "AnimationController.h"
     33 #include "CanvasRenderingContext.h"
     34 #include "CanvasRenderingContext2D.h"
     35 #include "CSSPropertyNames.h"
     36 #include "CSSStyleSelector.h"
     37 #include "FrameView.h"
     38 #include "GraphicsContext.h"
     39 #include "GraphicsLayer.h"
     40 #include "HTMLCanvasElement.h"
     41 #include "HTMLElement.h"
     42 #include "HTMLIFrameElement.h"
     43 #include "HTMLMediaElement.h"
     44 #include "HTMLNames.h"
     45 #include "InspectorInstrumentation.h"
     46 #include "KeyframeList.h"
     47 #include "PluginViewBase.h"
     48 #include "RenderApplet.h"
     49 #include "RenderBox.h"
     50 #include "RenderIFrame.h"
     51 #include "RenderImage.h"
     52 #include "RenderLayerCompositor.h"
     53 #include "RenderEmbeddedObject.h"
     54 #include "RenderVideo.h"
     55 #include "RenderView.h"
     56 #include "Settings.h"
     57 
     58 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
     59 #include "GraphicsContext3D.h"
     60 #endif
     61 
     62 using namespace std;
     63 
     64 namespace WebCore {
     65 
     66 using namespace HTMLNames;
     67 
     68 static bool hasBorderOutlineOrShadow(const RenderStyle*);
     69 static bool hasBoxDecorationsOrBackground(const RenderObject*);
     70 static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle*);
     71 static IntRect clipBox(RenderBox* renderer);
     72 
     73 static inline bool isAcceleratedCanvas(RenderObject* renderer)
     74 {
     75 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
     76     if (renderer->isCanvas()) {
     77         HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
     78         if (CanvasRenderingContext* context = canvas->renderingContext())
     79             return context->isAccelerated();
     80     }
     81 #else
     82     UNUSED_PARAM(renderer);
     83 #endif
     84     return false;
     85 }
     86 
     87 RenderLayerBacking::RenderLayerBacking(RenderLayer* layer)
     88     : m_owningLayer(layer)
     89     , m_artificiallyInflatedBounds(false)
     90 {
     91     createGraphicsLayer();
     92 }
     93 
     94 RenderLayerBacking::~RenderLayerBacking()
     95 {
     96     updateClippingLayers(false, false);
     97     updateOverflowControlsLayers(false, false, false);
     98     updateForegroundLayer(false);
     99     updateMaskLayer(false);
    100     destroyGraphicsLayer();
    101 }
    102 
    103 void RenderLayerBacking::createGraphicsLayer()
    104 {
    105     m_graphicsLayer = GraphicsLayer::create(this);
    106 
    107 #ifndef NDEBUG
    108     m_graphicsLayer->setName(nameForLayer());
    109 #endif  // NDEBUG
    110 
    111 #if USE(ACCELERATED_COMPOSITING)
    112     ASSERT(renderer() && renderer()->document() && renderer()->document()->frame());
    113     if (Frame* frame = renderer()->document()->frame())
    114         m_graphicsLayer->setContentsScale(frame->pageScaleFactor());
    115 #endif
    116 
    117     updateLayerOpacity(renderer()->style());
    118     updateLayerTransform(renderer()->style());
    119 }
    120 
    121 void RenderLayerBacking::destroyGraphicsLayer()
    122 {
    123     if (m_graphicsLayer)
    124         m_graphicsLayer->removeFromParent();
    125 
    126     m_graphicsLayer = 0;
    127     m_foregroundLayer = 0;
    128     m_clippingLayer = 0;
    129     m_maskLayer = 0;
    130 }
    131 
    132 void RenderLayerBacking::updateLayerOpacity(const RenderStyle* style)
    133 {
    134     m_graphicsLayer->setOpacity(compositingOpacity(style->opacity()));
    135 }
    136 
    137 void RenderLayerBacking::updateLayerTransform(const RenderStyle* style)
    138 {
    139     // FIXME: This could use m_owningLayer->transform(), but that currently has transform-origin
    140     // baked into it, and we don't want that.
    141     TransformationMatrix t;
    142     if (m_owningLayer->hasTransform()) {
    143         style->applyTransform(t, toRenderBox(renderer())->borderBoxRect().size(), RenderStyle::ExcludeTransformOrigin);
    144         makeMatrixRenderable(t, compositor()->canRender3DTransforms());
    145     }
    146 
    147     m_graphicsLayer->setTransform(t);
    148 }
    149 
    150 static bool hasNonZeroTransformOrigin(const RenderObject* renderer)
    151 {
    152     RenderStyle* style = renderer->style();
    153     return (style->transformOriginX().type() == Fixed && style->transformOriginX().value())
    154         || (style->transformOriginY().type() == Fixed && style->transformOriginY().value());
    155 }
    156 
    157 static bool layerOrAncestorIsTransformed(RenderLayer* layer)
    158 {
    159     for (RenderLayer* curr = layer; curr; curr = curr->parent()) {
    160         if (curr->hasTransform())
    161             return true;
    162     }
    163 
    164     return false;
    165 }
    166 
    167 #if ENABLE(FULLSCREEN_API)
    168 static bool layerOrAncestorIsFullScreen(RenderLayer* layer)
    169 {
    170     // Don't traverse through the render layer tree if we do not yet have a full screen renderer.
    171     if (!layer->renderer()->document()->fullScreenRenderer())
    172         return false;
    173 
    174     for (RenderLayer* curr = layer; curr; curr = curr->parent()) {
    175         if (curr->renderer()->isRenderFullScreen())
    176             return true;
    177     }
    178 
    179     return false;
    180 }
    181 #endif
    182 
    183 void RenderLayerBacking::updateCompositedBounds()
    184 {
    185     IntRect layerBounds = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer);
    186 
    187     // Clip to the size of the document or enclosing overflow-scroll layer.
    188     // If this or an ancestor is transformed, we can't currently compute the correct rect to intersect with.
    189     // We'd need RenderObject::convertContainerToLocalQuad(), which doesn't yet exist.  If this
    190     // is a fullscreen renderer, don't clip to the viewport, as the renderer will be asked to
    191     // display outside of the viewport bounds.
    192     if (compositor()->compositingConsultsOverlap() && !layerOrAncestorIsTransformed(m_owningLayer)
    193 #if ENABLE(FULLSCREEN_API)
    194         && !layerOrAncestorIsFullScreen(m_owningLayer)
    195 #endif
    196         ) {
    197         RenderView* view = m_owningLayer->renderer()->view();
    198         RenderLayer* rootLayer = view->layer();
    199 
    200         // Start by clipping to the view's bounds.
    201         IntRect clippingBounds = view->layoutOverflowRect();
    202 
    203         if (m_owningLayer != rootLayer)
    204             clippingBounds.intersect(m_owningLayer->backgroundClipRect(rootLayer, true));
    205 
    206         int deltaX = 0;
    207         int deltaY = 0;
    208         m_owningLayer->convertToLayerCoords(rootLayer, deltaX, deltaY);
    209         clippingBounds.move(-deltaX, -deltaY);
    210 
    211         layerBounds.intersect(clippingBounds);
    212     }
    213 
    214     // If the element has a transform-origin that has fixed lengths, and the renderer has zero size,
    215     // then we need to ensure that the compositing layer has non-zero size so that we can apply
    216     // the transform-origin via the GraphicsLayer anchorPoint (which is expressed as a fractional value).
    217     if (layerBounds.isEmpty() && hasNonZeroTransformOrigin(renderer())) {
    218         layerBounds.setWidth(1);
    219         layerBounds.setHeight(1);
    220         m_artificiallyInflatedBounds = true;
    221     } else
    222         m_artificiallyInflatedBounds = false;
    223 
    224     setCompositedBounds(layerBounds);
    225 }
    226 
    227 void RenderLayerBacking::updateAfterWidgetResize()
    228 {
    229     if (renderer()->isRenderPart()) {
    230         if (RenderLayerCompositor* innerCompositor = RenderLayerCompositor::frameContentsCompositor(toRenderPart(renderer()))) {
    231             innerCompositor->frameViewDidChangeSize();
    232             innerCompositor->frameViewDidChangeLocation(contentsBox().location());
    233         }
    234     }
    235 }
    236 
    237 void RenderLayerBacking::updateAfterLayout(UpdateDepth updateDepth, bool isUpdateRoot)
    238 {
    239     RenderLayerCompositor* layerCompositor = compositor();
    240     if (!layerCompositor->compositingLayersNeedRebuild()) {
    241         // Calling updateGraphicsLayerGeometry() here gives incorrect results, because the
    242         // position of this layer's GraphicsLayer depends on the position of our compositing
    243         // ancestor's GraphicsLayer. That cannot be determined until all the descendant
    244         // RenderLayers of that ancestor have been processed via updateLayerPositions().
    245         //
    246         // The solution is to update compositing children of this layer here,
    247         // via updateCompositingChildrenGeometry().
    248         updateCompositedBounds();
    249         layerCompositor->updateCompositingDescendantGeometry(m_owningLayer, m_owningLayer, updateDepth);
    250 
    251         if (isUpdateRoot) {
    252             updateGraphicsLayerGeometry();
    253             layerCompositor->updateRootLayerPosition();
    254         }
    255     }
    256 }
    257 
    258 bool RenderLayerBacking::updateGraphicsLayerConfiguration()
    259 {
    260     RenderLayerCompositor* compositor = this->compositor();
    261     RenderObject* renderer = this->renderer();
    262 
    263     bool layerConfigChanged = false;
    264     if (updateForegroundLayer(compositor->needsContentsCompositingLayer(m_owningLayer)))
    265         layerConfigChanged = true;
    266 
    267     if (updateClippingLayers(compositor->clippedByAncestor(m_owningLayer), compositor->clipsCompositingDescendants(m_owningLayer)))
    268         layerConfigChanged = true;
    269 
    270     if (updateOverflowControlsLayers(requiresHorizontalScrollbarLayer(), requiresVerticalScrollbarLayer(), requiresScrollCornerLayer()))
    271         layerConfigChanged = true;
    272 
    273     if (layerConfigChanged)
    274         updateInternalHierarchy();
    275 
    276     if (updateMaskLayer(renderer->hasMask()))
    277         m_graphicsLayer->setMaskLayer(m_maskLayer.get());
    278 
    279     if (m_owningLayer->hasReflection()) {
    280         if (m_owningLayer->reflectionLayer()->backing()) {
    281             GraphicsLayer* reflectionLayer = m_owningLayer->reflectionLayer()->backing()->graphicsLayer();
    282             m_graphicsLayer->setReplicatedByLayer(reflectionLayer);
    283         }
    284     } else
    285         m_graphicsLayer->setReplicatedByLayer(0);
    286 
    287     if (isDirectlyCompositedImage())
    288         updateImageContents();
    289 
    290     if ((renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing())
    291         || (renderer->isApplet() && toRenderApplet(renderer)->allowsAcceleratedCompositing())) {
    292         PluginViewBase* pluginViewBase = static_cast<PluginViewBase*>(toRenderWidget(renderer)->widget());
    293         m_graphicsLayer->setContentsToMedia(pluginViewBase->platformLayer());
    294     }
    295 #if ENABLE(VIDEO)
    296     else if (renderer->isVideo()) {
    297         HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(renderer->node());
    298         m_graphicsLayer->setContentsToMedia(mediaElement->platformLayer());
    299     }
    300 #endif
    301 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
    302     else if (isAcceleratedCanvas(renderer)) {
    303         HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
    304         if (CanvasRenderingContext* context = canvas->renderingContext())
    305             m_graphicsLayer->setContentsToCanvas(context->platformLayer());
    306         layerConfigChanged = true;
    307     }
    308 #endif
    309 
    310     if (renderer->isRenderPart())
    311         layerConfigChanged = RenderLayerCompositor::parentFrameContentLayers(toRenderPart(renderer));
    312 
    313     return layerConfigChanged;
    314 }
    315 
    316 static IntRect clipBox(RenderBox* renderer)
    317 {
    318     IntRect result = PaintInfo::infiniteRect();
    319     if (renderer->hasOverflowClip())
    320         result = renderer->overflowClipRect(0, 0);
    321 
    322     if (renderer->hasClip())
    323         result.intersect(renderer->clipRect(0, 0));
    324 
    325     return result;
    326 }
    327 
    328 void RenderLayerBacking::updateGraphicsLayerGeometry()
    329 {
    330     // If we haven't built z-order lists yet, wait until later.
    331     if (m_owningLayer->isStackingContext() && m_owningLayer->m_zOrderListsDirty)
    332         return;
    333 
    334     // Set transform property, if it is not animating. We have to do this here because the transform
    335     // is affected by the layer dimensions.
    336     if (!renderer()->animation()->isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyWebkitTransform))
    337         updateLayerTransform(renderer()->style());
    338 
    339     // Set opacity, if it is not animating.
    340     if (!renderer()->animation()->isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyOpacity))
    341         updateLayerOpacity(renderer()->style());
    342 
    343     RenderStyle* style = renderer()->style();
    344     m_graphicsLayer->setPreserves3D(style->transformStyle3D() == TransformStyle3DPreserve3D && !renderer()->hasReflection());
    345     m_graphicsLayer->setBackfaceVisibility(style->backfaceVisibility() == BackfaceVisibilityVisible);
    346 
    347     RenderLayer* compAncestor = m_owningLayer->ancestorCompositingLayer();
    348 
    349     // We compute everything relative to the enclosing compositing layer.
    350     IntRect ancestorCompositingBounds;
    351     if (compAncestor) {
    352         ASSERT(compAncestor->backing());
    353         ancestorCompositingBounds = compAncestor->backing()->compositedBounds();
    354     }
    355 
    356     IntRect localCompositingBounds = compositedBounds();
    357 
    358     IntRect relativeCompositingBounds(localCompositingBounds);
    359     int deltaX = 0, deltaY = 0;
    360     m_owningLayer->convertToLayerCoords(compAncestor, deltaX, deltaY);
    361     relativeCompositingBounds.move(deltaX, deltaY);
    362 
    363     IntPoint graphicsLayerParentLocation;
    364     if (compAncestor && compAncestor->backing()->hasClippingLayer()) {
    365         // If the compositing ancestor has a layer to clip children, we parent in that, and therefore
    366         // position relative to it.
    367         IntRect clippingBox = clipBox(toRenderBox(compAncestor->renderer()));
    368         graphicsLayerParentLocation = clippingBox.location();
    369     } else
    370         graphicsLayerParentLocation = ancestorCompositingBounds.location();
    371 
    372     if (compAncestor && m_ancestorClippingLayer) {
    373         // Call calculateRects to get the backgroundRect which is what is used to clip the contents of this
    374         // layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects
    375         // for a compositing layer, rootLayer is the layer itself.
    376         IntRect parentClipRect = m_owningLayer->backgroundClipRect(compAncestor, true);
    377         ASSERT(parentClipRect != PaintInfo::infiniteRect());
    378         m_ancestorClippingLayer->setPosition(FloatPoint() + (parentClipRect.location() - graphicsLayerParentLocation));
    379         m_ancestorClippingLayer->setSize(parentClipRect.size());
    380 
    381         // backgroundRect is relative to compAncestor, so subtract deltaX/deltaY to get back to local coords.
    382         IntSize rendererOffset(parentClipRect.location().x() - deltaX, parentClipRect.location().y() - deltaY);
    383         m_ancestorClippingLayer->setOffsetFromRenderer(rendererOffset);
    384 
    385         // The primary layer is then parented in, and positioned relative to this clipping layer.
    386         graphicsLayerParentLocation = parentClipRect.location();
    387     }
    388 
    389     m_graphicsLayer->setPosition(FloatPoint() + (relativeCompositingBounds.location() - graphicsLayerParentLocation));
    390 
    391     IntSize oldOffsetFromRenderer = m_graphicsLayer->offsetFromRenderer();
    392     m_graphicsLayer->setOffsetFromRenderer(localCompositingBounds.location() - IntPoint());
    393 
    394     // If the compositing layer offset changes, we need to repaint.
    395     if (oldOffsetFromRenderer != m_graphicsLayer->offsetFromRenderer())
    396         m_graphicsLayer->setNeedsDisplay();
    397 
    398     FloatSize oldSize = m_graphicsLayer->size();
    399     FloatSize newSize = relativeCompositingBounds.size();
    400     if (oldSize != newSize) {
    401         m_graphicsLayer->setSize(newSize);
    402         // A bounds change will almost always require redisplay. Usually that redisplay
    403         // will happen because of a repaint elsewhere, but not always:
    404         // e.g. see RenderView::setMaximalOutlineSize()
    405         m_graphicsLayer->setNeedsDisplay();
    406     }
    407 
    408     // If we have a layer that clips children, position it.
    409     IntRect clippingBox;
    410     if (m_clippingLayer) {
    411         clippingBox = clipBox(toRenderBox(renderer()));
    412         m_clippingLayer->setPosition(FloatPoint() + (clippingBox.location() - localCompositingBounds.location()));
    413         m_clippingLayer->setSize(clippingBox.size());
    414         m_clippingLayer->setOffsetFromRenderer(clippingBox.location() - IntPoint());
    415     }
    416 
    417     if (m_maskLayer) {
    418         if (m_maskLayer->size() != m_graphicsLayer->size()) {
    419             m_maskLayer->setSize(m_graphicsLayer->size());
    420             m_maskLayer->setNeedsDisplay();
    421         }
    422         m_maskLayer->setPosition(FloatPoint());
    423     }
    424 
    425     if (m_owningLayer->hasTransform()) {
    426         const IntRect borderBox = toRenderBox(renderer())->borderBoxRect();
    427 
    428         // Get layout bounds in the coords of compAncestor to match relativeCompositingBounds.
    429         IntRect layerBounds = IntRect(deltaX, deltaY, borderBox.width(), borderBox.height());
    430 
    431         // Update properties that depend on layer dimensions
    432         FloatPoint3D transformOrigin = computeTransformOrigin(borderBox);
    433         // Compute the anchor point, which is in the center of the renderer box unless transform-origin is set.
    434         FloatPoint3D anchor(relativeCompositingBounds.width()  != 0.0f ? ((layerBounds.x() - relativeCompositingBounds.x()) + transformOrigin.x()) / relativeCompositingBounds.width()  : 0.5f,
    435                             relativeCompositingBounds.height() != 0.0f ? ((layerBounds.y() - relativeCompositingBounds.y()) + transformOrigin.y()) / relativeCompositingBounds.height() : 0.5f,
    436                             transformOrigin.z());
    437         m_graphicsLayer->setAnchorPoint(anchor);
    438 
    439         RenderStyle* style = renderer()->style();
    440         if (style->hasPerspective()) {
    441             TransformationMatrix t = owningLayer()->perspectiveTransform();
    442 
    443             if (m_clippingLayer) {
    444                 m_clippingLayer->setChildrenTransform(t);
    445                 m_graphicsLayer->setChildrenTransform(TransformationMatrix());
    446             }
    447             else
    448                 m_graphicsLayer->setChildrenTransform(t);
    449         } else {
    450             if (m_clippingLayer)
    451                 m_clippingLayer->setChildrenTransform(TransformationMatrix());
    452             else
    453                 m_graphicsLayer->setChildrenTransform(TransformationMatrix());
    454         }
    455     } else {
    456         m_graphicsLayer->setAnchorPoint(FloatPoint3D(0.5f, 0.5f, 0));
    457     }
    458 
    459     if (m_foregroundLayer) {
    460         FloatPoint foregroundPosition;
    461         FloatSize foregroundSize = newSize;
    462         IntSize foregroundOffset = m_graphicsLayer->offsetFromRenderer();
    463         if (m_clippingLayer) {
    464             // If we have a clipping layer (which clips descendants), then the foreground layer is a child of it,
    465             // so that it gets correctly sorted with children. In that case, position relative to the clipping layer.
    466             foregroundSize = FloatSize(clippingBox.size());
    467             foregroundOffset = clippingBox.location() - IntPoint();
    468         }
    469 
    470         m_foregroundLayer->setPosition(foregroundPosition);
    471         m_foregroundLayer->setSize(foregroundSize);
    472         m_foregroundLayer->setOffsetFromRenderer(foregroundOffset);
    473     }
    474 
    475     if (m_owningLayer->reflectionLayer() && m_owningLayer->reflectionLayer()->isComposited()) {
    476         RenderLayerBacking* reflectionBacking = m_owningLayer->reflectionLayer()->backing();
    477         reflectionBacking->updateGraphicsLayerGeometry();
    478 
    479         // The reflection layer has the bounds of m_owningLayer->reflectionLayer(),
    480         // but the reflected layer is the bounds of this layer, so we need to position it appropriately.
    481         FloatRect layerBounds = compositedBounds();
    482         FloatRect reflectionLayerBounds = reflectionBacking->compositedBounds();
    483         reflectionBacking->graphicsLayer()->setReplicatedLayerPosition(FloatPoint() + (layerBounds.location() - reflectionLayerBounds.location()));
    484     }
    485 
    486     m_graphicsLayer->setContentsRect(contentsBox());
    487     updateDrawsContent();
    488     updateAfterWidgetResize();
    489 }
    490 
    491 void RenderLayerBacking::updateInternalHierarchy()
    492 {
    493     // m_foregroundLayer has to be inserted in the correct order with child layers,
    494     // so it's not inserted here.
    495     if (m_ancestorClippingLayer) {
    496         m_ancestorClippingLayer->removeAllChildren();
    497         m_graphicsLayer->removeFromParent();
    498         m_ancestorClippingLayer->addChild(m_graphicsLayer.get());
    499     }
    500 
    501     if (m_clippingLayer) {
    502         m_clippingLayer->removeFromParent();
    503         m_graphicsLayer->addChild(m_clippingLayer.get());
    504 
    505         // The clip for child layers does not include space for overflow controls, so they exist as
    506         // siblings of the clipping layer if we have one. Normal children of this layer are set as
    507         // children of the clipping layer.
    508         if (m_layerForHorizontalScrollbar) {
    509             m_layerForHorizontalScrollbar->removeFromParent();
    510             m_graphicsLayer->addChild(m_layerForHorizontalScrollbar.get());
    511         }
    512         if (m_layerForVerticalScrollbar) {
    513             m_layerForVerticalScrollbar->removeFromParent();
    514             m_graphicsLayer->addChild(m_layerForVerticalScrollbar.get());
    515         }
    516         if (m_layerForScrollCorner) {
    517             m_layerForScrollCorner->removeFromParent();
    518             m_graphicsLayer->addChild(m_layerForScrollCorner.get());
    519         }
    520     }
    521 }
    522 
    523 void RenderLayerBacking::updateDrawsContent()
    524 {
    525     m_graphicsLayer->setDrawsContent(containsPaintedContent());
    526 }
    527 
    528 // Return true if the layers changed.
    529 bool RenderLayerBacking::updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip)
    530 {
    531     bool layersChanged = false;
    532 
    533     if (needsAncestorClip) {
    534         if (!m_ancestorClippingLayer) {
    535             m_ancestorClippingLayer = GraphicsLayer::create(this);
    536 #ifndef NDEBUG
    537             m_ancestorClippingLayer->setName("Ancestor clipping Layer");
    538 #endif
    539             m_ancestorClippingLayer->setMasksToBounds(true);
    540             layersChanged = true;
    541         }
    542     } else if (m_ancestorClippingLayer) {
    543         m_ancestorClippingLayer->removeFromParent();
    544         m_ancestorClippingLayer = 0;
    545         layersChanged = true;
    546     }
    547 
    548     if (needsDescendantClip) {
    549         if (!m_clippingLayer) {
    550             m_clippingLayer = GraphicsLayer::create(this);
    551 #ifndef NDEBUG
    552             m_clippingLayer->setName("Child clipping Layer");
    553 #endif
    554             m_clippingLayer->setMasksToBounds(true);
    555             layersChanged = true;
    556         }
    557     } else if (m_clippingLayer) {
    558         m_clippingLayer->removeFromParent();
    559         m_clippingLayer = 0;
    560         layersChanged = true;
    561     }
    562 
    563     return layersChanged;
    564 }
    565 
    566 bool RenderLayerBacking::requiresHorizontalScrollbarLayer() const
    567 {
    568 #if !PLATFORM(CHROMIUM)
    569     if (!m_owningLayer->hasOverlayScrollbars())
    570         return false;
    571 #endif
    572     return m_owningLayer->horizontalScrollbar();
    573 }
    574 
    575 bool RenderLayerBacking::requiresVerticalScrollbarLayer() const
    576 {
    577 #if !PLATFORM(CHROMIUM)
    578     if (!m_owningLayer->hasOverlayScrollbars())
    579         return false;
    580 #endif
    581     return m_owningLayer->verticalScrollbar();
    582 }
    583 
    584 bool RenderLayerBacking::requiresScrollCornerLayer() const
    585 {
    586 #if !PLATFORM(CHROMIUM)
    587     if (!m_owningLayer->hasOverlayScrollbars())
    588         return false;
    589 #endif
    590     return !m_owningLayer->scrollCornerAndResizerRect().isEmpty();
    591 }
    592 
    593 bool RenderLayerBacking::updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer)
    594 {
    595     bool layersChanged = false;
    596     if (needsHorizontalScrollbarLayer) {
    597         if (!m_layerForHorizontalScrollbar) {
    598             m_layerForHorizontalScrollbar = GraphicsLayer::create(this);
    599 #ifndef NDEBUG
    600             m_layerForHorizontalScrollbar ->setName("horizontal scrollbar");
    601 #endif
    602             layersChanged = true;
    603         }
    604     } else if (m_layerForHorizontalScrollbar) {
    605         m_layerForHorizontalScrollbar.clear();
    606         layersChanged = true;
    607     }
    608 
    609     if (needsVerticalScrollbarLayer) {
    610         if (!m_layerForVerticalScrollbar) {
    611             m_layerForVerticalScrollbar = GraphicsLayer::create(this);
    612 #ifndef NDEBUG
    613             m_layerForVerticalScrollbar->setName("vertical scrollbar");
    614 #endif
    615             layersChanged = true;
    616         }
    617     } else if (m_layerForVerticalScrollbar) {
    618         m_layerForVerticalScrollbar.clear();
    619         layersChanged = true;
    620     }
    621 
    622     if (needsScrollCornerLayer) {
    623         if (!m_layerForScrollCorner) {
    624             m_layerForScrollCorner = GraphicsLayer::create(this);
    625 #ifndef NDEBUG
    626             m_layerForScrollCorner->setName("scroll corner");
    627 #endif
    628             layersChanged = true;
    629         }
    630     } else if (m_layerForScrollCorner) {
    631         m_layerForScrollCorner.clear();
    632         layersChanged = true;
    633     }
    634 
    635     return layersChanged;
    636 }
    637 
    638 bool RenderLayerBacking::updateForegroundLayer(bool needsForegroundLayer)
    639 {
    640     bool layerChanged = false;
    641     if (needsForegroundLayer) {
    642         if (!m_foregroundLayer) {
    643             m_foregroundLayer = GraphicsLayer::create(this);
    644 #ifndef NDEBUG
    645             m_foregroundLayer->setName(nameForLayer() + " (foreground)");
    646 #endif
    647             m_foregroundLayer->setDrawsContent(true);
    648             m_foregroundLayer->setPaintingPhase(GraphicsLayerPaintForeground);
    649             if (Frame* frame = renderer()->document()->frame())
    650                 m_foregroundLayer->setContentsScale(frame->pageScaleFactor());
    651             layerChanged = true;
    652         }
    653     } else if (m_foregroundLayer) {
    654         m_foregroundLayer->removeFromParent();
    655         m_foregroundLayer = 0;
    656         layerChanged = true;
    657     }
    658 
    659     if (layerChanged)
    660         m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
    661 
    662     return layerChanged;
    663 }
    664 
    665 bool RenderLayerBacking::updateMaskLayer(bool needsMaskLayer)
    666 {
    667     bool layerChanged = false;
    668     if (needsMaskLayer) {
    669         if (!m_maskLayer) {
    670             m_maskLayer = GraphicsLayer::create(this);
    671 #ifndef NDEBUG
    672             m_maskLayer->setName("Mask");
    673 #endif
    674             m_maskLayer->setDrawsContent(true);
    675             m_maskLayer->setPaintingPhase(GraphicsLayerPaintMask);
    676             if (Frame* frame = renderer()->document()->frame())
    677                 m_maskLayer->setContentsScale(frame->pageScaleFactor());
    678             layerChanged = true;
    679         }
    680     } else if (m_maskLayer) {
    681         m_maskLayer = 0;
    682         layerChanged = true;
    683     }
    684 
    685     if (layerChanged)
    686         m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
    687 
    688     return layerChanged;
    689 }
    690 
    691 GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() const
    692 {
    693     unsigned phase = GraphicsLayerPaintBackground;
    694     if (!m_foregroundLayer)
    695         phase |= GraphicsLayerPaintForeground;
    696     if (!m_maskLayer)
    697         phase |= GraphicsLayerPaintMask;
    698 
    699     return static_cast<GraphicsLayerPaintingPhase>(phase);
    700 }
    701 
    702 float RenderLayerBacking::compositingOpacity(float rendererOpacity) const
    703 {
    704     float finalOpacity = rendererOpacity;
    705 
    706     for (RenderLayer* curr = m_owningLayer->parent(); curr; curr = curr->parent()) {
    707         // We only care about parents that are stacking contexts.
    708         // Recall that opacity creates stacking context.
    709         if (!curr->isStackingContext())
    710             continue;
    711 
    712         // If we found a compositing layer, we want to compute opacity
    713         // relative to it. So we can break here.
    714         if (curr->isComposited())
    715             break;
    716 
    717         finalOpacity *= curr->renderer()->opacity();
    718     }
    719 
    720     return finalOpacity;
    721 }
    722 
    723 static bool hasBorderOutlineOrShadow(const RenderStyle* style)
    724 {
    725     return style->hasBorder() || style->hasBorderRadius() || style->hasOutline() || style->hasAppearance() || style->boxShadow();
    726 }
    727 
    728 static bool hasBoxDecorationsOrBackground(const RenderObject* renderer)
    729 {
    730     return hasBorderOutlineOrShadow(renderer->style()) || renderer->hasBackground();
    731 }
    732 
    733 static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle* style)
    734 {
    735     return hasBorderOutlineOrShadow(style) || style->hasBackgroundImage();
    736 }
    737 
    738 bool RenderLayerBacking::rendererHasBackground() const
    739 {
    740     // FIXME: share more code here
    741     if (renderer()->node() && renderer()->node()->isDocumentNode()) {
    742         RenderObject* htmlObject = renderer()->firstChild();
    743         if (!htmlObject)
    744             return false;
    745 
    746         if (htmlObject->hasBackground())
    747             return true;
    748 
    749         RenderObject* bodyObject = htmlObject->firstChild();
    750         if (!bodyObject)
    751             return false;
    752 
    753         return bodyObject->hasBackground();
    754     }
    755 
    756     return renderer()->hasBackground();
    757 }
    758 
    759 const Color RenderLayerBacking::rendererBackgroundColor() const
    760 {
    761     // FIXME: share more code here
    762     if (renderer()->node() && renderer()->node()->isDocumentNode()) {
    763         RenderObject* htmlObject = renderer()->firstChild();
    764         if (htmlObject->hasBackground())
    765             return htmlObject->style()->visitedDependentColor(CSSPropertyBackgroundColor);
    766 
    767         RenderObject* bodyObject = htmlObject->firstChild();
    768         return bodyObject->style()->visitedDependentColor(CSSPropertyBackgroundColor);
    769     }
    770 
    771     return renderer()->style()->visitedDependentColor(CSSPropertyBackgroundColor);
    772 }
    773 
    774 // A "simple container layer" is a RenderLayer which has no visible content to render.
    775 // It may have no children, or all its children may be themselves composited.
    776 // This is a useful optimization, because it allows us to avoid allocating backing store.
    777 bool RenderLayerBacking::isSimpleContainerCompositingLayer() const
    778 {
    779     RenderObject* renderObject = renderer();
    780     if (renderObject->isReplaced() ||       // replaced objects are not containers
    781         renderObject->hasMask())            // masks require special treatment
    782         return false;
    783 
    784     RenderStyle* style = renderObject->style();
    785 
    786     // Reject anything that has a border, a border-radius or outline,
    787     // or any background (color or image).
    788     // FIXME: we could optimize layers for simple backgrounds.
    789     if (hasBoxDecorationsOrBackground(renderObject))
    790         return false;
    791 
    792     if (m_owningLayer->hasOverflowControls())
    793         return false;
    794 
    795     // If we have got this far and the renderer has no children, then we're ok.
    796     if (!renderObject->firstChild())
    797         return true;
    798 
    799     if (renderObject->node() && renderObject->node()->isDocumentNode()) {
    800         // Look to see if the root object has a non-simple backgound
    801         RenderObject* rootObject = renderObject->document()->documentElement()->renderer();
    802         if (!rootObject)
    803             return false;
    804 
    805         style = rootObject->style();
    806 
    807         // Reject anything that has a border, a border-radius or outline,
    808         // or is not a simple background (no background, or solid color).
    809         if (hasBoxDecorationsOrBackgroundImage(style))
    810             return false;
    811 
    812         // Now look at the body's renderer.
    813         HTMLElement* body = renderObject->document()->body();
    814         RenderObject* bodyObject = (body && body->hasLocalName(bodyTag)) ? body->renderer() : 0;
    815         if (!bodyObject)
    816             return false;
    817 
    818         style = bodyObject->style();
    819 
    820         if (hasBoxDecorationsOrBackgroundImage(style))
    821             return false;
    822 
    823         // Check to see if all the body's children are compositing layers.
    824         if (hasNonCompositingDescendants())
    825             return false;
    826 
    827         return true;
    828     }
    829 
    830     // Check to see if all the renderer's children are compositing layers.
    831     if (hasNonCompositingDescendants())
    832         return false;
    833 
    834     return true;
    835 }
    836 
    837 // Conservative test for having no rendered children.
    838 bool RenderLayerBacking::hasNonCompositingDescendants() const
    839 {
    840     // Some HTML can cause whitespace text nodes to have renderers, like:
    841     // <div>
    842     // <img src=...>
    843     // </div>
    844     // so test for 0x0 RenderTexts here
    845     for (RenderObject* child = renderer()->firstChild(); child; child = child->nextSibling()) {
    846         if (!child->hasLayer()) {
    847             if (child->isRenderInline() || !child->isBox())
    848                 return true;
    849 
    850             if (toRenderBox(child)->width() > 0 || toRenderBox(child)->height() > 0)
    851                 return true;
    852         }
    853     }
    854 
    855     if (m_owningLayer->isStackingContext()) {
    856         // Use the m_hasCompositingDescendant bit to optimize?
    857         if (Vector<RenderLayer*>* negZOrderList = m_owningLayer->negZOrderList()) {
    858             size_t listSize = negZOrderList->size();
    859             for (size_t i = 0; i < listSize; ++i) {
    860                 RenderLayer* curLayer = negZOrderList->at(i);
    861                 if (!curLayer->isComposited())
    862                     return true;
    863             }
    864         }
    865 
    866         if (Vector<RenderLayer*>* posZOrderList = m_owningLayer->posZOrderList()) {
    867             size_t listSize = posZOrderList->size();
    868             for (size_t i = 0; i < listSize; ++i) {
    869                 RenderLayer* curLayer = posZOrderList->at(i);
    870                 if (!curLayer->isComposited())
    871                     return true;
    872             }
    873         }
    874     }
    875 
    876     if (Vector<RenderLayer*>* normalFlowList = m_owningLayer->normalFlowList()) {
    877         size_t listSize = normalFlowList->size();
    878         for (size_t i = 0; i < listSize; ++i) {
    879             RenderLayer* curLayer = normalFlowList->at(i);
    880             if (!curLayer->isComposited())
    881                 return true;
    882         }
    883     }
    884 
    885     return false;
    886 }
    887 
    888 bool RenderLayerBacking::containsPaintedContent() const
    889 {
    890     if (isSimpleContainerCompositingLayer() || paintingGoesToWindow() || m_artificiallyInflatedBounds || m_owningLayer->isReflection())
    891         return false;
    892 
    893     if (isDirectlyCompositedImage())
    894         return false;
    895 
    896     // FIXME: we could optimize cases where the image, video or canvas is known to fill the border box entirely,
    897     // and set background color on the layer in that case, instead of allocating backing store and painting.
    898 #if ENABLE(VIDEO)
    899     if (renderer()->isVideo() && toRenderVideo(renderer())->shouldDisplayVideo())
    900         return hasBoxDecorationsOrBackground(renderer());
    901 #endif
    902 #if PLATFORM(MAC) && USE(CA) && !defined(BUILDING_ON_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.
    913 bool RenderLayerBacking::isDirectlyCompositedImage() const
    914 {
    915     RenderObject* renderObject = renderer();
    916 
    917     if (!renderObject->isImage() || hasBoxDecorationsOrBackground(renderObject) || renderObject->hasClip())
    918         return false;
    919 
    920     RenderImage* imageRenderer = toRenderImage(renderObject);
    921     if (CachedImage* cachedImage = imageRenderer->cachedImage()) {
    922         if (cachedImage->hasImage())
    923             return cachedImage->image()->isBitmapImage();
    924     }
    925 
    926     return false;
    927 }
    928 
    929 void RenderLayerBacking::contentChanged(RenderLayer::ContentChangeType changeType)
    930 {
    931     if ((changeType == RenderLayer::ImageChanged) && isDirectlyCompositedImage()) {
    932         updateImageContents();
    933         return;
    934     }
    935 
    936     if ((changeType == RenderLayer::MaskImageChanged) && m_maskLayer) {
    937         // The composited layer bounds relies on box->maskClipRect(), which changes
    938         // when the mask image becomes available.
    939         bool isUpdateRoot = true;
    940         updateAfterLayout(CompositingChildren, isUpdateRoot);
    941     }
    942 
    943 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
    944     if ((changeType == RenderLayer::CanvasChanged) && isAcceleratedCanvas(renderer())) {
    945         m_graphicsLayer->setContentsNeedsDisplay();
    946         return;
    947     }
    948 #endif
    949 }
    950 
    951 void RenderLayerBacking::updateImageContents()
    952 {
    953     ASSERT(renderer()->isImage());
    954     RenderImage* imageRenderer = toRenderImage(renderer());
    955 
    956     CachedImage* cachedImage = imageRenderer->cachedImage();
    957     if (!cachedImage)
    958         return;
    959 
    960     Image* image = cachedImage->image();
    961     if (!image)
    962         return;
    963 
    964     // We have to wait until the image is fully loaded before setting it on the layer.
    965     if (!cachedImage->isLoaded())
    966         return;
    967 
    968     // This is a no-op if the layer doesn't have an inner layer for the image.
    969     m_graphicsLayer->setContentsToImage(image);
    970 
    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 
    977 FloatPoint3D 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 
    989 FloatPoint 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.
   1004 IntSize RenderLayerBacking::contentOffsetInCompostingLayer() const
   1005 {
   1006     return IntSize(-m_compositedBounds.x(), -m_compositedBounds.y());
   1007 }
   1008 
   1009 IntRect 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 
   1028 bool RenderLayerBacking::paintingGoesToWindow() const
   1029 {
   1030     if (m_owningLayer->isRootLayer())
   1031         return compositor()->rootLayerAttachment() != RenderLayerCompositor::RootLayerAttachedViaEnclosingFrame;
   1032 
   1033     return false;
   1034 }
   1035 
   1036 void 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
   1049 void 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 
   1070 static 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 
   1078 static 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?
   1086 void 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 
   1220 static 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.
   1235 void 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 
   1277 bool RenderLayerBacking::showDebugBorders() const
   1278 {
   1279     return compositor() ? compositor()->compositorShowDebugBorders() : false;
   1280 }
   1281 
   1282 bool RenderLayerBacking::showRepaintCounter() const
   1283 {
   1284     return compositor() ? compositor()->compositorShowRepaintCounter() : false;
   1285 }
   1286 
   1287 bool 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 
   1334 void RenderLayerBacking::animationPaused(double timeOffset, const String& animationName)
   1335 {
   1336     m_graphicsLayer->pauseAnimation(animationName, timeOffset);
   1337 }
   1338 
   1339 void RenderLayerBacking::animationFinished(const String& animationName)
   1340 {
   1341     m_graphicsLayer->removeAnimation(animationName);
   1342 }
   1343 
   1344 bool 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 
   1388 void 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 
   1395 void RenderLayerBacking::transitionFinished(int property)
   1396 {
   1397     AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
   1398     if (animatedProperty != AnimatedPropertyInvalid)
   1399         m_graphicsLayer->removeAnimation(GraphicsLayer::animationNameForTransition(animatedProperty));
   1400 }
   1401 
   1402 void RenderLayerBacking::notifyAnimationStarted(const GraphicsLayer*, double time)
   1403 {
   1404     renderer()->animation()->notifyAnimationStarted(renderer(), time);
   1405 }
   1406 
   1407 void 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.
   1414 void RenderLayerBacking::suspendAnimations(double time)
   1415 {
   1416     m_graphicsLayer->suspendAnimations(time);
   1417 }
   1418 
   1419 void RenderLayerBacking::resumeAnimations()
   1420 {
   1421     m_graphicsLayer->resumeAnimations();
   1422 }
   1423 
   1424 IntRect RenderLayerBacking::compositedBounds() const
   1425 {
   1426     return m_compositedBounds;
   1427 }
   1428 
   1429 void RenderLayerBacking::setCompositedBounds(const IntRect& bounds)
   1430 {
   1431     m_compositedBounds = bounds;
   1432 
   1433 }
   1434 int 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 
   1453 AnimatedPropertyID 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
   1468 String 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 
   1485 CompositingLayerType 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 
   1496 void 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