Home | History | Annotate | Download | only in rendering
      1 /*
      2  * Copyright (C) 2009, 2010 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 #include "RenderLayerCompositor.h"
     30 
     31 #include "AnimationController.h"
     32 #include "CanvasRenderingContext.h"
     33 #include "CSSPropertyNames.h"
     34 #include "Chrome.h"
     35 #include "ChromeClient.h"
     36 #include "Frame.h"
     37 #include "FrameView.h"
     38 #include "GraphicsLayer.h"
     39 #include "HTMLCanvasElement.h"
     40 #include "HTMLIFrameElement.h"
     41 #include "HTMLNames.h"
     42 #include "HitTestResult.h"
     43 #include "NodeList.h"
     44 #include "Page.h"
     45 #include "RenderApplet.h"
     46 #include "RenderEmbeddedObject.h"
     47 #include "RenderFullScreen.h"
     48 #include "RenderIFrame.h"
     49 #include "RenderLayerBacking.h"
     50 #include "RenderReplica.h"
     51 #include "RenderVideo.h"
     52 #include "RenderView.h"
     53 #include "Settings.h"
     54 
     55 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
     56 #include "HTMLMediaElement.h"
     57 #endif
     58 
     59 #if PROFILE_LAYER_REBUILD
     60 #include <wtf/CurrentTime.h>
     61 #endif
     62 
     63 #ifndef NDEBUG
     64 #include "RenderTreeAsText.h"
     65 #endif
     66 
     67 #if ENABLE(3D_RENDERING)
     68 // This symbol is used to determine from a script whether 3D rendering is enabled (via 'nm').
     69 bool WebCoreHas3DRendering = true;
     70 #endif
     71 
     72 namespace WebCore {
     73 
     74 using namespace HTMLNames;
     75 
     76 struct CompositingState {
     77     CompositingState(RenderLayer* compAncestor)
     78         : m_compositingAncestor(compAncestor)
     79         , m_subtreeIsCompositing(false)
     80 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
     81         , m_positionedSibling(false)
     82         , m_hasFixedElement(false)
     83 #endif
     84 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
     85         , m_hasScrollableElement(false)
     86 #endif
     87 #ifndef NDEBUG
     88         , m_depth(0)
     89 #endif
     90     {
     91     }
     92 
     93     RenderLayer* m_compositingAncestor;
     94     bool m_subtreeIsCompositing;
     95     // m_compositingBounds is only used in computeCompositingRequirements. It can be either the
     96     // ancestor bounds or the bounds for the sibling layers which are above the composited layer.
     97     // It is used to reject creating unnecesary layers.
     98     IntRect m_compositingBounds;
     99 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
    100     bool m_positionedSibling;
    101     bool m_hasFixedElement;
    102 #endif
    103 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
    104     bool m_hasScrollableElement;
    105 #endif
    106 #ifndef NDEBUG
    107     int m_depth;
    108 #endif
    109 };
    110 
    111 RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView)
    112     : m_renderView(renderView)
    113     , m_rootPlatformLayer(0)
    114     , m_updateCompositingLayersTimer(this, &RenderLayerCompositor::updateCompositingLayersTimerFired)
    115     , m_hasAcceleratedCompositing(true)
    116     , m_compositingTriggers(static_cast<ChromeClient::CompositingTriggerFlags>(ChromeClient::AllTriggers))
    117     , m_showDebugBorders(false)
    118     , m_showRepaintCounter(false)
    119     , m_compositingConsultsOverlap(true)
    120     , m_compositingDependsOnGeometry(false)
    121     , m_compositing(false)
    122     , m_compositingLayersNeedRebuild(false)
    123     , m_flushingLayers(false)
    124     , m_forceCompositingMode(false)
    125     , m_rootLayerAttachment(RootLayerUnattached)
    126 #if PROFILE_LAYER_REBUILD
    127     , m_rootLayerUpdateCount(0)
    128 #endif // PROFILE_LAYER_REBUILD
    129 {
    130     Settings* settings = m_renderView->document()->settings();
    131 
    132     // Even when forcing compositing mode, ignore child frames, or this will trigger
    133     // layer creation from the enclosing RenderIFrame.
    134     ASSERT(m_renderView->document()->frame());
    135     if (settings && settings->forceCompositingMode() && settings->acceleratedCompositingEnabled()
    136         && !m_renderView->document()->frame()->tree()->parent()) {
    137         m_forceCompositingMode = true;
    138         enableCompositingMode();
    139     }
    140 }
    141 
    142 RenderLayerCompositor::~RenderLayerCompositor()
    143 {
    144     ASSERT(m_rootLayerAttachment == RootLayerUnattached);
    145 }
    146 
    147 void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */)
    148 {
    149     if (enable != m_compositing) {
    150         m_compositing = enable;
    151 
    152         if (m_compositing) {
    153             ensureRootPlatformLayer();
    154             notifyIFramesOfCompositingChange();
    155         } else
    156             destroyRootPlatformLayer();
    157     }
    158 }
    159 
    160 void RenderLayerCompositor::cacheAcceleratedCompositingFlags()
    161 {
    162     bool hasAcceleratedCompositing = false;
    163     bool showDebugBorders = false;
    164     bool showRepaintCounter = false;
    165 
    166     if (Settings* settings = m_renderView->document()->settings()) {
    167         hasAcceleratedCompositing = settings->acceleratedCompositingEnabled();
    168         showDebugBorders = settings->showDebugBorders();
    169         showRepaintCounter = settings->showRepaintCounter();
    170     }
    171 
    172     // We allow the chrome to override the settings, in case the page is rendered
    173     // on a chrome that doesn't allow accelerated compositing.
    174     if (hasAcceleratedCompositing) {
    175         Frame* frame = m_renderView->frameView()->frame();
    176         Page* page = frame ? frame->page() : 0;
    177         if (page) {
    178             ChromeClient* chromeClient = page->chrome()->client();
    179             m_compositingTriggers = chromeClient->allowedCompositingTriggers();
    180             hasAcceleratedCompositing = m_compositingTriggers;
    181         }
    182     }
    183 
    184     if (hasAcceleratedCompositing != m_hasAcceleratedCompositing || showDebugBorders != m_showDebugBorders || showRepaintCounter != m_showRepaintCounter)
    185         setCompositingLayersNeedRebuild();
    186 
    187     m_hasAcceleratedCompositing = hasAcceleratedCompositing;
    188     m_showDebugBorders = showDebugBorders;
    189     m_showRepaintCounter = showRepaintCounter;
    190 }
    191 
    192 bool RenderLayerCompositor::canRender3DTransforms() const
    193 {
    194     return hasAcceleratedCompositing() && (m_compositingTriggers & ChromeClient::ThreeDTransformTrigger);
    195 }
    196 
    197 void RenderLayerCompositor::setCompositingLayersNeedRebuild(bool needRebuild)
    198 {
    199     if (inCompositingMode())
    200         m_compositingLayersNeedRebuild = needRebuild;
    201 }
    202 
    203 void RenderLayerCompositor::scheduleLayerFlush()
    204 {
    205     Frame* frame = m_renderView->frameView()->frame();
    206     Page* page = frame ? frame->page() : 0;
    207     if (!page)
    208         return;
    209 
    210     page->chrome()->client()->scheduleCompositingLayerSync();
    211 }
    212 
    213 void RenderLayerCompositor::flushPendingLayerChanges()
    214 {
    215     ASSERT(!m_flushingLayers);
    216     m_flushingLayers = true;
    217 
    218     // FIXME: FrameView::syncCompositingStateRecursive() calls this for each
    219     // frame, so when compositing layers are connected between frames, we'll
    220     // end up syncing subframe's layers multiple times.
    221     // https://bugs.webkit.org/show_bug.cgi?id=52489
    222     if (GraphicsLayer* rootLayer = rootPlatformLayer())
    223         rootLayer->syncCompositingState();
    224 
    225     ASSERT(m_flushingLayers);
    226     m_flushingLayers = false;
    227 }
    228 
    229 RenderLayerCompositor* RenderLayerCompositor::enclosingCompositorFlushingLayers() const
    230 {
    231     if (!m_renderView->frameView())
    232         return 0;
    233 
    234     for (Frame* frame = m_renderView->frameView()->frame(); frame; frame = frame->tree()->parent()) {
    235         RenderLayerCompositor* compositor = frame->contentRenderer() ? frame->contentRenderer()->compositor() : 0;
    236         if (compositor->isFlushingLayers())
    237             return compositor;
    238     }
    239 
    240     return 0;
    241 }
    242 
    243 void RenderLayerCompositor::scheduleCompositingLayerUpdate()
    244 {
    245     if (!m_updateCompositingLayersTimer.isActive())
    246         m_updateCompositingLayersTimer.startOneShot(0);
    247 }
    248 
    249 bool RenderLayerCompositor::compositingLayerUpdatePending() const
    250 {
    251     return m_updateCompositingLayersTimer.isActive();
    252 }
    253 
    254 void RenderLayerCompositor::updateCompositingLayersTimerFired(Timer<RenderLayerCompositor>*)
    255 {
    256     updateCompositingLayers();
    257 }
    258 
    259 void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType updateType, RenderLayer* updateRoot)
    260 {
    261     m_updateCompositingLayersTimer.stop();
    262 
    263     if (!m_compositingDependsOnGeometry && !m_compositing)
    264         return;
    265 
    266     bool checkForHierarchyUpdate = m_compositingDependsOnGeometry;
    267     bool needGeometryUpdate = false;
    268 
    269     switch (updateType) {
    270     case CompositingUpdateAfterLayoutOrStyleChange:
    271     case CompositingUpdateOnPaitingOrHitTest:
    272         checkForHierarchyUpdate = true;
    273         break;
    274     case CompositingUpdateOnScroll:
    275         if (m_compositingConsultsOverlap)
    276             checkForHierarchyUpdate = true; // Overlap can change with scrolling, so need to check for hierarchy updates.
    277 
    278         needGeometryUpdate = true;
    279         break;
    280     }
    281 
    282     if (!checkForHierarchyUpdate && !needGeometryUpdate)
    283         return;
    284 
    285     bool needHierarchyUpdate = m_compositingLayersNeedRebuild;
    286     if (!updateRoot || m_compositingConsultsOverlap) {
    287         // Only clear the flag if we're updating the entire hierarchy.
    288         m_compositingLayersNeedRebuild = false;
    289         updateRoot = rootRenderLayer();
    290     }
    291 
    292 #if PROFILE_LAYER_REBUILD
    293     ++m_rootLayerUpdateCount;
    294 
    295     double startTime = WTF::currentTime();
    296 #endif
    297 
    298     if (checkForHierarchyUpdate) {
    299         // Go through the layers in presentation order, so that we can compute which RenderLayers need compositing layers.
    300         // FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex.
    301         CompositingState compState(updateRoot);
    302         bool layersChanged = false;
    303 
    304 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
    305         compState.m_positionedSibling = false;
    306         compState.m_hasFixedElement = false;
    307 #endif
    308 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
    309         compState.m_hasScrollableElement = false;
    310 #endif
    311         if (m_compositingConsultsOverlap) {
    312             OverlapMap overlapTestRequestMap;
    313             computeCompositingRequirements(updateRoot, &overlapTestRequestMap, compState, layersChanged);
    314         } else
    315             computeCompositingRequirements(updateRoot, 0, compState, layersChanged);
    316 
    317         needHierarchyUpdate |= layersChanged;
    318     }
    319 
    320     if (needHierarchyUpdate) {
    321         // Update the hierarchy of the compositing layers.
    322         CompositingState compState(updateRoot);
    323         Vector<GraphicsLayer*> childList;
    324         rebuildCompositingLayerTree(updateRoot, compState, childList);
    325 
    326         // Host the document layer in the RenderView's root layer.
    327         if (updateRoot == rootRenderLayer()) {
    328             if (childList.isEmpty())
    329                 destroyRootPlatformLayer();
    330             else
    331                 m_rootPlatformLayer->setChildren(childList);
    332         }
    333     } else if (needGeometryUpdate) {
    334         // We just need to do a geometry update. This is only used for position:fixed scrolling;
    335         // most of the time, geometry is updated via RenderLayer::styleChanged().
    336         updateLayerTreeGeometry(updateRoot);
    337     }
    338 
    339 #if PROFILE_LAYER_REBUILD
    340     double endTime = WTF::currentTime();
    341     if (updateRoot == rootRenderLayer())
    342         fprintf(stderr, "Update %d: computeCompositingRequirements for the world took %fms\n",
    343                     m_rootLayerUpdateCount, 1000.0 * (endTime - startTime));
    344 #endif
    345     ASSERT(updateRoot || !m_compositingLayersNeedRebuild);
    346 
    347     if (!hasAcceleratedCompositing())
    348         enableCompositingMode(false);
    349 }
    350 
    351 bool RenderLayerCompositor::updateBacking(RenderLayer* layer, CompositingChangeRepaint shouldRepaint)
    352 {
    353     bool layerChanged = false;
    354 
    355 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
    356     if (needsToBeComposited(layer) || layer->shouldComposite()) {
    357 #else
    358     if (needsToBeComposited(layer)) {
    359 #endif
    360         enableCompositingMode();
    361 
    362         // 3D transforms turn off the testing of overlap.
    363         if (requiresCompositingForTransform(layer->renderer()))
    364             setCompositingConsultsOverlap(false);
    365 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
    366         // If we are a child of a scrollable layer, ignore the overlap from the
    367         // scrollable layer as it can cause child layers to become composited
    368         // siblings and will not scroll with the main content layer.
    369         if (layer->hasOverflowParent())
    370             setCompositingConsultsOverlap(false);
    371 #endif
    372 
    373         if (!layer->backing()) {
    374 
    375             // If we need to repaint, do so before making backing
    376             if (shouldRepaint == CompositingChangeRepaintNow)
    377                 repaintOnCompositingChange(layer);
    378 
    379             layer->ensureBacking();
    380 
    381 #if PLATFORM(MAC) && USE(CA)
    382             if (m_renderView->document()->settings()->acceleratedDrawingEnabled())
    383                 layer->backing()->graphicsLayer()->setAcceleratesDrawing(true);
    384             else if (layer->renderer()->isCanvas()) {
    385                 HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(layer->renderer()->node());
    386                 if (canvas->renderingContext() && canvas->renderingContext()->isAccelerated())
    387                     layer->backing()->graphicsLayer()->setAcceleratesDrawing(true);
    388             }
    389 #endif
    390             layerChanged = true;
    391         }
    392     } else {
    393         if (layer->backing()) {
    394             // If we're removing backing on a reflection, clear the source GraphicsLayer's pointer to
    395             // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection
    396             // are both either composited, or not composited.
    397             if (layer->isReflection()) {
    398                 RenderLayer* sourceLayer = toRenderBoxModelObject(layer->renderer()->parent())->layer();
    399                 if (RenderLayerBacking* backing = sourceLayer->backing()) {
    400                     ASSERT(backing->graphicsLayer()->replicaLayer() == layer->backing()->graphicsLayer());
    401                     backing->graphicsLayer()->setReplicatedByLayer(0);
    402                 }
    403             }
    404 
    405             layer->clearBacking();
    406             layerChanged = true;
    407 
    408             // The layer's cached repaints rects are relative to the repaint container, so change when
    409             // compositing changes; we need to update them here.
    410             layer->computeRepaintRects();
    411 
    412             // If we need to repaint, do so now that we've removed the backing
    413             if (shouldRepaint == CompositingChangeRepaintNow)
    414                 repaintOnCompositingChange(layer);
    415         }
    416     }
    417 
    418 #if ENABLE(VIDEO)
    419     if (layerChanged && layer->renderer()->isVideo()) {
    420         // If it's a video, give the media player a chance to hook up to the layer.
    421         RenderVideo* video = toRenderVideo(layer->renderer());
    422         video->acceleratedRenderingStateChanged();
    423     }
    424 #endif
    425 
    426     if (layerChanged && layer->renderer()->isRenderPart()) {
    427         RenderLayerCompositor* innerCompositor = frameContentsCompositor(toRenderPart(layer->renderer()));
    428         if (innerCompositor && innerCompositor->inCompositingMode())
    429             innerCompositor->updateRootLayerAttachment();
    430     }
    431 
    432     return layerChanged;
    433 }
    434 
    435 bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer, CompositingChangeRepaint shouldRepaint)
    436 {
    437     bool layerChanged = updateBacking(layer, shouldRepaint);
    438 
    439     // See if we need content or clipping layers. Methods called here should assume
    440     // that the compositing state of descendant layers has not been updated yet.
    441     if (layer->backing() && layer->backing()->updateGraphicsLayerConfiguration())
    442         layerChanged = true;
    443 
    444     return layerChanged;
    445 }
    446 
    447 void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer* layer)
    448 {
    449     // If the renderer is not attached yet, no need to repaint.
    450     if (layer->renderer() != m_renderView && !layer->renderer()->parent())
    451         return;
    452 
    453     RenderBoxModelObject* repaintContainer = layer->renderer()->containerForRepaint();
    454     if (!repaintContainer)
    455         repaintContainer = m_renderView;
    456 
    457     layer->repaintIncludingNonCompositingDescendants(repaintContainer);
    458     if (repaintContainer == m_renderView) {
    459         // The contents of this layer may be moving between the window
    460         // and a GraphicsLayer, so we need to make sure the window system
    461         // synchronizes those changes on the screen.
    462         m_renderView->frameView()->setNeedsOneShotDrawingSynchronization();
    463     }
    464 }
    465 
    466 // The bounds of the GraphicsLayer created for a compositing layer is the union of the bounds of all the descendant
    467 // RenderLayers that are rendered by the composited RenderLayer.
    468 IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer)
    469 {
    470     if (!canBeComposited(layer))
    471         return IntRect();
    472 
    473     IntRect boundingBoxRect = layer->localBoundingBox();
    474     if (layer->renderer()->isRoot()) {
    475         // If the root layer becomes composited (e.g. because some descendant with negative z-index is composited),
    476         // then it has to be big enough to cover the viewport in order to display the background. This is akin
    477         // to the code in RenderBox::paintRootBoxFillLayers().
    478         if (m_renderView->frameView()) {
    479             int rw = m_renderView->frameView()->contentsWidth();
    480             int rh = m_renderView->frameView()->contentsHeight();
    481 
    482             boundingBoxRect.setWidth(max(boundingBoxRect.width(), rw - boundingBoxRect.x()));
    483             boundingBoxRect.setHeight(max(boundingBoxRect.height(), rh - boundingBoxRect.y()));
    484         }
    485     }
    486 
    487     IntRect unionBounds = boundingBoxRect;
    488 
    489     if (layer->renderer()->hasOverflowClip() || layer->renderer()->hasMask()) {
    490         int ancestorRelX = 0, ancestorRelY = 0;
    491         layer->convertToLayerCoords(ancestorLayer, ancestorRelX, ancestorRelY);
    492         boundingBoxRect.move(ancestorRelX, ancestorRelY);
    493         return boundingBoxRect;
    494     }
    495 
    496     if (RenderLayer* reflection = layer->reflectionLayer()) {
    497         if (!reflection->isComposited()) {
    498             IntRect childUnionBounds = calculateCompositedBounds(reflection, layer);
    499             unionBounds.unite(childUnionBounds);
    500         }
    501     }
    502 
    503     ASSERT(layer->isStackingContext() || (!layer->m_posZOrderList || layer->m_posZOrderList->size() == 0));
    504 
    505     if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
    506         size_t listSize = negZOrderList->size();
    507         for (size_t i = 0; i < listSize; ++i) {
    508             RenderLayer* curLayer = negZOrderList->at(i);
    509             if (!curLayer->isComposited()) {
    510                 IntRect childUnionBounds = calculateCompositedBounds(curLayer, layer);
    511                 unionBounds.unite(childUnionBounds);
    512             }
    513         }
    514     }
    515 
    516     if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
    517         size_t listSize = posZOrderList->size();
    518         for (size_t i = 0; i < listSize; ++i) {
    519             RenderLayer* curLayer = posZOrderList->at(i);
    520             if (!curLayer->isComposited()) {
    521                 IntRect childUnionBounds = calculateCompositedBounds(curLayer, layer);
    522                 unionBounds.unite(childUnionBounds);
    523             }
    524         }
    525     }
    526 
    527     if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
    528         size_t listSize = normalFlowList->size();
    529         for (size_t i = 0; i < listSize; ++i) {
    530             RenderLayer* curLayer = normalFlowList->at(i);
    531             if (!curLayer->isComposited()) {
    532                 IntRect curAbsBounds = calculateCompositedBounds(curLayer, layer);
    533                 unionBounds.unite(curAbsBounds);
    534             }
    535         }
    536     }
    537 
    538     if (layer->paintsWithTransform(PaintBehaviorNormal)) {
    539         TransformationMatrix* affineTrans = layer->transform();
    540         boundingBoxRect = affineTrans->mapRect(boundingBoxRect);
    541         unionBounds = affineTrans->mapRect(unionBounds);
    542     }
    543 
    544     int ancestorRelX = 0, ancestorRelY = 0;
    545     layer->convertToLayerCoords(ancestorLayer, ancestorRelX, ancestorRelY);
    546     unionBounds.move(ancestorRelX, ancestorRelY);
    547 
    548     return unionBounds;
    549 }
    550 
    551 void RenderLayerCompositor::layerWasAdded(RenderLayer* /*parent*/, RenderLayer* /*child*/)
    552 {
    553     setCompositingLayersNeedRebuild();
    554 }
    555 
    556 void RenderLayerCompositor::layerWillBeRemoved(RenderLayer* parent, RenderLayer* child)
    557 {
    558     if (!child->isComposited() || parent->renderer()->documentBeingDestroyed())
    559         return;
    560 
    561     setCompositingParent(child, 0);
    562 
    563     RenderLayer* compLayer = parent->enclosingCompositingLayer();
    564     if (compLayer) {
    565         ASSERT(compLayer->backing());
    566         IntRect compBounds = child->backing()->compositedBounds();
    567 
    568         int offsetX = 0, offsetY = 0;
    569         child->convertToLayerCoords(compLayer, offsetX, offsetY);
    570         compBounds.move(offsetX, offsetY);
    571 
    572         compLayer->setBackingNeedsRepaintInRect(compBounds);
    573 
    574         // The contents of this layer may be moving from a GraphicsLayer to the window,
    575         // so we need to make sure the window system synchronizes those changes on the screen.
    576         m_renderView->frameView()->setNeedsOneShotDrawingSynchronization();
    577     }
    578 
    579     setCompositingLayersNeedRebuild();
    580 }
    581 
    582 RenderLayer* RenderLayerCompositor::enclosingNonStackingClippingLayer(const RenderLayer* layer) const
    583 {
    584     for (RenderLayer* curr = layer->parent(); curr != 0; curr = curr->parent()) {
    585         if (curr->isStackingContext())
    586             return 0;
    587 
    588         if (curr->renderer()->hasOverflowClip() || curr->renderer()->hasClip())
    589             return curr;
    590     }
    591     return 0;
    592 }
    593 
    594 void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer* layer, IntRect& layerBounds, bool& boundsComputed)
    595 {
    596     if (layer->isRootLayer())
    597         return;
    598 
    599     if (!boundsComputed) {
    600         layerBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox();
    601         // Empty rects never intersect, but we need them to for the purposes of overlap testing.
    602         if (layerBounds.isEmpty())
    603             layerBounds.setSize(IntSize(1, 1));
    604         boundsComputed = true;
    605     }
    606 
    607     overlapMap.add(layer, layerBounds);
    608 }
    609 
    610 bool RenderLayerCompositor::overlapsCompositedLayers(OverlapMap& overlapMap, const IntRect& layerBounds)
    611 {
    612     RenderLayerCompositor::OverlapMap::const_iterator end = overlapMap.end();
    613     for (RenderLayerCompositor::OverlapMap::const_iterator it = overlapMap.begin(); it != end; ++it) {
    614         const IntRect& bounds = it->second;
    615         if (layerBounds.intersects(bounds)) {
    616             return true;
    617         }
    618     }
    619 
    620     return false;
    621 }
    622 
    623 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
    624 
    625 bool RenderLayerCompositor::checkForPositionedElements(Vector<RenderLayer*>* list)
    626 {
    627     int listSize = list->size();
    628     int haveFixedLayer = -1;
    629     bool fixedSibling = false;
    630     bool positionedSibling = false;
    631 
    632 #if 0
    633     // For absolute positioned elements, we need to check if they are followed
    634     // by a composited element; if so, they also need to be composited, as the
    635     // layer display rendering might be incorrect (absolute elements being
    636     // removed from the flow).
    637     for (int i = 0; i < listSize; ++i) {
    638         RenderLayer* currentLayer = list->at(i);
    639         if (!needsToBeComposited(currentLayer)
    640             && !currentLayer->shouldComposite()
    641             && currentLayer->renderer()->isPositioned()) {
    642             positionedSibling = true;
    643             // check if there is a composited layer later, if so we should be
    644             // composited.
    645             for (int j = i + 1; j < listSize; ++j) {
    646                 RenderLayer* layer = list->at(j);
    647                 if (needsToBeComposited(layer)) {
    648                     currentLayer->setShouldComposite(true);
    649                     break;
    650                 }
    651             }
    652             break;
    653         }
    654     }
    655 #endif
    656 
    657     // If we find a fixed layer, let's mark all the following layers as being
    658     // composited. The layers' surfaces will be merged if needed UI-side.
    659     for (int j = 0; j < listSize; ++j) {
    660         RenderLayer* currentLayer = list->at(j);
    661 
    662         // clear the composited flag first
    663         currentLayer->setShouldComposite(false);
    664 
    665         if (currentLayer->isFixed() && needsToBeComposited(currentLayer)) {
    666             // Ignore fixed layers with a width or height or 1 or less...
    667             IntRect currentLayerBounds = currentLayer->renderer()->localToAbsoluteQuad(
    668                 FloatRect(currentLayer->localBoundingBox())).enclosingBoundingBox();
    669             if (currentLayerBounds.width() > 1 && currentLayerBounds.height() > 1) {
    670                 haveFixedLayer = j;
    671                 fixedSibling = true;
    672             }
    673             continue;
    674         }
    675 
    676         if (haveFixedLayer != -1)
    677             currentLayer->setShouldComposite(true);
    678     }
    679 
    680     return positionedSibling || fixedSibling;
    681 }
    682 
    683 #endif
    684 
    685 //  Recurse through the layers in z-index and overflow order (which is equivalent to painting order)
    686 //  For the z-order children of a compositing layer:
    687 //      If a child layers has a compositing layer, then all subsequent layers must
    688 //      be compositing in order to render above that layer.
    689 //
    690 //      If a child in the negative z-order list is compositing, then the layer itself
    691 //      must be compositing so that its contents render over that child.
    692 //      This implies that its positive z-index children must also be compositing.
    693 //
    694 void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, OverlapMap* overlapMap, struct CompositingState& compositingState, bool& layersChanged)
    695 {
    696     layer->updateLayerPosition();
    697     layer->updateZOrderLists();
    698     layer->updateNormalFlowList();
    699 #if PLATFORM(ANDROID)
    700     RenderObject* renderer = layer->renderer();
    701     bool intCom = requiresCompositingLayer(layer);
    702     layer->setIntrinsicallyComposited(intCom);
    703 #endif
    704 
    705     // Clear the flag
    706     layer->setHasCompositingDescendant(false);
    707 
    708     bool mustOverlapCompositedLayers = compositingState.m_subtreeIsCompositing;
    709 
    710     bool haveComputedBounds = false;
    711     IntRect absBounds;
    712     if (overlapMap && !overlapMap->isEmpty()) {
    713         // If we're testing for overlap, we only need to composite if we overlap something that is already composited.
    714         absBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox();
    715         // Empty rects never intersect, but we need them to for the purposes of overlap testing.
    716         if (absBounds.isEmpty())
    717             absBounds.setSize(IntSize(1, 1));
    718         haveComputedBounds = true;
    719         // If the current subtree is not compositing, and the layer is fully inside the current compositing bounnds,
    720         // there is no need to do the overlap test. This reduces the total number of the composited layers.
    721         if (compositingState.m_subtreeIsCompositing || !compositingState.m_compositingBounds.contains(absBounds))
    722             mustOverlapCompositedLayers = overlapsCompositedLayers(*overlapMap, absBounds);
    723     }
    724 
    725     layer->setMustOverlapCompositedLayers(mustOverlapCompositedLayers);
    726 
    727     // The children of this layer don't need to composite, unless there is
    728     // a compositing layer among them, so start by inheriting the compositing
    729     // ancestor with m_subtreeIsCompositing set to false.
    730     CompositingState childState(compositingState.m_compositingAncestor);
    731     if (compositingState.m_subtreeIsCompositing)
    732         childState.m_compositingBounds = absBounds;
    733     else
    734         childState.m_compositingBounds = compositingState.m_compositingBounds;
    735 #ifndef NDEBUG
    736     ++childState.m_depth;
    737 #endif
    738 
    739     bool willBeComposited = needsToBeComposited(layer);
    740 
    741 #if 0 && ENABLE(COMPOSITED_FIXED_ELEMENTS)
    742     willBeComposited |= layer->shouldComposite();
    743     layer->setMustOverlapCompositedLayers(layer->shouldComposite());
    744 #endif
    745 
    746 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
    747     // tell the parent it has scrollable descendants.
    748     if (layer->hasOverflowScroll())
    749         compositingState.m_hasScrollableElement = true;
    750 #endif
    751 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
    752     if (layer->isFixed())
    753         compositingState.m_hasFixedElement = true;
    754 #endif
    755     if (willBeComposited) {
    756         // Tell the parent it has compositing descendants.
    757         compositingState.m_subtreeIsCompositing = true;
    758         // This layer now acts as the ancestor for kids.
    759         childState.m_compositingAncestor = layer;
    760         childState.m_compositingBounds = absBounds;
    761         if (overlapMap)
    762             addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
    763     }
    764 
    765 #if ENABLE(VIDEO)
    766     // Video is special. It's a replaced element with a content layer, but has shadow content
    767     // for the controller that must render in front. Without this, the controls fail to show
    768     // when the video element is a stacking context (e.g. due to opacity or transform).
    769     if (willBeComposited && layer->renderer()->isVideo())
    770         childState.m_subtreeIsCompositing = true;
    771 #endif
    772 
    773     if (layer->isStackingContext()) {
    774         ASSERT(!layer->m_zOrderListsDirty);
    775         if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
    776             size_t listSize = negZOrderList->size();
    777 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
    778             childState.m_positionedSibling = compositingState.m_positionedSibling;
    779             if (checkForPositionedElements(negZOrderList))
    780                 childState.m_positionedSibling = true;
    781 #endif
    782             for (size_t i = 0; i < listSize; ++i) {
    783                 RenderLayer* curLayer = negZOrderList->at(i);
    784                 computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged);
    785 
    786                 // If we have to make a layer for this child, make one now so we can have a contents layer
    787                 // (since we need to ensure that the -ve z-order child renders underneath our contents).
    788 #ifdef ANDROID
    789                 // Normally we try to reduce the number of layers by not promoting all fixed
    790                 // or scrollable elements to their own compositing layer. But in the case that
    791                 // we have such an element in the negative z-order, we must make it a layer
    792                 // otherwise the content will be painted at a higher z-index. This breaks pages
    793                 // that set a large image with a z-index of -1 to implement a background image,
    794                 // for example.
    795                 bool childRequiresCompositing = childState.m_hasFixedElement || childState.m_hasScrollableElement;
    796                 if (!willBeComposited && (childState.m_subtreeIsCompositing || childRequiresCompositing)) {
    797 #else
    798                 if (!willBeComposited && childState.m_subtreeIsCompositing) {
    799 #endif
    800                     // make layer compositing
    801                     layer->setMustOverlapCompositedLayers(true);
    802                     childState.m_compositingAncestor = layer;
    803                     if (overlapMap)
    804                         addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
    805                     willBeComposited = true;
    806                 }
    807             }
    808         }
    809     }
    810 
    811     ASSERT(!layer->m_normalFlowListDirty);
    812     if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
    813         size_t listSize = normalFlowList->size();
    814 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
    815         childState.m_positionedSibling = compositingState.m_positionedSibling;
    816         if (checkForPositionedElements(normalFlowList))
    817             childState.m_positionedSibling = true;
    818 #endif
    819         for (size_t i = 0; i < listSize; ++i) {
    820             RenderLayer* curLayer = normalFlowList->at(i);
    821             computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged);
    822         }
    823     }
    824 
    825     if (layer->isStackingContext()) {
    826         if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
    827             size_t listSize = posZOrderList->size();
    828 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
    829             childState.m_positionedSibling = compositingState.m_positionedSibling;
    830             if (checkForPositionedElements(posZOrderList))
    831                 childState.m_positionedSibling = true;
    832 #endif
    833             for (size_t i = 0; i < listSize; ++i) {
    834                 RenderLayer* curLayer = posZOrderList->at(i);
    835                 computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged);
    836             }
    837         }
    838     }
    839 
    840     // If we just entered compositing mode, the root will have become composited (as long as accelerated compositing is enabled).
    841     if (layer->isRootLayer()) {
    842         if (inCompositingMode() && m_hasAcceleratedCompositing)
    843             willBeComposited = true;
    844     }
    845 
    846     ASSERT(willBeComposited == needsToBeComposited(layer));
    847 
    848     // If we have a software transform, and we have layers under us, we need to also
    849     // be composited. Also, if we have opacity < 1, then we need to be a layer so that
    850     // the child layers are opaque, then rendered with opacity on this layer.
    851     if (!willBeComposited && canBeComposited(layer) && childState.m_subtreeIsCompositing && requiresCompositingWhenDescendantsAreCompositing(layer->renderer())) {
    852         layer->setMustOverlapCompositedLayers(true);
    853         if (overlapMap)
    854             addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
    855         willBeComposited = true;
    856     }
    857 
    858     ASSERT(willBeComposited == needsToBeComposited(layer));
    859     if (layer->reflectionLayer())
    860         layer->reflectionLayer()->setMustOverlapCompositedLayers(willBeComposited);
    861 
    862     // Subsequent layers in the parent stacking context also need to composite.
    863     if (childState.m_subtreeIsCompositing)
    864         compositingState.m_subtreeIsCompositing = true;
    865 
    866 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
    867     if (childState.m_hasFixedElement)
    868         compositingState.m_hasFixedElement = true;
    869     if (childState.m_positionedSibling)
    870         compositingState.m_positionedSibling = true;
    871 #endif
    872 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
    873     if (childState.m_hasScrollableElement)
    874         compositingState.m_hasScrollableElement = true;
    875 #endif
    876 
    877     // Set the flag to say that this SC has compositing children.
    878     layer->setHasCompositingDescendant(childState.m_subtreeIsCompositing);
    879 
    880     // setHasCompositingDescendant() may have changed the answer to needsToBeComposited() when clipping,
    881     // so test that again.
    882     if (!willBeComposited && canBeComposited(layer) && clipsCompositingDescendants(layer)) {
    883         if (overlapMap)
    884             addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
    885         willBeComposited = true;
    886     }
    887 
    888     // If we're back at the root, and no other layers need to be composited, and the root layer itself doesn't need
    889     // to be composited, then we can drop out of compositing mode altogether.
    890 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
    891     // We also need to check that we don't have a scrollable layer, as this
    892     // would not have set the m_subtreeIsCompositing flag
    893     if (layer->isRootLayer() && !childState.m_subtreeIsCompositing
    894         && !childState.m_hasScrollableElement && !childState.m_positionedSibling && !childState.m_hasFixedElement
    895         && !requiresCompositingLayer(layer) && !m_forceCompositingMode) {
    896 #else
    897     if (layer->isRootLayer() && !childState.m_subtreeIsCompositing && !requiresCompositingLayer(layer) && !m_forceCompositingMode) {
    898 #endif
    899         enableCompositingMode(false);
    900         willBeComposited = false;
    901     }
    902 
    903     // If the layer is going into compositing mode, repaint its old location.
    904     ASSERT(willBeComposited == needsToBeComposited(layer));
    905     if (!layer->isComposited() && willBeComposited)
    906         repaintOnCompositingChange(layer);
    907 
    908     // Update backing now, so that we can use isComposited() reliably during tree traversal in rebuildCompositingLayerTree().
    909     if (updateBacking(layer, CompositingChangeRepaintNow))
    910         layersChanged = true;
    911 
    912     if (layer->reflectionLayer() && updateLayerCompositingState(layer->reflectionLayer(), CompositingChangeRepaintNow))
    913         layersChanged = true;
    914 }
    915 
    916 void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer)
    917 {
    918     ASSERT(!parentLayer || childLayer->ancestorCompositingLayer() == parentLayer);
    919     ASSERT(childLayer->isComposited());
    920 
    921     // It's possible to be called with a parent that isn't yet composited when we're doing
    922     // partial updates as required by painting or hit testing. Just bail in that case;
    923     // we'll do a full layer update soon.
    924     if (!parentLayer || !parentLayer->isComposited())
    925         return;
    926 
    927     if (parentLayer) {
    928         GraphicsLayer* hostingLayer = parentLayer->backing()->parentForSublayers();
    929         GraphicsLayer* hostedLayer = childLayer->backing()->childForSuperlayers();
    930 
    931         hostingLayer->addChild(hostedLayer);
    932     } else
    933         childLayer->backing()->childForSuperlayers()->removeFromParent();
    934 }
    935 
    936 void RenderLayerCompositor::removeCompositedChildren(RenderLayer* layer)
    937 {
    938     ASSERT(layer->isComposited());
    939 
    940     GraphicsLayer* hostingLayer = layer->backing()->parentForSublayers();
    941     hostingLayer->removeAllChildren();
    942 }
    943 
    944 #if ENABLE(VIDEO)
    945 bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const
    946 {
    947     if (!m_hasAcceleratedCompositing)
    948         return false;
    949 
    950     return o->supportsAcceleratedRendering();
    951 }
    952 #endif
    953 
    954 void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, const CompositingState& compositingState, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer)
    955 {
    956     // Make the layer compositing if necessary, and set up clipping and content layers.
    957     // Note that we can only do work here that is independent of whether the descendant layers
    958     // have been processed. computeCompositingRequirements() will already have done the repaint if necessary.
    959 
    960     RenderLayerBacking* layerBacking = layer->backing();
    961     if (layerBacking) {
    962         // The compositing state of all our children has been updated already, so now
    963         // we can compute and cache the composited bounds for this layer.
    964         layerBacking->updateCompositedBounds();
    965 
    966         if (RenderLayer* reflection = layer->reflectionLayer()) {
    967             if (reflection->backing())
    968                 reflection->backing()->updateCompositedBounds();
    969         }
    970 
    971         layerBacking->updateGraphicsLayerConfiguration();
    972         layerBacking->updateGraphicsLayerGeometry();
    973 
    974         if (!layer->parent())
    975             updateRootLayerPosition();
    976     }
    977 
    978     // If this layer has backing, then we are collecting its children, otherwise appending
    979     // to the compositing child list of an enclosing layer.
    980     Vector<GraphicsLayer*> layerChildren;
    981     Vector<GraphicsLayer*>& childList = layerBacking ? layerChildren : childLayersOfEnclosingLayer;
    982 
    983     CompositingState childState = compositingState;
    984     if (layer->isComposited())
    985         childState.m_compositingAncestor = layer;
    986 
    987 #ifndef NDEBUG
    988     ++childState.m_depth;
    989 #endif
    990 
    991     // The children of this stacking context don't need to composite, unless there is
    992     // a compositing layer among them, so start by assuming false.
    993     childState.m_subtreeIsCompositing = false;
    994 
    995     if (layer->isStackingContext()) {
    996         ASSERT(!layer->m_zOrderListsDirty);
    997 
    998         if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
    999             size_t listSize = negZOrderList->size();
   1000             for (size_t i = 0; i < listSize; ++i) {
   1001                 RenderLayer* curLayer = negZOrderList->at(i);
   1002                 rebuildCompositingLayerTree(curLayer, childState, childList);
   1003             }
   1004         }
   1005 
   1006         // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
   1007         if (layerBacking && layerBacking->foregroundLayer())
   1008             childList.append(layerBacking->foregroundLayer());
   1009     }
   1010 
   1011     ASSERT(!layer->m_normalFlowListDirty);
   1012     if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
   1013         size_t listSize = normalFlowList->size();
   1014         for (size_t i = 0; i < listSize; ++i) {
   1015             RenderLayer* curLayer = normalFlowList->at(i);
   1016             rebuildCompositingLayerTree(curLayer, childState, childList);
   1017         }
   1018     }
   1019 
   1020     if (layer->isStackingContext()) {
   1021         if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
   1022             size_t listSize = posZOrderList->size();
   1023             for (size_t i = 0; i < listSize; ++i) {
   1024                 RenderLayer* curLayer = posZOrderList->at(i);
   1025                 rebuildCompositingLayerTree(curLayer, childState, childList);
   1026             }
   1027         }
   1028     }
   1029 
   1030     if (layerBacking) {
   1031         bool parented = false;
   1032         if (layer->renderer()->isRenderPart())
   1033             parented = parentFrameContentLayers(toRenderPart(layer->renderer()));
   1034 
   1035         // If the layer has a clipping layer the overflow controls layers will be siblings of the clipping layer.
   1036         // Otherwise, the overflow control layers are normal children.
   1037         if (!layerBacking->hasClippingLayer()) {
   1038             if (GraphicsLayer* overflowControlLayer = layerBacking->layerForHorizontalScrollbar()) {
   1039                 overflowControlLayer->removeFromParent();
   1040                 layerChildren.append(overflowControlLayer);
   1041             }
   1042 
   1043             if (GraphicsLayer* overflowControlLayer = layerBacking->layerForVerticalScrollbar()) {
   1044                 overflowControlLayer->removeFromParent();
   1045                 layerChildren.append(overflowControlLayer);
   1046             }
   1047 
   1048             if (GraphicsLayer* overflowControlLayer = layerBacking->layerForScrollCorner()) {
   1049                 overflowControlLayer->removeFromParent();
   1050                 layerChildren.append(overflowControlLayer);
   1051             }
   1052         }
   1053 
   1054         if (!parented)
   1055             layerBacking->parentForSublayers()->setChildren(layerChildren);
   1056 
   1057 #if ENABLE(FULLSCREEN_API)
   1058         // For the sake of clients of the full screen renderer, don't reparent
   1059         // the full screen layer out from under them if they're in the middle of
   1060         // animating.
   1061         if (layer->renderer()->isRenderFullScreen() && toRenderFullScreen(layer->renderer())->isAnimating())
   1062             return;
   1063 #endif
   1064         childLayersOfEnclosingLayer.append(layerBacking->childForSuperlayers());
   1065     }
   1066 }
   1067 
   1068 void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset)
   1069 {
   1070     if (m_overflowControlsHostLayer)
   1071         m_overflowControlsHostLayer->setPosition(contentsOffset);
   1072 }
   1073 
   1074 void RenderLayerCompositor::frameViewDidChangeSize()
   1075 {
   1076     if (m_clipLayer) {
   1077         FrameView* frameView = m_renderView->frameView();
   1078         m_clipLayer->setSize(frameView->visibleContentRect(false /* exclude scrollbars */).size());
   1079 
   1080         IntPoint scrollPosition = frameView->scrollPosition();
   1081         m_scrollLayer->setPosition(FloatPoint(-scrollPosition.x(), -scrollPosition.y()));
   1082         updateOverflowControlsLayers();
   1083     }
   1084 }
   1085 
   1086 void RenderLayerCompositor::frameViewDidScroll(const IntPoint& scrollPosition)
   1087 {
   1088     if (m_scrollLayer)
   1089         m_scrollLayer->setPosition(FloatPoint(-scrollPosition.x(), -scrollPosition.y()));
   1090 }
   1091 
   1092 String RenderLayerCompositor::layerTreeAsText(bool showDebugInfo)
   1093 {
   1094     if (compositingLayerUpdatePending())
   1095         updateCompositingLayers();
   1096 
   1097     if (!m_rootPlatformLayer)
   1098         return String();
   1099 
   1100     // We skip dumping the scroll and clip layers to keep layerTreeAsText output
   1101     // similar between platforms.
   1102     return m_rootPlatformLayer->layerTreeAsText(showDebugInfo ? LayerTreeAsTextDebug : LayerTreeAsTextBehaviorNormal);
   1103 }
   1104 
   1105 RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderPart* renderer)
   1106 {
   1107     if (!renderer->node()->isFrameOwnerElement())
   1108         return 0;
   1109 
   1110     HTMLFrameOwnerElement* element = static_cast<HTMLFrameOwnerElement*>(renderer->node());
   1111     if (Document* contentDocument = element->contentDocument()) {
   1112         if (RenderView* view = contentDocument->renderView())
   1113             return view->compositor();
   1114     }
   1115     return 0;
   1116 }
   1117 
   1118 bool RenderLayerCompositor::parentFrameContentLayers(RenderPart* renderer)
   1119 {
   1120     RenderLayerCompositor* innerCompositor = frameContentsCompositor(renderer);
   1121     if (!innerCompositor || !innerCompositor->inCompositingMode() || innerCompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame)
   1122         return false;
   1123 
   1124     RenderLayer* layer = renderer->layer();
   1125     if (!layer->isComposited())
   1126         return false;
   1127 
   1128     RenderLayerBacking* backing = layer->backing();
   1129     GraphicsLayer* hostingLayer = backing->parentForSublayers();
   1130     GraphicsLayer* rootLayer = innerCompositor->rootPlatformLayer();
   1131     if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != rootLayer) {
   1132         hostingLayer->removeAllChildren();
   1133         hostingLayer->addChild(rootLayer);
   1134     }
   1135     return true;
   1136 }
   1137 
   1138 // This just updates layer geometry without changing the hierarchy.
   1139 void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer)
   1140 {
   1141     if (RenderLayerBacking* layerBacking = layer->backing()) {
   1142         // The compositing state of all our children has been updated already, so now
   1143         // we can compute and cache the composited bounds for this layer.
   1144         layerBacking->updateCompositedBounds();
   1145 
   1146         if (RenderLayer* reflection = layer->reflectionLayer()) {
   1147             if (reflection->backing())
   1148                 reflection->backing()->updateCompositedBounds();
   1149         }
   1150 
   1151         layerBacking->updateGraphicsLayerConfiguration();
   1152         layerBacking->updateGraphicsLayerGeometry();
   1153 
   1154         if (!layer->parent())
   1155             updateRootLayerPosition();
   1156     }
   1157 
   1158     if (layer->isStackingContext()) {
   1159         ASSERT(!layer->m_zOrderListsDirty);
   1160 
   1161         if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
   1162             size_t listSize = negZOrderList->size();
   1163             for (size_t i = 0; i < listSize; ++i)
   1164                 updateLayerTreeGeometry(negZOrderList->at(i));
   1165         }
   1166     }
   1167 
   1168     ASSERT(!layer->m_normalFlowListDirty);
   1169     if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
   1170         size_t listSize = normalFlowList->size();
   1171         for (size_t i = 0; i < listSize; ++i)
   1172             updateLayerTreeGeometry(normalFlowList->at(i));
   1173     }
   1174 
   1175     if (layer->isStackingContext()) {
   1176         if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
   1177             size_t listSize = posZOrderList->size();
   1178             for (size_t i = 0; i < listSize; ++i)
   1179                 updateLayerTreeGeometry(posZOrderList->at(i));
   1180         }
   1181     }
   1182 }
   1183 
   1184 // Recurs down the RenderLayer tree until its finds the compositing descendants of compositingAncestor and updates their geometry.
   1185 void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer* compositingAncestor, RenderLayer* layer, RenderLayerBacking::UpdateDepth updateDepth)
   1186 {
   1187     if (layer != compositingAncestor) {
   1188         if (RenderLayerBacking* layerBacking = layer->backing()) {
   1189             layerBacking->updateCompositedBounds();
   1190 
   1191             if (RenderLayer* reflection = layer->reflectionLayer()) {
   1192                 if (reflection->backing())
   1193                     reflection->backing()->updateCompositedBounds();
   1194             }
   1195 
   1196             layerBacking->updateGraphicsLayerGeometry();
   1197             if (updateDepth == RenderLayerBacking::CompositingChildren)
   1198                 return;
   1199         }
   1200     }
   1201 
   1202     if (layer->reflectionLayer())
   1203         updateCompositingDescendantGeometry(compositingAncestor, layer->reflectionLayer(), updateDepth);
   1204 
   1205     if (!layer->hasCompositingDescendant())
   1206         return;
   1207 
   1208     if (layer->isStackingContext()) {
   1209         if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
   1210             size_t listSize = negZOrderList->size();
   1211             for (size_t i = 0; i < listSize; ++i)
   1212                 updateCompositingDescendantGeometry(compositingAncestor, negZOrderList->at(i), updateDepth);
   1213         }
   1214     }
   1215 
   1216     if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
   1217         size_t listSize = normalFlowList->size();
   1218         for (size_t i = 0; i < listSize; ++i)
   1219             updateCompositingDescendantGeometry(compositingAncestor, normalFlowList->at(i), updateDepth);
   1220     }
   1221 
   1222     if (layer->isStackingContext()) {
   1223         if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
   1224             size_t listSize = posZOrderList->size();
   1225             for (size_t i = 0; i < listSize; ++i)
   1226                 updateCompositingDescendantGeometry(compositingAncestor, posZOrderList->at(i), updateDepth);
   1227         }
   1228     }
   1229 }
   1230 
   1231 
   1232 void RenderLayerCompositor::repaintCompositedLayersAbsoluteRect(const IntRect& absRect)
   1233 {
   1234     recursiveRepaintLayerRect(rootRenderLayer(), absRect);
   1235 }
   1236 
   1237 void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const IntRect& rect)
   1238 {
   1239     // FIXME: This method does not work correctly with transforms.
   1240     if (layer->isComposited())
   1241         layer->setBackingNeedsRepaintInRect(rect);
   1242 
   1243     if (layer->hasCompositingDescendant()) {
   1244         if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
   1245             size_t listSize = negZOrderList->size();
   1246             for (size_t i = 0; i < listSize; ++i) {
   1247                 RenderLayer* curLayer = negZOrderList->at(i);
   1248                 int x = 0;
   1249                 int y = 0;
   1250                 curLayer->convertToLayerCoords(layer, x, y);
   1251                 IntRect childRect(rect);
   1252                 childRect.move(-x, -y);
   1253                 recursiveRepaintLayerRect(curLayer, childRect);
   1254             }
   1255         }
   1256 
   1257         if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
   1258             size_t listSize = posZOrderList->size();
   1259             for (size_t i = 0; i < listSize; ++i) {
   1260                 RenderLayer* curLayer = posZOrderList->at(i);
   1261                 int x = 0;
   1262                 int y = 0;
   1263                 curLayer->convertToLayerCoords(layer, x, y);
   1264                 IntRect childRect(rect);
   1265                 childRect.move(-x, -y);
   1266                 recursiveRepaintLayerRect(curLayer, childRect);
   1267             }
   1268         }
   1269     }
   1270     if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
   1271         size_t listSize = normalFlowList->size();
   1272         for (size_t i = 0; i < listSize; ++i) {
   1273             RenderLayer* curLayer = normalFlowList->at(i);
   1274             int x = 0;
   1275             int y = 0;
   1276             curLayer->convertToLayerCoords(layer, x, y);
   1277             IntRect childRect(rect);
   1278             childRect.move(-x, -y);
   1279             recursiveRepaintLayerRect(curLayer, childRect);
   1280         }
   1281     }
   1282 }
   1283 
   1284 RenderLayer* RenderLayerCompositor::rootRenderLayer() const
   1285 {
   1286     return m_renderView->layer();
   1287 }
   1288 
   1289 GraphicsLayer* RenderLayerCompositor::rootPlatformLayer() const
   1290 {
   1291     if (m_overflowControlsHostLayer)
   1292         return m_overflowControlsHostLayer.get();
   1293     return m_rootPlatformLayer.get();
   1294 }
   1295 
   1296 void RenderLayerCompositor::didMoveOnscreen()
   1297 {
   1298     if (!inCompositingMode() || m_rootLayerAttachment != RootLayerUnattached)
   1299         return;
   1300 
   1301     RootLayerAttachment attachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient;
   1302     attachRootPlatformLayer(attachment);
   1303 }
   1304 
   1305 void RenderLayerCompositor::willMoveOffscreen()
   1306 {
   1307     if (!inCompositingMode() || m_rootLayerAttachment == RootLayerUnattached)
   1308         return;
   1309 
   1310     detachRootPlatformLayer();
   1311 }
   1312 
   1313 void RenderLayerCompositor::updateRootLayerPosition()
   1314 {
   1315     if (m_rootPlatformLayer) {
   1316         m_rootPlatformLayer->setSize(FloatSize(m_renderView->docWidth(), m_renderView->docHeight()));
   1317         m_rootPlatformLayer->setPosition(FloatPoint(m_renderView->docLeft(), m_renderView->docTop()));
   1318     }
   1319     if (m_clipLayer) {
   1320         FrameView* frameView = m_renderView->frameView();
   1321         m_clipLayer->setSize(frameView->visibleContentRect(false /* exclude scrollbars */).size());
   1322     }
   1323 }
   1324 
   1325 void RenderLayerCompositor::didStartAcceleratedAnimation(CSSPropertyID property)
   1326 {
   1327     // If an accelerated animation or transition runs, we have to turn off overlap checking because
   1328     // we don't do layout for every frame, but we have to ensure that the layering is
   1329     // correct between the animating object and other objects on the page.
   1330     if (property == CSSPropertyWebkitTransform)
   1331         setCompositingConsultsOverlap(false);
   1332 }
   1333 
   1334 bool RenderLayerCompositor::has3DContent() const
   1335 {
   1336     return layerHas3DContent(rootRenderLayer());
   1337 }
   1338 
   1339 bool RenderLayerCompositor::allowsIndependentlyCompositedFrames(const FrameView* view)
   1340 {
   1341 #if PLATFORM(MAC)
   1342     // frames are only independently composited in Mac pre-WebKit2.
   1343     return view->platformWidget();
   1344 #endif
   1345     return false;
   1346 }
   1347 
   1348 bool RenderLayerCompositor::shouldPropagateCompositingToEnclosingFrame() const
   1349 {
   1350 #if PLATFORM(ANDROID)
   1351     if (enclosingFrameElement() && !allowsIndependentlyCompositedFrames(m_renderView->frameView()))
   1352         return true;
   1353 #endif
   1354     // Parent document content needs to be able to render on top of a composited frame, so correct behavior
   1355     // is to have the parent document become composited too. However, this can cause problems on platforms that
   1356     // use native views for frames (like Mac), so disable that behavior on those platforms for now.
   1357     HTMLFrameOwnerElement* ownerElement = enclosingFrameElement();
   1358     RenderObject* renderer = ownerElement ? ownerElement->renderer() : 0;
   1359 
   1360     // If we are the top-level frame, don't propagate.
   1361     if (!ownerElement)
   1362         return false;
   1363 
   1364     if (!allowsIndependentlyCompositedFrames(m_renderView->frameView()))
   1365         return true;
   1366 
   1367     if (!renderer || !renderer->isRenderPart())
   1368         return false;
   1369 
   1370     // On Mac, only propagate compositing if the frame is overlapped in the parent
   1371     // document, or the parent is already compositing, or the main frame is scaled.
   1372     Frame* frame = m_renderView->frameView()->frame();
   1373     Page* page = frame ? frame->page() : 0;
   1374     if (page->mainFrame()->pageScaleFactor() != 1)
   1375         return true;
   1376 
   1377     RenderPart* frameRenderer = toRenderPart(renderer);
   1378     if (frameRenderer->widget()) {
   1379         ASSERT(frameRenderer->widget()->isFrameView());
   1380         FrameView* view = static_cast<FrameView*>(frameRenderer->widget());
   1381         if (view->isOverlappedIncludingAncestors() || view->hasCompositingAncestor())
   1382             return true;
   1383     }
   1384 
   1385     return false;
   1386 }
   1387 
   1388 HTMLFrameOwnerElement* RenderLayerCompositor::enclosingFrameElement() const
   1389 {
   1390     if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement())
   1391         return (ownerElement->hasTagName(iframeTag) || ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(objectTag)) ? ownerElement : 0;
   1392 
   1393     return 0;
   1394 }
   1395 
   1396 bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const
   1397 {
   1398     if (!canBeComposited(layer))
   1399         return false;
   1400 
   1401     // The root layer always has a compositing layer, but it may not have backing.
   1402 #if PLATFORM(ANDROID)
   1403     // If we do not have a root platform layer, don't use the
   1404     // mustOverlapCompositedLayers() as a cue that this layer needs to be
   1405     // composited -- the layers tree has been detached.
   1406     // Otherwise we can end up in a cycle where updateBacking() switches composited
   1407     // mode on because a layer has mustOverlapCompositedLayers() (by calling
   1408     // enableCompositingMode()), while computeCompositingRequirements() will
   1409     // (correctly) say that we do not need to be in composited mode and turns it
   1410     // off, rince and repeat...
   1411     return requiresCompositingLayer(layer)
   1412         || (m_rootPlatformLayer && layer->mustOverlapCompositedLayers())
   1413         || (inCompositingMode() && layer->isRootLayer());
   1414 #else
   1415     return requiresCompositingLayer(layer) || layer->mustOverlapCompositedLayers() || (inCompositingMode() && layer->isRootLayer());
   1416 #endif
   1417 }
   1418 
   1419 #if PLATFORM(ANDROID)
   1420 bool RenderLayerCompositor::requiresCompositingForAndroidLayers(const RenderLayer* layer) const
   1421 {
   1422 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
   1423     if (layer->hasOverflowScroll())
   1424         return true;
   1425     if (layer->isRootLayer() && m_renderView->frameView()->hasOverflowScroll())
   1426         return true;
   1427 #endif
   1428 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
   1429 
   1430     // Enable composited layers (for fixed elements)
   1431     if (layer->isFixed())
   1432         return true;
   1433 #endif
   1434 
   1435     if (layer->renderer()->isCanvas())
   1436         return true;
   1437 
   1438     if (layer->renderer()->style()->hasFixedBackgroundImage())
   1439         return true;
   1440 
   1441     return false;
   1442 }
   1443 #endif
   1444 
   1445 // Note: this specifies whether the RL needs a compositing layer for intrinsic reasons.
   1446 // Use needsToBeComposited() to determine if a RL actually needs a compositing layer.
   1447 // static
   1448 bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) const
   1449 {
   1450     RenderObject* renderer = layer->renderer();
   1451     // The compositing state of a reflection should match that of its reflected layer.
   1452     if (layer->isReflection()) {
   1453         renderer = renderer->parent(); // The RenderReplica's parent is the object being reflected.
   1454         layer = toRenderBoxModelObject(renderer)->layer();
   1455     }
   1456     return requiresCompositingForTransform(renderer)
   1457 #if PLATFORM(ANDROID)
   1458              || requiresCompositingForAndroidLayers(layer)
   1459 #endif
   1460              || requiresCompositingForVideo(renderer)
   1461              || requiresCompositingForCanvas(renderer)
   1462              || requiresCompositingForPlugin(renderer)
   1463              || requiresCompositingForFrame(renderer)
   1464              || (canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden)
   1465              || clipsCompositingDescendants(layer)
   1466              || requiresCompositingForAnimation(renderer)
   1467              || requiresCompositingForFullScreen(renderer);
   1468 }
   1469 
   1470 bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const
   1471 {
   1472     return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer();
   1473 }
   1474 
   1475 // Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips,
   1476 // up to the enclosing compositing ancestor. This is required because compositing layers are parented
   1477 // according to the z-order hierarchy, yet clipping goes down the renderer hierarchy.
   1478 // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy,
   1479 // but a sibling in the z-order hierarchy.
   1480 bool RenderLayerCompositor::clippedByAncestor(RenderLayer* layer) const
   1481 {
   1482     if (!layer->isComposited() || !layer->parent())
   1483         return false;
   1484 
   1485     RenderLayer* compositingAncestor = layer->ancestorCompositingLayer();
   1486     if (!compositingAncestor)
   1487         return false;
   1488 
   1489     // If the compositingAncestor clips, that will be taken care of by clipsCompositingDescendants(),
   1490     // so we only care about clipping between its first child that is our ancestor (the computeClipRoot),
   1491     // and layer.
   1492     RenderLayer* computeClipRoot = 0;
   1493     RenderLayer* curr = layer;
   1494     while (curr) {
   1495         RenderLayer* next = curr->parent();
   1496         if (next == compositingAncestor) {
   1497             computeClipRoot = curr;
   1498             break;
   1499         }
   1500         curr = next;
   1501     }
   1502 
   1503     if (!computeClipRoot || computeClipRoot == layer)
   1504         return false;
   1505 
   1506     IntRect backgroundRect = layer->backgroundClipRect(computeClipRoot, true);
   1507     return backgroundRect != PaintInfo::infiniteRect();
   1508 }
   1509 
   1510 // Return true if the given layer is a stacking context and has compositing child
   1511 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer
   1512 // into the hierarchy between this layer and its children in the z-order hierarchy.
   1513 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const
   1514 {
   1515 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
   1516     if (layer->hasOverflowScroll())
   1517         return false;
   1518 #endif
   1519     return layer->hasCompositingDescendant() &&
   1520            (layer->renderer()->hasOverflowClip() || layer->renderer()->hasClip());
   1521 }
   1522 
   1523 bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* renderer) const
   1524 {
   1525     if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger))
   1526         return false;
   1527 
   1528     RenderStyle* style = renderer->style();
   1529     // Note that we ask the renderer if it has a transform, because the style may have transforms,
   1530     // but the renderer may be an inline that doesn't suppport them.
   1531     return renderer->hasTransform() && (style->transform().has3DOperation() || style->transformStyle3D() == TransformStyle3DPreserve3D || style->hasPerspective());
   1532 }
   1533 
   1534 bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer) const
   1535 {
   1536     if (!(m_compositingTriggers & ChromeClient::VideoTrigger))
   1537         return false;
   1538 #if ENABLE(VIDEO)
   1539     if (renderer->isVideo()) {
   1540         RenderVideo* video = toRenderVideo(renderer);
   1541         return video->shouldDisplayVideo() && canAccelerateVideoRendering(video);
   1542     }
   1543 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
   1544     else if (renderer->isRenderPart()) {
   1545         if (!m_hasAcceleratedCompositing)
   1546             return false;
   1547 
   1548         Node* node = renderer->node();
   1549         if (!node || (!node->hasTagName(HTMLNames::videoTag) && !node->hasTagName(HTMLNames::audioTag)))
   1550             return false;
   1551 
   1552         HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(node);
   1553         return mediaElement->player() ? mediaElement->player()->supportsAcceleratedRendering() : false;
   1554     }
   1555 #endif // ENABLE(PLUGIN_PROXY_FOR_VIDEO)
   1556 #else
   1557     UNUSED_PARAM(renderer);
   1558 #endif
   1559     return false;
   1560 }
   1561 
   1562 bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer) const
   1563 {
   1564     if (!(m_compositingTriggers & ChromeClient::CanvasTrigger))
   1565         return false;
   1566 
   1567     if (renderer->isCanvas()) {
   1568         HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
   1569         return canvas->renderingContext() && canvas->renderingContext()->isAccelerated();
   1570     }
   1571     return false;
   1572 }
   1573 
   1574 bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) const
   1575 {
   1576     if (!(m_compositingTriggers & ChromeClient::PluginTrigger))
   1577         return false;
   1578 
   1579     bool composite = (renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing())
   1580                   || (renderer->isApplet() && toRenderApplet(renderer)->allowsAcceleratedCompositing());
   1581     if (!composite)
   1582         return false;
   1583 
   1584     m_compositingDependsOnGeometry = true;
   1585 
   1586     RenderWidget* pluginRenderer = toRenderWidget(renderer);
   1587     // If we can't reliably know the size of the plugin yet, don't change compositing state.
   1588     if (pluginRenderer->needsLayout())
   1589         return pluginRenderer->hasLayer() && pluginRenderer->layer()->isComposited();
   1590 
   1591     // Don't go into compositing mode if height or width are zero, or size is 1x1.
   1592     IntRect contentBox = pluginRenderer->contentBoxRect();
   1593 #if PLATFORM(ANDROID)
   1594     // allow all plugins including 1x1 to be composited, so that they are drawn,
   1595     // and acquire an ANativeWindow on the UI thread
   1596     return contentBox.height() * contentBox.width() > 0;
   1597 #else
   1598     return contentBox.height() * contentBox.width() > 1;
   1599 #endif
   1600 }
   1601 
   1602 bool RenderLayerCompositor::requiresCompositingForFrame(RenderObject* renderer) const
   1603 {
   1604     if (!renderer->isRenderPart())
   1605         return false;
   1606 
   1607     RenderPart* frameRenderer = toRenderPart(renderer);
   1608 
   1609     if (!frameRenderer->requiresAcceleratedCompositing())
   1610         return false;
   1611 
   1612     m_compositingDependsOnGeometry = true;
   1613 
   1614     RenderLayerCompositor* innerCompositor = frameContentsCompositor(frameRenderer);
   1615     if (!innerCompositor || !innerCompositor->shouldPropagateCompositingToEnclosingFrame())
   1616         return false;
   1617 
   1618     // If we can't reliably know the size of the iframe yet, don't change compositing state.
   1619     if (renderer->needsLayout())
   1620         return frameRenderer->hasLayer() && frameRenderer->layer()->isComposited();
   1621 
   1622     // Don't go into compositing mode if height or width are zero.
   1623     IntRect contentBox = frameRenderer->contentBoxRect();
   1624     return contentBox.height() * contentBox.width() > 0;
   1625 }
   1626 
   1627 bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const
   1628 {
   1629     if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
   1630         return false;
   1631 
   1632     if (AnimationController* animController = renderer->animation()) {
   1633 #if PLATFORM(ANDROID)
   1634         // android renders an opacity animation much faster if it's composited
   1635         return (animController->isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity))
   1636 #else
   1637         return (animController->isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity) && inCompositingMode())
   1638 #endif
   1639             || animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitTransform);
   1640     }
   1641     return false;
   1642 }
   1643 
   1644 bool RenderLayerCompositor::requiresCompositingWhenDescendantsAreCompositing(RenderObject* renderer) const
   1645 {
   1646     return renderer->hasTransform() || renderer->isTransparent() || renderer->hasMask() || renderer->hasReflection();
   1647 }
   1648 
   1649 bool RenderLayerCompositor::requiresCompositingForFullScreen(RenderObject* renderer) const
   1650 {
   1651 #if ENABLE(FULLSCREEN_API)
   1652     return renderer->isRenderFullScreen() && toRenderFullScreen(renderer)->isAnimating();
   1653 #else
   1654     UNUSED_PARAM(renderer);
   1655     return false;
   1656 #endif
   1657 }
   1658 
   1659 // If an element has negative z-index children, those children render in front of the
   1660 // layer background, so we need an extra 'contents' layer for the foreground of the layer
   1661 // object.
   1662 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const
   1663 {
   1664     return (layer->m_negZOrderList && layer->m_negZOrderList->size() > 0);
   1665 }
   1666 
   1667 bool RenderLayerCompositor::requiresScrollLayer(RootLayerAttachment attachment) const
   1668 {
   1669     // We need to handle our own scrolling if we're:
   1670     return !m_renderView->frameView()->platformWidget() // viewless (i.e. non-Mac, or Mac in WebKit2)
   1671         || attachment == RootLayerAttachedViaEnclosingFrame; // a composited frame on Mac
   1672 }
   1673 
   1674 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
   1675 {
   1676     if (!scrollbar)
   1677         return;
   1678 
   1679     context.save();
   1680     const IntRect& scrollbarRect = scrollbar->frameRect();
   1681     context.translate(-scrollbarRect.x(), -scrollbarRect.y());
   1682     IntRect transformedClip = clip;
   1683     transformedClip.move(scrollbarRect.x(), scrollbarRect.y());
   1684     scrollbar->paint(&context, transformedClip);
   1685     context.restore();
   1686 }
   1687 
   1688 void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip)
   1689 {
   1690     if (graphicsLayer == layerForHorizontalScrollbar())
   1691         paintScrollbar(m_renderView->frameView()->horizontalScrollbar(), context, clip);
   1692     else if (graphicsLayer == layerForVerticalScrollbar())
   1693         paintScrollbar(m_renderView->frameView()->verticalScrollbar(), context, clip);
   1694     else if (graphicsLayer == layerForScrollCorner()) {
   1695         const IntRect& scrollCorner = m_renderView->frameView()->scrollCornerRect();
   1696         context.save();
   1697         context.translate(-scrollCorner.x(), -scrollCorner.y());
   1698         IntRect transformedClip = clip;
   1699         transformedClip.move(scrollCorner.x(), scrollCorner.y());
   1700         m_renderView->frameView()->paintScrollCorner(&context, transformedClip);
   1701         context.restore();
   1702     }
   1703 }
   1704 
   1705 static bool shouldCompositeOverflowControls(ScrollView* view)
   1706 {
   1707     if (view->platformWidget())
   1708         return false;
   1709 #if !PLATFORM(CHROMIUM)
   1710     if (!view->hasOverlayScrollbars())
   1711         return false;
   1712 #endif
   1713     return true;
   1714 }
   1715 
   1716 bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const
   1717 {
   1718     ScrollView* view = m_renderView->frameView();
   1719     return shouldCompositeOverflowControls(view) && view->horizontalScrollbar();
   1720 }
   1721 
   1722 bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const
   1723 {
   1724     ScrollView* view = m_renderView->frameView();
   1725     return shouldCompositeOverflowControls(view) && view->verticalScrollbar();
   1726 }
   1727 
   1728 bool RenderLayerCompositor::requiresScrollCornerLayer() const
   1729 {
   1730     ScrollView* view = m_renderView->frameView();
   1731     return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible();
   1732 }
   1733 
   1734 void RenderLayerCompositor::updateOverflowControlsLayers()
   1735 {
   1736     bool layersChanged = false;
   1737 
   1738     if (requiresHorizontalScrollbarLayer()) {
   1739         m_layerForHorizontalScrollbar = GraphicsLayer::create(this);
   1740 #ifndef NDEBUG
   1741         m_layerForHorizontalScrollbar->setName("horizontal scrollbar");
   1742 #endif
   1743         m_overflowControlsHostLayer->addChild(m_layerForHorizontalScrollbar.get());
   1744         layersChanged = true;
   1745     } else if (m_layerForHorizontalScrollbar) {
   1746         m_layerForHorizontalScrollbar->removeFromParent();
   1747         m_layerForHorizontalScrollbar = 0;
   1748         layersChanged = true;
   1749     }
   1750 
   1751     if (requiresVerticalScrollbarLayer()) {
   1752         m_layerForVerticalScrollbar = GraphicsLayer::create(this);
   1753 #ifndef NDEBUG
   1754         m_layerForVerticalScrollbar->setName("vertical scrollbar");
   1755 #endif
   1756         m_overflowControlsHostLayer->addChild(m_layerForVerticalScrollbar.get());
   1757         layersChanged = true;
   1758     } else if (m_layerForVerticalScrollbar) {
   1759         m_layerForVerticalScrollbar->removeFromParent();
   1760         m_layerForVerticalScrollbar = 0;
   1761         layersChanged = true;
   1762     }
   1763 
   1764     if (requiresScrollCornerLayer()) {
   1765         m_layerForScrollCorner = GraphicsLayer::create(this);
   1766 #ifndef NDEBUG
   1767         m_layerForScrollCorner->setName("scroll corner");
   1768 #endif
   1769         m_overflowControlsHostLayer->addChild(m_layerForScrollCorner.get());
   1770         layersChanged = true;
   1771     } else if (m_layerForScrollCorner) {
   1772         m_layerForScrollCorner->removeFromParent();
   1773         m_layerForScrollCorner = 0;
   1774         layersChanged = true;
   1775     }
   1776 
   1777     if (layersChanged)
   1778         m_renderView->frameView()->positionScrollbarLayers();
   1779 }
   1780 
   1781 void RenderLayerCompositor::ensureRootPlatformLayer()
   1782 {
   1783     RootLayerAttachment expectedAttachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient;
   1784     if (expectedAttachment == m_rootLayerAttachment)
   1785          return;
   1786 
   1787     if (!m_rootPlatformLayer) {
   1788         m_rootPlatformLayer = GraphicsLayer::create(0);
   1789 #ifndef NDEBUG
   1790         m_rootPlatformLayer->setName("Root platform");
   1791 #endif
   1792         m_rootPlatformLayer->setSize(FloatSize(m_renderView->maxXLayoutOverflow(), m_renderView->maxYLayoutOverflow()));
   1793         m_rootPlatformLayer->setPosition(FloatPoint());
   1794 
   1795         // Need to clip to prevent transformed content showing outside this frame
   1796         m_rootPlatformLayer->setMasksToBounds(true);
   1797     }
   1798 
   1799     if (requiresScrollLayer(expectedAttachment)) {
   1800         if (!m_overflowControlsHostLayer) {
   1801             ASSERT(!m_scrollLayer);
   1802             ASSERT(!m_clipLayer);
   1803 
   1804             // Create a layer to host the clipping layer and the overflow controls layers.
   1805             m_overflowControlsHostLayer = GraphicsLayer::create(0);
   1806 #ifndef NDEBUG
   1807             m_overflowControlsHostLayer->setName("overflow controls host");
   1808 #endif
   1809 
   1810             // Create a clipping layer if this is an iframe
   1811             m_clipLayer = GraphicsLayer::create(this);
   1812 #ifndef NDEBUG
   1813             m_clipLayer->setName("iframe Clipping");
   1814 #endif
   1815             m_clipLayer->setMasksToBounds(true);
   1816 
   1817             m_scrollLayer = GraphicsLayer::create(this);
   1818 #ifndef NDEBUG
   1819             m_scrollLayer->setName("iframe scrolling");
   1820 #endif
   1821 
   1822             // Hook them up
   1823             m_overflowControlsHostLayer->addChild(m_clipLayer.get());
   1824             m_clipLayer->addChild(m_scrollLayer.get());
   1825             m_scrollLayer->addChild(m_rootPlatformLayer.get());
   1826 
   1827             frameViewDidChangeSize();
   1828             frameViewDidScroll(m_renderView->frameView()->scrollPosition());
   1829         }
   1830     } else {
   1831         if (m_overflowControlsHostLayer) {
   1832             m_overflowControlsHostLayer = 0;
   1833             m_clipLayer = 0;
   1834             m_scrollLayer = 0;
   1835         }
   1836     }
   1837 
   1838     // Check to see if we have to change the attachment
   1839     if (m_rootLayerAttachment != RootLayerUnattached)
   1840         detachRootPlatformLayer();
   1841 
   1842     attachRootPlatformLayer(expectedAttachment);
   1843 }
   1844 
   1845 void RenderLayerCompositor::destroyRootPlatformLayer()
   1846 {
   1847     if (!m_rootPlatformLayer)
   1848         return;
   1849 
   1850     detachRootPlatformLayer();
   1851 
   1852     if (m_layerForHorizontalScrollbar) {
   1853         m_layerForHorizontalScrollbar->removeFromParent();
   1854         m_layerForHorizontalScrollbar = 0;
   1855         if (Scrollbar* horizontalScrollbar = m_renderView->frameView()->verticalScrollbar())
   1856             m_renderView->frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size()));
   1857     }
   1858 
   1859     if (m_layerForVerticalScrollbar) {
   1860         m_layerForVerticalScrollbar->removeFromParent();
   1861         m_layerForVerticalScrollbar = 0;
   1862         if (Scrollbar* verticalScrollbar = m_renderView->frameView()->verticalScrollbar())
   1863             m_renderView->frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size()));
   1864     }
   1865 
   1866     if (m_layerForScrollCorner) {
   1867         m_layerForScrollCorner = 0;
   1868         m_renderView->frameView()->invalidateScrollCorner();
   1869     }
   1870 
   1871     if (m_overflowControlsHostLayer) {
   1872         m_overflowControlsHostLayer = 0;
   1873         m_clipLayer = 0;
   1874         m_scrollLayer = 0;
   1875     }
   1876     ASSERT(!m_scrollLayer);
   1877     m_rootPlatformLayer = 0;
   1878 }
   1879 
   1880 void RenderLayerCompositor::attachRootPlatformLayer(RootLayerAttachment attachment)
   1881 {
   1882     if (!m_rootPlatformLayer)
   1883         return;
   1884 
   1885     switch (attachment) {
   1886         case RootLayerUnattached:
   1887             ASSERT_NOT_REACHED();
   1888             break;
   1889         case RootLayerAttachedViaChromeClient: {
   1890             Frame* frame = m_renderView->frameView()->frame();
   1891             Page* page = frame ? frame->page() : 0;
   1892             if (!page)
   1893                 return;
   1894 
   1895             page->chrome()->client()->attachRootGraphicsLayer(frame, rootPlatformLayer());
   1896             break;
   1897         }
   1898         case RootLayerAttachedViaEnclosingFrame: {
   1899             // The layer will get hooked up via RenderLayerBacking::updateGraphicsLayerConfiguration()
   1900             // for the frame's renderer in the parent document.
   1901             scheduleNeedsStyleRecalc(m_renderView->document()->ownerElement());
   1902             break;
   1903         }
   1904     }
   1905 
   1906     m_rootLayerAttachment = attachment;
   1907     rootLayerAttachmentChanged();
   1908 }
   1909 
   1910 void RenderLayerCompositor::detachRootPlatformLayer()
   1911 {
   1912     if (!m_rootPlatformLayer || m_rootLayerAttachment == RootLayerUnattached)
   1913         return;
   1914 
   1915     switch (m_rootLayerAttachment) {
   1916     case RootLayerAttachedViaEnclosingFrame: {
   1917         // The layer will get unhooked up via RenderLayerBacking::updateGraphicsLayerConfiguration()
   1918         // for the frame's renderer in the parent document.
   1919         if (m_overflowControlsHostLayer)
   1920             m_overflowControlsHostLayer->removeFromParent();
   1921         else
   1922             m_rootPlatformLayer->removeFromParent();
   1923 
   1924         if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement())
   1925             scheduleNeedsStyleRecalc(ownerElement);
   1926         break;
   1927     }
   1928     case RootLayerAttachedViaChromeClient: {
   1929         Frame* frame = m_renderView->frameView()->frame();
   1930         Page* page = frame ? frame->page() : 0;
   1931         if (!page)
   1932             return;
   1933 
   1934         page->chrome()->client()->attachRootGraphicsLayer(frame, 0);
   1935     }
   1936     break;
   1937     case RootLayerUnattached:
   1938         break;
   1939     }
   1940 
   1941     m_rootLayerAttachment = RootLayerUnattached;
   1942     rootLayerAttachmentChanged();
   1943 }
   1944 
   1945 void RenderLayerCompositor::updateRootLayerAttachment()
   1946 {
   1947     ensureRootPlatformLayer();
   1948 }
   1949 
   1950 void RenderLayerCompositor::rootLayerAttachmentChanged()
   1951 {
   1952     // The attachment can affect whether the RenderView layer's paintingGoesToWindow() behavior,
   1953     // so call updateGraphicsLayerGeometry() to udpate that.
   1954     RenderLayer* layer = m_renderView->layer();
   1955     if (RenderLayerBacking* backing = layer ? layer->backing() : 0)
   1956         backing->updateDrawsContent();
   1957 }
   1958 
   1959 static void needsStyleRecalcCallback(Node* node)
   1960 {
   1961     node->setNeedsStyleRecalc(SyntheticStyleChange);
   1962 }
   1963 
   1964 void RenderLayerCompositor::scheduleNeedsStyleRecalc(Element* element)
   1965 {
   1966     if (ContainerNode::postAttachCallbacksAreSuspended())
   1967         ContainerNode::queuePostAttachCallback(needsStyleRecalcCallback, element);
   1968     else
   1969         element->setNeedsStyleRecalc(SyntheticStyleChange);
   1970 }
   1971 
   1972 // IFrames are special, because we hook compositing layers together across iframe boundaries
   1973 // when both parent and iframe content are composited. So when this frame becomes composited, we have
   1974 // to use a synthetic style change to get the iframes into RenderLayers in order to allow them to composite.
   1975 void RenderLayerCompositor::notifyIFramesOfCompositingChange()
   1976 {
   1977     Frame* frame = m_renderView->frameView() ? m_renderView->frameView()->frame() : 0;
   1978     if (!frame)
   1979         return;
   1980 
   1981     for (Frame* child = frame->tree()->firstChild(); child; child = child->tree()->traverseNext(frame)) {
   1982         if (child->document() && child->document()->ownerElement())
   1983             scheduleNeedsStyleRecalc(child->document()->ownerElement());
   1984     }
   1985 
   1986     // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so
   1987     // we need to schedule a style recalc in our parent document.
   1988     if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement())
   1989         scheduleNeedsStyleRecalc(ownerElement);
   1990 }
   1991 
   1992 bool RenderLayerCompositor::layerHas3DContent(const RenderLayer* layer) const
   1993 {
   1994     const RenderStyle* style = layer->renderer()->style();
   1995 
   1996     if (style &&
   1997         (style->transformStyle3D() == TransformStyle3DPreserve3D ||
   1998          style->hasPerspective() ||
   1999          style->transform().has3DOperation()))
   2000         return true;
   2001 
   2002     if (layer->isStackingContext()) {
   2003         if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
   2004             size_t listSize = negZOrderList->size();
   2005             for (size_t i = 0; i < listSize; ++i) {
   2006                 RenderLayer* curLayer = negZOrderList->at(i);
   2007                 if (layerHas3DContent(curLayer))
   2008                     return true;
   2009             }
   2010         }
   2011 
   2012         if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
   2013             size_t listSize = posZOrderList->size();
   2014             for (size_t i = 0; i < listSize; ++i) {
   2015                 RenderLayer* curLayer = posZOrderList->at(i);
   2016                 if (layerHas3DContent(curLayer))
   2017                     return true;
   2018             }
   2019         }
   2020     }
   2021 
   2022     if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
   2023         size_t listSize = normalFlowList->size();
   2024         for (size_t i = 0; i < listSize; ++i) {
   2025             RenderLayer* curLayer = normalFlowList->at(i);
   2026             if (layerHas3DContent(curLayer))
   2027                 return true;
   2028         }
   2029     }
   2030     return false;
   2031 }
   2032 
   2033 void RenderLayerCompositor::updateContentsScale(float scale, RenderLayer* layer)
   2034 {
   2035     if (!layer)
   2036         layer = rootRenderLayer();
   2037 
   2038     layer->updateContentsScale(scale);
   2039 
   2040     if (layer->isStackingContext()) {
   2041         if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
   2042             size_t listSize = negZOrderList->size();
   2043             for (size_t i = 0; i < listSize; ++i)
   2044                 updateContentsScale(scale, negZOrderList->at(i));
   2045         }
   2046 
   2047         if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
   2048             size_t listSize = posZOrderList->size();
   2049             for (size_t i = 0; i < listSize; ++i)
   2050                 updateContentsScale(scale, posZOrderList->at(i));
   2051         }
   2052     }
   2053 
   2054     if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
   2055         size_t listSize = normalFlowList->size();
   2056         for (size_t i = 0; i < listSize; ++i)
   2057             updateContentsScale(scale, normalFlowList->at(i));
   2058     }
   2059 }
   2060 
   2061 } // namespace WebCore
   2062 
   2063 #endif // USE(ACCELERATED_COMPOSITING)
   2064