前言
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了。