Backing Store ( 五 )的创建

    不是所有的RenderLayer都需要创建它的Backing Store,只有网页的RenderObject树之RenderLayer满足如下条件:

1 Transform:几何变换

2 Video:页面有<video>

3 Canvas: 页面有<canvas>

4 Plugin

5 Frame

6 3DTransforms

7 Animation

8 Filters:CSS过滤器

9 Position:CSS之定位

10 clipsCompositingDescendants:裁剪区合成到子孙

// Note: this specifies whether the RL needs a compositing layer for intrinsic reasons.
// Use needsToBeComposited() to determine if a RL actually needs a compositing layer.
// static
bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) const
{
    RenderObject* renderer = layer->renderer();
    // The compositing state of a reflection should match that of its reflected layer.
    if (layer->isReflection()) {
        renderer = renderer->parent(); // The RenderReplica's parent is the object being reflected.
        layer = toRenderBoxModelObject(renderer)->layer();
    }
    // The root layer always has a compositing layer, but it may not have backing.
    return requiresCompositingForTransform(renderer)
        || requiresCompositingForVideo(renderer)
        || requiresCompositingForCanvas(renderer)
        || requiresCompositingForPlugin(renderer)
        || requiresCompositingForFrame(renderer)
        || (canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden)
        || clipsCompositingDescendants(layer)
        || requiresCompositingForAnimation(renderer)
        || requiresCompositingForFilters(renderer)
        || requiresCompositingForPosition(renderer, layer);
}

      每次创建DOM节点的时候,发现存在样式( Style)或者样式被改变,webkit就创建相应RenderObject节点并设置其新样式。同时,要求更新本RenderObject节点的父亲--整颗RenderLayer树的样式,RenderLayer就会更新合成器的状态。

      创建RenderObject并且设置新样式:

#8  WebCore::RenderObject::setStyle (this=0xc16f18, style=...)RenderObject.cpp:1744

#9  WebCore::RenderObject::setAnimatableStyle (this=0xc16f18, style=...) RenderObject.cpp:1645

#10 WebCore::NodeRendererFactory::createRenderer (this)WebCore/dom/NodeRenderingContext.cpp:291

​#11 WebCore::NodeRendererFactory::createRendererIfNeeded (this=0x7fffffffcb50)NodeRenderingContext.cpp:324

#12 WebCore::Node::createRendererIfNeeded (this=0xc0aa80) WebCore/dom/Node.cpp:1378

#13 WebCore::Element::attach (this=0xc0aa80) at WebKit/Source/WebCore/dom/Element.cpp:941

#14 WebCore::executeTask (task=...) WebCore/html/parser/HTMLConstructionSite.cpp:102

#15 WebCore::HTMLConstructionSite::executeQueuedTasks (this=) WebCore/html/parser/HTMLConstructionSite.cpp:142

#16 WebCore::HTMLTreeBuilder::constructTreeFromAtomicToken (this=0xc89840, token=) HTMLTreeBuilder.cpp:475

#17 WebCore::HTMLTreeBuilder::constructTreeFromToken (this=0xc89840, rawToken=...)

    更新盒子模型:

#5  RenderBoxModelObject::styleDidChange (this, diff=WebCore::StyleDifferenceEqual, oldStyle) RenderBoxModelObject.cpp:445

#6  RenderBox::styleDidChange (this, diff=WebCore::StyleDifferenceEqual, oldStyle=0x0)RenderBox.cpp:233

​#7  WebCore::RenderBlock::styleDidChange (this=0xc16f18, diff=WebCore::StyleDifferenceEqual, oldStyle=0x0)RenderBlock.cpp:315

     要求更新整颗RenderLayer树的样式:

#4  WebCore::RenderLayer::styleChanged (this=0xc3d838, oldStyle=0x0) WebCore/rendering/RenderLayer.cpp:4886

       RenderLayer就会更新合成器的状态:

#3  RenderLayerCompositor::updateLayerCompositingState (layer, shouldRepaint=CompositingChangeRepaintNow)RenderLayerCompositor.cpp:558

     并首先更新后端存储区:

#2  RenderLayerCompositor::updateBacking (layer,  shouldRepaint=CompositingChangeRepaintNowRenderLayerCompositor.cpp:495

     先检查是否需要后端存储区:

bool RenderLayerCompositor::updateBacking(RenderLayer* layer, CompositingChangeRepaint shouldRepaint)
{
    bool layerChanged = false;

    if (<span style="background-color: rgb(51, 255, 51);">needsToBeComposited</span>(layer)) {
        enableCompositingMode();
        
        if (!layer->backing()) {
            // If we need to repaint, do so before making backing
            if (shouldRepaint == CompositingChangeRepaintNow)
                repaintOnCompositingChange(layer);

            layer-><span style="background-color: rgb(51, 255, 51);">ensureBacking</span>();

            // The RenderLayer's needs to update repaint rects here, because the target
            // repaintContainer may have changed after becoming a composited layer.
            // https://bugs.webkit.org/show_bug.cgi?id=80641
            if (layer->parent())
                layer->computeRepaintRects();

            layerChanged = true;
        }
创建后端存储区的管理类:

RenderLayerBacking* RenderLayer::<span style="background-color: rgb(51, 255, 51);">ensureBacking</span>()
{
    if (!m_backing) {
        m_backing = adoptPtr(new RenderLayerBacking(this));
        compositor()->layerBecameComposited(this);

#if ENABLE(CSS_FILTERS)
        updateOrRemoveFilterEffect();
#endif
    }
    return m_backing.get();
}

创建Backing Store:

RenderLayerBacking::RenderLayerBacking(RenderLayer* layer)
{     
    <span style="background-color: rgb(51, 255, 51);">createPrimaryGraphicsLayer</span>();
}
<pre name="code" class="cpp">void RenderLayerBacking::createPrimaryGraphicsLayer()
{
    String layerName;
#ifndef NDEBUG
    layerName = nameForLayer();
#endif
    
    // The call to createGraphicsLayer ends calling back into here as
    // a GraphicsLayerClient to ask if it shouldUseTileCache(). We only want
    // the tile cache on our main layer. This is pretty ugly, but saves us from
    // exposing the API to all clients.

    m_creatingPrimaryGraphicsLayer = true;
    m_graphicsLayer = <span style="background-color: rgb(51, 255, 51);">createGraphicsLayer</span>(layerName);
}


 
PassOwnPtr<GraphicsLayer> RenderLayerBacking::createGraphicsLayer(const String& name)
{
    OwnPtr<GraphicsLayer> graphicsLayer = <span style="background-color: rgb(51, 255, 51);">GraphicsLayer::create(</span>this);

    graphicsLayer->setMaintainsPixelAlignment(compositor()->keepLayersPixelAligned());

    return graphicsLayer.release();
}
     我们看看chrome的实现:
PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
{
    return adoptPtr(new GraphicsLayerChromium(client));
}
      GraphicsLayerChromium就是Backing Store的抽象类GraphicsLayer之具体实现!

以下是我的测试网页:

<html>
<head>

<style type="text/css">
div, video, canvas
{
-webkit-transform: rotateY(10deg) rotateX(-15deg);
}
</style>

</head>

<body>
<video src=http://media.w3.org/2010/05/sintel/trailer.mp4></video>
<div>
<canvas id="a12d"></canvas><br>
<canvas id="a13d"></canvas>
</div>
<script type="text/javascript">
	var size=100;
	//2d drawing
	var a12dCtx = document.getElementById('a12d').getContext.('2d');
	a12dCtx.canvas.width = size;
	a12dCtx.canvas.height = size;
	a12dCtx.canvas.fillStyle="rgba(0,92,92,80)";
	a12dCtx.canvas.fillRect(0,0,100,100);
</script>
</body>
</html>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值