转载请注明原文地址:http://blog.csdn.net/milado_nju

## 概述

在前面的章节中,笔者介绍了WebKit渲染引擎是如何有HTML网页构建DOM树、RenderObject树到RenderLayer树,以及它们之间的对应关系。这一渲染基础被软件渲染和硬件渲染共享,也就是说不管哪种类型的渲染机制,WebKit渲染引擎都会构建它们。不过对于软件渲染而言,到RenderLayer树就结束了,后面不会建立其它额外的树来对应于RenderLayer树。但是,对于硬件渲染来说,这是漫长阶段的一个部分,在RenderLayer树之后,WebKit渲染引擎为硬件渲染提供了更多的内部结构来支持这个机制。本文将在介绍WebKit中的内部结构之上,同时介绍Chromium又构建的新内部结构,用于该项目中引入的众多纷繁复杂的技术,例如线程化合成器,线程化绘图等等。

## WebKit基础设施

一个RenderLayer对象如果需要后端存储,它会创建一个RenderLayerBacking对象,该对象负责Renderlayer对象所需要的各种存储。正如前面所述,理想情况下,每个RenderLayer都可以创建自己的后端存储,事实上不是所有RenderLayer都有自己的RenderLayerBacking对象。如果一个RenderLayer对象被像样的创建后端存储,那么将该RenderLayer称为合成层(Compositing Layer)。

哪些RenderLayer可以是合成层呢?如果一个RenderLayer对象具有以下的特征之一,那么它就是合成层:

1.      RenderLayer具有CSS 3D属性或者CSS透视效果。

2.      RenderLayer包含的RenderObject节点表示的是使用硬件加速的视频解码技术的HTML5 ”video”元素。

3.      RenderLayer包含的RenderObject节点表示的是使用硬件加速的Canvas2D元素或者WebGL技术。

4.      RenderLayer使用了CSS透明效果的动画或者CSS变换的动画。

5.      RenderLayer使用了硬件加速的CSSfilters技术。

6.      RenderLayer使用了剪裁(clip)或者反射(reflection)属性,并且它的后代中包括了一个合成层。

7.     RenderLayer有一个Z坐标比自己小的兄弟节点,该节点是一个合成层。

至于为什么这么做,不外乎两个原因,第一当然是合并一些RenderLayer层,这样减少内存的使用量,其二是在合并之后尽量减少合并带来的重绘性能和处理上的困难,其三同时对于那些使用单独层能够显著提升性能的RenderLayer对象,继续使用这些好处,例如使用WebGL技术的canvas元素。

每个合成层都有一个RenderLayerBacking,RenderLayerBacking负责管理RenderLayer所需要的所有后端存储,因为后端存储可能需要多个存储空间。在WebKit中,存储空间使用类GraphicsLayer来表示。

下图就是WebKit构建的从RenderLayer树到RenderLayBacking树,再到GraphicsLayer树,并给出这些硬件加速基础设施的对应关系。在RenderLayer树中的第四个节点没有创建RenderLayerBacking对象,因为不符合上面的创建条件,而对于每个RenderLayerBacking对象,它也至少需要一个GraphicsLayer对象,当然也可能需要多个,图中的RenderLayerBacking分别需要2个,1个或者4个GraphicsLayer对象,这些对象分别表示什么呢?

为什么一个RenderLayerBacking对象需要这么多层呢?原因有很多,例如是需要将滚动条独立开来称为一个层,需要前景层、背景层等,需要两个容器层来表示RenderLayer对应的Z坐标为正数的子女和Z坐标负数的子女,将可能需要滚动的内容建立新层,还有剪裁层和反射层,那么这些层次是如何组织并且它们的绘制顺序是如何呢?上图中的GraphicsLayer树状结构按照一定顺序,具体可以参考于Chromium工程师的文档”Compositing in Blink / WebCore: FromWebCore::RenderLayer to cc:Layer”,图中每个层就是一个GraphicsLayer对象,对于某个RenderLayerBacking对象来说,其中主层是肯定存在的,其它层则不一定存在,因为不是每个RenderLayer对象都需要用到它们。 这其中还有众多的其它层,这里不一一介绍了。

## Chromium基础设施

