您的位置:首页 > 产品设计 > UI/UE

Android 7.1 GUI系统-surfaceflinger(四)

2017-11-25 19:53 465 查看
surfaceflinger的启动:

frameworks/native/services/surfaceflinger/surfaceflinger.rc
service surfaceflinger /system/bin/surfaceflinger
class core
user system
group graphics drmrpc readproc
onrestart restart zygote
writepid /dev/stune/foreground/tasks


surfaceflinger属于系统的底层支撑服务,应该在系统开机的早期就要起来,比如开机动画的绘制就要依赖surfaceflinger,从它的rc文件可知,这个服务的class是core,所以在解析init.rc时,通过class_startcore就启动了所有class是core的服务。而且在surfaceflinger重启时,关键进程zygote也会重启。
插播截取的一段init.rc的代码看下究竟:
system/core/rootdir/init.rc
//长按power键,Healthd会通过发一个property信号触发一个full boot,也即是当属性sys.boot_from_charger_mode满足了值为1时就会触发,接着会触发late-init 这个action。
on property:sys.boot_from_charger_mode=1
class_stop charger
trigger late-init

//late-init这个action,主要是挂载文件系统,然后触发boot。
on late-init
trigger early-fs
trigger fs
trigger late-fs
trigger boot

//在boot事件中,基础网络初始话,基本的kernel参数,系统服务和后台进程的权限设置等,最后启动class类型是core的系统服务。
on boot
hostname localhost
write /proc/sys/vm/overcommit_memory 1
chmod 0664 /sys/module/lowmemorykiller/parameters/adj
chown system system /sys/power/state
class_start core

接着分析surfaceflinger的启动。
main_surfaceflinger.cpp

int main(int, char**)@main_surfaceflinger.cpp {
//下面这三行代码是一个独立的进程起来时,必须调用的,其中ps->startThreadPool()会间接调用到IPCThreadState::self()->joinThreadPool(mIsMain);最终让这个进程进入一个binder_loop的循环。
ProcessState::self()->setThreadPoolMaxThreadCount(4);
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
//实例化一个surfaceflinger,就是new SurfaceFlinger();
sp<SurfaceFlinger> flinger = DisplayUtils::getInstance()→getSFInstance();
//设置进程优先级,PRIORITY_URGENT_DISPLAY这是级别还是很高的。
setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
//在client发起连接之前执行初始化。
flinger→init();
//把surfaceflinger,GpuService注册到ServiceManager。
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);
sp<GpuService> gpuservice = new GpuService();
sm->addService(String16(GpuService::SERVICE_NAME), gpuservice, false);
//运行surfaceflinger,等待client的请求。
flinger->run();
return 0;
}


SurfaceFlinger的构造函数中没有做太多事情,只是给变量赋了初始值,在它第一次被引用时会执行其onFirstRef函数。

void SurfaceFlinger::onFirstRef()@SurfaceFlinger.cpp{
//初始化事件队列MessageQueue,
mEventQueue.init(this);
}


//这个MessageQueue.cpp是surfaceflinger自定义的,是消息循环处理机制的管理者,但是并不是系统标准的消息队列。
void MessageQueue::init(const sp<SurfaceFlinger>& flinger)@MessageQueue.cpp{
mFlinger = flinger;
//Looper是系统中通用的实现,system/core/libutils/looper.cpp
mLooper = new Looper(true);
//Handler也是surfaceflinger自定义的一个事件处理器,是MessageQueue.h的内部类,并不是通用的Handler。
mHandler = new Handler(*this);
}

//surfaceflinger的初始化,包括egl的运行环境的设置,跟vsync脉冲信号有关的EventThread等。这块内容不在这里做展开。

void SurfaceFlinger::init() @SurfaceFlinger.cpp{
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(mEGLDisplay, NULL, NULL);
sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
vsyncPhaseOffsetNs, true, "app");
mEventThread = new EventThread(vsyncSrc, *this);
mHwc = new HWComposer(this);
mHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
mEventControlThread = new EventControlThread(this);
mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
initializeDisplays();
}


接下来分析surfaceflinger的工作线程是怎么运行起来的。
void SurfaceFlinger::run() @SurfaceFlinger.cpp{
//可以看到这里是一个无线循环。
do {
waitForEvent();
} while (true);
}

//进一步调用MessageQueue中的waitMessage。
void SurfaceFlinger::waitForEvent() @SurfaceFlinger.cpp{
mEventQueue.waitMessage();
}

//这里依然是死循环,永远不会跳出,即使发生了错误,这也可以理解,surfaceflinger是整个GUI系统的核心,如果它退出了,基本系统也就瘫了。
void MessageQueue::waitMessage() @MessageQueue.cpp{
do {
IPCThreadState::self()->flushCommands();
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");
continue;
case Looper::POLL_TIMEOUT:
// timeout (should not happen)
continue;
default:
// should not happen
ALOGE("Looper::pollOnce() returned unknown status %d", ret);
continue;
}
} while (true);
}

在上面的循环中,会通过mLooper->pollOnce(-1);不断的读取消息进行处理。前面说过这里的MessageQueue并不是android系统通用的消息队列,它是消息循环处理机制的管理者,在它的init函数中也看到,内部包含了looper和hander,Looper中的mMessageEnvelopes才是真正存储消息的地方,而这个handle也只是一个中介,并没有实际去处理发给surfaceflinger的消息请求,而是进一步回调了surfaceflinger的onMessageReceived方法。
void MessageQueue::Handler::handleMessage(const Message& message) @MessageQueue.cpp{
switch (message.what) {
case INVALIDATE:
android_atomic_and(~eventMaskInvalidate, &mEventMask);
mQueue.mFlinger->onMessageReceived(message.what);
break;
case REFRESH:
android_atomic_and(~eventMaskRefresh, &mEventMask);
mQueue.mFlinger->onMessageReceived(message.what);
break;
}
}

通过上面的分析,知道surfaceflinger的消息处理框架是通过MessageQueue把消息请求发送到Looper的mMessageEnvelopes队列,然后通过mLooper->pollOnce(-1);方法依次取出事件处理,其中的handle会把INVALIDATE,REFRESH这两类消息请求转给surfaceflinger做实质的处理。

应用程序向surfaceflinger发送的消息请求分同步、异步两种,异步推送就是消息发过去就直接返回了,不需要等待执行结果。接下来主要看下同步的请求是怎么处理的?
以前面的应用程序申请创建一个layer为例:
status_t Client::createSurface()@Client.cpp{
class MessageCreateLayer : public MessageBase {
virtual bool handler() {
result = flinger->createLayer(name, client, w, h, format, flags,
handle, gbp);
return true;
}
}
sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),…);
mFlinger->postMessageSync(msg);
}


省略了很多代码,只关注消息处理相关的,这里通过postMessageSync发出一个同步消息,
status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
nsecs_t reltime, uint32_t /* flags */) @SurfaceFlinger.cpp{
status_t res = mEventQueue.postMessage(msg, reltime);
if (res == NO_ERROR) {
msg->wait();
}
return res;
}

在上面的函数中,除了调用mEventQueue.postMessage把消息入队外,还调用了msg->wait();这个wait从字面意思也能看出是让调用者线程挂起了。
//下面的MessageQueue依然是surfaceflinger自定义的类。

MessageQueue.h
class MessageBase : public MessageHandler{
void wait() const { barrier.wait(); }
}


这里是使用barrier来实现的同步,这个barrier只在surfaceflinger中有使用,应该说是专门为surfaceflinger设计的,所以有必要去了解下它的实现原理:
frameworks/native/services/surfaceflinger/Barrier.h
class Barrier
{
public:
inline Barrier() : state(CLOSED) { }
inline ~Barrier() { }
//释放等待在这个barrier上的线程。
void open() {
Mutex::Autolock _l(lock);
state = OPENED;
cv.broadcast();
}
//重新设置barrier,wait方法会被block,直到open方法被调用。
void close() {
Mutex::Autolock _l(lock);
state = CLOSED;
}
//这里会一直等待,直到barrier的状态是OPEN。
void wait() const {
Mutex::Autolock _l(lock);
while (state == CLOSED) {
cv.wait(lock);
}
}
private:
enum { OPENED, CLOSED };
mutable     Mutex       lock;
mutable     Condition   cv;
volatile    int         state;
};


可以看到barrier是基于Mutex和condition实现的一个模型。Mutex实际上是基于pthread接口的在封装,只要是涉及到对某个共享资源的访问,都可以认为是Mutex的问题领域;但是有时候对某一个共享资源的访问的目的,只是想判断它是不是满足了某个条件,比如state==CLOSED,并且什么时候满足这一条件是未知的,这种情况下,如果依然用Mutex来处理,就要一直去轮询,这显然是太浪费cpu资源了,所以才有了condition,但是condition本身并不完整,比如它没有指定具体的条件是什么,所以它需要被填充了具体条件才能真正的使用,这里的barrier就是一个填充了具体条件的condition,这里的具体条件就是state
== CLOSED或者state == OPEN。

介绍完了Barrier的实现原理,再来看下它是怎么使用的,postMessageSync时调用了barrier.wait()把调用者线程挂起,那什么时候把它唤醒呢?一种可能的情况就是这个消息请求被处理了,就应该把调用者唤醒,让他继续执行未完成的工作。
所以要从消息处理的接口入手:
前面分析过,在MessageQueue的waitMessage中,是通过mLooper->pollOnce(-1);不断的读取消息进行处理的。

system/core/libutils/Looper.cpp
int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) @Looper.cpp{
result = pollInner(timeoutMillis);
}

//从pollInner看出,它调用了message的handle中的方法handleMessage。

int Looper::pollInner(int timeoutMillis) {
const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);
sp<MessageHandler> handler = messageEnvelope.handler;
handler->handleMessage(message);
}


所以要看发送的那条消息中的handler是哪里来的?
MessageCreateLayer继承自MessageBase(MessageQueue.cpp中),
MessageQueue.cpp
void MessageBase::handleMessage(const Message&) {
this->handler();
barrier.open();
};

由于MessageBase的handler的方法是纯虚函数,所以这里调用的handle是子类的handler的方法,也即是MessageCreateLayer中的handler方法,这个方法会调用surfaceflinger来完成请求。
然后调用了barrier.open();唤醒被等待的线程。

分析了surfaceflinger的消息处理机制,再来看应用程序端是如何跟surfaceflinger通信的。
前面在分析BufferQueue时,引用过GLTest::SetUp()中一段代码,其中创建了SurfaceComposerClient实例,可以作为应用程序跟surfaceflinger通信的一个桥梁。

SurfaceComposerClient.cpp
void SurfaceComposerClient::onFirstRef() {
sp<ISurfaceComposer> sm(ComposerService::getComposerService());
if (sm != 0) {
sp<ISurfaceComposerClient> conn = sm->createConnection();
if (conn != 0) {
mClient = conn;
mStatus = NO_ERROR;
}
}
}


上面的实现中,首先获取surfaceflinger的句柄ISurfaceComposer,这个名字起的容易误解,surfaceflinger虽然注册在ServiceManager中的名字是“surfaceflinger”,但是其服务端实现的binder接口却是ISurfaceComposer,可以从它的继承关系得到验证:

class SurfaceFlinger : public BnSurfaceComposer,private Ibinder::DeathRecipient,
private HWComposer::EventHandler{}

接着SurfaceComposerClient::onFirstRef() 分析,通过surfaceflinger的 createConnection返回一个ISurfaceComposerClient 实例,ISurfaceComposerClient对应的服务端是Client,
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
@SurfaceFlinger.cpp{
sp<ISurfaceComposerClient> bclient;
sp<Client> client(new Client(this));
status_t err = client->initCheck();
if (err == NO_ERROR) {
bclient = client;
}
return bclient;
}


这个Client才是surfaceflinger跟应用程序交互的纽带,比如应用程序申请surface的请求就是经过client传递到surfaceFlinger,可以任务client是surfaceflinger安排在应用程序中一个代理,任何有UI界面的应用程序在surfaceflinger中都有对应的Client实例,但是应用程序并没有直接使用Client,而是通过ISurfaceComposerClient,ISurfaceComposerClient是应用程序与Client之间的binder接口,所以应用程序端一个请求先是通过ISurfaceComposerClient,然后传到Client,client收到者请求后,没有让surfaceflinger马上执行,而是把让先投递到surfaceflinger的消息队列,然后让client所在的线程wait,因为surfaceflinger会处理所有应用程序的请求,不能来一个请求就就打断surfaceflinger正在执行的操作,最后SurfaceFlinger处理完成后,返回结果,唤醒wait的应用程序。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: