[074]RenderEngineType简介

前言

RenderEngine是一个静态库,主要作用于SurfaceFlinger进行client layer合成。
简单理解就是将client buffer layer合成到FramebufferSurface

frameworks\native\libs\renderengine\

一、RenderEngineType

RenderEngineType是指RenderEngine的合成方式实现类型,目前有四种类型实现如下。

enum class RenderEngineType {
    GLES = 1,//opengl
    THREADED = 2,//opengl异步线程
    SKIA_GL = 3,//skia
    SKIA_GL_THREADED = 4,//skia异步线程
};
同步 异步
skia SKIA_GL SKIA_GL_THREADED
opengl GLES THREADED

异步的意思会另起一个名叫RenderEngine的线程中处理合成任务。
同步的意思是会在SurfaceFlinger的主线程中处理合成任务
如图:异步处理合成任务的Trace。


二、RenderEngine初始化流程

基于最新的代码安卓代码

1.1 SurfaceFlinger.cpp

SurfaceFlinger init的时候会构建RenderEngine,并且确认RenderEngineType

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

void SurfaceFlinger::init() {
...
    // Get a RenderEngine for the given display / config (can't fail)
    // TODO(b/77156734): We need to stop casting and use HAL types when possible.
    // Sending maxFrameBufferAcquiredBuffers as the cache size is tightly tuned to single-display.
    mCompositionEngine->setRenderEngine(renderengine::RenderEngine::create(
            renderengine::RenderEngineCreationArgs::Builder()
                    .setPixelFormat(static_cast(defaultCompositionPixelFormat))
                    .setImageCacheSize(maxFrameBufferAcquiredBuffers)
                    .setUseColorManagerment(useColorManagement)
                    .setEnableProtectedContext(enable_protected_contents(false))
                    .setPrecacheToneMapperShaderOnly(false)
                    .setSupportsBackgroundBlur(mSupportsBlur)
                    .setContextPriority(
                            useContextPriority
                                    ? renderengine::RenderEngine::ContextPriority::REALTIME
                                    : renderengine::RenderEngine::ContextPriority::MEDIUM)
                    .build()));//跳转到1.2
    mMaxRenderTargetSize =
            std::min(getRenderEngine().getMaxTextureSize(), getRenderEngine().getMaxViewportDims());

    ....
}

1.2 RenderEngine

提供了setRenderEngineType的接口,默认缺省值是SKIA_GL_THREADED

frameworks/native/libs/renderengine/include/renderengine/RenderEngine.h

struct RenderEngineCreationArgs::Builder {
...
    Builder& setRenderEngineType(RenderEngine::RenderEngineType renderEngineType) {
        this->renderEngineType = renderEngineType;
        return *this;
    }
...

private:
    // 1 means RGBA_8888
    int pixelFormat = 1;
    uint32_t imageCacheSize = 0;
    bool useColorManagement = true;
    bool enableProtectedContext = false;
    bool precacheToneMapperShaderOnly = false;
    bool supportsBackgroundBlur = false;
    RenderEngine::ContextPriority contextPriority = RenderEngine::ContextPriority::MEDIUM;
    RenderEngine::RenderEngineType renderEngineType =
            RenderEngine::RenderEngineType::SKIA_GL_THREADED;//缺省值
};

} // namespace renderengine

可以通过设置"debug.renderengine.backend",改变RenderEngineType。
配置项:gles,threaded, skiagl,skiaglthread 分别对应四种类型

frameworks/native/libs/renderengine/RenderEngine.cpp

#define PROPERTY_DEBUG_RENDERENGINE_BACKEND "debug.renderengine.backend"

std::unique_ptr RenderEngine::create(RenderEngineCreationArgs args) {
    // Keep the ability to override by PROPERTIES:
    char prop[PROPERTY_VALUE_MAX];
    property_get(PROPERTY_DEBUG_RENDERENGINE_BACKEND, prop, "");
    if (strcmp(prop, "gles") == 0) {
        args.renderEngineType = RenderEngineType::GLES;
    }
    if (strcmp(prop, "threaded") == 0) {
        args.renderEngineType = RenderEngineType::THREADED;
    }
    if (strcmp(prop, "skiagl") == 0) {
        args.renderEngineType = RenderEngineType::SKIA_GL;
    }
    if (strcmp(prop, "skiaglthreaded") == 0) {
        args.renderEngineType = RenderEngineType::SKIA_GL_THREADED;
    }

    switch (args.renderEngineType) {
        case RenderEngineType::THREADED:
            ALOGD("Threaded RenderEngine with GLES Backend");
            return renderengine::threaded::RenderEngineThreaded::create(
                    [args]() { return android::renderengine::gl::GLESRenderEngine::create(args); },
                    args.renderEngineType);
        case RenderEngineType::SKIA_GL:
            ALOGD("RenderEngine with SkiaGL Backend");
            return renderengine::skia::SkiaGLRenderEngine::create(args);
        case RenderEngineType::SKIA_GL_THREADED: {
            ALOGD("Threaded RenderEngine with SkiaGL Backend");
            return renderengine::threaded::RenderEngineThreaded::create(
                    [args]() {
                        return android::renderengine::skia::SkiaGLRenderEngine::create(args);
                    },
                    args.renderEngineType);
        }
        case RenderEngineType::GLES:
        default:
            ALOGD("RenderEngine with GLES Backend");
            return renderengine::gl::GLESRenderEngine::create(args);
    }
}

三、小结

android S以后原生配置的是SKIA_GL_THREADED,目前窗口的blurs效果,只在skia实现上
opengl模式不支持blurs。

Some new features (e.g. cross window blurs) are only implemented in Skia
RenderEngine. Turn it on for all Pixel devices. Other devices can still
turn it off with PROPERTY_DEBUG_RENDERENGINE_BACKEND.

细心你可能会发现前面SKIA_GL_THREADED的drawlayers中并没有发挥异步的作用。本质上还是会Block SF的主线程。



目前我只发现REThreaded::unmapExternalTextureBuffer这个方法是异步处理了,相比SKIA_GL,有一定程度上的性能提升。


但是据说可能一些极限情况的下并发读写的问题,我相信后续android会不断的完善SKIA_GL_THREADED,后续可能就渐渐放弃GLES了。

你可能感兴趣的:([074]RenderEngineType简介)