Chromium网页GraphicsLayerTree创建过程分析全解.docx

上传人:b****1 文档编号:14062036 上传时间:2023-06-20 格式:DOCX 页数:63 大小:217.68KB
下载 相关 举报
Chromium网页GraphicsLayerTree创建过程分析全解.docx_第1页
第1页 / 共63页
Chromium网页GraphicsLayerTree创建过程分析全解.docx_第2页
第2页 / 共63页
Chromium网页GraphicsLayerTree创建过程分析全解.docx_第3页
第3页 / 共63页
Chromium网页GraphicsLayerTree创建过程分析全解.docx_第4页
第4页 / 共63页
Chromium网页GraphicsLayerTree创建过程分析全解.docx_第5页
第5页 / 共63页
Chromium网页GraphicsLayerTree创建过程分析全解.docx_第6页
第6页 / 共63页
Chromium网页GraphicsLayerTree创建过程分析全解.docx_第7页
第7页 / 共63页
Chromium网页GraphicsLayerTree创建过程分析全解.docx_第8页
第8页 / 共63页
Chromium网页GraphicsLayerTree创建过程分析全解.docx_第9页
第9页 / 共63页
Chromium网页GraphicsLayerTree创建过程分析全解.docx_第10页
第10页 / 共63页
Chromium网页GraphicsLayerTree创建过程分析全解.docx_第11页
第11页 / 共63页
Chromium网页GraphicsLayerTree创建过程分析全解.docx_第12页
第12页 / 共63页
Chromium网页GraphicsLayerTree创建过程分析全解.docx_第13页
第13页 / 共63页
Chromium网页GraphicsLayerTree创建过程分析全解.docx_第14页
第14页 / 共63页
Chromium网页GraphicsLayerTree创建过程分析全解.docx_第15页
第15页 / 共63页
Chromium网页GraphicsLayerTree创建过程分析全解.docx_第16页
第16页 / 共63页
Chromium网页GraphicsLayerTree创建过程分析全解.docx_第17页
第17页 / 共63页
Chromium网页GraphicsLayerTree创建过程分析全解.docx_第18页
第18页 / 共63页
Chromium网页GraphicsLayerTree创建过程分析全解.docx_第19页
第19页 / 共63页
Chromium网页GraphicsLayerTree创建过程分析全解.docx_第20页
第20页 / 共63页
亲,该文档总共63页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

Chromium网页GraphicsLayerTree创建过程分析全解.docx

《Chromium网页GraphicsLayerTree创建过程分析全解.docx》由会员分享,可在线阅读,更多相关《Chromium网页GraphicsLayerTree创建过程分析全解.docx(63页珍藏版)》请在冰点文库上搜索。

Chromium网页GraphicsLayerTree创建过程分析全解.docx

Chromium网页GraphicsLayerTree创建过程分析全解

Chromium网页GraphicsLayerTree创建过程分析

在前面一文中,我们分析了网页RenderLayerTree的创建过程。

在创建RenderLayer的同时,WebKit还会为其创建GraphicsLayer。

这些GraphicsLayer形成一个GraphicsLayerTree。

GraphicsLayer可看作是一个图形缓冲区,被若干RenderLayer共用。

本文接下来就分析GraphicsLayerTree的创建过程。

网页的RenderLayerTree与GraphicsLayerTree的关系可以通过图1描述,如下所示:

在WebKit中,GraphicsLayer又称为CompositedLayer。

我们可以将GraphicsLayer看作是CompositedLayer的一种具体实现。

这种具体实现是由WebKit的使用者Chromium提供的。

CompositedLayer描述的是一个具有后端存储的图层,因此可以将它看作是一个图形缓冲区。

在软件渲染方式中,这个图形缓冲区就是一块系统内存;在硬件渲染方式中,这个图形缓冲区就是一个OpenGL里面的一个FrameBufferObject(FBO)。

CompositedLayer涉及到的一个重要概念是“LayerCompositing”。

LayerCompositing是现代UI框架普遍采用的一种渲染机制。

例如,Android系统的UI子系统(SurfaceFlinger)就是通过CompositingSurface来获得最终要显示在屏幕上的内容的。

这里的Surface就相当于是Chromium的Layer。

关于Android系统的SurfaceFlinger的详细分析,可以参考这个系列的文章。

LayerCompositing的三个主要任务是:

1.确定哪些内容应该在哪些CompositedLayer上绘制;

2.绘制每一个CompositedLayer;

