《WebKit 技术内幕》之七(3): 渲染基础

3 渲染方式

3.1 绘图上下文(GraphicsContext)

        上面介绍了WebKit的内部表示结构,RenderObject对象知道如何绘制自己,但是,问题是RenderObject对象用什么来绘制内容呢?在WebKit中,绘图操作被定义了一个抽象层,这就是绘图上下文,所有绘图的操作都是在该上下文中来进行的。绘图上下文可以分成两种类型,第一种是用来绘制2D图形的上下文,称之为2D绘图上下文(GraphicsContext);第二种是绘制3D图形的上下文,称之为3D绘图上下文(GraphicsContext3D)。这两种上下文都是抽象基类,也就是说它们只提供接口,因为WebKit需要支持不同的移植。而这两个抽象基类的具体绘制则由不同的移植提供不同的实现,每个移植使用的实际绘图类非常不一样,依赖的图形率也不一样,图7-7描述了抽象类和WebKit的移植实现类的关系。

                                        图绘图上下文类和移植相关的绘图上下文类

        PlatfromGraphicsContext类和PlatformGraphicsContext3D类是两个表示上下文的类,其实它们的类定义取决于各个移植。在WebKit的Safari移植中,这两个类其实是CGContext和CGLContextObj;而在Chromium移植中,它们则是PlatformContextSkia和GrContext。同之前描述的基类和子类的关系不一样,这些不是父子类关系,而是WebKit直接通过C语言的typedef来将每个不同移植的类重命名成PlatfromGraphicsContext和PlatformGraphicsContext3D。

        2D绘图上下文的具体作用就是提供基本绘图单元的绘制接口以及设置绘图的样式。绘图接口包括画点、画线、画图片、画多边形、画文字等,绘图样式包括颜色、线宽、字号大小、渐变等。RenderObject对象知道自己需要画什么样的点,什么样的图片,所以RenderObject对象调用绘图上下文的这些基本操作就是绘制实际的显示结果,图7-8描述了RenderObject类和GraphicsContext类的关系。

                             图 描述了RenderObject和绘图上下文之间的关系。

           关于3D绘图上下文的介绍,我们将在第8章中介绍,它的主要用处是支持CSS3D、WebGL等。

          在现有的网页中,由于HTML5标准引入了很多新的技术,所以同一网页中可能会既需要使用2D绘图上下文,也需要使用3D绘图上下文。对于2D绘图上下文来说,其平台相关的实现既可以使用CPU来完成2D相关的操作,也可以使用3D图形接口(如OpenGL)来完成2D相关的操作。而对于3D绘图上下文来说,因为性能的问题,WebKit的移值通常都是使用3D图形接口(如OpenGL或者Direct3D等技术)来实现。

