绘制(Paint)---创建绘制指令
绘制阶段是将布局信息转换为绘制指令,生成绘制列表,告诉浏览器如何绘制每个元素。为后续的光栅化阶段做准备。
主线程会为每个层单独产生绘制指令集,这些指令集详细描述了每一层的内容该如何绘制出来。这些指令集包含了颜色、形状、边框、阴影等视觉元素的信息。
绘制指令示例
- 绘制矩形 :
- 指令内容:绘制一个特定颜色、大小和位置的矩形。
- 示例:绘制一个红色、宽度为100像素、高度为50像素、位于页面左上角(x=0, y=0)的矩形。
- 绘制文本 :
- 指令内容:在特定位置绘制一段文本,包括文本内容、字体、颜色和大小等信息。
- 示例:在页面中心位置(x=屏幕宽度/2, y=屏幕高度/2)绘制一段黑色、大小为24像素的文本"Hello, World!"。
控制台查看绘制指令集
图1 图2
!!!重要:
重绘(repaint) 的本质就是重新根据分层信息计算了绘制指令。
当改动可见样式后,就需要重新计算绘制指令,引发 Repaint。
由于元素的布局(Layout)信息也属于可见样式,所以重排( Reflow) 一定会引起 Repaint。
了解合成线程:
完成生成绘制指令集之后,主线程会将每个图层的绘制指令信息提交给合成线程,剩余工作将由合成线程完成。
合成线程首先会对每个图层进行分块,将其划分成更多的小区域。它会从线程池中拿出多个线程来完成分块工作。
分块(Tiling)
- 定义:分块是将页面划分为多个更小的区域,即图块(tiles),以便更高效地进行渲染。
- 目的 :通过分块,浏览器可以优先处理那些当前需要显示的图块,从而减少不必要的工作,提高渲染效率。
- 过程:合成线程首先对每个图层进行分块,将其划分为多个小区域。这些图块通常具有固定的大小,如256x256或512x512像素。然后,合成线程会从线程池中拿取多个线程来完成分块工作,以并行处理的方式提高效率。
分块,接近视口的块优先级高,优先显示出来。
因为:需要滚动很久才能到底的页面,页面很长、很大,则接近视口的内容优先级最高,因为希望用户能尽早的看到页面的内容。
可以将其视为更底层的"懒加载"。
光栅化(Rasterization)
- 定义:光栅化是将绘制指令转换为像素数据的过程,它生成实际用于显示的图像。
- 过程 :
- 在分块完成后,每个图块都会根据其绘制指令生成相应的像素。这些像素数据构成了页面的视觉表示。
- 光栅化任务通常由一个或多个栅格线程处理,这些线程运行在渲染器进程中。
- 为了加速处理,光栅化通常在GPU(图形处理单元)上完成,因为GPU非常擅长处理并行任务,如将矢量图形转换为像素。
- 复杂的CSS动画、过大的图片或视频以及高分辨率屏幕等因素都可能影响光栅化的性能。
光栅化就是将每个块变成位图(像素点)
位图:可以简单理解成用二维数组存储的像素信息。
合成线程会将块信息交给 GPU 进程,以极高的速度完成光栅化,生成一块一块的位图 。并且优先处理靠近视口区域的块。
画(Paint)
1、合成线程拿到每个层、每个块的位图后,生成一个个**指引(quad)**信息。
2、指引会标识出每个位图应该画到屏幕的哪个位置,以及会考虑到旋转、缩放等变形。
(变形发生在合成线程,与渲染主线程无关---transform效率高的原因。)
3、合成线程会把 quad 提交给 GPU 进程,由 GPU 进程产生系统调用,提交给 GPU 硬件,完成最终的屏幕成像。
输出显示
浏览器进程将图像数据发送给显卡的后缓冲区,这两个缓冲区(前缓冲区和后缓冲区)不断交替使用,以确保图像能以显示器60Hz的刷新率顺利显示。
- 帧与帧率:渲染流水线生成的单张图像称为一帧。每秒渲染的帧数称为帧率,例如,60帧每秒即为60FPS。
- 显卡的作用:显卡负责合成新的图像,并将这些图像存储在后缓冲区中。显卡内部维护了两个主要区域:前缓冲区和后缓冲区。
- 前缓冲区:显示器的刷新频率通常是固定的,如60Hz,即每秒刷新60次。显示器每秒60次地从显卡的前缓冲区读取图像并显示在屏幕上。
- 后缓冲区:显卡将合成好的图像存储在后缓冲区中。一旦图像存储完成,后缓冲区和前缓冲区会进行交换。当用户进行滚动或缩放等操作时,渲染引擎通过渲染流水线生成新的图像,并将这些图像发送到显卡的后缓冲区。在正常情况下,显卡的更新频率与显示器的刷新频率保持一致。但在处理复杂场景时,显卡合成一张图像的速度可能会变慢,导致视觉上的卡顿现象。
我的csdn原创地址:blog.csdn.net/huazi99/art...