GraphicsLayer是对一个渲染后端存储的抽象,同众多其它WebKit所定义的抽象类一样,在WebKit移植中,它还需要具体的实现类来支持该类提供的功能。为了完成这一功能,Chromium提供了更为复杂的设施类,这一节主要介绍从GraphicsLayer类到合成器这一过程中所设计的众多内部结构。

下图中描述了从WebCore中同移植无关的GraphicsLayer到之后Chromium移植及Chromium浏览器所设计的Chromium合成器的LayerImpl类这一过程,读者可以看到,中间有好几层,原因在于抽象和合成机制的复杂性,以及性能等众多方面的考虑,从上到下主要类依次是:

GraphicsLayerChromium:GraphicsLayer的子类,实现了GraphicsLayer需要的一个功能,并且加入了Chromium的所需信息。

WebLayer:WebKit的Chromium移植的抽象接口类,它被GraphicsLayerChromium等调用,主要目的是将Chromium的实际后端存储类抽象出来,以便WebCore使用它们。

WebLayerImpl:WebLayer类的实现类,具体作用是将合成器的层能力暴露出来,跟Layer类一一对应。

Layer:合成器的层表示类,是Chromium合成器的接口类,用于表示合成器的合成层,它会形成一颗合成树。

LayerImpl:同Layer对象一一对应,是实际的实现类,包含有后端存储,可能更Layer树在不同的线程,具体在后面介绍。

由上面介绍可以看出,这个过程基本上就是各种类的映射,从GraphicsLayer类到LayerImpl类,目的是将WebKit的合成层映射到合成器中的合成层,合成器最终合成这些层。合成过程在合成器小节中介绍。

## Chromium合成器

合成器的作用就是合成多个合成层,所以它的输入是多个待合成的合成层,每个层都有一些属性(例如3D变形等)。它的输出就是一个后端存储,例如是一个GPU的纹理缓冲区。

Chromium合成器是一个独立并且复杂的模块,顾名思义,它的作用是合成网页划分后的合成层,但是,这里的合成器同网页没有必然的绑定关系,它既可以合成网页,也可合成用户界面,或者多个标签页。其实,按照笔者的理解,如果你的项目中需要合成器,可以尝试移植该合成器为自己所用,当然,该合成器有一些依赖关系需要解除,难度也很大,这些都是题外话。

在架构设计上,合成器采用将表示和实现分离开的原则,也就是前面介绍合成器Layer层(同GraphicsLayer类一一对应)同具体合成器所要合成的操作分离的原则,下图描述了这一思想。WebKit中对合成层的各种设置,最后都使用Layer树来表示,里面包含3D变形、剪裁等属性,但是将这些属性应用到后端存储并合成这一过程并不是在Layer树中进行,而是将这些功能委托LayerImpl树来完成,两者之间通过代理来同步。Layer树所有的信息都会复制到LayerImpl树中,代理的作用是协调和同步两者之间的这些操作。

上图中描述的Layer树工作在主线程,但是LayerImpl树在实现部分的线程,这里可以它理解为就是工作在主线程也可是是单独的一个线程,两者在Chromium中目前都被使用。实现部分作为单独一个线程是在Renderer进程中用来合成网页的时候,通常也称为合成器(compositor)线程,后者也称为线程化合成(threaded compositing)。在Chrome的Android版本,合成实现部分则是在主线程,目的是同浏览器界面的合成,称为线程内合成(in-thread compositing)。

在目前的Chromium合成器中,具体的工作非常复杂,例如还有线程化绘图(impl side painting),远远超出了文章"Chromium硬件加速合成"章节中介绍的合成器过程,希望以后可以在专门的章节中来介绍它们。

## 参考资料

1. https://docs.google.com/presentation/d/1dDE5u76ZBIKmsqkWi2apx3BqV8HOcNf4xxBdyNywZR8/edit?pli=1#slide=id.g9ade3ed5_017

By yongsheng@chromium.org