3.2 渲染方式

        在完成构建DOM树之后,WebKit所要做的事情就是构建渲染的内部表示并使用图形库将这些模型绘制出来。提到网页的渲染方式,目前主要有两种方式,第一种是软件渲染,第二种是硬件加速渲染。其实这种描述并不精确,因为还有一种混合模式。要理解这一概念,笔者还得接着本章介绍的RenderLayer树来继续深入挖掘。

        每个RenderLayer对象可以被想象成图像中的一个层,各个层一同构成了一个图像。在渲染的过程中,浏览器也可以作同样的理解。每个层对应网页中的一个或者一些可视元素,这些元素都绘制内容到该层上,在本书中,一律把这一过程称为绘图操作。如果绘图操作使用CPU来完成,那么称之为软件绘图。如果绘图操作由GPU来完成,称之为GPU硬件加速绘图。理想情况下,每个层都有个绘制的存储区域,这个存储区域用来保存绘图的结果。最后,需要将这些层的内容合并到同一个图像之中,本书中称之为合成(Compositing),使用了合成技术的渲染称之为合成化渲染。

        所以在RenderObject树和RenderLayer树之后,WebKit的机制操作将内部模型转换成可视的结果分为两个阶段:每层的内容进行绘图工作及之后将这些绘图的结果合成为一个图像。对于软件渲染机制,WebKit需要使用CPU来绘制每层的内容,按照上面的介绍,读者可能觉得需要合成这些层,其实软件渲染机制是没有合成阶段的,为什么?原因很简单,没有必要。在软件渲染中,通常渲染的结果就是一个位图(Bitmap),绘制每一层的时候都使用该位图,区别在于绘制的位置可能不一样,当然每一层都按照从后到前的顺序。当然,你也可以为每层分配一个位图,问题是,一个位图就已经能够解决所有问题。下图是网页的三种渲染方式。

                                        图网页的三种渲染方式

        从上图可以看到,软件渲染中网页使用的一个位图,实际上就是一块CPU使用的内存空间。图7-9中的第二种和第三种方式,都是使用了合成化的渲染技术,也就是使用GPU硬件来加速合成这些网页层,合成的工作都是由GPU来做,这里称为硬件加速合成(Accelerated Compositing)。但是,对于每个层,这两种方式有不同的选择。其中某些层,第二种方式使用CPU来绘图,另外一些层使用GPU来绘图。对于使用CPU来绘图的层,该层的结果首先当然保存在CPU内存中,之后被传输到GPU的内存中,这主要是为了后面的合成工作。第三种渲染方式使用GPU来绘制所有合成层。第二种方式和第三种方式其实都属于硬件加速渲染方式。前面的这些描述,是把RenderLayer对象和实际的存储空间对应,现实中不是这样的,这只是理想的情况。

       到这里,读者可能感到奇怪为什么会有三种渲染方式,这是因为三种方式各有各的优缺点和适用场景,在介绍它们的特点之前,先了解一些渲染方面的基本知识。

        首先,对于常见的2D绘图操作,使用GPU来绘图不一定比使用CPU绘图在性能上有优势,例如绘制文字、点、线等,原因是CPU的使用缓存机制有效减少了重复绘制的开销而且不需要GPU并行性。其次,GPU的内存资源相对CPU的内存资源来说比较紧张,而且网页的分层使得GPU的内存使用相对比较多。鉴于此,就目前的情况来看,三者都存在是有其合理性的,下面分析一下它们的特点。

  • 软件渲染是目前很常见的技术,也是浏览器最早使用的渲染方式这一技术比较节省内存,特别是更宝贵的GPU内存,但是软件渲染只能处理2D方面的操作。简单的网页没有复杂绘图或者多媒体方面的需求,软件渲染方式就比较合适来渲染该类型的网页。问题是,一旦遇上了HTML5的很多新技术,软件渲染显然无能为力,一是因为能力不足,典型的例子是CSS3D、WebGL等;二是因为性能不好,例如视频、Canvas 2D等。所以,软件渲染技术被使用得越来越少,特别是在移动领域。软件渲染同硬件加速渲染另外一个很不同的地方就是对更新区域的处理。当网页中有一个更新小型区域的请求(如动画)时,软件渲染可能只需要计算一个极小的区域,而硬件渲染可能需要重新绘制其中的一层或者多层,然后再合成这些层。硬件渲染的代价可能会大得多。
  • 对于硬件加速的合成化渲染方式来说,每个层的绘制和所有层的合成均使用GPU硬件来完成,这对需要使用3D绘图的操作来说特别适合。这种方式下,在RenderLayer树之后,WebKit和Chromium还需要建立更多的内部表示,例如GraphicsLayer树、合成器中的层(如Chromium的CCLayer)等,目的是支持硬件加速机制,这显然会消耗更多的内存资源。但是,一方面,硬件加速机制能够支持现在所有的HTML5定义的2D或者3D绘图标准;另一方面,关于更新区域的讨论,如果需要更新某个层的一个区域,因为软件渲染没有为每一层提供后端存储,因而它需要将和这个区域有重叠部分的所有层次的相关区域依次从后向前重新绘制一遍,而硬件加速渲染只需要重新绘制更新发生的层次。因而在某些情况下,软件渲染的代价更大。当然,这取决于网页的结构和渲染策略,这些都是需要重点关注和讨论的。
  • 软件绘图的合成化渲染方式结合了前面两种方式的优点,这是因为很多网页可能既包含基本的HTML元素,也包含一些HTML5新功能,使用CPU绘图方式来绘制某些层,使用GPU来绘制其他一些层。原因当然是前面所述的基于性能和内存方面综合考虑的结果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/639271.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

