Chromium源码分析二:LifeofaPixel.pdf

LifeofaPixel.pdf像素的一生,跟随像素的一生去理解Chromium的工作原理。据说是Chromium的入门培训PPT
网址:​​​​​​​​​​​​​​https://docs.google.com/presentation/d/1boPxbgNrTU0ddsc144rcXayGA_WF53k96imRH8Mp34Y/edit?usp=sharing

在网上找到了比较精简的笔记
图片转载自:https://blog.csdn.net/hebhljdx/article/details/139473588

LifeofaPixel

个人观点

ccLayer树

用过PhotoShop的人都知道图层这个概念。做前端的人也熟悉CSS(层叠样式表)。我们在屏幕上看到的最终图像其实是处于不同图层的图像拼合起来的。

对应到前端层面(html+javascript+css)
就是DOM树,DOM树的每个节点都有自己的大小、位置、样式,画到一起就是图像了。
这里有个特别要提到的就是“ShaddowDOM”,ShaddowDom通过独立组件的方式,避免了在样式、行为上受外层dom的影响。

对应到C++的实现层面这就是ccLayer树,cc(Chromium Compositor)前文讲过,是chromium的合成器。
ccLayer树的节点是View类,后面的各种页面的组件(窗口、button、text、toast之类的)都是继承的view类。View类有如下常用的API:

//设置View的位置和大小
  void SetBounds(int x, int y, int width, int height);
  //添加一个子view
  void AddChildView(View* view);
  //删除一个子view
  void RemoveChildView(View* view);
  //获取View对应的Widget
  Widget* GetWidget();
  //获取当前view孩子的数量
  int child_count()
  //获取parent view
  View* parent()
  //设置view是否可见
  void SetVisible(bool visible)
  //触发一次view树排版
  void Layout()
  //标示当前view区域需要重绘并立马重绘
  void SchedulePaint()
  //每次绘制,都会进入该方法收集绘制指令并绘制
  void Paint()
  //为当前view设置背景
  void SetBackground(std::unique_ptr<Background> b);
  //如果view设置这个属性,说明该view的声明周期自己负责,父view析构不会影响当当前view;若没有设置这个属性,并且当前view被添加为parent_view的child_view,则parent_view析构的时候,会一并析构调该child_view
  void set_owned_by_client()

也就是说,每个页面中的组件都有位置和大小,合成图像的时候,只要把各个层级的ccLayer树遍历一遍,每个节点调用一下Paint函数,图像就画出来了。
这个遍历是并非是根据节点关系遍历的,是根据图层的前后顺序遍历的,background先paint,foreground的后paint,还有一些不visible的,就不paint了。

paint的过程就是光栅化的过程,和PhotoShop里说的光栅化差不多。就是把矢量图转成位图了。比较复杂的操作,比如把图片放大、缩小、旋转、糊化之类的操作还有可能被送到gpu中去做。
这里面就涉及到了图像处理相关的知识了。简单介绍一下skia、vulkan、openGL、openCV。

skia、vulkan、openGL、openCV

Skia

用途:Skia 是一个高性能的 2D 图形处理库,主要用于绘制文本、形状、图像和矢量图形。它提供了跨平台的图形API,支持多种输出格式,如位图、PDF 和 SVG。
应用场景:Skia 常用于构建用户界面,如网页、移动应用和桌面应用的渲染引擎。它是 Google Chrome、Chromium 和 Android 操作系统的核心图形库。

Vulkan

用途:Vulkan 是一种低级别的图形和计算API,允许开发者直接访问GPU硬件,以实现高性能的3D图形渲染和并行计算。
应用场景:Vulkan 适用于游戏开发、虚拟现实、科学计算和图形密集型应用,它减少了CPU的负载,提高了多线程性能和跨平台兼容性。

OpenGL

用途:OpenGL 是一种跨平台的API,用于渲染2D和3D图形,提供了一套标准的图形绘制功能,包括纹理映射、光照和阴影效果。
应用场景:OpenGL 广泛应用于游戏开发、CAD/CAM、科学可视化和教育软件,支持从简单的图形到复杂的3D场景。

OpenCV

用途:OpenCV 是一个开源的计算机视觉和机器学习库,提供了一系列函数和算法,用于图像处理、特征检测、物体识别和视频分析。
应用场景:OpenCV 主要用于计算机视觉研究、安全监控、医学影像分析、机器人视觉和自动驾驶等领域。

区别

抽象级别:OpenGL 和 Vulkan 处理图形渲染,但Vulkan提供了更低级别的硬件访问,而OpenGL提供了更高层次的抽象。
用途范围:Skia 和 OpenGL/Vulkan 主要用于图形渲染,而OpenCV专注于图像处理和计算机视觉任务。
计算能力:Vulkan 支持并行计算和GPU加速,而Skia、OpenGL 和 OpenCV 更侧重于图形和视觉处理的特定方面。

联系

图形渲染:Skia 和 OpenGL/Vulkan 都涉及图形渲染,但它们的使用场景和抽象级别不同。
GPU加速:Vulkan 和 OpenCV 都可以利用GPU加速,前者用于图形渲染,后者用于图像处理和机器学习任务。
跨平台性:Skia、OpenGL 和 Vulkan 都支持跨平台应用,提供了一致的API,以适应不同的操作系统和硬件。
总的来说,Skia、Vulkan、OpenGL 和 OpenCV 在图形和视觉处理领域各自发挥着独特的作用,它们之间的联系主要体现在图形渲染和GPU加速方面,而区别则在于它们的应用场景、抽象级别和计算能力。

之后就是上篇笔记讲到的,把绘图和渲染任务分配到render进程,最终放display到显示屏上。在此过程中,chromium也做了很多的优化,比如PrePaint,PrePaint在实际绘制之前预先计算和准备所有必要的渲染信息,避免在渲染过程中进行昂贵的计算,从而减少重绘和布局的成本。

PrePaint

PrePaint在 Chromium 中的主要作用

预计算和缓存:PrePaint 阶段会计算和缓存各种渲染属性,如图层的位置、大小、可见性、变换矩阵、滚动偏移等。这些信息在后续的绘制阶段可以直接使用,避免了重复计算。
资源准备:PrePaint 还会准备渲染所需的资源,如纹理、字体、图像等,确保在实际绘制时这些资源已经加载完成并可用,减少绘制延迟。
优化渲染路径:PrePaint 会分析图层树和视图层次结构,决定哪些图层需要绘制,哪些可以被裁剪或复用,从而优化渲染路径,减少不必要的重绘。
滚动和动画预测:PrePaint 能够预测用户可能的滚动和动画操作,提前计算和准备相关的渲染信息,确保动画和滚动的流畅性。
异步渲染准备:PrePaint 还支持异步渲染,可以在后台线程上进行预计算,减少主线程的负担,提高渲染性能。
避免重绘:通过在 PrePaint 阶段计算哪些部分需要更新,可以避免不必要的重绘,只更新发生了变化的部分,提高渲染效率。
性能分析:PrePaint 还提供了性能分析和调试的手段,可以帮助开发者理解和优化渲染性能瓶颈。
总之,PrePaint 在 Chromium 中起到了桥梁的作用,它连接了布局和绘制两个阶段,通过预计算和资源准备,大大提高了渲染性能和用户体验。通过将昂贵的计算移到实际绘制之前,PrePaint 能够确保渲染流程的高效和平滑。

posted on 2024-11-15 19:42  步孤天  阅读(3)  评论(0编辑  收藏  举报