概述
本系列是基于android Q 即android10
SurfaceFlinger学习笔记(一)应用启动流程
SurfaceFlinger学习笔记(二)之Surface
SurfaceFlinger学习笔记(三)之SurfaceFlinger进程
SurfaceFlinger学习笔记(四)之HWC2
SurfaceFlinger学习笔记(五)之HWUI
SurfaceFlinger学习笔记(六)之View Layout Draw过程分析
android底层用到了许多C++11,参考C++11简介
在Android中,一个窗口用一个Surface描述。多个窗口(窗口不一定都是Activity),需要同时显示,我们就需要将多个窗口进行合并。这就需要显示系统中重量级的服务SurfaceFlinger,Surfaceflinger控制窗口的合成,将多个窗口合并成一个,再送到LCD


SurfaceFlinger合成,有两种方式,Client和Device。Client就是Client合成完Layer后再将合成后的数据给到HWComposer,HWComposer此时做的工作很少,直接给到Display。Device则是将未合成的Layer,给到硬件合成的设备,合成完后再给到Display
应用启动流程回顾
详细流程参考
SurfaceFlinger学习笔记(一)应用启动流程
SurfaceFlinger学习笔记(二)之Surface和HWUI
- Activity::startActivityForResult调用mInstrumentation.execStartActivity调用ActivityManager.getService().startActivity
- ActivityManagerService::startActivityAsUser调用ActivityStartController.obtainStarter调用ActivityStarter.execute调用ActivityStarter.startActivityMayWait
ActivityStarter.startActivityUnchecked(这个方法里会根据启动标志位和Activity启动模式来决定如何启动一个Activity以及是否要调用deliverNewIntent方法通知Activity有一个Intent试图重新启动它)- ActivityStackSupervisor.resumeFocusedStackTopActivityLocked调用ActivityStack.resumeTopActivityInnerLocked
- 在ActivityStack.resumeTopActivityInnerLocked方法中会去判断是否有Activity处于Resume状态,如果有的话会先让这个Activity执行Pausing过程,然后再执行startSpecificActivityLocked方法启动要启动Activity
栈顶Activity执行onPause方法退出流程
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
- 在ActivityStack.startPausingLocked方法中通过ClientLifecycleManager的scheduleTransaction方法把PauseActivityItem事件加入到执行计划中,开始栈顶的pausing过程,然后执行ClientTransaction.schedule,ClientTransaction.schedule方法的mClient是一个IApplicationThread类型,ActivityThread的内部类ApplicationThread派生这个接口类并实现了对应的方法。所以直接跳转到ApplicationThread中的scheduleTransaction方法。ActivityThread类中并没有定义scheduleTransaction方法,所以调用的是他父类ClientTransactionHandler的scheduleTransaction方法
- 在ClientTransactionHandler.scheduleTransaction方法中调用了sendMessage方法,这个方法是一个抽象方法,其实现在ClientTransactionHandler派生类的ActivityThread中,ActivityThread.sendMessage方法会把消息发送给内部名字叫H的Handler
- Handler H的实例接收到EXECUTE_TRANSACTION消息后调用TransactionExecutor.execute方法切换Activity状态。TransactionExecutor.execute方法里面先执行Callbacks,然后改变Activity当前的生命周期状态。此处由于没有Callback所以直接跳转executeLifecycleState方法。
- 在executeLifecycleState方法里面,会先去调用TransactionExecutor.cycleToPath执行当前生命周期状态之前的状态,然后执行ActivityLifecycleItem.execute方法。由于是从ON_RESUME状态到ON_PAUSE状态切换,中间没有其他状态,cycleToPath这个情况下没有做什么实质性的事情,直接执行execute方法。前面在ActivityStack.startPausingLocked方法里面scheduleTransaction传递的是PauseActivityItem对象,所以executeLifecycleState方法里调用的execute方法其实是PauseActivityItem.execute方法。
- 在PauseActivityItem.execute方法中调用ActivityThread.handlePauseActivity方法,经过一步步调用来到performPauseActivity方法,在这个方法中会先去判断是否需要调用callActivityOnSaveInstanceState方法来保存临时数据,然后执行Instrumentation.callActivityOnPause方法继续执行pasue流程。
- Instrumentation.callActivityOnPause方法中直接调用Activity.performPause
Activity所在的应用进程启动过程
- ActivityStackSupervisor.startSpecificActivityLocked方法,在这个方法中会去根据进程和线程是否存在判断App是否已经启动,如果已经启动,就会调用realStartActivityLocked方法继续处理。如果没有启动则调用ActivityManagerService.startProcessLocked方法创建新的进程处理。接下来跟踪一下一个新的Activity是如何一步步启动的。
- ActivityManagerService.startProcessLocked方法经过多次跳转最终会通过Process.start方法来为应用创建进程。经过一步步调用,可以发现其最终调用了Zygote并通过socket通信的方式让Zygote进程fork出一个新的进程,并根据传递的”android.app.ActivityThread”字符串,反射出该对象并执行ActivityThread的main方法对其进行初始化
- 在ActivityThread.main方法中对ActivityThread进行了初始化,创建了主线程的Looper对象并调用Looper.loop()方法启动Looper,把自定义Handler类H的对象作为主线程的handler。接下来跳转到ActivityThread.attach方法
- 在ActivityThread.attach方法中,首先会通过ActivityManagerService为这个应用绑定一个Application,然后添加一个垃圾回收观察者,每当系统触发垃圾回收的时候就会在run方法里面去计算应用使用了多少内存,如果超过总量的四分之三就会尝试释放内存。最后,为根View添加config回调接收config变化相关的信息
- 在ActivityManagerService.attachApplication方法中经过多次跳转执行到ActivityStackSupervisor.attachApplicationLocked调用ActivityStackSupervisor.realStartActivityLocked方法。在ActivityStackSupervisor.realStartActivityLocked方法中为ClientTransaction对象添加LaunchActivityItem的callback,然后设置当前的生命周期状态,最后调用ClientLifecycleManager.scheduleTransaction方法执行
- 调用ClientLifecycleManager.scheduleTransaction方法之后具体是如何执行的前面已经分析过了,这里就不再分析了。callback后跳转到LaunchActivityItem.execute,然后执行到ActivityThread.handleLaunchActivity
- 在ActivityThread.performLaunchActivity方法中首先对Activity的ComponentName、ContextImpl、Activity以及Application对象进行了初始化并相互关联,然后设置Activity主题,最后调用Instrumentation.callActivityOnCreate方法。
- 从Instrumentation.callActivityOnCreate方法继续追踪,跳转到Activity.performCreate方法,在这里我们看到了Activity.onCreate方法。
- 至此executeCallbacks执行完毕,开始执行executeLifecycleState方法。先执行cycleToPath方法,生命周期状态是从ON_CREATE状态到ON_RESUME状态,中间有一个ON_START状态,所以会执行ActivityThread.handleStartActivity方法。
10 . 执行完毕cycleToPath,开始执行ResumeActivityItem.execute方法。经过上面的多次跳转最终调用到Activity.onResume方法,Activity启动完毕。
Surface相关的基础知识介绍

