http://blog.csdn.net/lewif/article/details/50559904
目录(?)[+]
这篇文章只分析SF消息驱动流程的建立,不涉及具体的功能实现,关于SF和HWC如何交互后续分析,基于Android 4.4,以下将surfaceflinger简称为SF。
如何启动
android 4.4中SF在init.rc中启动,如下所示:
service surfaceflinger /system/bin/surfaceflinger
class main
user system
group graphics drmrpc
onrestartrestart zygote
可以看出,SF是/system/bin/下的一个应用程序,在makefile中搜索LOCAL_MODULE:=surfaceflinger即可找到具体的makefile和代码,
#首先是个SF的动态库
LOCAL_MODULE:=libsurfaceflinger
include$(BUILD_SHARED_LIBRARY)
# 其次是surfaceflinger,
LOCAL_SRC_FILES:= \
main_surfaceflinger.cpp
LOCAL_SHARED_LIBRARIES:= \
libsurfaceflinger \
libcutils \
liblog \
libbinder \
libutils
LOCAL_MODULE:= surfaceflinger
include$(BUILD_EXECUTABLE)
从上面makefile就能看出来,首先有个动态库libsurfaceflinger.so,然后SF只是对库的一个“封装调用”,多了一个main_surfaceflinger.cpp,里面仅有个main函数,下面展开。
执行流程
只关注SF流程,不关注binder线程等。
int main(int argc, char** argv) {
// When SF is launched in its ownprocess, limit the number of
// binder threads to 4.
ProcessState::self()->setThreadPoolMaxThreadCount(4);
// start the thread pool
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
// instantiate surfaceflinger
// ①
sp<SurfaceFlinger> flinger =newSurfaceFlinger();
#ifdefined(HAVE_PTHREADS)
setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
#endif
set_sched_policy(0, SP_FOREGROUND);
// initialize before clients can connect
// ②
flinger->init();
// publish surface flinger
sp<IServiceManager>sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);
// run in this thread
// ③
flinger->run();
return0;
}
main函数主要的内容包含三方面,逐步分析。
new SurfaceFlinger
首先,new了一个SF,并使用sp指针,所以我们需要关注SF类中是否实现了onFirstRef()函数。
sp
构造函数中初始化一些值,
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),
mDebugFps(0),
mDebugDisableTransformHint(0),
mDebugInSwapBuffers(0),
mLastSwapBufferTime(0),
mDebugInTransaction(0),
mLastTransactionTime(0),
mBootFinished(false),
mPrimaryHWVsyncEnabled(false),
mHWVsyncAvailable(false),
mDaltonize(false)
{
//一些调试的变量等
}
SF确实实现了onFirstRef()函数,
//mutableMessageQueue mEventQueue;
voidSurfaceFlinger::onFirstRef()
{
mEventQueue.init(this);
}
调用MessageQueue的init,在MessageQueue中建了一个Looper和Handler,注意不是Java中的,native实现的。 到后面就可以看到SF的核心就是接收消息,处理消息。
voidMessageQueue::init(constsp
{
mFlinger =flinger;
mLooper = new Looper(true);
mHandler = new Handler(*this);
}
init函数
init中主要创建了OpenGL ES环境,对显示器的初始化等。
voidSurfaceFlinger::init() {
ALOGI( "SurfaceFlinger's main thread ready to run. "
"Initializing graphics H/W...");
status_t err;
Mutex::Autolock_l(mStateLock);
// initialize EGL for the defaultdisplay
mEGLDisplay =eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(mEGLDisplay, NULL, NULL);
// Initialize the H/W composerobject. There may or may not be an
// actual hardware composer underneath.
mHwc = new HWComposer(this,
*static_cast
// First try to get an ES2 config
err =selectEGLConfig(mEGLDisplay, mHwc->getVisualID(), EGL_OPENGL_ES2_BIT,
&mEGLConfig);
if (err !=NO_ERROR) {
// If ES2 fails, try ES1
err =selectEGLConfig(mEGLDisplay, mHwc->getVisualID(),
EGL_OPENGL_ES_BIT, &mEGLConfig);
}
if (err !=NO_ERROR) {
// still didn't work, probably becausewe're on the emulator...
// try a simplified query
ALOGW("no suitable EGLConfig found,trying a simpler query");
err =selectEGLConfig(mEGLDisplay, mHwc->getVisualID(), 0, &mEGLConfig);
}
if (err !=NO_ERROR) {
// this EGL is too lame for android
LOG_ALWAYS_FATAL("no suitable EGLConfig found, giving up");
}
// print some debugging info
EGLint r,g,b,a;
eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_RED_SIZE, &r);
eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_GREEN_SIZE, &g);
eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_BLUE_SIZE, &b);
eglGetConfigAttrib(mEGLDisplay,mEGLConfig, EGL_ALPHA_SIZE, &a);
ALOGI("EGL informations:");
ALOGI("vendor : %s",eglQueryString(mEGLDisplay, EGL_VENDOR));
ALOGI("version : %s",eglQueryString(mEGLDisplay, EGL_VERSION));
ALOGI("extensions: %s",eglQueryString(mEGLDisplay, EGL_EXTENSIONS));
ALOGI("Client API: %s",eglQueryString(mEGLDisplay, EGL_CLIENT_APIS)?:"Not Supported");
ALOGI("EGLSurface: %d-%d-%d-%d,config=%p", r, g, b, a, mEGLConfig);
// get a RenderEngine for the givendisplay / config (can't fail)
mRenderEngine =RenderEngine::create(mEGLDisplay, mEGLConfig);
// retrieve the EGL context that wasselected/created
mEGLContext =mRenderEngine->getEGLContext();
// figure out which format we got
eglGetConfigAttrib(mEGLDisplay,mEGLConfig,
EGL_NATIVE_VISUAL_ID, &mEGLNativeVisualId);
LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
"couldn't create EGLContext");
// initialize our non-virtual displays
for (size_t i=0 ;i
DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
// set-up the displays that are alreadyconnected
if(mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
// All non-virtual displays arecurrently considered secure.
bool isSecure = true;
createBuiltinDisplayLocked(type);
wp
sp
sp
sp
type, allocateHwcDisplayId(type), isSecure, token,
fbs, bq,
mEGLConfig);
if (i >DisplayDevice::DISPLAY_PRIMARY) {
// FIXME: currently we don't getblank/unblank requests
// for displays other than the maindisplay, so we always
// assume a connected display is unblanked.
ALOGD("markingdisplay %d as acquired/unblanked", i);
hw->acquireScreen();
}
mDisplays.add(token, hw);
}
}
// make the GLContext current so that wecan create textures when creating Layers
// (which may happens before we rendersomething)
getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
// start the EventThread
sp
vsyncPhaseOffsetNs, true);
mEventThread = newEventThread(vsyncSrc);
sp
sfVsyncPhaseOffsetNs, false);
mSFEventThread= new EventThread(sfVsyncSrc);
mEventQueue.setEventThread(mSFEventThread);
mEventControlThread = new EventControlThread(this);
mEventControlThread->run("EventControl",PRIORITY_URGENT_DISPLAY);
// set a fake vsync period if there isno HWComposer
if(mHwc->initCheck() != NO_ERROR) {
mPrimaryDispSync.setPeriod(16666667);
}
// initialize our drawing state
mDrawingState =mCurrentState;
// set initial conditions (e.g. unblankdefault device)
initializeDisplays();
// start boot animation
startBootAnim();
}
最后部分启动了开机动画程序bootanim,肯定是SF启动起来后才能去执行绘画相关的进程。
void SurfaceFlinger::startBootAnim() {
// start boot animation
property_set("service.bootanim.exit", "0");
property_set("ctl.start", "bootanim");
}
run函数
run函数非常简单,但却是SF的核心,是个while循环,循环处理消息等。
void SurfaceFlinger::run() {
do {
waitForEvent();
} while (true);
}
void SurfaceFlinger::waitForEvent() {
mEventQueue.waitMessage();
}
可以看到,接收处理消息的关键在mLooper->pollOnce(-1);,
voidMessageQueue::waitMessage(){
do {
IPCThreadState::self()->flushCommands();
int32_t ret= mLooper->pollOnce(-1);
switch (ret) {
caseALOOPER_POLL_WAKE:
caseALOOPER_POLL_CALLBACK:
continue;
caseALOOPER_POLL_ERROR:
ALOGE("ALOOPER_POLL_ERROR");
caseALOOPER_POLL_TIMEOUT:
// timeout (shouldnot happen)
continue;
default:
// should not happen
ALOGE("Looper::pollOnce()returned unknown status %d", ret);
continue;
}
} while (true);
}
给SF发消息
首先关注如何给SF发送消息,以Client创建surface为例,
status_t Client::createSurface(
const String8&name,
uint32_t w,uint32_t h, PixelFormat format, uint32_t flags,
sp
sp
{
/*
* createSurface must be called from the GLthread so that it can
* have access to the GL context.
*/
classMessageCreateLayer : public MessageBase {
SurfaceFlinger* flinger;
Client*client;
sp
sp
status_tresult;
const String8&name;
uint32_t w,h;
PixelFormatformat;
uint32_tflags;
public:
MessageCreateLayer(SurfaceFlinger*flinger,
const String8&name, Client* client,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
sp
sp
: flinger(flinger), client(client),
handle(handle), gbp(gbp),
name(name), w(w), h(h), format(format), flags(flags) {
}
status_tgetResult() const { return result; }
//handler是执行消息动作的地方,
virtualbool handler() {
result= flinger->createLayer(name, client, w, h, format, flags,
handle, gbp);
returntrue;
}
};
//首先封装消息
sp
name, this, w, h, format,flags, handle, gbp);
//调用SF的postMessageSync发送同步消息
mFlinger->postMessageSync(msg);
returnstatic_cast
}
类MessageBase就是封装了类似于一个Handler,里面有个Barrier,我们能够猜到,这个Barrier 肯定是用来进行同步发送消息的,利用Barrier 去等待”wait”。
class MessageBase : public MessageHandler
{
public:
MessageBase();
// return true if message has a handler
virtualbool handler() = 0;
// waits for the handler to be processed
void wait() const {barrier.wait(); }
protected:
virtual ~MessageBase();
private:
virtualvoidhandleMessage(const Message&message);
mutable Barrierbarrier;
};
MessageBase的handleMessage函数,可以看到MessageBase的handler()函数是真正消息处理的地方,执行完成后,调用barrier.open();,打开barrier,这样调用barrier.wait()的地方就能退出了。
voidMessageBase::handleMessage(const Message&) {
this->handler();
barrier.open();
};
接着分析mFlinger->postMessageSync(msg);,这是给SF发同步消息的入口,当然也可以发异步消息,实现是类似的,
status_tSurfaceFlinger::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;
}
可以看到在同步发送消息中,barrier在postMessageSync函数中一直等着呢(wait),等待SF调用handleMessage()函数去将barrier这个栅栏打开(open)。
SF处理消息
上面提到,处理消息的关键就在mLooper->pollOnce(-1);函数中,而pollOnce又会调用pollInner,只摘取了处理消息的一段,
intLooper::pollInner(int timeoutMillis){
// Invoke pending message callbacks.
mNextMessageUptime = LLONG_MAX;
while(mMessageEnvelopes.size() != 0) {
nsecs_t now= systemTime(SYSTEM_TIME_MONOTONIC);
constMessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);
if (messageEnvelope.uptime <= now) {
// Remove the envelope from the list.
// We keep a strong reference to thehandler until the call to handleMessage
// finishes. Then we drop it so that the handler can bedeleted *before*
// we reacquire our lock.
{ // obtain handler
sp
Message message = messageEnvelope.message;
//把头删除啊
mMessageEnvelopes.removeAt(0);
mSendingMessage = true;
mLock.unlock();
#ifDEBUG_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 ofthe queue determines the next wakeup time.
mNextMessageUptime = messageEnvelope.uptime;
break;
}
}
}
从上面代码可以看到,发给SF的消息被封装在MessageEnvelope结构中,SF一直在mMessageEnvelopes队列中从头部取出消息,然后执行,即handler->handleMessage(message);,
voidMessageBase::handleMessage(const Message&) {
this->handler();
//打开栅栏
barrier.open();
};
调用handleMessage执行handler(),所以SF创建Surface的核心代码就是SF的createLayer函数,
result =flinger->createLayer(name, client, w, h, format, flags,
handle, gbp);
执行完成后,打开barrier。