天天看点

Android 7.1 GUI系统-surfaceflinger(四)

surfaceflinger的启动:

Android P 图形显示系统 https://www.jianshu.com/u/f92447ae8445

Android GUI系统之SurfaceFlinger https://blog.csdn.net/vviccc/article/details/104860616

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的应用程序。

继续阅读