Android(安卓)TV native层中Canvas库的实现思路
Canvas是封装图形绘制操作的一个类:
就如Canvas.java中的类功能注释所描述的:The Canvas class holds the "draw" calls。
一、首先我们看下整个Canvas类体系的整体框架
我们可以找到Canvas.h(frameworks/base/include/private/graphics/Canvas.h)
这个头文件的实现是在:SkiaCanvas.cpp(frameworks/base/core/jni/android/graphics/SkiaCanvas.cpp)
而这个文件是属于libandroid_runtime.so的一部分
查看frameworks/base/core/jni/Android.mk可以知道libandroid_runtime.so依赖一个libskia的动态链接库
libskia.so 是由external/skia目录下的代码生成的。
因此,当应用调用java层的Canvas类的时候,最终会调用到基类Canvas.java,进而调用到native层的Canvas.h
然后调用到libandroid_runtime.so中,最后调用到libskia.so中的具体实现。
因此
Canvas部分的整体架构思路是:Java层的各Canvas派生类最后会调用到基类Canvas,然后通过jni调用到Canvas.h,进而使用在libandroid_runtime中封装的libskia.so的绘制能力。
二、我们看下硬件绘制部分的实现
上面的Canvas只是一些基本功能,比如派生类HardwareCanvas就拥有新的能力drawRenderNode。这部分能力是libskia中没有的
java层有一个Canvas派生类GLES20Canvas(frameworks/base/core/java/android/view/GLES20Canvas.java)
这个类继承HardwareCanvas,其实现了drawRenderNode接口
调用到了android_view_GLES20Canvas.cpp(frameworks/base/core/jni/android_view_GLES20Canvas.cpp)
这个文件也是libandroid_runtime.so的一部分
这个jni实现类里封装了DisplayListRenderer的实现(frameworks/base/libs/hwui/DisplayListRenderer.cpp)
由文件位置可以知道DisplayListRenderer.cpp被编译到一个libhwui.so中。
并且,显然libandroid_runtime.so也依赖了libhwui.so
因此
这部分新增派生能力的架构思路是:派生类直接通过jni直接利用libandroid_runtime.so调用libhwui.so的能力。
三、对比上面两种绘制能力实现方式,一个利用libskia.so,一个利用libhwui.so
我们可以发现对于相同的基础能力,比如GLES20Canvas的scale和rotate,其实现是不一样的。
我们跟踪以下DisplayListRenderer.cpp中的scale的实现,可以发现并没有再调用到libskia中去,
因此这里可以说对于部分基础功能,硬件渲染在libhwui.so中做了另一套实现。
但是查看libhwui.so的Android.mk(frameworks/base/libs/hwui/Android.mk)
发现libhwui有依赖libskia库。从代码看,也确实有利用libskia的能力。
因此
libhwui可以看做在libskia基础上拓展了硬件渲染能力的动态链接库。
更多相关文章
- 探究Android(安卓)View 绘制流程,Canvas 的由来。
- Android(安卓)ServiceConnection
- Android(安卓)SurfaceFlinger 学习之路(二)----SurfaceFlinger概
- Android(安卓)绘制线程动画
- 如何启用Service,如何停用Service。
- 移动架构39_RxAndroid二(变换调用:map、flatMap、lift、compose)
- 这是我见过有关Android(安卓)RecyclerView最好的一篇文章:深入解
- Android图形显示系统——上层显示2:硬件加速实现
- Android(安卓)Service组件的生命周期及用法总结