Skia UI Library 渲染流程(初见)

1,016 阅读2分钟

我们在Java层声明的View最后都要通过Canvas来进行绘制,在调用Canvas.draw()之前,我们已经为View树在此帧的坐标颜色路径等参数一一设置完成,只等Canvas进行绘制。

Canvas的初始化:

它的构造方法和它其他的接口方法一样,都是本地方法的接口,实际执行的是JNI的native函数,Canvas初始化就是调用了InitRaster(),此接口实际映射的是android_graphic_canvas.cpp下的create_canvas()函数,实际上初始化的是native层的Canvas对象,并返回一个long型的ptr给Java层的Canvas,来调用其他的native层的函数。

Native层Canvas的执行流程:

当Java层Canvas调用本地接口诸如drawBitmap(),drawPath(),drawRect(),执行的是native层的Canvas的drawRect(),而Native层Canvas由SkiaCanvas实例化,SkiaCanvas在初始化时同时初始化一个Bitmap对象,至于来自上层调用的接口又转发给SkDraw来实现,SkDraw作为绘制的实际执行者,它通过SkiaCanvas设置的PointMode,以及可以获取的坐标xy,宽高,颜色等,将全部种类的draw接口诸如drawRect(),drawArc(),drawPath()等统一解析成path参数

渲染:

通过SkScan设置下不同的刷新方式,如LineProc,PointProc,RectProc所对应的线性,点型,矩形渲染方式,进行渲染,之后需要将Path转换成一个SkPoint[]数组,对应Path的关键点坐标和其他参数,之后调用vertline(x,y,blitter)执行针对此单元Path的光栅化,通过blitter的设置来执行8位/32位色深,是否抗锯齿,是否有阴影等,最后得出的片段包含坐标,宽度色值等信息,至此,整个解析-渲染流程执行完了,最后将片段参数赋值到 SkPixmap对象 fDevice数组中,fDevice就是映射到屏幕像素的缓冲区,这是纯Cpu的软件绘制流程,如果开启OpenGL/Vukan加速,fDevice就是Gpu持有的缓冲区了。

总之:Canvas的绘制流程就是将抽象的包含绘制对象,坐标,颜色等参数的绘制命令,全部解析成包含不同参数的单元路径集合,然后根据刷新方式执行单元路径的光栅化,将其转成一个个对应屏幕像素缓存区内的光栅片段,之后输出到屏幕上。

因为Skia实现比较复杂且没有具体的注释和流程介绍,只能通过一些方法跳转来摸一下渲染的流程,所以有很多没涉及到的地方,总体而言,渲染引擎听着很高大上,其实流程上直来直去,没什么设计模式,只是具体实现上特别特别繁琐,分析来分析去也没什么收获。