之前讨论过skia codec部分在o,p上的变化,比如增加了heif解码等。
其实skia在android o,p的变化不只这些。
印象最深刻的还是渲染部分
从o开始hwui渲染支持skia opengl,原来hwui只支持opengl渲染,只不过在o里,skia opengl是可选的方式,默认还是opengl,但在p上已经默认采用skia opengl了,而且去掉了选择。
Android o上的选项
Android O上相关的代码
/**
* Defines the rendering pipeline to be used by the ThreadedRenderer.
*
* Possible values:
* "opengl", will use the existing OpenGL renderer
* "skiagl", will use Skia's OpenGL renderer
* "skiavk", will use Skia's Vulkan renderer
*
* @hide
*/
public static final String DEBUG_RENDERER_PROPERTY = "debug.hwui.renderer";
上边定义了可选的几个选项,是不是看到了vulkan,看来android早有打算
Readback& RenderThread::readback() {
if (!mReadback) {
auto renderType = Properties::getRenderPipelineType();
switch (renderType) {
case RenderPipelineType::OpenGL:
mReadback = new OpenGLReadbackImpl(*this);
break;
case RenderPipelineType::SkiaGL:
case RenderPipelineType::SkiaVulkan:
// It works to use the OpenGL pipeline for Vulkan but this is not
// ideal as it causes us to create an OpenGL context in addition
// to the Vulkan one.
mReadback = new skiapipeline::SkiaOpenGLReadback(*this);
break;
default:
LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t) renderType);
break;
}
}
return *mReadback;
}
同样看到了vulkan,以及相关代码,但是并没有启动,应该还没有实现好
Android P上的代码
Readback& RenderThread::readback() {
if (!mReadback) {
auto renderType = Properties::getRenderPipelineType();
switch (renderType) {
case RenderPipelineType::OpenGL:
mReadback = new OpenGLReadbackImpl(*this);
break;
case RenderPipelineType::SkiaGL:
mReadback = new skiapipeline::SkiaOpenGLReadback(*this);
break;
case RenderPipelineType::SkiaVulkan:
mReadback = new skiapipeline::SkiaVulkanReadback(*this);
break;
default:
LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t)renderType);
break;
}
}
return *mReadback;
}
看上去p上hwui已经开始支持vulkan了
class SkiaVulkanReadback : public Readback {
public:
SkiaVulkanReadback(renderthread::RenderThread& thread) : Readback(thread) {}
virtual CopyResult copySurfaceInto(Surface& surface, const Rect& srcRect,
SkBitmap* bitmap) override {
//TODO: implement Vulkan readback.
return CopyResult::UnknownError;
}
virtual CopyResult copyGraphicBufferInto(GraphicBuffer* graphicBuffer,
SkBitmap* bitmap) override {
//TODO: implement Vulkan readback.
return CopyResult::UnknownError;
}
但看代码实际上还是未启用状态可能有很多问题还没解决
效率问题
skia opengl会比opengl快吗?
网上很多人都表示skia opengl比opengl快,但是从实现的角度上讲核心没有不同,不同的可能是模块代码结构流程,并没有实质的提升,更不会出现能从使用者的角度观察到变化。因此做了一个实验,在60fps的一个场景下对opengl和skia opengl的gl绘制耗时做了一个对比。
OpenGL
OpenGL skia
draw: display list绘制信息
prepare: 同步时间
Process: gl绘制时间
Execute: swapbuffer时间
从上边的数据可以看到两种方式process的时间基本没有差别,而且整体渲染的时间也不相上下。所以从实验角度也不存在谁比谁更快。
而且两个cpu使用情况也基本相同。没什么差别。
真正的提升应该是在vulkan实现之后
arm官方和提供了一些测试数据表明无论从性能还是功耗上都比opengl es有很大提升。如下链接有些可能需要翻墙。
https://community.arm.com/gra...
https://www.youtube.com/watch...
这是官方的数据,有必要去了解下android vulkan以及skia vulkan。
android 2DUI的渲染发展大概是这么一个进化过程
Android早期通过skia库进行2d渲染,后来加入了hwui利用opengl替换skia进行大部分渲染工作,现在开始用skia opengl替换掉之前的opengl,从p的代码结构上也可以看出,p开始skia库不再作为一个单独的动态库so,而是静态库a编译到hwui的动态库里,将skia整合进hwui,hwui调用skia opengl,也为以后hwui使用skia vulkan做铺垫。