3.将所有已经绘制好的CompositedLayer再次将绘制在一个最终的、可以显示在屏幕上进行显示的图形缓冲区中。

其中,第1个任务它完成之后就可以获得一个GraphicsLayerTree,第3个任务要求按照一定的顺序对CompositedLayer进行绘制。

注意,这个绘制顺序非常重要,否则最终合成出来的UI就会出现不正确的Overlapping。

同时,这个绘制顺序对理解GraphicsLayerTree的组成也非常重要。

因此,接下来我们首先介绍与这个绘制顺序有关的概念。

为了方便描述,本文将上述绘制顺序称为CompositedLayer的绘制顺序。

在介绍CompositedLayer的绘制顺序之前,我们还需要回答一个问题:

为什么要采用LayerCompositing这种UI渲染机制?

主要有两个原因:

1.避免不必要的重绘。

考虑一个网页有两个Layer。

在网页的某一帧显示中,Layer1的元素发生了变化,Layer2的元素没有发生变化。

这时候只需要重新绘制Layer1的内容,然后再与Layer2原有的内容进行Compositing,就可以得到整个网页的内容。

这样就可以避免对没有发生变化的Layer2进行不必要的绘制。

2.利用硬件加速高效实现某些UI特性。

例如网页的某一个Layer设置了可滚动、3D变换、透明度或者滤镜,那么就可以通过GPU来高效实现。

在默认情况下,网页元素的绘制是按照RenderObjectTree的先序遍历顺序进行的,并且它们在空间上是按照各自的display属性值依次进行布局的。

例如,如果一个网页元素的display属性值为"inline",那么它就会以内联元素方式显示,也就是紧挨在前一个绘制的元素的后面进行显示。

又如,如果一个网页元素的display属性值为"block",那么它就会以块级元素进行显示,也就是它的前后会各有一个换行符。

我们将这种网页元素绘制方式称为NormalFlow或者InFlow。

有默认情况,就会有例外情况。

例如,如果一个网页元素同时设置了position和z-index属性,那么它可能就不会以InFlow的方式进行显示,而是以OutofFlow的方式进行显示。

在默认情况下,一个网页元素的position和z-index属性值被设置为“static”和"auto"。

网页元素的position属性还可以取值为“relative”、“absolute”和“fixed”,这一类网页元素称为Positioned元素。

当一个Positioned元素的z-index属性值不等于"auto"时,它就会以OutofFlow的方式进行显示。

CSS2.1规范规定网页渲染引擎要为每一个z-index属性值不等于"auto"的Positioned元素创建一个StackingContext。

对于其它的元素,它们虽然没有自己的StackingContext,但是它们会与最近的、具有自己的StackingContext的元素共享同相同的StackingContext。

不同StackingContext的元素的绘制顺序是不会相互交叉的。

假设有两个StackingContext,一个包含有A和B两个元素,另一个包含有C和D两个元素,那么A、B、C和D四个元素的绘制顺序只可能为:

1.A、B、C、D

2.B、A、C、D

3.A、B、D、C

4.B、A、D、C

5.C、D、A、B

6.C、D、B、A

7.D、C、A、B

8.D、C、B、A

StackingContext的这个特性,使得它可以成为一个观念上的原子类型绘制层(AtomicConceptualLayerforPainting)。

也就是说,只要我们定义好StackingContext内部元素的绘制顺序,那么再根据拥有StackingContext的元素的z-index属性值,那么就可以得到网页的所有元素的绘制顺序。

我们可以通过图2所示的例子直观地理解StackingContext的上述特性,如下所示:

在图2的左边,一共有4个StackingContext。

最下面的StackingContext的z-index等于-1;中间的StackingContext的z-index等于0;最上面的StackingContext的z-index等于1,并且嵌套了另外一个z-index等于6的StackingContext。

我们观察被嵌套的z-index等于6的StackingContext,它包含了另外一个z-index也是等于6的元素,但是这两个z-index的含义是不一样的。

其中,StackingContext的z-index值是放在父StackingContext中讨论才有意义,而元素的z-index放在当前它所在的StackingContext讨论才有意义。

再者,我们是下面和中间的两个StackingContext,虽然它们都包含有三个z-index分别等于7、8和9的元素,但是它们是完全不相干的。

如果我们将图2左边中间的StackingContext的z-index修改为2,那么它就会变成最上面的StackingContext,并且会重叠在z-index等于1的StackingContext上,以及嵌套在这个StackingContext里面的那个StackingContext。

