Android webkit image的加载过程解析(二)

 

还是顺着前面的内容进行分析,前面一篇文章中,是对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等,这些将在接下来进行研究

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值