- 显示层(Layer)和屏幕组成

- 屏幕位于一个三维坐标系中,其中Z轴从屏幕内指向屏幕外
- 编号为①②③的矩形块叫显示层(Layer)。每一层有自己的属性,例如颜色、透明度、所处屏幕的位置、宽、高等。除了属性之外,每一层还有自己对应的显示内容,也就是需要显示的图像。
- 在Android中,Surface系统工作时,会由SurfaceFlinger对这些按照Z轴排好序的显示层进行图像混合,混合后的图像就是在屏幕上看到的美妙画面了
Surface系统提供了三种属性,一共四种不同的显示层
- 第一种属性是eFXSurfaceNormal属性,大多数的UI界面使用的就是这种属性。它有两种模式:
1)Normal模式,这种模式的数据,是通过前面的mView.draw(canvas)画上去的。这也是绝大多数UI所采用的方式。
2)PushBuffer模式,这种模式对应于视频播放、摄像机摄录/预览等应用场景。以摄像机为例,当摄像机运行时,来自Camera的预览数据直接push到Buffer中,无须应用层自己再去draw了。- 第二种属性是eFXSurfaceBlur属性,这种属性的UI有点朦胧美,看起来很像隔着一层毛玻璃。
- 第三种属性是eFXSurfaceDim属性,这种属性的UI看起来有点暗,好像隔了一层深色玻璃。从视觉上讲,虽然它的UI看起来有点暗,但并不模糊。而eFXSurfaceBlur不仅暗,还有些模糊。
关于Surface系统的显示层属性定义,读者可参考ISurfaceComposer.h
PageFlipping
PageFlipping的中文名叫画面交换,其操作过程如下所示:
- 分配一个能容纳两帧数据的缓冲,前面一个缓冲叫FrontBuffer,后面一个缓冲叫BackBuffer。
- 消费者使用FrontBuffer中的旧数据,而生产者用新数据填充BackBuffer,二者互不干扰。
- 当需要更新显示时,BackBuffer变成FrontBuffer,FrontBuffer变成BackBuffer。如此循环,这样就总能显示最新的内容了。这个过程很像我们平常的翻书动作,所以它被形象地称为PageFlipping。
说白了,PageFlipping其实就是使用了一个只有两个成员的帧缓冲队列,以后在分析数据传输的时候还会见到诸如dequeue和queue的操作
图像混合
Surface系统支持软硬两个层面的图像混合
- 软件层面的混合:例如使用copyBlt进行源数据和目标数据的混合
- 硬件层面的混合:使用Overlay系统提供的接口
无论是硬件还是软件层面,都需将源数据和目标数据进行混合,混合需考虑很多内容,例如源的颜色和目标的颜色叠加后所产生的颜色
copyBlt和Overlay
- copyBlt,从名字上看,是数据拷贝,它也可以由硬件实现,例如现在很多的2D图形加速就是将copyBlt改由硬件来实现,以提高速度的。但不必关心这些,我们只需关心如何调用copyBlt相关的函数进行数据混合即可
- Overlay方法必须有硬件支持才可以,它主要用于视频的输出,例如视频播放、摄像机摄像等,因为视频的内容往往变化很快,所以如改用硬件进行混合效率会更高
应用进程
- 应用进程的SurfaceSession 的创建会调用 JNI,在 JNI 调用 nativeCreate,创建 SurfaceComposerClient 对象, 作为跟 SurfaceFlinger 通信的代理对象
* frameworks/base/core/jni/android_view_SurfaceSession.cpp
static jlong nativeCreate(JNIEnv* env, jclass clazz) {
SurfaceComposerClient* client = new SurfaceComposerClient();
client->incStrong((void*)nativeCreate);
return reinterpret_cast<jlong>(client);
}
* frameworks/native/libs/gui/SurfaceComposerClient.cpp
void SurfaceComposerClient::onFirstRef() {
//getComposerService() 将返回 SF 的 Binder 代理端的 BpSurfaceFlinger 对象
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
if (sf != nullptr && mStatus == NO_INIT) {
sp<ISurfaceComposerClient> conn;
//先调用 SF 的 createConnection()
conn = sf->createConnection();
if (conn != nullptr) {
mClient = conn;
mStatus = NO_ERROR;
}
}
}
ComposerService:
定义:frameworks\native\include\private\gui\ComposerService.h
实现:frameworks\native\libs\gui\SurfaceComposerClient.cpp
作用:通过Singleton,定义单例类,初始化时候调用connectLocked,获取SurfaceFlinger服务代理ISurfaceComposer,并注册死亡通知
SurfaceComposerClient:
定义:frameworks\native\include\gui\SurfaceComposerClient.h
实现:frameworks\native\libs\gui\SurfaceComposerClient.cpp
作用:这个对象会和SurfaceFlinger进行交互,因为SurfaceFlinger派生于SurfaceComposer
通过ComposerService和服务端通信,并通过调用binder的createConnection获取ISurfaceComposerClient
onFirstRef:第一次引用的时候,调用binder的createConnection才真正的建立连接,向服务端创建一个ISurfaceComposerClient类型的mClient,负责和服务端通信
- java层的SurfaceControl在构造时调用jni方法,nativeCreate,传递一个SurfaceSession,然后通过SurfaceSession 获取SurfaceComposerClient,SurfaceSession 的创建会调用 JNI,在 JNI 调用 SurfaceSession.nativeCreate,创建 SurfaceComposerClient 对象, 作为跟 SurfaceFlinger 通信的代理对象,然后调用SurfaceComposerClient.createSurfaceChecked创建一个native层的SurfaceControl
* frameworks/base/core/jni/android_view_SurfaceControl.cpp
static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj ...) {
sp<SurfaceComposerClient> client;
if (sessionObj != NULL) {
client = android_view_SurfaceSession_getClient(env, sessionObj);
} else {
client = SurfaceComposerClient::getDefault();//调用内部类DefaultComposerClient创建一个单例SurfaceComposerClient
}
SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject);
sp<SurfaceControl> surface;
LayerMetadata metadata;
Parcel* parcel = parcelForJavaObject(env, metadataParcel);
if (parcel && !parcel->objectsCount()) {
status_t err = metadata.readFromParcel(parcel);
...
}
status_t err = client->createSurfaceChecked(
String8(name.c_str()), w, h, format, &surface, flags, parent, std::move(metadata));
...
surface->incStrong((void *)nativeCreate);
return reinterpret_cast<jlong>(surface.get());
}
* frameworks/native/libs/gui/SurfaceComposerClient.cpp
void SurfaceComposerClient::onFirstRef() {
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
if (sf != nullptr && mStatus == NO_INIT) {
sp<ISurfaceComposerClient> conn;
conn = sf->createConnection();
if (conn != nullptr) {
mClient = conn;
mStatus = NO_ERROR;
}
}
}
status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,PixelFormat format,sp<SurfaceControl>* outSurface, uint32_t flags,SurfaceControl* parent,LayerMetadata metadata) {
...
err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),
&handle, &gbp);
if (err == NO_ERROR) {
*outSurface = new SurfaceControl(this, handle, gbp, true /* owned */);
}
return err;
}
这里和服务端通信的接口有和ISurfaceComposer.createConnection
SurfaceFlinger进程
进程启动:
SurfaceFlinger是一个系统级的服务,Android系统启动的过程中就会启动SurfaceFlinger,通过init.rc配置bin启动,然后调用到main_surfaceflinger的main中,然后通过surfaceflinger::createSurfaceFlinger进入到SurfaceFlingerFactory启动SurfaceFlinger主服务,并调用init
SurfacFlinger进程中主要4个服务:
- startGraphicsAllocatorService主要是启动allocator
- DisplayService,主要负责DisplayEvent的处理,在main_surfaceflinger中启动
- SurfaceFlinger,主要显示相关的,最重要的服务