这样,我们就得到了StackingContext的绘制顺序。

如前所述,接下来只要定义好StackingContext内的元素的绘制顺序,那么就可以网页的所有元素的绘制顺序。

StackingContext内的元素的绘制顺序如下所示:

1.背景(Backgrounds)和边界(Borders),也就是拥有StackingContext的元素的背景和边界。

2.Z-index值为负数的子元素。

3.内容(Contents),也就是拥有StackingContext的元素的内容。

4.NormalFlow类型的子元素。

5.Z-index值为正数的子元素。

以上就是与CompositedLayer的绘制顺序有关的背景知识。

这些背景知识在后面分析GraphicsLayerTree的创建过程时就会用到。

从图1可以看到,GraphicsLayerTree是根据RenderLayerTree创建的。

也就是说,RenderLayer与GraphicsLayer存在对应关系,如下所示:

原则上,RenderLayerTree中的每一个RenderLayer都对应有一个CompositedLayerMapping,每一个CompositedLayerMapping又包含有若干个GraphicsLayer。

但是这样将会导致创建大量的GraphicsLayer。

创建大量的GraphicsLayer意味着需要耗费大量的内存资源。

这个问题称为”LayerExplosion“问题。

为了解决“LayerExplosion”问题,每一个需要创建CompositedLayerMapping的RenderLayer都需要给出一个理由。

这个理由称为“CompositingReason”,它描述的实际上是RenderLayer的特征。

例如,如果一个RenderLayer关联的RenderObject设置了3DTransform属性,那么就需要为该RenderLayer创建一个CompositedLayerMapping。

WebKit一共定义了54个CompositingReason,如下所示:

