Android窗口管理分析(四)—— Android View绘制图层内存的分配、传递、使用

Android窗口管理分析(四)—— Android View绘制图层内存的分配、传递、使用

本文来看Android是怎么利用Ashmem分配及绘制的

View视图内存是怎么分配的?

添加窗口时,WMS为APP分配一个WindowState,标识当前窗口用于窗口管理,

Surface握有一块可以绘图的内存,这块内存是APP端需要的时候,通过sp GraphicBufferProducer申请的。

如何获得sp gdp这个服务代理?

在createNormalLayer中,建立了一个sp gbp容器 ——> 请求SurfaceFlinger分配填充内容 ——> SurfaceFlinger收到请求后为WMS建立与APP端对应的Layer ——> 分配sp gbp ——> 填充到Surface中返回给APP

APP端如何获得申请内存的句柄BpGraphicBufferProducer?

BufferQueueProducer是一个Binder通信对象,在服务端是BnGraphicBufferProducer,在App端是BpInterface{}

SurfaceFlinger创建Binder实体 ——> 打包Surface对象 ——> 通过binder通信传递给APP端 ——> APP端通过反序列化将其恢复出来——> APP端获得了申请内存句柄BpGraphicBufferProducer

BpGraphicBufferProducer有什么作用呢?

ViewRootImpl的draw ——> surface.nativeLockCanvas ——> Surface.dequeueBuffer ——> BpGraphicBufferProducer.dequeueBuffer请求分配内存

在Linux中一切都是文件,共享内存也是文件,分配成功后,跨进程传递tmpfs临时文件的描述符fd。

View绘制内存是怎么传递的?

fd利用Binder通信传递给App进程 ——> App获取fd后,将共享内存映射到自己的进程空间,进行图形绘制 ——> 等到App对GraphicBuffer反序列化的时候,将共享内存mmap到当前进程空间 ——> 这样进程就拿到绘制后的数据了

View绘制内存是怎么使用的?

当内存经过反序列化,拿到内存地址后 ——> 封装一个ANativeWindow_Buffer给上层调用 ——> 对于2d绘图,利用skia库填充Bitmap对应的共享内存 ——> 绘制完成 ——> 通过unlock通知SurfaceFlinger服务进行图层合成

Android View局部重绘的原理是什么?

lockCanvas ——> 判断buffer宽高格式是否一致 ——> 如果一致则进行数据拷贝 ——> 如果不一致则整块绘制 ——> 将绘制UI数据拷贝到申请内存中 ——> 在拷贝数据中进行脏区域重绘