美文网首页
[074]RenderEngineType简介

[074]RenderEngineType简介

作者: 王小二的技术栈 | 来源:发表于2022-04-08 17:49 被阅读0次

    前言

    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<int32_t>(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> 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简介

          本文链接:https://www.haomeiwen.com/subject/hlkssrtx.html