[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片

//Intrinsicreasonsthatcanbeknownrightawaybythelayer

constuint64_tCompositingReason3DTransform=UINT64_C

(1)<<0;

constuint64_tCompositingReasonVideo=UINT64_C

(1)<<1;

constuint64_tCompositingReasonCanvas=UINT64_C

(1)<<2;

constuint64_tCompositingReasonPlugin=UINT64_C

(1)<<3;

constuint64_tCompositingReasonIFrame=UINT64_C

(1)<<4;

constuint64_tCompositingReasonBackfaceVisibilityHidden=UINT64_C

(1)<<5;

constuint64_tCompositingReasonActiveAnimation=UINT64_C

(1)<<6;

constuint64_tCompositingReasonTransitionProperty=UINT64_C

(1)<<7;

constuint64_tCompositingReasonFilters=UINT64_C

(1)<<8;

constuint64_tCompositingReasonPositionFixed=UINT64_C

(1)<<9;

constuint64_tCompositingReasonOverflowScrollingTouch=UINT64_C

(1)<<10;

constuint64_tCompositingReasonOverflowScrollingParent=UINT64_C

(1)<<11;

constuint64_tCompositingReasonOutOfFlowClipping=UINT64_C

(1)<<12;

constuint64_tCompositingReasonVideoOverlay=UINT64_C

(1)<<13;

constuint64_tCompositingReasonWillChangeCompositingHint=UINT64_C

(1)<<14;

//Overlapreasonsthatrequireknowingwhat'sbehindyouinpaint-orderbeforeknowingtheanswer

constuint64_tCompositingReasonAssumedOverlap=UINT64_C

(1)<<15;

constuint64_tCompositingReasonOverlap=UINT64_C

(1)<<16;

constuint64_tCompositingReasonNegativeZIndexChildren=UINT64_C

(1)<<17;

constuint64_tCompositingReasonScrollsWithRespectToSquashingLayer=UINT64_C

(1)<<18;

constuint64_tCompositingReasonSquashingSparsityExceeded=UINT64_C

(1)<<19;

constuint64_tCompositingReasonSquashingClippingContainerMismatch=UINT64_C

(1)<<20;

constuint64_tCompositingReasonSquashingOpacityAncestorMismatch=UINT64_C

(1)<<21;

constuint64_tCompositingReasonSquashingTransformAncestorMismatch=UINT64_C

(1)<<22;

constuint64_tCompositingReasonSquashingFilterAncestorMismatch=UINT64_C

(1)<<23;

constuint64_tCompositingReasonSquashingWouldBreakPaintOrder=UINT64_C

(1)<<24;

constuint64_tCompositingReasonSquashingVideoIsDisallowed=UINT64_C

(1)<<25;

constuint64_tCompositingReasonSquashedLayerClipsCompositingDescendants=UINT64_C

(1)<<26;

//Subtreereasonsthatrequireknowingwhatthestatusofyoursubtreeisbeforeknowingtheanswer

constuint64_tCompositingReasonTransformWithCompositedDescendants=UINT64_C

(1)<<27;

constuint64_tCompositingReasonOpacityWithCompositedDescendants=UINT64_C

(1)<<28;

constuint64_tCompositingReasonMaskWithCompositedDescendants=UINT64_C

(1)<<29;

constuint64_tCompositingReasonReflectionWithCompositedDescendants=UINT64_C

(1)<<30;

constuint64_tCompositingReasonFilterWithCompositedDescendants=UINT64_C

(1)<<31;

constuint64_tCompositingReasonBlendingWithCompositedDescendants=UINT64_C

(1)<<32;

constuint64_tCompositingReasonClipsCompositingDescendants=UINT64_C

(1)<<33;

constuint64_tCompositingReasonPerspectiveWith3DDescendants=UINT64_C

(1)<<34;

constuint64_tCompositingReasonPreserve3DWith3DDescendants=UINT64_C

(1)<<35;

constuint64_tCompositingReasonReflectionOfCompositedParent=UINT64_C

(1)<<36;

constuint64_tCompositingReasonIsolateCompositedDescendants=UINT64_C

(1)<<37;

//Therootlayerisaspecialcasethatmaybeforcedtobealayer,butalsoitneedstobe

//alayerifanythingelseinthesubtreeiscomposited.

constuint64_tCompositingReasonRoot=UINT64_C

(1)<<38;

//CompositedLayerMappinginternalhierarchyreasons

constuint64_tCompositingReasonLayerForAncestorClip=UINT64_C

(1)<<39;

constuint64_tCompositingReasonLayerForDescendantClip=UINT64_C

(1)<<40;

constuint64_tCompositingReasonLayerForPerspective=UINT64_C

(1)<<41;

constuint64_tCompositingReasonLayerForHorizontalScrollbar=UINT64_C

(1)<<42;

constuint64_tCompositingReasonLayerForVerticalScrollbar=UINT64_C

(1)<<43;

constuint64_tCompositingReasonLayerForScrollCorner=UINT64_C

(1)<<44;

constuint64_tCompositingReasonLayerForScrollingContents=UINT64_C

(1)<<45;

constuint64_tCompositingReasonLayerForScrollingContainer=UINT64_C

(1)<<46;

constuint64_tCompositingReasonLayerForSquashingContents=UINT64_C

(1)<<47;

constuint64_tCompositingReasonLayerForSquashingContainer=UINT64_C

(1)<<48;

constuint64_tCompositingReasonLayerForForeground=UINT64_C

(1)<<49;

constuint64_tCompositingReasonLayerForBackground=UINT64_C

(1)<<50;

constuint64_tCompositingReasonLayerForMask=UINT64_C

(1)<<51;

constuint64_tCompositingReasonLayerForClippingMask=UINT64_C

(1)<<52;

constuint64_tCompositingReasonLayerForScrollingBlockSelection=UINT64_C

(1)<<53;

这些CompositingReason定义在文件external/chromium_org/third_party/WebKit/Source/platform/graphics/CompositingReasons.h中。

其中,有3个CompositingReason比较特殊,如下所示:

[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片

constuint64_tCompositingReasonComboSquashableReasons=

CompositingReasonOverlap

|CompositingReasonAssumedOverlap

|CompositingReasonOverflowScrollingParent;

它们是CompositingReasonOverlap、CompositingReasonAssumedOverlap和CompositingReasonOverflowScrollingParent,称为SquashableReason。

WebKit不会为具有这三种特征的RenderLayer之一的RenderLayer创建CompositedLayerMapping。

如果启用了OverlapTesting,那么WebKit会根据上述的StackingContext顺序计算每一个RenderLayer的后面是否有其它的RenderLayer与其重叠。

如果有,并且与其重叠的RenderLayer有一个对应的CompositedLayerMapping,那么就会将位于上面的RenderLayer的CompositingReason设置为CompositingReasonOverlap。

如果没有启用OverlapTesting,那么WebKit会根据上述的StackingContext顺序检查每一个RenderLayer的后面是否有一个具有CompositedLayerMapping的RenderLayer。

只要有,不管它们是否重叠,那么就会将位于上面的RenderLayer的CompositingReason设置为CompositingReasonAssumedOverlap。

最后,如果一个RenderLayer包含在一个具有overflow属性为"scrol

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2