⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 renderlayercompositor.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */#include "config.h"#if USE(ACCELERATED_COMPOSITING)#include "RenderLayerCompositor.h"#include "AnimationController.h"#include "ChromeClient.h"#include "CSSPropertyNames.h"#include "Frame.h"#include "FrameView.h"#include "GraphicsLayer.h"#include "HitTestRequest.h"#include "HitTestResult.h"#include "Page.h"#include "RenderLayerBacking.h"#include "RenderView.h"#if PROFILE_LAYER_REBUILD#include <wtf/CurrentTime.h>#endif#ifndef NDEBUG#include "CString.h"#include "RenderTreeAsText.h"#endif#if ENABLE(3D_TRANSFORMS)// This symbol is used to determine from a script whether 3D transforms are enabled (via 'nm').bool WebCoreHas3DTransforms = true;#endifnamespace WebCore {struct CompositingState {    CompositingState(RenderLayer* compAncestor)        : m_subtreeIsCompositing(false)        , m_compositingAncestor(compAncestor)#ifndef NDEBUG        , m_depth(0)#endif    {    }        bool m_subtreeIsCompositing;    RenderLayer* m_compositingAncestor;#ifndef NDEBUG    int m_depth;#endif};static TransformationMatrix flipTransform(){    TransformationMatrix flipper;    flipper.flipY();    return flipper;}RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView)    : m_renderView(renderView)    , m_rootPlatformLayer(0)    , m_compositing(false)    , m_rootLayerAttached(false)    , m_compositingLayersNeedUpdate(false)#if PROFILE_LAYER_REBUILD    , m_rootLayerUpdateCount(0)#endif // PROFILE_LAYER_REBUILD{}RenderLayerCompositor::~RenderLayerCompositor(){    ASSERT(!m_rootLayerAttached);    delete m_rootPlatformLayer;}void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */){    if (enable != m_compositing) {        m_compositing = enable;                // We never go out of compositing mode for a given page,        // but if all the layers disappear, we'll just be left with        // the empty root layer, which has minimal overhead.        if (m_compositing)            ensureRootPlatformLayer();    }}void RenderLayerCompositor::setCompositingLayersNeedUpdate(bool needUpdate){    if (inCompositingMode())        m_compositingLayersNeedUpdate = needUpdate;}void RenderLayerCompositor::updateCompositingLayers(RenderLayer* updateRoot){    if (!m_compositingLayersNeedUpdate)        return;    ASSERT(inCompositingMode());    if (!updateRoot) {        // Only clear the flag if we're updating the entire hierarchy        m_compositingLayersNeedUpdate = false;        updateRoot = rootRenderLayer();    }#if PROFILE_LAYER_REBUILD    ++m_rootLayerUpdateCount;        double startTime = WTF::currentTime();#endif            // Go through the layers in presentation order, so that we can compute which    // RLs need compositing layers.    // FIXME: we could maybe do this in one pass, but the parenting logic would be more    // complex.    {        CompositingState compState(updateRoot);        computeCompositingRequirements(updateRoot, compState);    }    // Now create and parent the compositing layers.    {        CompositingState compState(updateRoot);        rebuildCompositingLayerTree(updateRoot, compState);    }    #if PROFILE_LAYER_REBUILD    double endTime = WTF::currentTime();    if (!updateRoot)        fprintf(stderr, "Update %d: computeCompositingRequirements for the world took %fms\n"                    m_rootLayerUpdateCount, 1000.0 * (endTime - startTime));#endif    ASSERT(updateRoot || !m_compositingLayersNeedUpdate);}bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer, StyleDifference diff){    bool needsLayer = needsToBeComposited(layer);    bool layerChanged = false;    if (needsLayer) {        enableCompositingMode();        if (!layer->backing()) {            layer->ensureBacking();            layerChanged = true;        }    } else {        if (layer->backing()) {            layer->clearBacking();            layerChanged = true;        }    }        if (layerChanged) {        // Invalidate the parent in this region.        RenderLayer* compLayer = layer->ancestorCompositingLayer();        if (compLayer) {            // We can't reliably compute a dirty rect, because style may have changed already,             // so just dirty the whole parent layer            compLayer->setBackingNeedsRepaint();            // The contents of this layer may be moving between the window            // and a GraphicsLayer, so we need to make sure the window system            // synchronizes those changes on the screen.            m_renderView->frameView()->setNeedsOneShotDrawingSynchronization();        }    }    if (!needsLayer)        return layerChanged;    if (layer->backing()->updateGraphicsLayers(needsContentsCompositingLayer(layer),                                               clippedByAncestor(layer),                                               clipsCompositingDescendants(layer),                                               diff >= StyleDifferenceRepaint))        layerChanged = true;    return layerChanged;}// The bounds of the GraphicsLayer created for a compositing layer is the union of the bounds of all the descendant// RenderLayers that are rendered by the composited RenderLayer.IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer, IntRect* layerBoundingBox){    IntRect boundingBoxRect, unionBounds;    boundingBoxRect = unionBounds = layer->localBoundingBox();        ASSERT(layer->isStackingContext() || (!layer->m_posZOrderList || layer->m_posZOrderList->size() == 0));    Vector<RenderLayer*>* negZOrderList = layer->negZOrderList();    if (negZOrderList) {        for (Vector<RenderLayer*>::iterator it = negZOrderList->begin(); it != negZOrderList->end(); ++it) {            RenderLayer* curLayer = (*it);            if (!curLayer->isComposited()) {                IntRect childUnionBounds = calculateCompositedBounds(curLayer, layer);                unionBounds.unite(childUnionBounds);            }        }    }    Vector<RenderLayer*>* posZOrderList = layer->posZOrderList();    if (posZOrderList) {        for (Vector<RenderLayer*>::iterator it = posZOrderList->begin(); it != posZOrderList->end(); ++it) {            RenderLayer* curLayer = (*it);            if (!curLayer->isComposited()) {                IntRect childUnionBounds = calculateCompositedBounds(curLayer, layer);                unionBounds.unite(childUnionBounds);            }        }    }    Vector<RenderLayer*>* normalFlowList = layer->normalFlowList();    if (normalFlowList) {        for (Vector<RenderLayer*>::iterator it = normalFlowList->begin(); it != normalFlowList->end(); ++it) {            RenderLayer* curLayer = (*it);            if (!curLayer->isComposited()) {                IntRect curAbsBounds = calculateCompositedBounds(curLayer, layer);                unionBounds.unite(curAbsBounds);            }        }    }    if (!layer->isComposited() && layer->transform()) {        TransformationMatrix* affineTrans = layer->transform();        boundingBoxRect = affineTrans->mapRect(boundingBoxRect);        unionBounds = affineTrans->mapRect(unionBounds);    }    int ancestorRelX = 0, ancestorRelY = 0;    layer->convertToLayerCoords(ancestorLayer, ancestorRelX, ancestorRelY);    unionBounds.move(ancestorRelX, ancestorRelY);    if (layerBoundingBox) {        boundingBoxRect.move(ancestorRelX, ancestorRelY);        *layerBoundingBox = boundingBoxRect;    }        return unionBounds;}void RenderLayerCompositor::layerWasAdded(RenderLayer* /*parent*/, RenderLayer* /*child*/){    setCompositingLayersNeedUpdate();}void RenderLayerCompositor::layerWillBeRemoved(RenderLayer* parent, RenderLayer* child){    if (child->isComposited())        setCompositingParent(child, 0);        // If the document is being torn down (document's renderer() is null), then there's    // no need to do any layer updating.    if (parent->renderer()->documentBeingDestroyed())        return;    RenderLayer* compLayer = parent->enclosingCompositingLayer();    if (compLayer) {        IntRect ancestorRect = calculateCompositedBounds(child, compLayer);        compLayer->setBackingNeedsRepaintInRect(ancestorRect);        // The contents of this layer may be moving from a GraphicsLayer to the window,        // so we need to make sure the window system synchronizes those changes on the screen.        m_renderView->frameView()->setNeedsOneShotDrawingSynchronization();    }    setCompositingLayersNeedUpdate();}RenderLayer* RenderLayerCompositor::enclosingNonStackingClippingLayer(const RenderLayer* layer) const{    for (RenderLayer* curr = layer->parent(); curr != 0; curr = curr->parent()) {        if (curr->isStackingContext())            return 0;        if (curr->renderer()->hasOverflowClip())            return curr;    }    return 0;}//  Recurse through the layers in z-index and overflow order (which is equivalent to painting order)//  For the z-order children of a compositing layer://      If a child layers has a compositing layer, then all subsequent layers must//      be compositing in order to render above that layer.////      If a child in the negative z-order list is compositing, then the layer itself//      must be compositing so that its contents render over that child.//      This implies that its positive z-index children must also be compositing.//void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, struct CompositingState& ioCompState){    layer->updateLayerPosition();    layer->updateZOrderLists();    layer->updateNormalFlowList();        // Clear the flag    layer->setHasCompositingDescendant(false);    setForcedCompositingLayer(layer, ioCompState.m_subtreeIsCompositing);        const bool isCompositingLayer = needsToBeComposited(layer);    ioCompState.m_subtreeIsCompositing = isCompositingLayer;    CompositingState childState = ioCompState;    if (isCompositingLayer)        childState.m_compositingAncestor = layer;    // The children of this stacking context don't need to composite, unless there is    // a compositing layer among them, so start by assuming false.    childState.m_subtreeIsCompositing = false;#ifndef NDEBUG    ++childState.m_depth;#endif    if (layer->isStackingContext()) {        ASSERT(!layer->m_zOrderListsDirty);        Vector<RenderLayer*>* negZOrderList = layer->negZOrderList();        if (negZOrderList && negZOrderList->size() > 0) {            for (Vector<RenderLayer*>::const_iterator it = negZOrderList->begin(); it != negZOrderList->end(); ++it) {                RenderLayer* curLayer = (*it);                computeCompositingRequirements(curLayer, childState);                // if we have to make a layer for this child, make one now so we can have a contents layer                // (since we need to ensure that the -ve z-order child renders underneath our contents)                if (childState.m_subtreeIsCompositing) {                    // make |this| compositing                    setForcedCompositingLayer(layer, true);                    childState.m_compositingAncestor = layer;                }            }        }    }        ASSERT(!layer->m_normalFlowListDirty);    Vector<RenderLayer*>* normalFlowList = layer->normalFlowList();    if (normalFlowList && normalFlowList->size() > 0) {        for (Vector<RenderLayer*>::const_iterator it = normalFlowList->begin(); it != normalFlowList->end(); ++it) {            RenderLayer* curLayer = (*it);            computeCompositingRequirements(curLayer, childState);        }    }    if (layer->isStackingContext()) {        Vector<RenderLayer*>* posZOrderList = layer->posZOrderList();        if (posZOrderList && posZOrderList->size() > 0) {            for (Vector<RenderLayer*>::const_iterator it = posZOrderList->begin(); it != posZOrderList->end(); ++it) {                RenderLayer* curLayer = (*it);                computeCompositingRequirements(curLayer, childState);            }        }    }    // If we have a software transform, and we have layers under us, we need to also    // be composited. Also, if we have opacity < 1, then we need to be a layer so that    // the child layers are opaque, then rendered with opacity on this layer.    if (childState.m_subtreeIsCompositing &&        (layer->renderer()->hasTransform() || layer->renderer()->style()->opacity() < 1))        setForcedCompositingLayer(layer, true);    // Subsequent layers in the parent stacking context also need to composite.    if (childState.m_subtreeIsCompositing)        ioCompState.m_subtreeIsCompositing = true;    // Set the flag to say that this SC has compositing children.    // this can affect the answer to needsToBeComposited() when clipping,    // but that's ok here.    layer->setHasCompositingDescendant(childState.m_subtreeIsCompositing);}void RenderLayerCompositor::setForcedCompositingLayer(RenderLayer* layer, bool force){    if (force) {        layer->ensureBacking();        layer->backing()->forceCompositingLayer();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -