SurfaceFlinger的启动
从surfaceFlinger service的入口开始,这里只看主要内容,allocator service/进程优先级的内容以后在别处再展开。接下来开启无聊的撸code时间。
//frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
int main(int, char**) {
// instantiate surfaceflinger
sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();
// initialize before clients can connect
flinger->init();
// publish surface flinger
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);
// run surface flinger in this thread
flinger->run();
return 0;
}
createSurfaceFlinger()
SurfaceFlinger的实例创建用到了工厂设计模式的概念,关于设计模式的知识点推荐大家去学习下《Head First Design Pattern》这本书,讲得很棒。
//frameworks/native/services/surfaceflinger/SurfaceFlingerFactory.cpp
sp<SurfaceFlinger> createSurfaceFlinger() {
static DefaultFactory factory;
return new SurfaceFlinger(factory);
}
//frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipInitialization){
}
SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag)
: mEventQueue(mFactory.createMessageQueue()),
mCompositionEngine(mFactory.createCompositionEngine()) {
}
createSurfaceFlinger内容很简单,new一个SurfaceFlinger对象,并初始化其内部的各个成员。暂时先关注下两个重要的成员:mEventQueue和mCompositionEngine。
来看看createMessageQueue干了什么事情:
//frameworks/native/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp
std::unique_ptr<MessageQueue> DefaultFactory::createMessageQueue() {
return std::make_unique<android::impl::MessageQueue>();
}
通过默认构造函数构造了一个MessageQueue。
//frameworks/native/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp
std::unique_ptr<compositionengine::CompositionEngine> DefaultFactory::createCompositionEngine() {
return compositionengine::impl::createCompositionEngine();
}
//frameworks/native/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() {
return std::make_unique<CompositionEngine>();
也是通过默认构造函数构造了一个CompositionEngine。
SurfaceFlinger::onFirstRef()
当SurfaceFlinger创建成功第一次被引用时,会调用到它的onFirstRef函数。
//frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::onFirstRef() {
mEventQueue->init(this);
}
//frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp
void MessageQueue::init(const sp<SurfaceFlinger>& flinger) {
mFlinger = flinger;
mLooper = new Looper(true);
mHandler = new Handler(*this);
}
这里会对messagequeue做初始化的动作。创建了一个looper和一个handler,looper封装了epoll机制,这里主要是监听vsync消息。Handler负责处理消息,将收到的信息传递入surfaceflinger,交由surfaceflinger处理。
关于messagequeue的细节后面的文章再展开,这里继续正题。
SurfaceFlinger::init()
接下来Init函数很庞大,我们一点一点分析:
//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()));
//省略
}
为CompositionEngine设置RenderEngine,setRenderEngine接口内调用的是创建RenderEngine的函数create,而create内部那一坨只是打包众多参数成一个参数:RenderEngineCreationArgs。我们主要看看create做了什么:
//frameworks/native/libs/renderengine/RenderEngine.cpp
std::unique_ptr<RenderEngine> RenderEngine::create(const RenderEngineCreationArgs& args) {
RenderEngineType renderEngineType = args.renderEngineType;
// Keep the ability to override by PROPERTIES:
char prop[PROPERTY_VALUE_MAX];
property_get(PROPERTY_DEBUG_RENDERENGINE_BACKEND, prop, "");
if (strcmp(prop, "gles") == 0) {
renderEngineType = RenderEngineType::GLES;
}
if (strcmp(prop, "threaded") == 0) {
renderEngineType = RenderEngineType::THREADED;
}
if (strcmp(prop, "skiagl") == 0) {
renderEngineType = RenderEngineType::SKIA_GL;
}
if (strcmp(prop, "skiaglthreaded") == 0) {
renderEngineType = RenderEngineType::SKIA_GL_THREADED;
}
switch (renderEngineType) {
case RenderEngineType::THREADED:
ALOGD("Threaded RenderEngine with GLES Backend");
return renderengine::threaded::RenderEngineThreaded::create(
[args]() { return android::renderengine::gl::GLESRenderEngine::create(args); },
renderEngineType);
case RenderEngineType::SKIA_GL:
ALOGD("RenderEngine with SkiaGL Backend");
return renderengine::skia::SkiaGLRenderEngine::create(args);
case RenderEngineType::SKIA_GL_THREADED: {
// These need to be recreated, since they are a constant reference, and we need to
// let SkiaRE know that it's running as threaded, and all GL operation will happen on
// the same thread.
RenderEngineCreationArgs skiaArgs =
RenderEngineCreationArgs::Builder()
.setPixelFormat(args.pixelFormat)
.setImageCacheSize(args.imageCacheSize)
.setUseColorManagerment(args.useColorManagement)
.setEnableProtectedContext(args.enableProtectedContext)
.setPrecacheToneMapperShaderOnly(args.precacheToneMapperShaderOnly)
.setSupportsBackgroundBlur(args.supportsBackgroundBlur)
.setContextPriority(args.contextPriority)
.setRenderEngineType(renderEngineType)
.build();
ALOGD("Threaded RenderEngine with SkiaGL Backend");
return renderengine::threaded::RenderEngineThreaded::create(
[skiaArgs]() {
return android::renderengine::skia::SkiaGLRenderEngine::create(skiaArgs);
},
renderEngineType);
}
case RenderEngineType::GLES:
default:
ALOGD("RenderEngine with GLES Backend");
return renderengine::gl::GLESRenderEngine::create(args);
}
}
PROPERTY_DEBUG_RENDERENGINE_BACKEND这个property并未设置值,传进来的参数中也并未设置RenderEngineType,但是从RenderEngineCreationArgs::Builder结构体中可以看到已经预设了值:
//frameworks/native/libs/renderengine/include/renderengine/RenderEngine.h
struct RenderEngineCreationArgs::Builder {
//省略
private:
RenderEngine::RenderEngineType renderEngineType =
RenderEngine::RenderEngineType::SKIA_GL_THREADED;
};
所以,在RenderEngine::create中走的分支是RenderEngineType::SKIA_GL_THREADED。
//frameworks/native/libs/renderengine/RenderEngine.cpp
std::unique_ptr<RenderEngine> RenderEngine::create(const RenderEngineCreationArgs& args) {
RenderEngineType renderEngineType = args.renderEngineType;
//省略
switch (renderEngineType) {
//省略
case RenderEngineType::SKIA_GL_THREADED: {
// These need to be recreated, since they are a constant reference, and we need to
// let SkiaRE know that it's running as threaded, and all GL operation will happen on
// the same thread.
RenderEngineCreationArgs skiaArgs =
RenderEngineCreationArgs::Builder()
.setPixelFormat(args.pixelFormat)
.setImageCacheSize(args.imageCacheSize)
.setUseColorManagerment(args.useColorManagement)
.setEnableProtectedContext(args.enableProtectedContext)
.setPrecacheToneMapperShaderOnly(args.precacheToneMapperShaderOnly)
.setSupportsBackgroundBlur(args.supportsBackgroundBlur)
.setContextPriority(args.contextPriority)
.setRenderEngineType(renderEngineType)
.build();
ALOGD("Threaded RenderEngine with SkiaGL Backend");
return renderengine::threaded::RenderEngineThreaded::create(
[skiaArgs]() {
return android::renderengine::skia::SkiaGLRenderEngine::create(skiaArgs);
},
renderEngineType);
}
}
}
这里是要创建一个RenderEngineThreaded实例。
//frameworks/native/libs/renderengine/threaded/RenderEngine.h
using CreateInstanceFactory = std::function<std::unique_ptr<renderengine::RenderEngine>()>;
//frameworks/native/libs/renderengine/RenderEngine.cpp
std::unique_ptr<RenderEngineThreaded> RenderEngineThreaded::create(CreateInstanceFactory factory,
RenderEngineType type) {
return std::make_unique<RenderEngineThreaded>(std::move(factory), type);
}
RenderEngineThreaded::RenderEngineThreaded(CreateInstanceFactory factory, RenderEngineType type)
: RenderEngine(type) {
ATRACE_CALL();
std::lock_guard lockThread(mThreadMutex);
mThread = std::thread(&RenderEngineThreaded::threadMain, this, factory);
}
我们注意到create传入的参数是一个CreateInstanceFactory ,它实际上就是一个std::function函数封装器(参见Android常用C++特性之std::function),它代表的就是传入的lambda表达式(参见Android常用C++特性之lambda表达式),而这个lambda表达式的作用就是创建一个SkiaGLRenderEngine。(std::lock_guard可参见Android常用C++特性之std::lock_guard)
稍微总结以下,就是RenderEngineThreaded::create接受两个参数,第一个是能够返回SkiaGLRenderEngine的函数指针(lambda表达式),第二个是SKIA_GL_THREADED类型。然后再依据这两个参数去构造出RenderEngineThreaded。构造函数内部使用std::thread(参见Android常用C++特性之std::thread)创建了一个线程:RenderEngineThreaded::threadMain(),而threadMain()接受的参数就是前面的lambda表达式。threadMain()内部直接调用lambda表达式来创建出SkiaGLRenderEngine并保存在mRenderEngine中。下面为了方便再贴一次lambda表达式:
//frameworks/native/libs/renderengine/RenderEngine.cpp
[skiaArgs]() {
return android::renderengine::skia::SkiaGLRenderEngine::create(skiaArgs);
}
//frameworks/native/libs/renderengine/skia/SkiaGLRenderEngine.cpp
std::unique_ptr<SkiaGLRenderEngine> SkiaGLRenderEngine::create(
const RenderEngineCreationArgs& args) {
// initialize EGL for the default display
// 省略
// initialize the renderer while GL is current
std::unique_ptr<SkiaGLRenderEngine> engine =
std::make_unique<SkiaGLRenderEngine>(args, display, ctxt, placeholder, protectedContext,
protectedPlaceholder);
ALOGI("OpenGL ES informations:");
ALOGI("vendor : %s", extensions.getVendor());
ALOGI("renderer : %s", extensions.getRenderer());
ALOGI("version : %s", extensions.getVersion());
ALOGI("extensions: %s", extensions.getExtensions());
ALOGI("GL_MAX_TEXTURE_SIZE = %zu", engine->getMaxTextureSize());
ALOGI("GL_MAX_VIEWPORT_DIMS = %zu", engine->getMaxViewportDims());
return engine;
}
可以看出,SkiaGLRenderEngine::create()做的事情比较简单,一个是初始化EGL环境以及加载opengles的真正实现libGLES_mali.so(这里对于EGL及opengles的知识点在以后的章节再展开讲解。),另一个则是直接构造出SkiaGLRenderEngine返回给调用者。我们可以看下打印的信息是个什么样子的:
I RenderEngine: OpenGL ES informations:
I RenderEngine: vendor : ARM
I RenderEngine: renderer : Mali-G57
I RenderEngine: version : OpenGL ES 3.2 v1.r34p0-01eac0.00b4816cebe6cac7791927d202fe00cc
I RenderEngine: extensions: GL_EXT_debug_marker GL_ARM_rgba8 GL_ARM_mali_shader_binary GL_OES_depth24 GL_OES_depth_texture GL_OES_depth_texture_cube_map GL_OES_packed_depth_stencil GL_OES_rgb8_rgba8 GL_EXT_read_format_bgra GL_OES_compressed_paletted_texture GL_OES_compressed_ETC1_RGB8_texture GL_OES_standard_derivatives GL_OES_EGL_image GL_OES_EGL_image_external GL_OES_EGL_image_external_essl3 GL_OES_EGL_sync GL_OES_texture_npot GL_OES_vertex_half_float GL_OES_required_internalformat GL_OES_vertex_array_object GL_OES_mapbuffer GL_EXT_texture_format_BGRA8888 GL_EXT_texture_rg GL_EXT_texture_type_2_10_10_10_REV GL_OES_fbo_render_mipmap GL_OES_element_index_uint GL_EXT_shadow_samplers GL_OES_texture_compression_astc GL_KHR_texture_compression_astc_ldr GL_KHR_texture_compression_astc_hdr GL_KHR_texture_compression_astc_sliced_3d GL_EXT_texture_compression_astc_decode_mode GL_EXT_texture_compression_astc_decode_mode_rgb9e5 GL_KHR_debug GL_EXT_occlusion_query_boolean GL_EXT_disjoint_timer_query GL_EXT_blend_minmax GL_EXT_discard_
I RenderEngine: GL_MAX_TEXTURE_SIZE = 16383
I RenderEngine: GL_MAX_VIEWPORT_DIMS = 16383
到此,RenderEngine就创建完毕了。我们以图形的方式稍微总结下,到目前为止,surfaceflinger总共创建了些什么: