Android12 显示框架之SurfaceFlinger启动(一)

目录:Android显示终极宝典

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总共创建了些什么:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值