xcode 设置 ios苹果图标,为Flutter应用程序配置iOS图标

图标设置 1,根据图片构建各类尺寸的图标2.xcode打开ios文件3.xcode设置图标4.打包提交审核,即可(打包教程可通过我的主页查找) 1,根据图片构建各类尺寸的图标 工具网址:https://icon.wuruihong.com/ 下载之后文件目录如下 拷贝到项目的ios\Runner\Assets.xcassets\AppIcon.ap…

java简单的抽奖工具类(含测试方法)

文章目录 结果代码 结果 代码 import lombok.AllArgsConstructor; import lombok.Data; import lombok.ToString;import java.util.ArrayList; import java.util.List;/****/ public class LotteryUtils {public static void main(String[] args) throws InterruptedException…

PythonNet,Csharp如何白嫖Python生态和使用Matplotlib

文章目录 前言PythonNet环境配置Python环境配置Csharp Nuget配置运行代码测试运行结果 总结 前言 我既然用Csharp去尝试学习机器视觉,我就想试试用Csharp去使用Python的库。 这个世界上有没有编程语言既有Python的开发效率,又有C/C/ PythonNet Pythonne…

Android:JNI实战,加载三方库、编译C/C++

一.概述 Android Jni机制让开发者可以在Java端调用到C/C,也是Android应用开发需要掌握的一项重要的基础技能。 计划分两篇博文讲述Jni实战开发。 本篇主要从项目架构上剖析一个Android App如何通过Jni机制加载三方库和C/C文件。 二.Native C Android Studio可…

精准核酸检测 - 华为OD统一考试

OD统一考试(C卷) 分值: 100分 题解: Java / Python / C 题目描述 为了达到新冠疫情精准防控的需要,为了避免全员核酸检测带来的浪费,需要精准圈定可能被感染的人群。 现在根据传染病流调以及大数据分析&a…

【代码实战】从0到1实现transformer

获取数据 import pathlibimport tensorflow as tf# download dataset provided by Anki: https://www.manythings.org/anki/ text_file tf.keras.utils.get_file(fname"fra-eng.zip",origin"http://storage.googleapis.com/download.tensorflow.org/data/fra-…

transdata笔记:手机数据处理

1 mobile_stay_duration 每个停留点白天和夜间的持续时间 transbigdata.mobile_stay_duration(staydata, col[stime, etime], start_hour8, end_hour20) 1.1 主要参数 staydata停留数据(每一行是一条数据)col 列名,顺序为[‘starttime’,…

[足式机器人]Part2 Dr. CAN学习笔记- 最优控制Optimal Control Ch07-2 动态规划 Dynamic Programming

本文仅供学习使用 本文参考: B站:DR_CAN Dr. CAN学习笔记 - 最优控制Optimal Control Ch07-2 动态规划 Dynamic Programming 1. 基本概念2. 代码详解3. 简单一维案例 1. 基本概念 Richoard Bell man 最优化理论: An optimal policy has the …

纯C无操作系统轻量协程库Protothread使用记录

文章目录 目的源码说明使用演示总结 目的 在单片机开发中很多时候都是无操作系统环境,这时候如果要实现异步操作,并且流程逻辑比较复杂时处理起来会稍稍麻烦。这时候可以试试 Protothread 这个协程库。 官网: https://dunkels.com/adam/pt/…

深入剖析:Kafka流数据处理引擎的核心面试问题解析75问(5.7万字参考答案)

Kafka 是一款开源的分布式流处理平台,被广泛应用于构建实时数据管道、日志聚合、事件驱动的架构等场景。本文将深入探究 Kafka 的基本原理、特点以及其在实际应用中的价值和作用。 Kafka 的基本原理是建立在发布-订阅模式之上的。生产者将消息发布到主题&#xff08…

37-WEB漏洞-反序列化之PHPJAVA全解(上)

WEB漏洞-反序列化之PHP&JAVA全解(上) 一、PHP 反序列化原理二、案例演示2.1、无类测试2.1.1、本地2.1.2、CTF 反序列化小真题2.1.3、CTF 反序列化类似题 2.2、有类魔术方法触发2.2.1、本地2.2.2、网鼎杯 2020 青龙大真题 三、参考资料 一、PHP 反序列…

SpringMVC(八)处理AJAX请求

一、处理AJAX之准备工作: 首先我们创建一个新的工程: 我们将pom.xml复制过来: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-in…

【项目日记(三)】内存池的整体框架设计

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:项目日记-高并发内存池⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你做项目   &#x1f51d;&#x1f51d; 开发环境: Visual Studio 2022 项目日…

MES管理系统为何成为汽配企业的刚需

随着经济全球化、产品定制化及安全法规的严格化&#xff0c;汽配企业的经营环境变得越来越复杂。中国劳动力资源和原辅料成本的持续上升&#xff0c;导致行业利润率不断下滑。为了应对这些挑战&#xff0c;汽配企业需要引入一种精益制造和管理的工具&#xff0c;而MES管理系统正…

四款通用组织架构图模板-一键高清导出

组织架构图作为一种直观的图形化工具&#xff0c;能够帮助我们更好地理解和规划组织结构&#xff0c;提高工作效率。今天&#xff0c;我们就为大家带来四款通用组织架构图模板&#xff0c;让你一键高清导出&#xff0c;轻松搞定组织架构设计&#xff01; 第一款&#xff1a;某基…

Excel乱码?教你3个简单解决方法!

“我在编辑一个文件时&#xff0c;Excel突然就乱码了&#xff0c;怎么会这样呢&#xff1f;这个文件对我来说是比较重要的&#xff01;有什么方法可以快速解决吗&#xff1f;” 在处理Excel文件时&#xff0c;我们有时会遇到乱码问题。乱码不仅影响数据的可读性&#xff0c;还可…

PySide6/PyQt6中Qt窗口标志/窗口属性汇总,如何正确的设置窗口标志/窗口属性

文章目录 📖 介绍 📖🏡 环境 🏡📒 使用方法 📒📚 窗口标志汇总📚 窗口属性汇总📝 使用方法📝 注意事项⚓️ 相关链接 ⚓️📖 介绍 📖 在Qt框架中,窗口标志(window flags)是用于控制窗口的各种属性和行为的强大工具。它们通过设置窗口的属性,如边框…

vue3中Fragment特性的一个bug,需要留意的注意事项

vue3中的Fragment 模版碎片特性是什么&#xff0c;简单的理解就是template模板代码不在像vue2中那样必须在根节点在包裹一层节点了。 vue2写法 <template><div><h1>标题</h1><p>正文内容</p></div> </template>vue3写法 &l…

【OCR项目】之用HALCON的深度学习工具进行文字识别,并导出到C++调用

前言 HALCON是一个强大的机器视觉工具&#xff0c;包含了2D&#xff0c;3D图像各种算子&#xff0c;以及各种任务的深度学习工具&#xff0c;包括目标检测&#xff0c;实例分割&#xff0c;文字识别等。 这次从实际生产的角度&#xff0c;来分享一下如何用HALCON进行文字识别…