理解WebKit和Chromium: 硬件加速之RenderLayer树到合成树的更多相关文章

  1. 理解WebKit和Chromium(电子书)

    前言   基础篇 WebKit, WebKit2, Chromium和Chrome介绍 WebKit和Blink WebKit和Chromium代码目录结构介绍 WebKit和Chromium功能模块 ...

  2. Chromium硬件加速渲染的UI合成过程分析

    在Chromium中.Render端和WebGL端绘制出来的UI终于是通过Browser端显示在屏幕上的.换句话说.就是Browser端负责合成Render端和WebGL端的UI.这涉及到不同Open ...

  3. 理解WebKit和Chromium: Android 4.4 上的Chromium WebView

    转载请注明原文地址:http://blog.csdn.net/milado_nju ## 概述 相信读者已经注意到了,在最新的Android 4.4 Kitkat版本中,原本基于Android Web ...

  4. 理解WebKit和Chromium: Chromium WebView和Chrome浏览器渲染机制

    转载请注明原文地址:http://blog.csdn.net/milado_nju ## 数据对比 前面介绍过Chromium WebView的时候,说过有关ChromiumWebView同Chrom ...

  5. 理解WebKit和Chromium: 调试Android系统上的Chromium

    转载请注明原文地址:http://blog.csdn.net/milado_nju 1. Android上的调试技术 在Android系统上,开发人员能够使用两种不同的语言来开发应用程序,一种是Jav ...

  6. 理解WebKit和Chromium: JavaScript引擎简介

    转载请注明原文地址:http://blog.csdn.net/milado_nju 1. 什么是JavaScript引擎 什么是JavaScript引擎?简单来讲,就是能够提供执行JavaScript ...

  7. 【转】理解WebKit和Chromium: JavaScript引擎简介

    转载请注明原文地址:http://blog.csdn.net/milado_nju1. 什么是JavaScript引擎什么是JavaScript引擎?简单来讲,就是能够提供执行JavaScript代码 ...

  8. 理解WebKit和Chromium: Chromium插件和扩展基础

    转载请注明原文地址:http://blog.csdn.net/milado_nju ##概述 插件和扩展是一种扩充浏览器功能的技术,在之前我们介绍过NPAPI插件技术,在Chromium中,远远不只是 ...

  9. 理解WebKit和Chromium: 网页渲染的基本过程

    转载请注明原文地址:http://blog.csdn.net/milado_nju ## 概述 前面介绍了一些渲染引擎的功能,包括网络,资源加载,DOM树,RenderObject树等等,但是,给人以 ...

随机推荐

  1. ftp传二进制文件时一定要用二进制模式,否则内容会有变化,造成后处理莫名其妙的错误,还以为传输前后内容一致,其实已变化。

    ftp传二进制文件时一定要用二进制模式,否则内容会有变化,造成后处理莫名其妙的错误,还以为传输前后内容一致,其实已变化.

  2. CRM客户关系管理系统(六)

    第六章.排序和搜索功能开发  6.1.排序功能开发 (1)kingadmin_tags.py @register.simple_tag def get_sorted_column(column,sor ...

  3. Java内存泄漏分析系列之七:使用MAT的Histogram和Dominator Tree定位溢出源

    原文地址:http://www.javatang.com 基础概念 先列出几个基础的概念: Shallow Heap 和 Retained Heap Shallow Heap表示对象本身占用内存的大小 ...

  4. AWS EC2 CentOS release 6.5 部署zookeeper、kafka、dubbo

    AWS EC2 CentOS release 6.5 部署zookeeper.kafka.dubbo参考:http://blog.csdn.net/yizezhong/article/details/ ...

  5. Cloudera: Start Impala service by cloudera manager in docker quickstart image

    How to start Impala service in docker quickstart image docker run --hostname=quickstart.cloudera --p ...

  6. Openstack:Instance cannot ping by domain name

    Issue: When you created an instance inside Openstack, you may find that you cannot ping address by d ...

  7. 你知道如何为iOS工程改名吗?

    我们在iOS开发中,难免会遇到项目做到一半要改名字的情况.如果项目名差的太大,工程名看起来总是不舒服的,有良心的开发者可能就会想着为工程改个贴切的名字,那么你就为用到本文记录的内容. 如果我们开发的两 ...

  8. UIKit中ImageView动画堆叠显示的微调整

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 网上看到一个PackingList项目(如果需要源代码可以Q我 ...

  9. sql server中高并发情况下 同时执行select和update语句死锁问题 (二)

    SQL Server死锁使我们经常遇到的问题,数据库操作的死锁是不可避免的,本文并不打算讨论死锁如何产生,重点在于解决死锁.希望对您学习SQL Server死锁方面能有所帮助. 死锁对于DBA或是数据 ...

  10. Select标签 根据value值默认选中 Jquery

    网上找了很多都是错的,不行的. 下面方法可以的 <script type="text/javascript"> $(document).ready(function() ...