基于Flutter 1.5,从源码视角来深入剖析flutter渲染机制,相关源码目录见文末附录
一、概述
看Flutter的渲染绘制过程的核心过程包括在ui线程和gpu线程,上一篇文章Flutter渲染机制—UI线程已经详细介绍了UI线程的工作原理,
本文则介绍GPU线程的工作原理,这里需要注意的是,gpu线程是指运行着GPU Task Runner的名叫gpu的线程,其实依然是是在CPU上执行,用于将ui线程传递过来的layer tree转换为GPU命令并方法送到GPU,但这个执行过程会等待GPU的执行结果。
1.1 GPU线程的绘制流程图
GPUDraw
Flutter渲染机制在UI线程执行到compositeFrame()过程经过多层调用,将栅格化的任务Post到GPU线程来执行。GPU线程一旦空闲则会执行Rasterizer的draw()操作。图中LayerTree::Paint()过程是一个比较重要的操作,会嵌套调用不同layer的Paint过程,比如TransformLayer,PhysicalShapeLayer,ClipRectLayer,PictureLayer等都执行完成会执行flush()将数据发送给GPU。
1.2 Surface类图
ClassSurface
三种不同的AndroidSurface,见小节2.6.3,说明如下:
硬件VSYNC方式,且开启VULKAN,则采用AndroidSurfaceVulkan,这是当前默认的方式;
硬件VSYNC方式,且未开启VULKAN,则采用AndroidSurfaceGL;
使用软件模拟的VSYNC方式,则采用AndroidSurfaceSoftware;
1.3 Layer类图
ClassLayer
LayerTree的root_layer来源于SceneBuilder过程初始化,第一个调用PushLayer()的layer便成为root_layer_,后面的调用会形成一个树状结构。从上图,可知ContainerLayer共有9个子类,由这些子类组合成为了一个layer tree,具体的组合方式取决于业务使用方,在LayerTree的Prepoll和Paint过程便会调用这些layer的方法,下面来看看这9个类:
ClipRectLayer:矩形裁剪层,可指定矩形和裁剪行为参数,其中裁剪行为有Clip.none,hardEdge,antiAlias,antiAliasWithSaveLayer四种行为;
ClipRRectLayer:圆角矩形裁剪层,可指定圆角矩形和裁剪行为参数,同上四种行为;
ClipPathLayer:路径裁剪层,可指定路径和裁剪行为参数,同上四种行为;
OpacityLayer:透明层,可指定透明度和偏移量参数,其中偏移量是指从画布坐标系原点到调用者坐标系原点的偏移量;
ShaderMaskLayer:着色层,可指定着色器、矩阵和混合模式参数;
ColorFilterLayer:颜色过滤层,可指定颜色和混合模式参数;
Transformayer:变换图层,可指定转换矩阵参数;
BackdropFilterLayer:背景过滤层,可指定背景图参数;
PhysicalShapeLayer:物理形状层,可指定颜色等八个参数。
二、GPU线程渲染过程
2.1 MessageLoopImpl::RunExpiredTasks
[-> flutter/fml/message_loop_impl.cc]
void MessageLoopImpl::RunExpiredTasks() {
TRACE_EVENT0("fml", "MessageLoop::RunExpiredTasks");
std::vector<:closure> invocations;
{
std::lock_guard<:mutex> lock(delayed_tasks_mutex_);
//当没有待处理的task则直接返回
if (delayed_tasks_.empty()) {
return;
}
auto now = fml::TimePoint::Now();
while (!delayed_tasks_.empty()) {
const auto& top = delayed_tasks_.top();
if (top.target_time > now) {