#############################################

本文为极度寒冰原创,转载请注明出处#############################################

还是顺着前面的内容进行分析,前面一篇文章中,是对image标签进行了解析。我们分析了一个img的标签,其所对应的资源被下载的全过程。

当我们load img标签的时候,我们会发现进行了预下载的工作。
这也被我们判断为webkit渲染速度比其它引擎快速的一个原因。毕竟直接从cache里面读取是比从网络上下载要快非常多的。
而当我们load之后,接下来进行的工作是什么呢?图片到底是怎么被显示在终端上面的呢?
下面准备接着对这样的内容进行分析。
(gdb) bt#0  WebCore::RenderImage::paint (this=0x2a4fd634, paintInfo=..., tx=0, ty=0) at external/webkit/Source/WebCore/rendering/RenderImage.cpp:330#1  0x48d98538 in WebCore::InlineBox::paint (this=0x2a4e4f44, paintInfo=<value optimized out>, tx=<value optimized out>, ty=<value optimized out>)    at external/webkit/Source/WebCore/rendering/InlineBox.cpp:184#2  WebCore::InlineBox::paint (this=0x2a4e4f44, paintInfo=<value optimized out>, tx=<value optimized out>, ty=<value optimized out>) at external/webkit/Source/WebCore/rendering/InlineBox.cpp:162#3  0x48d9b7a0 in WebCore::InlineFlowBox::paint (this=<value optimized out>, paintInfo=..., tx=0, ty=0, lineTop=33, lineBottom=52) at external/webkit/Source/WebCore/rendering/InlineFlowBox.cpp:1014#4  0x48df7bfa in WebCore::RootInlineBox::paint (this=0x2a4e4f6c, paintInfo=..., tx=0, ty=0, lineTop=33, lineBottom=52) at external/webkit/Source/WebCore/rendering/RootInlineBox.cpp:183#5  0x48dd1618 in WebCore::RenderLineBoxList::paint (this=0x2a4fd628, renderer=0x2a4fd5b8, paintInfo=<value optimized out>, tx=0, ty=0)        at external/webkit/Source/WebCore/rendering/RenderLineBoxList.cpp:262#6  0x48da1b9c in WebCore::RenderBlock::paintContents (this=0x2a4fd5b8, paintInfo=..., tx=0, ty=0) at external/webkit/Source/WebCore/rendering/RenderBlock.cpp:2422#7  WebCore::RenderBlock::paintContents (this=0x2a4fd5b8, paintInfo=..., tx=0, ty=0) at external/webkit/Source/WebCore/rendering/RenderBlock.cpp:2413#8  0x48da9e8a in WebCore::RenderBlock::paintObject (this=0x2a4fd5b8, paintInfo=..., tx=0, ty=0) at external/webkit/Source/WebCore/rendering/RenderBlock.cpp:2536#9  0x48da0a50 in WebCore::RenderBlock::paint (this=0x2a4fd5b8, paintInfo=..., tx=0, ty=0) at external/webkit/Source/WebCore/rendering/RenderBlock.cpp:2312#10 0x48da1ad8 in WebCore::RenderBlock::paintChildren (this=0x2a4fd244, paintInfo=..., tx=0, ty=0) at external/webkit/Source/WebCore/rendering/RenderBlock.cpp:2465#11 0x48da9e8a in WebCore::RenderBlock::paintObject (this=0x2a4fd244, paintInfo=..., tx=0, ty=0) at external/webkit/Source/WebCore/rendering/RenderBlock.cpp:2536#12 0x48da0a50 in WebCore::RenderBlock::paint (this=0x2a4fd244, paintInfo=..., tx=0, ty=0) at external/webkit/Source/WebCore/rendering/RenderBlock.cpp:2312#13 0x48da1ad8 in WebCore::RenderBlock::paintChildren (this=0x2a4fd1c8, paintInfo=..., tx=0, ty=0) at external/webkit/Source/WebCore/rendering/RenderBlock.cpp:2465#14 0x48da9e8a in WebCore::RenderBlock::paintObject (this=0x2a4fd1c8, paintInfo=..., tx=0, ty=0) at external/webkit/Source/WebCore/rendering/RenderBlock.cpp:2536#15 0x48da0a50 in WebCore::RenderBlock::paint (this=0x2a4fd1c8, paintInfo=..., tx=0, ty=0) at external/webkit/Source/WebCore/rendering/RenderBlock.cpp:2312#16 0x48da1ad8 in WebCore::RenderBlock::paintChildren (this=0x2a4fd06c, paintInfo=..., tx=0, ty=0) at external/webkit/Source/WebCore/rendering/RenderBlock.cpp:2465#17 0x48da9e8a in WebCore::RenderBlock::paintObject (this=0x2a4fd06c, paintInfo=..., tx=0, ty=0) at external/webkit/Source/WebCore/rendering/RenderBlock.cpp:2536#18 0x48da0a50 in WebCore::RenderBlock::paint (this=0x2a4fd06c, paintInfo=..., tx=0, ty=0) at external/webkit/Source/WebCore/rendering/RenderBlock.cpp:2312#19 0x48dcc43c in WebCore::RenderLayer::paintLayer (this=<value optimized out>, rootLayer=0x2a4fcf8c, p=<value optimized out>, paintDirtyRect=..., paintBehavior=0, paintingRoot=0x0,             overlapTestRequests=0x4a8c2644, paintFlags=<value optimized out>) at external/webkit/Source/WebCore/rendering/RenderLayer.cpp:2725#20 0x48dcc996 in WebCore::RenderLayer::paintList (this=0x2a4fcf8c, list=0x2a4d2758, rootLayer=0x2a4fcf8c, p=0x4a8c2758, paintDirtyRect=..., paintBehavior=0, paintingRoot=0x0,                 overlapTestRequests=0x4a8c2644, paintFlags=0) at external/webkit/Source/WebCore/rendering/RenderLayer.cpp:2784#21 0x48dcc4f8 in WebCore::RenderLayer::paintLayer (this=<value optimized out>, rootLayer=0x2a4fcf8c, p=<value optimized out>, paintDirtyRect=..., paintBehavior=0, paintingRoot=0x0,                     overlapTestRequests=0x4a8c2644, paintFlags=<value optimized out>) at external/webkit/Source/WebCore/rendering/RenderLayer.cpp:2746#22 0x48dcca28 in WebCore::RenderLayer::paint (this=<value optimized out>, p=0x4a8c2758, damageRect=..., paintBehavior=<value optimized out>, paintingRoot=0x0)                        at external/webkit/Source/WebCore/rendering/RenderLayer.cpp:2519#23 0x48d62b76 in WebCore::FrameView::paintContents (this=0x2a4faf40, p=0x4a8c2758, rect=...) at external/webkit/Source/WebCore/page/FrameView.cpp:2424#24 0x48e4c5ac in android::WebFrameView::draw (this=<value optimized out>, gc=0x4a8c2758, rect=...) at external/webkit/Source/WebKit/android/jni/WebFrameView.cpp:61#25 0x48e4f7bc in android::WebViewCore::paintContents (this=<value optimized out>, gc=0x4a8c2758, dirty=...) at external/webkit/Source/WebKit/android/jni/WebViewCore.cpp:751#26 0x48f92832 in WebCore::PicturePile::updatePicture (this=<value optimized out>, painter=0x2a0c7788, pc=...) at external/webkit/Source/WebKit/android/jni/PicturePile.cpp:199#27 0x48f92f78 in WebCore::PicturePile::updatePicturesIfNeeded (this=0x2a0c77a4, painter=0x2a0c7788) at external/webkit/Source/WebKit/android/jni/PicturePile.cpp:160#28 0x48e4fdb8 in android::WebViewCore::recordPicturePile (this=0x2a0c7780) at external/webkit/Source/WebKit/android/jni/WebViewCore.cpp:722#29 0x48e56068 in android::WebViewCore::recordContent (this=0x2a0c7780, point=0x4a8c2c48) at external/webkit/Source/WebKit/android/jni/WebViewCore.cpp:915#30 0x48e560a0 in RecordContent (env=0x2a11f140, obj=<value optimized out>, nativeClass=<value optimized out>, pt=0x36300005) at external/webkit/Source/WebKit/android/jni/WebViewCore.cpp:4549#31 0x4070fe34 in dvmPlatformInvoke () at dalvik/vm/arch/arm/CallEABI.S:258#32 0x4073ee6a in dvmCallJNIMethod (args=0x4a3a8e20, pResult=0x2a1118a0, method=0x44da09c8, self=0x2a111890) at dalvik/vm/Jni.cpp:1155#33 0x4072ad88 in dvmCheckCallJNIMethod (args=<value optimized out>, pResult=0x2a1118a0, method=0x44da09c8, self=0x2a111890) at dalvik/vm/CheckJni.cpp:145#34 0x40719264 in dalvik_mterp () at dalvik/vm/mterp/out/InterpAsm-armv7-a.S:16239#35 0x4071db30 in dvmInterpret (self=0x2a111890, method=<value optimized out>, pResult=0x4a8c2eb0) at dalvik/vm/interp/Interp.cpp:1964#36 0x40751594 in dvmCallMethodV (self=0x2a111890, method=0x44bf1d40, obj=<value optimized out>, fromJni=<value optimized out>, pResult=0x4a8c2eb0, args=...) at dalvik/vm/interp/Stack.cpp:526#37 0x407515be in dvmCallMethod (self=<value optimized out>, method=<value optimized out>, obj=<value optimized out>, pResult=0x4a8c2eb0) at dalvik/vm/interp/Stack.cpp:429#38 0x40746176 in interpThreadStart (arg=0x2a111890) at dalvik/vm/Thread.cpp:1538#39 0x40038db4 in __thread_entry (func=0x407460d5 <interpThreadStart>, arg=0x2a111890, tls=<value optimized out>) at bionic/libc/bionic/pthread.c:217#40 0x40038518 in pthread_create (thread_out=0x2a0ddbf0, attr=0xbee99818, start_routine=0x407460d5 <interpThreadStart>, arg=0x2a111890) at bionic/libc/bionic/pthread.c:356

