blink渲染知识10 - render tree的构建点

何时在哪里thread构建的,先找到构建rendertreecode.

RenderTreeBuilder类。

上面1.16rendering basics中讲了,RenderTree是通过对dom节点执行attach操作建立的。在dom被建立时,对其节点执行attach操作,即可创建renderobject, 建立rendertree. docuemnt关闭,或从dom中移除一个节点时,对该节点执行detach操作,就可将他对应的rendreobjectrendertree中移除。









下面看看最简单的调用element::attachcallstack,是在收到了html数据加载完之后,先对document节点执行attach,他会对子节点执行attach.

#0 WebCore::Element::attach(this=0x3ea08068, context=...) at../../third_party/WebKit/Source/core/dom/Element.cpp:1357

#1 0x60d15a9c inWebCore::Node::reattach(this=this@entry=0x3ea08068, context=...) at../../third_party/WebKit/Source/core/dom/Node.cpp:973

#2 0x60d0cbce inWebCore::Element::recalcOwnStyle(this=this@entry=0x3ea08068, change=change@entry=WebCore::Force) at../../third_party/WebKit/Source/core/dom/Element.cpp:1552

#3 0x60d0cd0a inWebCore::Element::recalcStyle(this=0x3ea08068, change=WebCore::Force, nextTextSibling=0x0) at../../third_party/WebKit/Source/core/dom/Element.cpp:1518

#4 0x60d034f6 inWebCore::Document::updateStyle(this=this@entry=0x3ea04000, change=<optimized out>,change@entry=WebCore::NoChange) at../../third_party/WebKit/Source/core/dom/Document.cpp:1946

#5 0x60d038e6 inWebCore::Document::updateRenderTree(this=this@entry=0x3ea04000,change=change@entry=WebCore::NoChange) at../../third_party/WebKit/Source/core/dom/Document.cpp:1882

#6 0x60d03a32 inWebCore::Document::updateRenderTreeIfNeeded(this=this@entry=0x3ea04000) at../../third_party/WebKit/Source/core/dom/Document.h:486

#7 0x60d04744 inWebCore::Document::finishedParsing(this=0x3ea04000) at../../third_party/WebKit/Source/core/dom/Document.cpp:4705

#8 0x60b9e1bc inWebCore::HTMLConstructionSite::finishedParsing (this=<optimizedout>) at../../third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp:543

#9 0x60bae026 inWebCore::HTMLTreeBuilder::finished(this=<optimized out>) at../../third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp:2796

#10 0x60b9f71c inWebCore::HTMLDocumentParser::end (this=this@entry=0x2e46c480) at../../third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp:828

#11 0x60b9f730 inWebCore::HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd(this=this@entry=0x2e46c480) at../../third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp:839

#12 0x60ba008c inWebCore::HTMLDocumentParser::prepareToStopParsing (this=0x2e46c480)at../../third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp:240

#13 0x60ba13d6 inWebCore::HTMLDocumentParser::processParsedChunkFromBackgroundParser(this=this@entry=0x2e46c480, popChunk=...) at../../third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp:491

#14 0x60ba1538 inWebCore::HTMLDocumentParser::pumpPendingSpeculations(this=this@entry=0x2e46c480) at../../third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp:530

#15 0x60ba1770 inWebCore::HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser(this=0x2e46c480, chunk=...) at../../third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp:363

#16 0x60b9b6c2 in operator()(p1=..., c=..., this=<optimized out>) at../../third_party/WebKit/Source/wtf/Functional.h:210

#17WTF::BoundFunctionImpl<WTF::FunctionWrapper<void(WebCore::HTMLDocumentParser::*)(WTF::PassOwnPtr<WebCore::HTMLDocumentParser::ParsedChunk>)>,void (WTF::WeakPtr<WebCore::HTMLDocumentParser>,WTF::PassOwnPtr<W

#18 0x6154d7fc in operator()(this=0x650edab8) at../../third_party/WebKit/Source/wtf/Functional.h:577

#19 WTF::callFunctionObject(context=0x650edab8) at../../third_party/WebKit/Source/wtf/MainThread.cpp:62

#20 0x6144d6d6 in Run (a1=<optimizedout>, this=<synthetic pointer>) at../../base/bind_internal.h:171

#21 MakeItSo (a1=<optimized out>,runnable=...) at ../../base/bind_internal.h:871

#22 base::internal::Invoker<1,base::internal::BindState<base::internal::RunnableAdapter<void(*)(void*)>, void (void*), void (void*)>, void(void*)>::Run(base::internal::BindStateBase*) (base=<optimizedout>)

at../../base/bind_internal.h:1169

#23 0x614f31f0 in Run(this=0x65ce4d00) at ../../base/callback.h:401