Client和SurfaceFlinger的关系:

应用端SurfaceComposerClient通过接口ISurfaceComposerClient和SurfaceFlinger的Client建立联系。
服务端创建Client后,把指针返回给应用端,并保存为ISurfaceComposerClient。
应用端通过的ComposerService通过ISurfaceComposer和SurfaceFlinger建立联系。
- SurfaceFlinger初始化流程
- onFirstRef中创建了自己的消息队列mEventQueue,SurfaceFlinger的消息队列
- 启动EventThread,主要是用以处理和分发Vsync。调用mScheduler的createConnection函数创建的,它的名字是"app"
- 初始化了Client合成模式(GPU)合成时,需要用到的RenderEngine
- 初始化HWComposer,注册回调接口registerCallback,HAL会回调一些方法。
- 如果是VR模式,创建mVrFlinger
- 创建mEventControlThread,处理Event事件,如Vsync事件和hotplug事件。
- 初始化显示设备initializeDisplays
* frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::init() {
mAppConnectionHandle = mScheduler->createConnection("app", mPhaseOffsets->getCurrentAppOffset(), resyncCallback, impl::EventThread::InterceptVSyncsCallback());
mSfConnectionHandle = mScheduler->createConnection("sf", mPhaseOffsets->getCurrentSfOffset(), resyncCallback,
[this](nsecs_t timestamp) {
mInterceptor->saveVSyncEvent(timestamp); });
mEventQueue->setEventConnection(mScheduler->getEventConnection(mSfConnectionHandle));
mVsyncModulator.setSchedulerAndHandles(mScheduler.get(), mAppConnectionHandle.get(), mSfConnectionHandle.get());
...
renderEngineFeature |= (useColorManagement ? renderengine::RenderEngine::USE_COLOR_MANAGEMENT : 0);
renderEngineFeature |= (useContextPriority ? renderengine::RenderEngine::USE_HIGH_PRIORITY_CONTEXT : 0);
renderEngineFeature |= (enable_protected_contents(false) ? renderengine::RenderEngine::ENABLE_PROTECTED_CONTEXT : 0);
// 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(static_cast<int32_t>(defaultCompositionPixelFormat),renderEngineFeature, maxFrameBufferAcquiredBuffers));
LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay, "Starting with vr flinger active is not currently supported.");
mCompositionEngine->setHwComposer(getFactory().createHWComposer(getBE().mHwcServiceName));
mCompositionEngine->getHwComposer().registerCallback(this, getBE().mComposerSequenceId);
// Process any initial hotplug and resulting display changes.
processDisplayHotplugEventsLocked();
..
// initialize our drawing state
mDrawingState = mCurrentState;
// set initial conditions (e.g. unblank default device)
initializeDisplays();
...
}
EventThread
EventThread并不是一个线程,它的内部有一个线程,这个线程就是用来处理底层Vsync的接收以及分发的,这个线程是一个死循环,当它没收到事件请求时会通过C++条件变量调用wait陷入等待状态
应用层请求Vsync的过程其实就是通过这个条件变量调用notify唤醒EventThread内部这个线程,然后从mPendingEvents中获取到Vsync信息分发给感兴趣的进程
Scheduler.createConnection
- createConnection这个函数在SurfaceFlinger中调用了两次,一次是创建"app"的Connection,一次是创建"sf"的Connection,我们可以理解为创建两套连接,一套给app使用,一套个surfaceFlinger使用,两套连接的用connectionName以及id进行标识,(id为0,connectionName等于”app“的)与(id为1,connectionName等于”sf“的)
- createConnection函数根据connectionName创建EventThread,根据EventThread创建EventThreadConnection,然后创建ConnectionHandle,根据ConnectionHandle,EventThreadConnection,EventThread最终创建Connection,并以id为key,Connection为value加入到mConnections的map中,最终返回”app“的ConnectionHandle
EventThreadConnection
继承BnDisplayEventConnection,为DisplayEvent的服务端,构造函数中最重要的就是创建了mChannel,mChannel是gui::BitTube类型
EventThreadConnection代表应用层到SurfaceFlinger进程的连接,每一个上层的ViewRootImpl都对应一个EventThreadConnection,因为每个View视图都需要Vsync来开启绘制工作
gui::BitTube
gui::BitTube的构造函数:这里传递的DefaultSize为4kb,定义在DEFAULT_SOCKET_BUFFER_SIZE
BitTube的init函数主要是通过socketpair函数创建一对socket,socketpair()函数用于创建一对无名的、相互连接的socket,如果成功,则返回0,创建好的socket分别是sv[0]和sv[1];否则返回-1
- 这对socket可以用于全双工通信,每一个socket既可以读也可以写。例如,可以往sv[0]中写,从sv[1]中读,或者从sv[1]中写,从sv[0]中读
- 如果往一个socket(如sv[0])中写入后,再从该socket读时会阻塞,只能在另一个socket中(sv[1])上读成功
- 读、写操作可以位于同一个进程,也可以分别位于不同的进程
通过socketpair创建好了一对socket之后,再通过setsockopt对socket进行设置,再调用fcntl函数针对socket描述符提供控制
首先应用层想要绘制UI,则需要向native层注册接收下一个到来的Vsync,注册的过程是通过EventThreadConnection的Bp端最终调用到SurfaceFlinger进程的EventThread的requestNextVsync函数
* frameworks/native/services/surfaceflinger/Scheduler/Scheduler.cpp
sp<Scheduler::ConnectionHandle> Scheduler


1514

被折叠的 条评论
为什么被折叠?