这是一个非常复杂的backtrace....
但是我们没有必要紧张,可以一点一点的来看这个问题:
#30 0x48e560a0 in RecordContent (env=0x2a11f140, obj=<value optimized out>, nativeClass=<value optimized out>, pt=0x36300005) at external/webkit/Source/WebKit/android/jni/WebViewCore.cpp:4549

一看这个函数我们就知道涉及到的是JNI的操作了。
查看一下对应关系: { "nativeRecordContent", "(ILandroid/graphics/Point;)I", (void*) RecordContent },
看到native函数,我们就明白了这个函数其实是由java端对native层的调用了。
继续来追一下这个调用:
WebViewCore.java中对native函数的调用有两处,
1. private void webkitDraw()
2. private void saveViewState(OutputStream stream, ValueCallback<Boolean> callback)
经过debug,我们发现在正常打开一个网页的时候,主要进行的是webkitDraw的操作。

所以我们继续追踪一下webkitDraw的调用过成。
case WEBKIT_DRAW:    webkitDraw();    break;
可以看到,在接受到WEBKIT_DRAW的信号的时候,就会进行webkitDraw的工作。那么,在我们正常加载一张图片的时候,这个信息是由谁发出的呢?
有三个地方对WEBKIT_DRAW的信号进行了发送的通知,分别是:
void contentDraw()
void resumeWebKitDraw()
void webkitDraw()
这边我们主要关心的是contentDraw()。
看到contentDraw函数的注释就可以知道这个函数called from JNI or WebView thread。
相对应的,我们在webviewcore.cpp里面找到了向对应的函数:
void WebViewCore::contentDraw(){    JNIEnv* env = JSC::Bindings::getJNIEnv();    AutoJObject javaObject = m_javaGlue->object(env);    if (!javaObject.get())        return;    env->CallVoidMethod(javaObject.get(), m_javaGlue->m_contentDraw);    checkException(env);}
既然找到了在native的接口,那么我们先研究一下调用到这边函数的一个过程,然后再去研究上面的那一个复杂的堆栈。

