荐 Android 图形架构 之二—— SurfaceFlinger 启动和连接
前言
Android 图形架构 之一 ——概述
Android 图形架构 之二—— SurfaceFlinger 创建和连接
Android 图形架构 之三—— 创建Surface
Android 图形架构 之四——图形缓冲区GraphicBuffer
Android 图形架构 之五——Activity、WindowManagerService、Surface的关系
Android图形架构 之六——硬件VSync、VSync-app、Vsync-sf
Android图形架构 之七——SurfaceFlinger 合成Layer
上一篇文章从全局来分析了Android 图形架构,本篇文章来分析SurfaceFlinger,surface的创建、图像的处理,管理设备的帧缓冲区等等,它是图像流的消费者,是本系列文章的核心
一、SurfaceFlinger的启动过程
启动概述
SurfaceFlinger服务是一个独立进程。
关于硬件方面的服务都在 frameworks/native/services/ 文件夹下,例如:audiomanager、powermanager、inputflinger、sensorservice、surfaceflinger等。我们接下来
SurfaceFlinger服务配置,位于frameworks/native/services/surfaceflinger/surfaceflinger.rc中:
service surfaceflinger /system/bin/surfaceflinger
class core animation
user system
group graphics drmrpc readproc
onrestart restart zygote
writepid /dev/stune/foreground/tasks
socket pdx/system/vr/display/client stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0
socket pdx/system/vr/display/manager stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0
socket pdx/system/vr/display/vsync stream 0666 system graphics u:object_r:pdx_display_vsync_endpoint_socket:s0
SurfaceFlinger服务配置,位于frameworks/native/services/surfaceflinger/Android.mk 中:
###############################################################
# build surfaceflinger's executable
include $(CLEAR_VARS)
LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\"
# SurfaceFlinger启动文件
LOCAL_SRC_FILES:= \
main_surfaceflinger.cpp
LOCAL_SHARED_LIBRARIES := \
libsurfaceflinger \
libcutils \
liblog \
libbinder \
libutils
# SurfaceFlinger是个动态库
LOCAL_MODULE:= surfaceflinger
ifdef TARGET_32_BIT_SURFACEFLINGER
LOCAL_32_BIT_ONLY := true
endif
include $(BUILD_EXECUTABLE)
从Makefile文件可以看出,相关依赖和主文件会被编译成libsurfaceflinger.so,然后SurfaceFlinger是对库的一个“封装调用”,里面有个main_surfaceflinger.cpp,我们可以沿着它的main函数往下分析
SurfaceFlinger流程图,
启动过程
SurfaceFlinger的main函数在framework/native/services/surfaceflinger/main_surfaceflinger.cpp中:
代码一:
int main(int, char**) {
// When SF is launched in its own process, limit the number of
// binder threads to 4.
//在该进程设置了binder线程池最大数为4
ProcessState::self()->setThreadPoolMaxThreadCount(4);
// start the thread pool
//将当前线程加入到这个Binder线程池中去。例如:app进程通过binder通信,通知SurfaceFlinger进行渲染
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
// instantiate surfaceflinger
//创建一个SurfaceFlinger强引用对象
sp<SurfaceFlinger> flinger = new SurfaceFlinger();
#if defined(HAVE_PTHREADS)
setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
#endif
set_sched_policy(0, SP_FOREGROUND);
// initialize before clients can connect
//SurfaceFlinger 初始化
flinger->init();
// publish surface flinger
//把SurfaceFlinger服务注册到ServiceManager中
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);
// run in this thread
//运行线程,无限循环等待数据到来
flinger->run();
return 0;
}
接下来重点分析 创建SurfaceFlinger对象,执行init函数,和运行UI渲染流程。
创建SurfaceFlinger对象
new一个SurfaceFlinger对象,并赋给强引用指针。我们先看看它的构造函数,位于frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp中:
代码二:
SurfaceFlinger::SurfaceFlinger()
: BnSurfaceComposer(),
mTransactionFlags(0),
mTransactionPending(false),
mAnimTransactionPending(false),
mLayersRemoved(false),
mRepaintEverything(0),
mRenderEngine(NULL),
mBootTime(systemTime()),
mVisibleRegionsDirty(false),
mHwWorkListDirty(false),
mAnimCompositionPending(false),
mDebugRegion(0),
mDebugDDMS(0),
mDebugDisableHWC(0),
mDebugDisableTransformHint(0),
mDebugInSwapBuffers(0),
mLastSwapBufferTime(0),
mDebugInTransaction(0),
mLastTransactionTime(0),
mBootFinished(false),
mPrimaryHWVsyncEnabled(false),//主显屏硬件VSync信号关闭
mHWVsyncAvailable(false),
mDaltonize(false),
mHasColorMatrix(false)
{
ALOGI("SurfaceFlinger is starting");
//一些调试变量,忽略一下内容
// debugging stuff...
char value[PROPERTY_VALUE_MAX];
property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
mGpuToCpuSupported = !atoi(value);
property_get("debug.sf.showupdates", value, "0");
mDebugRegion = atoi(value);
property_get("debug.sf.ddms", value, "0");
mDebugDDMS = atoi(value);
if (mDebugDDMS) {
if (!startDdmConnection()) {
// start failed, and DDMS debugging not enabled
mDebugDDMS = 0;
}
}
ALOGI_IF(mDebugRegion, "showupdates enabled");
ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
}
SurfaceFlinger类继承了BnSurfaceComposer类,而后者是一个实现了ISurfaceComposer接口的Binder本地对象类。 该对象被赋值给一个强指针引用flinger
当一个对象第一次被一个强指针引用时,该对象的成员函数onFirstRef就会被调用。下面来看SurfaceFlinger的成员函数onFirstRef
代码三:
// mEventQueue在SurfaceFlinger.h中声明
// these are thread safe
mutable MessageQueue mEventQueue;
// SurfaceFlinger.cpp中定义
void SurfaceFlinger::onFirstRef()
{
mEventQueue.init(this);
}
MessageQueue 类在frameworks/native/services/surfaceflinger/MessageQueue.h中定义,init函数如下:
代码四:
void MessageQueue::init(const sp<SurfaceFlinger>& flinger)
{
mFlinger = flinger;
mLooper = new Looper(true);
mHandler = new Handler(*this);
}
调用MessageQueue的init,在MessageQueue中建了一个Looper和Handler,注意不是Java中的,native实现的。SurfaceFlinger的核心就是接收消息,处理消息。
执行init函数
回到代码一,继续往下执行init函数
void SurfaceFlinger::init() {
ALOGI( "SurfaceFlinger's main thread ready to run. "
"Initializing graphics H/W...");
status_t err;
Mutex::Autolock _l(mStateLock);
//初始化OpenGL 图形库相关配置
// initialize EGL for the default display 将EGL初始化成默认的显示,默认是主屏幕,编号为0
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(mEGLDisplay, NULL, NULL);
//创建显示设备的抽象代表,负责和显示设备打交道
// Initialize the H/W composer object. There may or may not be an
// actual hardware composer underneath.
mHwc = new HWComposer(this,
*static_cast<HWComposer::EventHandler *>(this));
// get a RenderEngine for the given display / config (can't fail)
mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID());
// retrieve the EGL context that was selected/created
mEGLContext = mRenderEngine->getEGLContext();
LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
"couldn't create EGLContext");
// initialize our non-virtual displays
//创建显示设备对象
for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
// set-up the displays that are already connected
if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
// All non-virtual displays are currently considered secure.
bool isSecure = true;
createBuiltinDisplayLocked(type);
wp<IBinder> token = mBuiltinDisplays[i];
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer,
new GraphicBufferAlloc());
sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i,
consumer);
int32_t hwcId = allocateHwcDisplayId(type);
sp<DisplayDevice> hw = new DisplayDevice(this,
type, hwcId, mHwc->getFormat(hwcId), isSecure, token,
fbs, producer,
mRenderEngine->getEGLConfig());
if (i > DisplayDevice::DISPLAY_PRIMARY) {
// FIXME: currently we don't get blank/unblank requests
// for displays other than the main display, so we always
// assume a connected display is unblanked.
ALOGD("marking display %zu as acquired/unblanked", i);
hw->setPowerMode(HWC_POWER_MODE_NORMAL);
}
mDisplays.add(token, hw);
}
}
// make the GLContext current so that we can create textures when creating Layers
// (which may happens before we render something)
getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
// start the EventThread
//创建两个软件VSync,它们会根据硬件的VSync 来设置频率,稳定后,硬件VSync就会停止,使用软件生成的VSync
//app的VSync信号,也就是Systrace中的VSync-app,它最终是发往到choreographer,主要处理三件事情INPUT、ANIMATION、TRAVERSAL
sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
vsyncPhaseOffsetNs, true, "app");
mEventThread = new EventThread(vsyncSrc);
//SF的VSync信号,也就是Systrace中的VSync-sf,,它最终是发往到SurfaceFlinger,读取GraphicBuffer,最后通过Gralloc 把数据写入FrameBuffer
sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
sfVsyncPhaseOffsetNs, true, "sf");
mSFEventThread = new EventThread(sfVsyncSrc);
//SF的VSync信号控制逻辑也要放入mEventQueue消息队列
mEventQueue.setEventThread(mSFEventThread);
//VSync信号闸刀控制线程
mEventControlThread = new EventControlThread(this);
mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
// set a fake vsync period if there is no HWComposer
//如果硬件设备检测有问题,或者没有硬件设备驱动提供Vsync信号,则设置软件VSync信号
if (mHwc->initCheck() != NO_ERROR) {
mPrimaryDispSync.setPeriod(16666667);
}
// initialize our drawing state
mDrawingState = mCurrentState;
// set initial conditions (e.g. unblank default device)
//初始化显示设备,调用initializeDisplays完成
initializeDisplays();
// start boot animation
//启动开机动画,调用了startBootAnim函数,只是设置了两个属性,其中一个ctl.start是启动了bootanim进程
startBootAnim();
}
关于VSync 信号,后面会详细讲解
SurfaceFlinger 的run函数
再次回到代码一,执行了flinger->run()
,运行线程,等待数据。下面就来看看SurfaceFlinger 的run函数
void SurfaceFlinger::run() {
do {
waitForEvent();
} while (true);
}
void SurfaceFlinger::waitForEvent() {
mEventQueue.waitMessage();
}
调用了EventQueue的waitMessage方法,记住这里是在主线程中循环调用的。
void MessageQueue::waitMessage() {
do {
//flushCommands主要是清理工作的
IPCThreadState::self()->flushCommands();
//pollOnce是消息机制,主要调用了epoll_wait函数,会阻塞,阻塞完了会分发消息队列中的消息
int32_t ret = mLooper->pollOnce(-1);
switch (ret) {
case Looper::POLL_WAKE:
case Looper::POLL_CALLBACK:
continue;
case Looper::POLL_ERROR:
ALOGE("Looper::POLL_ERROR");
case Looper::POLL_TIMEOUT:
// timeout (should not happen)
continue;
default:
// should not happen
ALOGE("Looper::pollOnce() returned unknown status %d", ret);
continue;
}
} while (true);
}
发送消息
调用SurfaceFlinger 的postMessageSync(msg); 来发送消息
status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
nsecs_t reltime, uint32_t /* flags */) {
//向mEventQueue,即MessageQueue中发送消息
status_t res = mEventQueue.postMessage(msg, reltime);
//这里等着,同步就在同步函数中等着
if (res == NO_ERROR) {
msg->wait();
}
return res;
}
处理消息
从上面waitMessage得知,消息处理都位于里面无限循环处的的int32_t ret = mLooper->pollOnce(-1);我们追寻到Looper中的pollOnce函数,位于system/core/libutils/Looper.cpp中:
int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
int result = 0;
for (;;) {
...
result = pollInner(timeoutMillis);
}
}
调用Looper 的函数 pollInner
int Looper::pollInner(int timeoutMillis) {
// Invoke pending message callbacks.
mNextMessageUptime = LLONG_MAX;
while (mMessageEnvelopes.size() != 0) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);
if (messageEnvelope.uptime <= now) {
// Remove the envelope from the list.
// We keep a strong reference to the handler until the call to handleMessage
// finishes. Then we drop it so that the handler can be deleted *before*
// we reacquire our lock.
{ // obtain handler
sp<MessageHandler> handler = messageEnvelope.handler;
Message message = messageEnvelope.message;
//把头删除啊
mMessageEnvelopes.removeAt(0);
mSendingMessage = true;
mLock.unlock();
#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d",
this, handler.get(), message.what);
#endif
//处理消息啊
handler->handleMessage(message);
} // release handler
mLock.lock();
mSendingMessage = false;
result = ALOOPER_POLL_CALLBACK;
} else {
// The last message left at the head of the queue determines the next wakeup time.
mNextMessageUptime = messageEnvelope.uptime;
break;
}
}
}
发给SF的消息被封装在MessageEnvelope结构中,SF一直在mMessageEnvelopes队列中从头部取出消息,然后执行,即handler->handleMessage(message),这个即是我们上面提到的framework/native/services/surfaceflinger/MessageQueue.cpp中:
void MessageBase::handleMessage(const Message&) {
this->handler();
//打开栅栏
barrier.open();
};
后面会以创建surface为例,来详细介绍SurfaceFlinger是如何 发送处理消息的
二、SurfaceFlinger的连接过程
每一个有UI的Android应用程序都需要与SurfaceFlinger服务建立一个连接,以便可以通过这个连接来请求SurfaceFlinger服务为它创建和渲染Surface。
应用程序和SurfaceFlinger服务 是运行在不同的进程中,所以在连接的过程中,涉及到很多进程间通信,主要联系可参考下图:
在下面介绍的很多类,会使用类继承的接口来表示,下图是主要类关系,蓝色表示在客户端,紫色表示服务端
当应用程序需要请求SurfaceFlinger服务时,首先需要构造SurfaceComposerClient对象,通过SurfaceComposerClient对象就可以访问SurfaceFlinger服务了。基本的服务流程都是这么走的,我们看一下SurfaceComposerClient的构造函数:
代码一:
SurfaceComposerClient::SurfaceComposerClient()
: mStatus(NO_INIT), mComposer(Composer::getInstance())
{
}
SurfaceComposerClient 继承于RefBase类,在创建SurfaceComposerClient对象,系统第一次引用SurfaceComposerClient对象时,onFirstRef函数自动调用,我们看一下它的onFirstRef
代码二:
void SurfaceComposerClient::onFirstRef() {
//1、获得SurfaceFlinger服务,从上图可知SurfaceFlinger 继承了ISurfaceComposer
sp<ISurfaceComposer> sm(ComposerService::getComposerService());
if (sm != 0) {
//2、与SurfaceFlinger建立连接
sp<ISurfaceComposerClient> conn = sm->createConnection();
if (conn != 0) {
//之后就可以通过这个连接,进行通信
mClient = conn;
mStatus = NO_ERROR;
}
}
}
来看一下获取SurfaceFlinger服务的过程
代码三:
sp<ISurfaceComposer> ComposerService::getComposerService() {
//ComposerService 是单例模式
ComposerService& instance = ComposerService::getInstance();
Mutex::Autolock _l(instance.mLock);
if (instance.mComposerService == NULL) {
//获取SurfaceFlinger服务的代理对象
ComposerService::getInstance().connectLocked();
assert(instance.mComposerService != NULL);
ALOGD("ComposerService reconnected");
}
return instance.mComposerService;
}
代码四:
void ComposerService::connectLocked() {
const String16 name("SurfaceFlinger");
//获取SurfaceFlinger服务的代理对象,这里属于binder通信的代理对象获取过程,就不跟踪下去了
//mComposerService中保存了 该代理对象
while (getService(name, &mComposerService) != NO_ERROR) {
usleep(250000);
}
assert(mComposerService != NULL); //省略了一些东西。。。
}
这里我们回到代码一:sp<ISurfaceComposerClient> conn = sm->createConnection();
因为在代码一中,我们获取到的SurfaceFlinger服务的代理对象,是继承了BpSurfaceComposer,所以调用 sm->createConnection()
会执行到下面的函数。
代码五:
class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
{
...省略若干代码。。。
virtual sp<ISurfaceComposerClient> createConnection()
{
Parcel data, reply;
//写入数据
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
//发送进程通信的数据
remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
//等待服务端的进程通信返回后(就是代码六返回),才会执行下面的语句
//进程通信的返回值reply.readStrongBinder()
//interface_cast 该函数是为了获取binder通信中代理对象,通过它可获得binder实体对象 对应的binder代理对象
return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
}
...省略若干代码。。。
}
进程通信服务端的处理,也就是SurfaceFlinger服务 ,处理从客户端发来的CREATE_CONNECTION消息
代码六:
status_t BnSurfaceComposer::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
case CREATE_CONNECTION: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
//createConnection 该函数的实现在SurfaceFlinger.cpp中
sp<IBinder> b = IInterface::asBinder(createConnection());
//把结果写入reply中,在客户端就会收到这个返回值,接着就会执行代码五的return 语句
reply->writeStrongBinder(b);
return NO_ERROR;
}
}
}
接着,我们到SurfaceFlinger中看看createConnection的具体实现:
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {
//创建Client,持有了SurfaceFlinger的强引用对象
//接着调用了initClient,
return initClient(new Client(this));
}
//进行一些检查,然后返回client,这里的client 是Binder实体对象,可以理解为服务端
static sp<ISurfaceComposerClient> initClient(const sp<Client>& client) {
status_t err = client->initCheck();
if (err == NO_ERROR) {
return client;
}
return nullptr;
}
至此,建立连接的流程就分析完了,之后再应用程序端,就可以使用Client的Binder代理对象,与SurfaceFlinger进行通信了
拓展
在app端请求与SurfaceFlinger中创建连接时,在SurfaceFlinger会创建Client对象,每个app 对应一个Client
上面在app端 拿到了Client的代理对象,之后可通过它来进行Binder 通信,但是注意,这个通信只是通知,具体内容的数据传输,使用的是匿名共享内存,因为UI的数据量很大,使用Binder通信效率低
为了方便使用,将这块匿名共享内存 结构化为SharedClient
在每一个SharedClient里面,有至多31个SharedBufferStack。字面上来看,SharedBufferStack就是共享缓冲区堆栈。怎么理解呢?首先,Shared表明这个堆栈共享的。那么由谁来共享呢?当然就是Android应用程序和SurfaceFlinger服务了。其次,Buffer表明这个堆栈的内容是缓冲区。什么样的缓冲区呢?当然就是用来描述UI元数据的缓冲区了。再者,Stack表明用来描述UI元数据的缓冲区是需要按照一定的规则来访问的。综合起来,我们就可以认为每一个SharedBufferStack就是用来描述一系列需要按照一定规则来访问的缓冲区。
过去绘制UI的时候,都会采用一种称为“双缓冲”的技术。双缓冲意味着要使用两个缓冲区,其中一个称为Front Buffer,另外一个称为Back Buffer。UI总是先在Back Buffer中绘制,然后再和Front Buffer交换,渲染到显示设备中。SurfaceFlinger服务只不过是将传统的“双缓冲”技术升华和抽象为了一个SharedBufferStack。可别小看了这个升华和抽象,有了SharedBufferStack之后,SurfaceFlinger服务就可以使用N个缓冲区技术来绘制UI了。N值的取值范围为2到16。例如,在Android 2.3中,N的值等于2,而在Android 4.1中,据说就等于3了。
参考:
Android4.4深入浅出之SurfaceFlinger与Client通信框架(一)
Android 图形显示简述
Android SurfaceFlinger 学习之路(四)----SurfaceFlinger服务的启动与连接过程
概述和学习计划
本文地址:https://blog.csdn.net/xx326664162/article/details/108880222
下一篇: 悦跑圈步幅如何看 跑友进阶技巧介绍