一 DeprecatedPaintLayer(RenderLayer) 的综述
所有具有可见性的DOM Tree中的节点都会创建对应的LayoutObject节点,然后这些LayoutObject节点形成一颗RenderTree。而RenderTree中的LayoutObject在满足一定条件
会创建DeprecatedPaintLayer,DeprecatedPaintLayer可能由一个或多个LayoutObject组成。
在前一篇(三)中,分析LocalDOMWindow::installNewDocument()会创建DeprecetedPaintLayerCompositor,并设置它状态,每一个LayoutView都会有一个DeprecetedPaintLayerCompositor,它主要用来管理DeprecatedPaintLayerTree。
二 DeprecatedPaintLayer 的创建
在LayoutObject创建的同时会进行判断是否需要创建DeprecatedPaintLayer。
创建DeprecatedPaintLayer的起点是在LayoutTreeBuilder::createlayoutObject()函数中,
Call Stack:
#0 blink::LayoutBox::layerTypeRequired()
#1 blink::LayoutBoxModelObject::styleDidChange(blink::StyleDifference diff,
const blink::ComputedStyle * oldStyle)
#2 blink::LayoutBox::styleDidChange(blink::StyleDifference diff, const blink::ComputedStyle * oldStyle)
#3 blink::LayoutBlock::styleDidChange(blink::StyleDifference diff, const blink::ComputedStyle * oldStyle)
#4 blink::LayoutBlockFlow::styleDidChange(blink::StyleDifference diff,
const blink::ComputedStyle * oldStyle)
#5 blink::LayoutObject::setStyle(WTF::PassRefPtr<blink::ComputedStyle> style)
#6 blink::LayoutTreeBuilderForElement::createLayoutObject()
#7 blink::LayoutTreeBuilderForElement::createLayoutObjectIfNeeded()
#8 blink::Element::attach(const blink::Node::AttachContext & context)
#9 blink::ContainerNode::attachChildren(const blink::Node::AttachContext & context)
#10 blink::ContainerNode::attach(const blink::Node::AttachContext & context)
#11 blink::Element::attach(const blink::Node::AttachContext & context)
#12 blink::ContainerNode::attachChildren(const blink::Node::AttachContext & context)
#13 blink::ContainerNode::attach(const blink::Node::AttachContext & context)
#14 blink::Element::attach(const blink::Node::AttachContext & context)
#15 blink::Node::reattach(const blink::Node::AttachContext & context)
#16 blink::Element::recalcOwnStyle(blink::StyleRecalcChange change)
#17 blink::Element::recalcStyle(blink::StyleRecalcChange change,
blink::Text * nextTextSibling)
#18 blink::Document::updateStyle(blink::StyleRecalcChange change)
#19 blink::Document::updateLayoutTree(blink::StyleRecalcChange change)
#20 blink::Document::updateLayoutTreeIfNeeded()
#21 blink::Document::finishedParsing()
#22 blink::HTMLConstructionSite::finishedParsing()
#23 blink::HTMLTreeBuilder::finished()
#24 blink::HTMLDocumentParser::end()
#25 blink::HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd()
#26 blink::HTMLDocumentParser::prepareToStopParsing()+
#27 blink::HTMLDocumentParser::processParsedChunkFromBackgroundParser(
WTF::PassOwnPtr<blink::HTMLDocumentParser::ParsedChunk> popChunk)
#28 blink::HTMLDocumentParser::pumpPendingSpeculations()
#29 blink::HTMLDocumentParser::resumeParsingAfterYield()
#30 blink::HTMLParserScheduler::continueParsing()
其中,#0 判断当前LayoutObject是否需要创建DeprecatedPaintLayer, 以及创建何种类型的DeprecatedPaintLayer;
#1 是具体创建DeprecatedPaintLayer的地方,如果需要创建DeprecatedPaintLayer,那么就会调用createLayer(DeprecatedPaintLayerType type), 它的具体代码如下:
void LayoutBoxModelObject::createLayer(DeprecatedPaintLayerType type)
{
ASSERT(!m_layer);
m_layer = adoptPtr(new DeprecatedPaintLayer(this, type));
setHasLayer(true);
m_layer->insertOnlyThisLayer();
}
insertOnlyThisLayer()也是非常重要的函数,它会决定如何向当前DeprecatedPaintLayerTree中添加刚刚创建的DeprecatedPaintLayer。
二 DeprecatedPaintLayerTree(RenderLayer Tree) 的创建
DeprecatedPaintLayerTree的创建都由insertOnlyThisLayer这个函数开始,进行DeprecatedPaintLayerTree的相关创建:
void DeprecatedPaintLayer::insertOnlyThisLayer()
{
if (!m_parent && layoutObject()->parent()) {
// We need to connect ourselves when our layoutObject() has a parent.
// Find our enclosingLayer and add ourselves.
DeprecatedPaintLayer* parentLayer = layoutObject()->parent()->enclosingLayer();
ASSERT(parentLayer);
DeprecatedPaintLayer* beforeChild = !parentLayer->reflectionInfo() || parentLayer->reflectionInfo()->reflectionLayer() != this ? layoutObject()->parent()->findNextLayer(parentLayer, layoutObject()) : 0;
parentLayer->addChild(this, beforeChild);
}
// Remove all descendant layers from the hierarchy and add them to the new position.
for (LayoutObject* curr = layoutObject()->slowFirstChild(); curr; curr = curr->nextSibling())
curr->moveLayers(m_parent, this);
// Clear out all the clip rects.
m_clipper.clearClipRectsIncludingDescendants();
}
版权声明:本文为博主原创文章,未经博主允许不得转载。