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

本文为极度寒冰原创,转载请注明出处 ############################################# 顺着前面的文章进行分析,我们就可以找到我们需要继续解析的堆栈。
#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的方法

更多相关文章

  1. android 中的 edittext属性大全
  2. Android学习笔记:androidmanifest.xml 高级属性
  3. 关于android:configChanges的属性
  4. LinearLayout && RelativeLayout 常用属性
  5. Android中自定义属性(attrs.xml,TypedArray的使用)
  6. android 属性系统 及其 补充
  7. Android GridView 特殊属性

随机推荐

  1. 面向对象 oop 与类的进阶
  2. 再谈Android应用架构——Jetpack VS 生命
  3. 分布式事务,一种保守玩法
  4. oracle学习笔记
  5. PostgreSQL和PostGIS常用入门命令
  6. 多线程详解之优先级
  7. django中的session实现
  8. COOKIE SESSION 与初识命名空间
  9. isset()与empty()函数 switch语句改写简
  10. 阅读代码:Spark 与 Flink 中的 RPC 实现