这边我们以打开一个google的网页为例进行说明。 (此时的cache,data都已经清零)

这个比刚才的backtrace还要复杂的堆栈是出现在第一次断点被断掉的地方。。。

虽然堆栈很多也很大,但是这边有很多我们已经分析过的log。
起码到WebCore::HTMLTreeBuilder::processStartTagForInBody之前的log,我们应该已经非常的熟悉了。

#17 0x48fc6476 in WebCore::HTMLConstructionSite::attach<WebCore::Element> (this=<value optimized out>, rawParent=0x2a421148, prpChild=<value optimized out>)                    at external/webkit/Source/WebCore/html/parser/HTMLConstructionSite.cpp:108#18 0x48fc64ae in WebCore::HTMLConstructionSite::attachToCurrent (this=<value optimized out>, child=<value optimized out>) at external/webkit/Source/WebCore/html/parser/HTMLConstructionSite.cpp:260#19 0x48fc6512 in WebCore::HTMLConstructionSite::insertHTMLElement (this=0x2a1fa59c, token=<value optimized out>) at external/webkit/Source/WebCore/html/parser/HTMLConstructionSite.cpp:290#20 0x48f2fcde in WebCore::HTMLTreeBuilder::processStartTagForInBody (this=<value optimized out>, token=...) at external/webkit/Source/WebCore/html/parser/HTMLTreeBuilder.cpp:1032
这个堆栈我们应该也不会感到陌生。

