hwui opengl VS skia opengl VS skia vulkan?

嗜简如命 2019-06-29

之前讨论过skia codec部分在o,p上的变化,比如增加了heif解码等。
其实skia在android o,p的变化不只这些。

印象最深刻的还是渲染部分

从o开始hwui渲染支持skia opengl,原来hwui只支持opengl渲染,只不过在o里,skia opengl是可选的方式,默认还是opengl,但在p上已经默认采用skia opengl了,而且去掉了选择。

Android o上的选项

hwui opengl VS skia opengl VS skia vulkan?

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;
}

但看代码实际上还是未启用状态可能有很多问题还没解决

RenderPipelineType Properties::getRenderPipelineType() {
if (sRenderPipelineType != RenderPipelineType::NotInitialized) {
    return sRenderPipelineType;
}
char prop[PROPERTY_VALUE_MAX];
property_get(PROPERTY_RENDERER, prop, "skiagl");
if (!strcmp(prop, "skiagl")) {
    ALOGD("Skia GL Pipeline");
    sRenderPipelineType = RenderPipelineType::SkiaGL;
} else if (!strcmp(prop, "skiavk")) {
    ALOGD("Skia Vulkan Pipeline");
    sRenderPipelineType = RenderPipelineType::SkiaVulkan;
} else {  //"opengl"
    ALOGD("HWUI GL Pipeline");
    sRenderPipelineType = RenderPipelineType::OpenGL;
}
return sRenderPipelineType;

Android p上默认已经是skiagl了,而且skiavk已经ready或者至少可以work了

效率问题

skia opengl会比opengl快吗?

网上很多人都表示skia opengl比opengl快,但是从实现的角度上讲核心没有不同,不同的可能是模块代码结构流程,并没有实质的提升,更不会出现能从使用者的角度观察到变化。因此做了一个实验,在60fps的一个场景下对opengl和skia opengl的gl绘制耗时做了一个对比。
OpenGL
hwui opengl VS skia opengl VS skia vulkan?

OpenGL skia
hwui opengl VS skia opengl VS skia vulkan?

draw: display list绘制信息
prepare: 同步时间
Process: gl绘制时间
Execute: swapbuffer时间

从上边的数据可以看到两种方式process的时间基本没有差别,而且整体渲染的时间也不相上下。所以从实验角度也不存在谁比谁更快。
而且两个cpu使用情况也基本相同。没什么差别。
hwui opengl VS skia opengl VS skia vulkan?

真正的提升应该是在vulkan实现之后

arm官方和提供了一些测试数据表明无论从性能还是功耗上都比opengl es有很大提升。如下链接有些可能需要翻墙。
https://community.arm.com/gra...
https://www.youtube.com/watch...
hwui opengl VS skia opengl VS skia vulkan?

hwui opengl VS skia opengl VS skia vulkan?

这是官方的数据,有必要去了解下android vulkan以及skia vulkan。

  • Allows to set rendering pipeline mode to OpenGL (default), Skia OpenGL

    • or Vulkan.

*/
//#define PROPERTY_RENDERER “debug.hwui.renderer"
在android p上可以通过设置上边的属性为skiavk来指定vulkan,但是在o上不要这么做,因为在o上vulkan还没有真正实现,会有很多问题比如应用打不开等等。
下边是在android p上同一场景的一组数据对比,看数据总体上skia vulkan比skia opengl有很比较大的提升,但是又一些很大的凸起,不太稳定,没有skia opengl平稳,可能还没优化好,也许要等到adnroid 9.2或者android Q才能正式发布。
skia OpenGL
hwui opengl VS skia opengl VS skia vulkan?

skia vulkan
hwui opengl VS skia opengl VS 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做铺垫。