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

顺着前面的文章进行分析,我们就可以找到我们需要继续解析的堆栈。

#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
其实Render的部分也没有想象中的那么复杂,只是会有一些布局,排版方面的交错的地方。
前面的分析我们知道了RenderBoxModelObject::styleDidChange,那么我们先来看一下这个函数的实现:
void RenderBoxModelObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
    RenderObject::styleDidChange(diff, oldStyle);
    updateBoxModelInfoFromStyle();
    
    if (requiresLayer()) {
        if (!layer()) {
            if (s_wasFloating && isFloating())
                setChildNeedsLayout(true);
            m_layer = new (renderArena()) RenderLayer(this);
            setHasLayer(true);
            m_layer->insertOnlyThisLayer();
            if (parent() && !needsLayout() && containingBlock()) {
                m_layer->setNeedsFullRepaint();
                m_layer->updateLayerPositions();
            }
        }
    } else if (layer() && layer()->parent()) {
        setHasTransform(false); // Either a transform wasn't specified or the object doesn't support transforms, so just null out the bit.
        setHasReflection(false);
        m_layer->removeOnlyThisLayer(); // calls destroyLayer() which clears m_layer
        if (s_wasFloating && isFloating())
            setChildNeedsLayout(true);
    }

    if (layer()) {
        layer()->styleChanged(diff, oldStyle);
        if (s_hadLayer && layer()->isSelfPaintingLayer() != s_layerWasSelfPainting)
            setChildNeedsLayout(true);
    }
}
这个函数有一个requiresLayer()的判断,requiresLayer的函数原型为:
virtual bool requiresLayer() const { return isRoot() || isPositioned() || isRelPositioned() || isTransparent() || hasOverflowClip() || hasTransform() || hasMask() || hasReflection() || style()->specifiesColumns() || style()->hasFixedBackgroundImage(); }
这个里面的值来简单的说明一下:
isRoot() --> 顾名思义,判断当前节点是否为根节点
isPositioned()  --> 判断是否为absolute定位方式,或者fixed定位方式
isRelPositioned()  --> 判断是否为relative定位方式
isTransparent()  --> 对应于css属性的opacity(透明度),只有当opacity小于1.0时,返回值才为真。
hasOverflowClip()  --> 判断属性规定当内容溢出元素框时发生的事情。当overflow:auto/scroll/hidden的时候会被置为true.
hasTransform()  --> Transform是CSS3的一种高级属性,字面上就是变形,改变的意思。在CSS3中transform主要包括以下几种:旋转rotate、扭曲skew、缩放scale和移动translate以及矩阵变形matrix
hasMask()  -->  Mask在Css3中,属性为对象建立一个覆盖于表面的膜
hasReflection()  --> reflection常被用来做图片倒影时使用
style()->specifiesColumns() --> 这些都是节点的内部属性
style()->hasFixedBackgroundImage() -->  这些都是节点的内部属性
如果要创建一个RenderLayer,就需要上面的requiresLayer()返回为真,所以能够触发创建一个RenderLayer的css属性为:position:absolute,relative,fixed(static不能,它为无特殊定位,对象遵循HTML定位规则);opacity:小于1 (大于1,isTransparent()函数返回假,不会创建RenderLayer;小于0的时候,该函数也返回真,会创建RenderLayer)
因为CSS为排版的属性,而排版对应不同的RenderLayer,所以必需遵循一定的规则才可以进行RenderLayer的创建(满足上述条件之一即可认定需要创建RenderLayer)。
然后在下面的判断中,如果当前没有一个RenderLayer的话,就会去重新创建一个新的m_layer, 紧接着去设置setHasLayer(true).
setHasLayer是设置内部的变量m_hasLayer为true。而通过查看hasLayer之后,我们可以确定,只有在m_hasLayer为true之后,RenderLayer才会被创建。
m_layer->insertOnlyThisLayer()函数就会将新创建的RenderLayer插入到RenderLayer树中去了。
在这边,因为刚才已经成功创建了RenderLayer,所以layer()肯定是有值为true,于是进入到了这个判断中。于是执行RenderLayer中的styleChanged方法。
RenderLayer的styleChanged方法中,也有一点需要注意的问题。即软件渲染和硬件加速的问题。
我们经常碰到一些问题是在硬件加速的情况下才会出现,比如模拟器在没有打开gpu on的时候,就是启用软件加速。
这边的话 #if USE(ACCELERATED_COMPOSITING) 肯定是为true的,我们进入到了这个里面的判断。
于是就有了刚才堆栈中的compositor()->updateLayerCompositingState(this)这个函数。
从名字中我们就可以看出,这个是使用硬件加速开始进行Layer的合成。
先介绍一下RenderLayerCompositor类:WebKit中渲染部分‘掌控大局’的类,管理RenderLayer树结构,它通过浏览器的设置来决定是否创建RenderLayer以及是否硬件加速合成,同时也决定是否为RenderLayer创建RenderLayerBacking
那么什么是RenderLayerBacking呢?RenderLayerBacking主要用来管理和控制相对应的RenderLayer的合成行为,包含很多GraphicsLayer对象,这些对象用于表示层内容,前景(foreground)内容等等
updateLayerCompositingState主要用来判断当前的RenderLayerBacking是否需要更新。
在这个堆栈的
#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
部分都是比较好理解的,按照这个函数搜一下code,就可以了解这个都是一些100%要进行的调用。
在android平台上面,如果是一个独立的element,并且Tag是iframeTag,frame,object的时候就返回所对应的标签。
如果是这些标签的话,我们就会在RootLayerAttachment expectedAttachment = shouldPropagateCompositingToEnclosingFrame() ?RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient;的时候得到RootLayerAttachedViaEnclosingFrame标签,而如果不是的话,就会得到的是RootLayerAttachedViaChromeClient标签。
因此,在void RenderLayerCompositor::attachRootPlatformLayer(RootLayerAttachment attachment)中,我们就可以看到page->chrome()->client()->attachRootGraphicsLayer(frame, rootPlatformLayer());
于是就对应到了android::ChromeClientAndroid::attachRootGraphicsLayer。。
到了这个函数,我们也就找到了android使用contentDraw的方法
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值