if (parent->attached() && !child->attached())
child->attach();
的操作中,因为child是一个Element类型的变量,所以这边会去调用Element类中的attached方法。
attached是一个非常非常重要的方法, 函数原型为:
void Element::attach(){    suspendPostAttachCallbacks();    RenderWidget::suspendWidgetHierarchyUpdates(); //RenderWidget类主要负责的作用是负责调度页面渲染和页面更新等操作。    createRendererIfNeeded();// 非常重要的函数,判断当前的节点是否需要渲染    StyleSelectorParentPusher parentPusher(this);    if (Node* shadow = shadowRoot()) {        parentPusher.push();        shadow->attach();    }    if (firstChild())        parentPusher.push();    ContainerNode::attach();    if (hasRareData()) {        ElementRareData* data = rareData();        if (data->needsFocusAppearanceUpdateSoonAfterAttach()) {            if (isFocusable() && document()->focusedNode() == this)                document()->updateFocusAppearanceSoon(false /* don't restore selection */);            data->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);        }    }    RenderWidget::resumeWidgetHierarchyUpdates();    resumePostAttachCallbacks();}
在这个函数中,我们首先关心的是createRendererIfNeeded()。
函数的实现在Node.cpp,函数的原型为:
void Node::createRendererIfNeeded(){    if (!document()->shouldCreateRenderers()) //判断当前的节点是否需要Renderers,如果不需要的话就直接返回。        return;    ASSERT(!renderer());    RenderObject* newRenderer = createRendererAndStyle();  //RenderObject类的作用是所有RenderTree的基类,类似Node在Dom中的作用            #if ENABLE(FULLSCREEN_API)    if (document()->webkitIsFullScreen() && document()->webkitCurrentFullScreenElement() == this)        newRenderer = wrapWithRenderFullScreen(newRenderer, document());#endif    if (!newRenderer) //如果newRenderer没有创建成功的话,就返回。 容错判断        return;    // Note: Adding newRenderer instead of renderer(). renderer() may be a child of newRenderer.    parentNodeForRenderingAndStyle()->renderer()->addChild(newRenderer, nextRenderer());}
Node::createRendererAndStyle()的实现中,我们会进行RefPtr<RenderStyle> style = styleForRenderer()的操作。RenderStyle的作用是什么呢?这个往往用来描述一个RenderObject所可能涉及的CSS属性数据,也就是说在这个style里面,我们已经保存了当前节点的css的相关属性。这边获取css的属性方面也很复杂,不过相比与现在分析的这个Image的渲染过程还是相对应比较简单的。
在style创建完成之后,RenderObject* newRenderer = createRenderer(document()->renderArena(), style.get());就会获取当前的style的相关属性并且赋值给newRenderer,这样的话,函数返回值的newRenderer已经包含了当前dom树的属性,并且同步具有了css的相关属性。

在创建完RenderObject对象之后,会对RenderObject对象设置RenderStyle属性,然后在该DOM Node的父节点对应的RenderObject中添加刚刚新建的RenderObject,这样的作用是用于构建RenderTree。
是否可以认为在createRendererIfNeeded之后,当前节点已经插入到了RenderTree中呢? 接下来接着分析。
#0  android::WebViewCore::contentDraw (this=0x2a1c6f68) at external/webkit/Source/WebKit/android/jni/WebViewCore.cpp:969#1  0x48f8ad3c in android::ChromeClientAndroid::attachRootGraphicsLayer (this=<value optimized out>, layer=<value optimized out>)    at external/webkit/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp:112#2  0x48dcfd8c in WebCore::RenderLayerCompositor::attachRootPlatformLayer (this=0x2a3b3f58, attachment=WebCore::RenderLayerCompositor::RootLayerAttachedViaChromeClient)        at external/webkit/Source/WebCore/rendering/RenderLayerCompositor.cpp:1895    #3  0x48dd03e4 in WebCore::RenderLayerCompositor::ensureRootPlatformLayer (this=0x2a3b3f58) at external/webkit/Source/WebCore/rendering/RenderLayerCompositor.cpp:1842#4  0x48dd0432 in WebCore::RenderLayerCompositor::enableCompositingMode (this=0x2a3b3f58, enable=<value optimized out>) at external/webkit/Source/WebCore/rendering/RenderLayerCompositor.cpp:153#5  WebCore::RenderLayerCompositor::enableCompositingMode (this=0x2a3b3f58, enable=<value optimized out>) at external/webkit/Source/WebCore/rendering/RenderLayerCompositor.cpp:147#6  0x48dd051a in WebCore::RenderLayerCompositor::updateBacking (this=0x2a3b3f58, layer=0x2a3fa67c, shouldRepaint=WebCore::RenderLayerCompositor::CompositingChangeRepaintNow)            at external/webkit/Source/WebCore/rendering/RenderLayerCompositor.cpp:360#7  0x48dd05da in WebCore::RenderLayerCompositor::updateLayerCompositingState (this=<value optimized out>, layer=0x2a3fa67c, shouldRepaint=<value optimized out>)                at external/webkit/Source/WebCore/rendering/RenderLayerCompositor.cpp:437#8  0x48dca85a in WebCore::RenderLayer::styleChanged (this=0x2a3fa67c, diff=WebCore::StyleDifferenceEqual, oldStyle=0x0) at external/webkit/Source/WebCore/rendering/RenderLayer.cpp:4119#9  0x48db78e6 in WebCore::RenderBoxModelObject::styleDidChange (this=0x2a3fa600, diff=WebCore::StyleDifferenceEqual, oldStyle=0x0) at external/webkit/Source/WebCore/rendering/RenderBoxModelObject.cpp:363#10 0x48db2122 in WebCore::RenderBox::styleDidChange (this=0x2a3fa600, diff=<value optimized out>, oldStyle=0x0) at external/webkit/Source/WebCore/rendering/RenderBox.cpp:300#11 0x48da903a in WebCore::RenderBlock::styleDidChange (this=0x2a3fa600, diff=WebCore::StyleDifferenceEqual, oldStyle=<value optimized out>) at external/webkit/Source/WebCore/rendering/RenderBlock.cpp:239#12 0x48dd998a in WebCore::RenderObject::setStyle (this=0x2a3fa600, style=<value optimized out>) at external/webkit/Source/WebCore/rendering/RenderObject.cpp:1634#13 0x48dd9260 in WebCore::RenderObject::setAnimatableStyle (this=0x2a3fa600, style=<value optimized out>) at external/webkit/Source/WebCore/rendering/RenderObject.cpp:1551#14 0x48d06d82 in WebCore::Node::createRendererAndStyle (this=0x2a42fb70) at external/webkit/Source/WebCore/dom/Node.cpp:1508#15 0x48d06de2 in WebCore::Node::createRendererIfNeeded (this=0x2a42fb70) at external/webkit/Source/WebCore/dom/Node.cpp:1533#16 0x48ef01a2 in WebCore::Element::attach (this=0x2a42fb70) at external/webkit/Source/WebCore/dom/Element.cpp:991#17 0x48fc6476 in WebCore::HTMLConstructionSite::attach<WebCore::Element> (this=<value optimized out>, rawParent=0x2a421148, prpChild=<value optimized out>)                    at external/webkit/Source/WebCore/html/parser/HTMLConstructionSite.cpp:108#18 0x48fc64ae in WebCore::HTMLConstructionSite::attachToCurrent (this=<value optimized out>, child=<value optimized out>) at external/webkit/Source/WebCore/html/parser/HTMLConstructionSite.cpp:260#19 0x48fc6512 in WebCore::HTMLConstructionSite::insertHTMLElement (this=0x2a1fa59c, token=<value optimized out>) at external/webkit/Source/WebCore/html/parser/HTMLConstructionSite.cpp:290#20 0x48f2fcde in WebCore::HTMLTreeBuilder::processStartTagForInBody (this=<value optimized out>, token=...) at external/webkit/Source/WebCore/html/parser/HTMLTreeBuilder.cpp:1032#21 0x48f30caa in WebCore::HTMLTreeBuilder::processStartTag (this=0x2a1fa588, token=...) at external/webkit/Source/WebCore/html/parser/HTMLTreeBuilder.cpp:1338#22 0x48f32424 in WebCore::HTMLTreeBuilder::constructTreeFromAtomicToken (this=0x2a1fa588, token=<value optimized out>) at external/webkit/Source/WebCore/html/parser/HTMLTreeBuilder.cpp:462#23 0x48f3255a in WebCore::HTMLTreeBuilder::constructTreeFromToken (this=0x2a1fa588, rawToken=...) at external/webkit/Source/WebCore/html/parser/HTMLTreeBuilder.cpp:452#24 0x48f26aba in WebCore::HTMLDocumentParser::pumpTokenizer (this=0x2a3fb1f8, mode=WebCore::HTMLDocumentParser::AllowYield) at external/webkit/Source/WebCore/html/parser/HTMLDocumentParser.cpp:276#25 0x48f26d52 in WebCore::HTMLDocumentParser::append (this=0x2a3fb1f8, source=...) at external/webkit/Source/WebCore/html/parser/HTMLDocumentParser.cpp:367#26 WebCore::HTMLDocumentParser::append (this=0x2a3fb1f8, source=...) at external/webkit/Source/WebCore/html/parser/HTMLDocumentParser.cpp:337#27 0x48fbe314 in WebCore::DecodedDataDocumentParser::appendBytes (this=0x2a3fb1f8, writer=<value optimized out>,                         data=0x2a3e95c0 "agName&&\"click\"==k&&(a.preventDefault?a.preventDefault():a.returnValue=!1),d.d)d.d(b);else{var s;if((e=c.document)&&!e.createEvent&&e.createEventObject)try{s=e.createEventObject(a)}catch(U){s=a}else s"..., length=2230, shouldFlush=false) at external/webkit/Source/WebCore/dom/DecodedDataDocumentParser.cpp:54#28 0x48f3853a in WebCore::DocumentWriter::addData (this=0x2a2ebf8c,                             str=0x2a3e95c0 "agName&&\"click\"==k&&(a.preventDefault?a.preventDefault():a.returnValue=!1),d.d)d.d(b);else{var s;if((e=c.document)&&!e.createEvent&&e.createEventObject)try{s=e.createEventObject(a)}catch(U){s=a}else s"..., len=2230, flush=<value optimized out>) at external/webkit/Source/WebCore/loader/DocumentWriter.cpp:207#29 0x48f36c8c in WebCore::DocumentLoader::commitData (this=0x2a2ebf38,                                 bytes=0x2a3e95c0 "agName&&\"click\"==k&&(a.preventDefault?a.preventDefault():a.returnValue=!1),d.d)d.d(b);else{var s;if((e=c.document)&&!e.createEvent&&e.createEventObject)try{s=e.createEventObject(a)}catch(U){s=a}else s"..., length=2230) at external/webkit/Source/WebCore/loader/DocumentLoader.cpp:321#30 0x48f8beac in android::FrameLoaderClientAndroid::committedLoad (this=0x2a032940, loader=0x2a2ebf38,                                     data=0x2a3e95c0 "agName&&\"click\"==k&&(a.preventDefault?a.preventDefault():a.returnValue=!1),d.d)d.d(b);else{var s;if((e=c.document)&&!e.createEvent&&e.createEventObject)try{s=e.createEventObject(a)}catch(U){s=a}else s"..., length=2230) at external/webkit/Source/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp:732#31 0x48f36abc in WebCore::DocumentLoader::commitLoad (this=0x2a2ebf38,                                         data=0x2a3e95c0 "agName&&\"click\"==k&&(a.preventDefault?a.preventDefault():a.returnValue=!1),d.d)d.d(b);else{var s;if((e=c.document)&&!e.createEvent&&e.createEventObject)try{s=e.createEventObject(a)}catch(U){s=a}else s"..., length=2230) at external/webkit/Source/WebCore/loader/DocumentLoader.cpp:307#32 0x48d51310 in WebCore::ResourceLoader::didReceiveData (this=0x2a2eac88,                                             data=0x2a3e95c0 "agName&&\"click\"==k&&(a.preventDefault?a.preventDefault():a.returnValue=!1),d.d)d.d(b);else{var s;if((e=c.document)&&!e.createEvent&&e.createEventObject)try{s=e.createEventObject(a)}catch(U){s=a}else s"..., length=2230, encodedDataLength=2230, allAtOnce=false) at external/webkit/Source/WebCore/loader/ResourceLoader.cpp:288#33 0x48f38d1a in WebCore::MainResourceLoader::didReceiveData (this=<value optimized out>,                                                 data=0x2a3e95c0 "agName&&\"click\"==k&&(a.preventDefault?a.preventDefault():a.returnValue=!1),d.d)d.d(b);else{var s;if((e=c.document)&&!e.createEvent&&e.createEventObject)try{s=e.createEventObject(a)}catch(U){s=a}else s"..., length=2230, encodedDataLength=2230, allAtOnce=false) at external/webkit/Source/WebCore/loader/MainResourceLoader.cpp:454#34 0x48d5104e in WebCore::ResourceLoader::didReceiveData (this=<value optimized out>, data=<value optimized out>, length=<value optimized out>, encodedDataLength=2230)                                                    at external/webkit/Source/WebCore/loader/ResourceLoader.cpp:439                                                    ---Type <return> to continue, or q <return> to quit---#35 0x48e4229a in android::WebUrlLoaderClient::didReceiveData (this=0x2a3052b8, buf=<value optimized out>, size=2230) at external/webkit/Source/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp:398#36 0x48e441b2 in DispatchToMethod<android::WebUrlLoaderClient, void (android::WebUrlLoaderClient::*)(scoped_refptr<net::IOBuffer>, int), scoped_refptr<net::IOBuffer>, int> (this=0x2a1ffad0)                                                        at external/chromium/base/tuple.h:558#37 RunnableMethod<android::WebUrlLoaderClient, void (android::WebUrlLoaderClient::*)(scoped_refptr<net::IOBuffer>, int), Tuple2<scoped_refptr<net::IOBuffer>, int> >::Run (this=0x2a1ffad0)                                                            at external/chromium/base/task.h:332#38 0x48e41f1a in RunTask (v=<value optimized out>) at external/webkit/Source/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp:343#39 0x48d0045a in WTF::dispatchFunctionsFromMainThread () at external/webkit/Source/JavaScriptCore/wtf/MainThread.cpp:155#40 0x48e48cbe in android::JavaSharedClient::ServiceFunctionPtrQueue () at external/webkit/Source/WebKit/android/jni/JavaSharedClient.cpp:134#41 0x4070fe34 in dvmPlatformInvoke () at dalvik/vm/arch/arm/CallEABI.S:258#42 0x4073ee6a in dvmCallJNIMethod (args=0x4abd2f28, pResult=0x2a098700, method=0x44d9cf40, self=0x2a0986f0) at dalvik/vm/Jni.cpp:1155#43 0x4072ad88 in dvmCheckCallJNIMethod (args=<value optimized out>, pResult=0x2a098700, method=0x44d9cf40, self=0x2a0986f0) at dalvik/vm/CheckJni.cpp:145#44 0x40719264 in dalvik_mterp () at dalvik/vm/mterp/out/InterpAsm-armv7-a.S:16239#45 0x4071db30 in dvmInterpret (self=0x2a0986f0, method=<value optimized out>, pResult=0x4acd2eb0) at dalvik/vm/interp/Interp.cpp:1964#46 0x40751594 in dvmCallMethodV (self=0x2a0986f0, method=0x44bf1d40, obj=<value optimized out>, fromJni=<value optimized out>, pResult=0x4acd2eb0, args=...) at dalvik/vm/interp/Stack.cpp:526#47 0x407515be in dvmCallMethod (self=<value optimized out>, method=<value optimized out>, obj=<value optimized out>, pResult=0x4acd2eb0) at dalvik/vm/interp/Stack.cpp:429#48 0x40746176 in interpThreadStart (arg=0x2a0986f0) at dalvik/vm/Thread.cpp:1538#49 0x40038db4 in __thread_entry (func=0x407460d5 <interpThreadStart>, arg=0x2a0986f0, tls=<value optimized out>) at bionic/libc/bionic/pthread.c:217#50 0x40038518 in pthread_create (thread_out=0x2a146578, attr=0xbe975818, start_routine=0x407460d5 <interpThreadStart>, arg=0x2a0986f0) at bionic/libc/bionic/pthread.c:356#51 0x2a0f45f8 in ?? ()                                                            Cannot access memory at address 0x0#52 0x2a0f45f8 in ?? ()                                                            Cannot access memory at address 0x0                                                            Backtrace stopped: previous frame identical to this frame (corrupt stack?)
经过刚才的分析,我们的堆栈只剩下了下面的部分:
#0  android::WebViewCore::contentDraw (this=0x2a1c6f68) at external/webkit/Source/WebKit/android/jni/WebViewCore.cpp:969                                                                                     #1  0x48f8ad3c in android::ChromeClientAndroid::attachRootGraphicsLayer (this=<value optimized out>, layer=<value optimized out>)    at external/webkit/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp:112#2  0x48dcfd8c in WebCore::RenderLayerCompositor::attachRootPlatformLayer (this=0x2a3b3f58, attachment=WebCore::RenderLayerCompositor::RootLayerAttachedViaChromeClient)            at external/webkit/Source/WebCore/rendering/RenderLayerCompositor.cpp:1895                #3  0x48dd03e4 in WebCore::RenderLayerCompositor::ensureRootPlatformLayer (this=0x2a3b3f58) at external/webkit/Source/WebCore/rendering/RenderLayerCompositor.cpp:1842#4  0x48dd0432 in WebCore::RenderLayerCompositor::enableCompositingMode (this=0x2a3b3f58, enable=<value optimized out>) at external/webkit/Source/WebCore/rendering/RenderLayerCompositor.cpp:153#5  WebCore::RenderLayerCompositor::enableCompositingMode (this=0x2a3b3f58, enable=<value optimized out>) at external/webkit/Source/WebCore/rendering/RenderLayerCompositor.cpp:147#6  0x48dd051a in WebCore::RenderLayerCompositor::updateBacking (this=0x2a3b3f58, layer=0x2a3fa67c, shouldRepaint=WebCore::RenderLayerCompositor::CompositingChangeRepaintNow)                            at external/webkit/Source/WebCore/rendering/RenderLayerCompositor.cpp:360#7  0x48dd05da in WebCore::RenderLayerCompositor::updateLayerCompositingState (this=<value optimized out>, layer=0x2a3fa67c, shouldRepaint=<value optimized out>)                                            at external/webkit/Source/WebCore/rendering/RenderLayerCompositor.cpp:437#8  0x48dca85a in WebCore::RenderLayer::styleChanged (this=0x2a3fa67c, diff=WebCore::StyleDifferenceEqual, oldStyle=0x0) at external/webkit/Source/WebCore/rendering/RenderLayer.cpp:4119#9  0x48db78e6 in WebCore::RenderBoxModelObject::styleDidChange (this=0x2a3fa600, diff=WebCore::StyleDifferenceEqual, oldStyle=0x0) at external/webkit/Source/WebCore/rendering/RenderBoxModelObject.cpp:363#10 0x48db2122 in WebCore::RenderBox::styleDidChange (this=0x2a3fa600, diff=<value optimized out>, oldStyle=0x0) at external/webkit/Source/WebCore/rendering/RenderBox.cpp:300#11 0x48da903a in WebCore::RenderBlock::styleDidChange (this=0x2a3fa600, diff=WebCore::StyleDifferenceEqual, oldStyle=<value optimized out>) at external/webkit/Source/WebCore/rendering/RenderBlock.cpp:239#12 0x48dd998a in WebCore::RenderObject::setStyle (this=0x2a3fa600, style=<value optimized out>) at external/webkit/Source/WebCore/rendering/RenderObject.cpp:1634#13 0x48dd9260 in WebCore::RenderObject::setAnimatableStyle (this=0x2a3fa600, style=<value optimized out>) at external/webkit/Source/WebCore/rendering/RenderObject.cpp:1551#14 0x48d06d82 in WebCore::Node::createRendererAndStyle (this=0x2a42fb70) at external/webkit/Source/WebCore/dom/Node.cpp:1508
到了这一步的话,可能就不那么让人感觉繁琐了。
在刚才分析了newRenderer创建之后,通过backtrace,我们发现setAnimatableStyle是进入contentDraw的一个关键点。下面就对这个函数进行分析说明:
newRenderer->setAnimatableStyle(style.release())
通过注释我们可以先有个简单的了解: setAnimatableStyle() can depend on renderer() already being set.
进入函数之后,发现都会进行setStyle的操作。

setStyle的处理是比较复杂的。这边的主要处理有这样两步:
1. 保存了一个RenderStyle的指针: m_style = style;
2. 指向了一个RenderObject: styleDidChange(diff, oldStyle.get());

styleDidChange是一个虚函数,而RenderObject是Render树的一个根节点,所以在下面的很多子类中都有具体的实现。
比如:RenderText,RenderBox,RenderInline,RenderImage等~

这个堆栈再往后就是一些render方面比较深的操作了,比如renderlayer,renderbox等,这些将在接下来进行研究

更多相关文章

  1. C语言函数以及函数的使用
  2. android NDK JNI设置自己的log输出函数
  3. Android build/envsetup.sh 脚本分析(lunch函数)
  4. Android Hook学习之ptrace函数的使用
  5. Android中回调函数的理解---本人Android纯新手
  6. 【Android NDK 开发】Ubuntu 函数库交叉编译 ( Android 动态库交
  7. Android学习札记12:对Parcelable中describeContents()函数的一种
  8. android常用函数参数补充
  9. .NET应用函数定义与用法汇总

随机推荐

  1. Android(安卓)进程和线程模型
  2. 用 Golang 开发 Android(安卓)应用(七)——
  3. 最近Android有点烦
  4. Android学习路线图
  5. 想抢先体验Android操作系统的魅力吗?那就
  6. Android中的Junit单元测试
  7. Android应用坐标系统全面详解
  8. Android周学习Step By Step(5)--常用widget
  9. 编译自己的windows版本android sdk
  10. Android(安卓)Activity应用窗口的创建过