SurfaceFlinger自启动之后,主要有三种类型线程参与工作:
1.binder线程,负责监控binder设备完成与客户端的交接
2.控制台事件监控线程,负责监控硬件帧缓冲区的睡眠/唤醒状态切换事件。
3.UI渲染线程,负责渲染UI。
一 UI渲染线程
UI渲染线程平时是处于休眠状态,一旦binder线程监测到有其他进程发过来的请求渲染UI的消息就会唤醒UI渲染线程,另一方面一旦SurfaceFlinger服务的控制台事件监控线程发现硬件帧缓冲区即将要进入睡眠或者唤醒状态时,它就会往SurfaceFlinger服务的UI渲染线程的消息队列中发送一个消息,以便SurfaceFlinger服务的UI渲染线程可以执行冻结或者解冻显示屏的操作。(摘自老罗的android之旅)接下来我从客户端一个请求渲染UI的请求入手开始研究渲染UI的整个过程
UI渲染线程的运行过程:
这里在说明一下,SurfaceFlinger的各个代理负责的事情:前面讲述的BpSurfaceComposer是SF在客户端的Binder代理,BnSurfaceComposer是本地对象负责和BpXXX交互,他们主要负责客户端请求连的整个过程和监控binder设备。而客户端与server端真正的交易则交给BpSurfaceComposerClient和BnSurfaceComposerClient来做,他们负责通知管理一个UI的渲染等重要过程。那我就从BpSurfaceComposerClient代理入手,还记得这个BpSurfaceComposerClient是哪里诞生的吗?在之前客户端请求连接到server的时候:
void SurfaceComposerClient::onFirstRef() {
sp sm(ComposerService::getComposerService());
if (sm != 0) {
sp conn = sm->createConnection();
if (conn != 0) {
mClient = conn;
mStatus = NO_ERROR;
}
}
}
当中的一句 mClient = conn;即把返回来的surfacecomposerclient保存了下来,又因为mClient是强指针,导致最终其实mClient就是BpSurfaceComposerClient类的对象,具体原因之前在研究SF启动过程中有详细说明。从连接之后,就获得了一个BpSurfaceComposerClient对象,这样连接后就可以进行下一步的渲染工作了。我们再看下BpSurfaceComposerClient这个类:
class BpSurfaceComposerClient : public BpInterface
{
public:
BpSurfaceComposerClient(const sp& impl)
: BpInterface(impl) {
}
virtual status_t createSurface(const String8& name, uint32_t w,
uint32_t h, PixelFormat format, uint32_t flags,
sp* handle,
sp* gbp) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
data.writeString8(name);
data.writeInt32(w);
data.writeInt32(h);
data.writeInt32(format);
data.writeInt32(flags);
remote()->transact(CREATE_SURFACE, data, &reply);
*handle = reply.readStrongBinder();
*gbp = interface_cast(reply.readStrongBinder());
return reply.readInt32();
}
virtual status_t destroySurface(const sp& handle) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
data.writeStrongBinder(handle);
remote()->transact(DESTROY_SURFACE, data, &reply);
return reply.readInt32();
}
};
他有两个成员函数,分别是createSurface和destroySurface对应创建和销毁一个surface。两个核心函数的核心语句都在remote()->transact(CREATE_SURFACE, data, &reply);
即transact这个函数,之前也介绍过这是和binder设备打交道的必经之路。不做过多深入,这里意思就是简单的发个消息 CREATE_SURFACE给服务端,并把一个surface的信息打包成data一并发送过去。
server端这边会有线程监控binder设备,一旦收到消息自然调用对应的函数。这里就是BnSurfaceComposerClient负责了,不过这边跟之前的BnSurfaceComposer有点不一样,BnSurfaceComposerClient派生出一个Client类来负责这件事了,我们来看下这个类:
class Client : public BnSurfaceComposerClient
{
public:
Client(const sp& flinger);
~Client();
status_t initCheck() const;
// protected by SurfaceFlinger::mStateLock
void attachLayer(const sp& handle, const sp& layer);
void detachLayer(const Layer* layer);
sp getLayerUser(const sp& handle) const;
private:
// ISurfaceComposerClient interface
virtual status_t createSurface(
const String8& name,
uint32_t w, uint32_t h,PixelFormat format, uint32_t flags,
sp* handle,
sp* gbp);
virtual status_t destroySurface(const sp& handle);
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
// constant
sp mFlinger;
// protected by mLock
DefaultKeyedVector< wp, wp > mLayers;
// thread-safe
mutable Mutex mLock;
};
其实核心的成员函数就两个 一个是createSurface和onTransact。首先看onTransact,毕竟他负责接收消息。
status_t Client::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
// these must be checked
IPCThreadState* ipc = IPCThreadState::self();
const int pid = ipc->getCallingPid();
const int uid = ipc->getCallingUid();
const int self_pid = getpid();
if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) {
// we're called from a different process, do the real check
if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger))
{
ALOGE("Permission Denial: "
"can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
return PERMISSION_DENIED;
}
}
return BnSurfaceComposerClient::onTransact(code, data, reply, flags);
}
这里前面的语句为了判断是否得到进入使用SF的权限,看他的返回 BnSurfaceComposerClient::onTransact(code, data, reply, flags);直接调用了另外一个onTransact接着看BnSurfaceComposerClient类中的onTransact
status_t BnSurfaceComposerClient::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
case CREATE_SURFACE: {
CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
String8 name = data.readString8();
uint32_t w = data.readInt32();
uint32_t h = data.readInt32();
PixelFormat format = data.readInt32();
uint32_t flags = data.readInt32();
sp handle;
sp gbp;
status_t result = createSurface(name, w, h, format, flags,
&handle, &gbp);
reply->writeStrongBinder(handle);
reply->writeStrongBinder(gbp->asBinder());
reply->writeInt32(result);
return NO_ERROR;
} break;
case DESTROY_SURFACE: {
CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
reply->writeInt32( destroySurface( data.readStrongBinder() ) );
return NO_ERROR;
} break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
这才是处理的核心中间人,还记得刚刚传的消息是CREATE_SURFACE,所以这里走第一个分支,首先解析数据包得到一些数据例如surface名字,长宽,还有格式等。然后在经过createSurface创建,但是到这里有个问题,这里的createSurface没有指明属于哪个类,发现去追踪起定义这追踪不到,这才想起这是调用了他子类Client的函数。我们回到之前client类中的createSurface;
status_t Client::createSurface(
const String8& name,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
sp* handle,
sp* gbp)
{
/*
* createSurface must be called from the GL thread so that it can
* have access to the GL context.
*/
class MessageCreateLayer : public MessageBase {
SurfaceFlinger* flinger;
Client* client;
sp* handle;
sp* gbp;
status_t result;
const String8& name;
uint32_t w, h;
PixelFormat format;
uint32_t flags;
public:
MessageCreateLayer(SurfaceFlinger* flinger,
const String8& name, Client* client,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
sp* handle,
sp* gbp)
: flinger(flinger), client(client),
handle(handle), gbp(gbp),
name(name), w(w), h(h), format(format), flags(flags) {
}
status_t getResult() const { return result; }
virtual bool handler() {
result = flinger->createLayer(name, client, w, h, format, flags,
handle, gbp);
return true;
}
};
sp msg = new MessageCreateLayer(mFlinger.get(),
name, this, w, h, format, flags, handle, gbp);
mFlinger->postMessageSync(msg);
return static_cast( msg.get() )->getResult();
}
这个函数才真正的是程序进入SF领域的分水岭,函数内部定义了一个MessageCreateLayer类,我的理解是这个类把一个surface封装成了一个消息,这个消息当中含有surface的所有信息。sp
我们看下这个函数:
status_t SurfaceFlinger::postMessageSync(const sp& msg,
nsecs_t reltime, uint32_t flags) {
status_t res = mEventQueue.postMessage(msg, reltime);
if (res == NO_ERROR) {
msg->wait();
}
return res;
}
调用postMessage()
status_t MessageQueue::postMessage(
const sp& messageHandler, nsecs_t relTime)
{
const Message dummyMessage;
if (relTime > 0) {
mLooper->sendMessageDelayed(relTime, messageHandler, dummyMessage);
} else {
mLooper->sendMessage(messageHandler, dummyMessage);
}
return NO_ERROR;
}
这边 无论是sendMessageDelayed还是sendMessage都将会触发线程,将主线程(渲染UI)唤醒。那么我用一张图来介绍下主线程:
图画的很粗糙不过大致走向就是这样,当主线程收到消息后,就执行handleMessage。到这里可以去参考之前钱几篇SF流程系列文章看接下去是怎么渲染的。