Android Skia的绘制系统

和你一起终身学习,这里是程序员Android

经典好文推荐,通过阅读本文,您将收获以下知识点:

一、View的绘制机制
二、HWUI绘制架构
三、渲染设备Device
四、ImageView绘制
五、绘制时的几何处理SkMatrix

Android Q渲染系统,最大的改动就是增加了skia的戏份,之前Android P绘制时,直接是在hwui中封装一下,绘制封装到op中,直接去调GPU实现了;现在在Android Q中,除了hwui中的封装,在hwui中有个DisplayList外,在skia中再次封装,在skia中还有一个GrOpList

具体的细节,就让我们一起来看看吧

一、View的绘制机制

首先我们来看看View的绘制机制吧!View的一个统称。相信不少同学都自定义过View~ 我们自定义一个View,是不是都要去重写onDraw方法,但是onDraw方法是什么时候去调的呢!让我们来看看吧!

我们来看看关键点:

  • 编舞者Choreographer
    主要处理DisplayEventReceiver接受到的Vsync信号,控制绘制的节拍,和底层的显示进行同步!

  • ViewRootImpl
    一个窗口中所有View的根,所有View都是按照数据结构Tree进行组织

  • ThreadedRenderer
    线程化的渲染器,里面会封装渲染线程,硬件加速主要走这里,早期没有硬件加速走的drawSoftware,现在还保留只为兼容!

  • 一个View对应一个渲染节点RenderNode,充分体现了Tree结构的概念!

  • Canvas
    俗称画布,提供什么样的画布就具有什么样的能力,渲染的途径就不一样!

我们以ImageView的渲染为例,看看其调用栈!

12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at android.graphics.BaseRecordingCanvas.drawBitmap(BaseRecordingCanvas.java:88)
12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:548)
12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at android.widget.ImageView.onDraw(ImageView.java:1434)
12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at com.android.example.cropper.CropImageView.onDraw(CropImageView.java:167)
12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at android.view.View.draw(View.java:21594)
... ...
12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4231)
12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at android.view.View.draw(View.java:21601)
12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at com.android.internal.policy.DecorView.draw(DecorView.java:831)
12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at android.view.View.updateDisplayListIfDirty(View.java:20437)
12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:575)
12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:581)
12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:654)
12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at android.view.ViewRootImpl.draw(ViewRootImpl.java:3828)
12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3619)
12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2939)
12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1849)
12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8013)
12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:969)
12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at android.view.Choreographer.doCallbacks(Choreographer.java:793)
12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at android.view.Choreographer.doFrame(Choreographer.java:728)
12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:954)
12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at android.os.Handler.handleCallback(Handler.java:883)
12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at android.os.Handler.dispatchMessage(Handler.java:100)
12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at android.os.Looper.loop(Looper.java:224)
12-30 13:45:51.476 10246 26422 26422 E AndroidRuntime:  at android.app.ActivityThread.main(ActivityThread.java:7509)

这个栈里我们隐藏掉了一部分View的Tree的调用!展示了从收到Vsync到开始绘制之间的调用流程!

二、HWUI绘制架构

之前,hwui中对绘制操作进行封装后,直接送GPU进行渲染,通过OpenGL或Vulkan进行封装!Q版本后,不一样,都是通过skia进行封装再通过OpenGL或Vulkan进行封装,最后才给到GPU渲染。

skia的作用用处,明显加强了!
通过代码分析,skia是通过静态库的形式被hwui引用的!

hwui的流程和之前的差别主要就体现在skia的二次封装~ 我们来看看hwui的绘制流程!

  • SkiaOpenGLPipeline和SkiaVulkanPipeline两个分别是对OpenGL和Vulkan的封装!

  • skia的代码分两个部分,这个图里面的主要是hwui中的,还有一部分是skia独立的静态库中!

  • skia有对应的结构和hwui匹配!

我们就简单看一下SkiaCanvas的一个调用流程:

01-02 17:19:52.510 31741 32145 D xm-gfx-skia: SkCanvas: #00 pc
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员Android

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值