#24 base::MessageLoop::RunTask(this=this@entry=0x5abea008, pending_task=...) at../../base/message_loop/message_loop.cc:450

#25 0x614f329c inbase::MessageLoop::DeferOrRunPendingTask (this=this@entry=0x5abea008,pending_task=...) at ../../base/message_loop/message_loop.cc:462

#26 0x614f39b2 inbase::MessageLoop::DoWork (this=0x5abea008) at../../base/message_loop/message_loop.cc:576

#27 0x614f3f02 inbase::MessagePumpDefault::Run (this=0x5abea500, delegate=0x5abea008)at ../../base/message_loop/message_pump_default.cc:32

#28 0x614f35d6 inbase::MessageLoop::RunHandler (this=0x5abea008) at../../base/message_loop/message_loop.cc:400

#29 0x614fab78 in base::RunLoop::Run(this=this@entry=0x65ce4d70) at ../../base/run_loop.cc:49

#30 0x614f2c04 inbase::MessageLoop::Run (this=<optimized out>) at../../base/message_loop/message_loop.cc:293

#31 0x615036d6 inbase::Thread::ThreadMain (this=0x57b80c78) at../../base/threading/thread.cc:225

#32 0x615014fe in base::(anonymousnamespace)::ThreadFunc (params=<optimized out>) at../../base/threading/platform_thread_posix.cc:80

#33 0x40196a5c in __thread_entry ()from /tmp/tshao-adb-gdb-libs/system/lib/libc.so







void Element::attach(constAttachContext& context)

{

RenderTreeBuilder(this,//创建本节点的renderer.context.resolvedStyle).createRendererForElementIfNeeded();



ContainerNode::attach(context);//对本节点的childern执行attach.

。。。

}



这里使用RenderTreeBuilder.来针对一个dom节点建立renderobject并加入到rendertree中。

voidRenderTreeBuilder::createRendererForElementIfNeeded()

{

Element* element =toElement(m_node);

RenderStyle& style =this->style();



RenderObject* newRenderer = element->createRenderer(&style);

这里创建renderobject,实际调用RenderObject::createObject.

RenderObject* parentRenderer =this->parentRenderer();

RenderObject* nextRenderer =this->nextRenderer();

element->setRenderer(newRenderer);

newRenderer->setStyle(&style);// setStyle() can depend on renderer() already being set.

parentRenderer->addChild(newRenderer, nextRenderer);

创建renderer,并把其加入parentrenderer的孩子,够在renderobject tree.

}

我们看看如何创建RenderObject:

RenderObject*RenderObject::createObject(Element* element, RenderStyle* style)

{

ASSERT(isAllowedToModifyRenderTreeStructure(element->document()));



// Minimal support for contentproperties replacing an entire element.

// Works only if we have exactlyone piece of content and it's a URL.

// Otherwise acts as if wedidn't support this feature.

const ContentData* contentData =style->contentData();

if (contentData &&!contentData->next() && contentData->isImage() &&!element->isPseudoElement()) {

RenderImage* image = newRenderImage(element);

//RenderImageResourceStyleImage requires a style being present on theimage but we don't want to

// trigger a style changenow as the node is not fully attached. Moving this code to stylechange

// doesn't make sense as itshould be run once at renderer creation.

image->setStyleInternal(style);

if (const StyleImage*styleImage = static_cast<constImageContentData*>(contentData)->image()) {

image->setImageResource(RenderImageResourceStyleImage::create(const_cast<StyleImage*>(styleImage)));

image->setIsGeneratedContent();

} else

image->setImageResource(RenderImageResource::create());

image->setStyleInternal(nullptr);

return image;

}



switch (style->display()) {

case NONE:

return 0;

case INLINE:

return newRenderInline(element);

case BLOCK:

case INLINE_BLOCK:

return newRenderBlockFlow(element);

case LIST_ITEM:

return newRenderListItem(element);

case TABLE:

case INLINE_TABLE:

return newRenderTable(element);

case TABLE_ROW_GROUP:

case TABLE_HEADER_GROUP:

case TABLE_FOOTER_GROUP:

return newRenderTableSection(element);

case TABLE_ROW:

return newRenderTableRow(element);

case TABLE_COLUMN_GROUP:

case TABLE_COLUMN:

return newRenderTableCol(element);

case TABLE_CELL:

return newRenderTableCell(element);

case TABLE_CAPTION:

return newRenderTableCaption(element);

case BOX:

case INLINE_BOX:

return newRenderDeprecatedFlexibleBox(element);

case FLEX:

case INLINE_FLEX:

return newRenderFlexibleBox(element);

case GRID:

case INLINE_GRID:

return newRenderGrid(element);

}



return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值