作為一個 Native 的 Service, 想當然爾是在某個 main_xxx 帶起來的.
讓我們看看 init.rc, 果然找到了服務如下:
service surfaceflinger /system/bin/surfaceflinger
class core
user system
group graphics drmrpc
onrestart restart zygote
surfaceflinger 的 Makefile 放在 frameworks/native/services/surfaceflinger 下面
=> main_surfaceflinger.cpp
int main(int, char**) {
...
// instantiate surfaceflinger
sp<SurfaceFlinger> flinger = new SurfaceFlinger();
// initialize before clients can connect
flinger->init();
// publish surface flinger
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);
...
// run in this thread
flinger->run();
}
1.) new SurfaceFlinger();
=> 建構子讀了一些 property 並設置對應的 debug 訊息, 暫時跳過.
這邊可以看到它繼承了 BnSurfaceComposer
SurfaceFlinger::SurfaceFlinger()
: BnSurfaceComposer(), xxx
=> 第一次建立 SurfaceFlinger 時, 呼叫 MessageQueue 的 init
void SurfaceFlinger::onFirstRef()
{
mEventQueue.init(this);
}
=> 這裡保存了 mFlinger, 並生出 Looper & Handler
void MessageQueue::init(const sp<SurfaceFlinger>& flinger)
{
mFlinger = flinger;
mLooper = new Looper(true);
mHandler = new Handler(*this);
}
# mHandler 是定義在 MessageQueue 裡面的 subClass,
它繼承了 MessageHandler, 並在 mQueue 保存了自己這個 MessageQueue
class Handler : public MessageHandler {
enum {
eventMaskInvalidate = 0x1,
eventMaskRefresh = 0x2,
eventMaskTransaction = 0x4
};
MessageQueue& mQueue;
int32_t mEventMask;
public:
Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) { }
virtual void handleMessage(const Message& message);
void dispatchRefresh();
void dispatchInvalidate();
void dispatchTransaction();
};
2.) flinger->init();
這邊先貼上完整的代碼, 下面一步一步分析
void SurfaceFlinger::init() {
ALOGI( "SurfaceFlinger's main thread ready to run. "
"Initializing graphics H/W...");
Mutex::Autolock _l(mStateLock);
// initialize EGL for the default display
// EGL 是 OpenGL ES 的接點, 主要功能是完成 OpenGL 創建 Context, 繪製Surface, 配置Framebuffer属性、Swap提交繪製結果
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(mEGLDisplay, NULL, NULL);
// start the EventThread
sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
vsyncPhaseOffsetNs, true, "app");
mEventThread = new EventThread(vsyncSrc);
sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
sfVsyncPhaseOffsetNs, true, "sf");
mSFEventThread = new EventThread(sfVsyncSrc);
mEventQueue.setEventThread(mSFEventThread);
// 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());
// 為什麼這裡要自己 new GraphicBufferAlloc() 而不是跟 Layer 一樣只有呼叫 producer & consumer ?
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);
mEventControlThread = new EventControlThread(this);
mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
// set a fake vsync period if there is no HWComposer
if (mHwc->initCheck() != NO_ERROR) {
mPrimaryDispSync.setPeriod(16666667);
}
// initialize our drawing state
mDrawingState = mCurrentState;
// set initial conditions (e.g. unblank default device)
initializeDisplays();
// start boot animation
startBootAnim();
}
=> 先跳過EGL, 來看 DispSyncSource,
它繼承了 VSyncSource 跟 DispSync::Callback, 並傳入了 mPrimaryDispSync 的 address.
這個 mPrimaryDispSync 的類型是 DispSync, 它會啟動一個 DispSyncThread
DispSync::DispSync() :
mRefreshSkipCount(0),
mThread(new DispSyncThread()) {
mThread->run("DispSync", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
reset();
beginResync();
}
=> 這個 threadLoop 會進行計時, 並在計時結束時,
把所有需要觸發 callback 的 listener 蒐集到 callbackInvocations 裡面一起觸發
while (true) {
Vector<CallbackInvocation> callbackInvocations;
nsecs_t targetTime = 0;
// Scope for lock
{
if (mPeriod == 0) {
err = mCond.wait(mMutex);
continue;
}
nextEventTime = computeNextEventTimeLocked(now);
targetTime = nextEventTime;
bool isWakeup = false;
if (now < targetTime) {
err = mCond.waitRelative(mMutex, targetTime - now);
if (err == TIMED_OUT) {
isWakeup = true;
}
}
now = systemTime(SYSTEM_TIME_MONOTONIC);
if (isWakeup) {
mWakeupLatency = ((mWakeupLatency * 63) +
(now - targetTime)) / 64;
if (mWakeupLatency > 500000) {
// Don't correct by more than 500 us
mWakeupLatency = 500000;
}
}
callbackInvocations = gatherCallbackInvocationsLocked(now);
}
if (callbackInvocations.size() > 0) {
fireCallbackInvocations(callbackInvocations);
}
}
=> 觸發就是呼叫 onDispSyncEvent
void fireCallbackInvocations(const Vector<CallbackInvocation>& callbacks) {
for (size_t i = 0; i < callbacks.size(); i++) {
callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime);
}
}
=> 回到一開始 DispSyncSource 繼承的 DispSync::Callback 如下, 需要 implement onDispSyncEvent
class Callback: public virtual RefBase {
public:
virtual ~Callback() {};
virtual void onDispSyncEvent(nsecs_t when) = 0;
};
=> 可以看到在內部的實作如下
class DispSyncSource : public VSyncSource, private DispSync::Callback {
private:
virtual void onDispSyncEvent(nsecs_t when) {
sp<VSyncSource::Callback> callback;
{
Mutex::Autolock lock(mCallbackMutex);
callback = mCallback;
if (mTraceVsync) {
mValue = (mValue + 1) % 2;
ATRACE_INT(mVsyncEventLabel.string(), mValue);
}
}
if (callback != NULL) {
callback->onVSyncEvent(when);
}
}
}
=> 那麼 mCallback 又是從哪來的?
=> 答案是透過 setCallback 來的,
下一行的 mEventThread = new EventThread(vsyncSrc);
透過它的 EventThread::enableVSyncLocked function 來呼叫,
他的 Callback class 如下:
class Callback: public virtual RefBase {
public:
virtual ~Callback() {}
virtual void onVSyncEvent(nsecs_t when) = 0;
};
=> 而實作的形式為
void EventThread::onVSyncEvent(nsecs_t timestamp) {
Mutex::Autolock _l(mLock);
mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
mVSyncEvent[0].header.id = 0;
mVSyncEvent[0].header.timestamp = timestamp;
mVSyncEvent[0].vsync.count++;
mCondition.broadcast();
}
所以當一個 DispSync 的 Event 來時, 會透過 onDispSyncEvent => onVSyncEvent
=> 下一行的 mSFEventThread 也做了差不多的事情,
只是這邊多呼叫了 mEventQueue.setEventThread(mSFEventThread),
將 mSFEventThread 保存到 MessageQueue 裡面的 mEventThread 變量
(這邊看不出來要幹嘛...好像沒用到?)
=> 再來生成了一個 HW Composer
mHwc = new HWComposer(this,
*static_cast<HWComposer::EventHandler *>(this));
=> 這裡會跟 VSync 掛勾 (mCBContext->procs.vsync = &hook_vsync,
把Callback function註冊給HWC)
HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger, EventHandler& handler)
{
...
// Note: some devices may insist that the FB HAL be opened before HWC.
int fberr = loadFbHalModule();
loadHwcModule();
if (mHwc) {
ALOGI("Using %s version %u.%u", HWC_HARDWARE_COMPOSER,
(hwcApiVersion(mHwc) >> 24) & 0xff,
(hwcApiVersion(mHwc) >> 16) & 0xff);
if (mHwc->registerProcs) {
mCBContext->hwc = this;
mCBContext->procs.invalidate = &hook_invalidate;
mCBContext->procs.vsync = &hook_vsync;
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
mCBContext->procs.hotplug = &hook_hotplug;
else
mCBContext->procs.hotplug = NULL;
memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
mHwc->registerProcs(mHwc, &mCBContext->procs);
}
// don't need a vsync thread if we have a hardware composer
needVSyncThread = false;
// always turn vsync off when we start
eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);
// the number of displays we actually have depends on the
// hw composer version
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) {
// 1.3 adds support for virtual displays
mNumDisplays = MAX_HWC_DISPLAYS;
}
}
}
=> 呼叫 RenderEngine::create(), 將 EGLDisplay 與 hwc format 放入
RenderEngine* RenderEngine::create(EGLDisplay display, int hwcFormat) {
RenderEngine* engine = NULL;
switch (version) {
engine = new GLESXXRenderEngine();
}
engine->setEGLHandles(config, ctxt);
return engine;
}
=> 對所有 non-virtual diplay 進行初始化
// 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());
/* 不曉得為什麼這裡要自己 new GraphicBufferAlloc(),
而不是跟 Layer 一樣只有呼叫 producer & consumer ? */
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);
}
}
=> createBufferQueue 之前會先 new 一個 allocator 出來 (new GraphicBufferAlloc())
不過在 createBufferQueue 內部也會檢查 allocator 是否為 NULL ... 然後最終還是會呼叫到 new GraphicBufferAlloc()
=> 之後在 BufferQueueProducer 呼叫 dequeueBuffer / allocateBuffers 時會透過這個 allocator 生成 GraphicBuffer
透過 GraphicBuffer 與 GraphicBufferAlloctor 也就是 gralloc module 進行交互 (注意是 GraphicBufferAlloctor 而不是 GraphicBufferAlloc ...)
主要是透過 gralloc module 去進行緩衝區的分配 (Either on RAM or Framebuffer)
=> createBufferQueue 對 producer 跟 consumer 進行了配置, 分別對應到 BufferQueueProducer 跟 BufferQueueConsumer
他們藉由 BufferQueueCore(allocator) 進行交互. (另外雖然 allocator 也帶入了 core, 但好像沒有拿來用)
=> 接下來生成一個 FramebufferSurface, 並帶入了 HWComposer 與剛剛生成的 consumer
=> consumer 作為 FramebufferSurface 繼承的父類別的 ConsumerBase 內部的 mConsumer 對象被保存起來
hwc 則保存在 mHwc 對象中, 稍微爬了一下代碼, 裡面會呼叫 Hwc 對於 fence 的操作等功能
=> 後面在 BufferQueueProducer 的內部, 我們會看到它取出了 frameAvailableListener = mCore->mConsumerListener;
並去呼叫 frameAvailableListener->onFrameAvailable(item);
mCore->mConsumerListener = consumerListener; 則是在 BufferQueueConsumer::connect() 賦值的, 這個我們後面會再看到.
=> 再來, 生成 DisplayDevice, 這裡將 producer 帶入
DisplayDevice::DisplayDevice()
{
mNativeWindow = new Surface(producer, false);
ANativeWindow* const window = mNativeWindow.get();
/*
* Create our display's surface
*/
EGLSurface surface;
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (config == EGL_NO_CONFIG) {
config = RenderEngine::chooseEglConfig(display, format);
}
surface = eglCreateWindowSurface(display, config, window, NULL);
...
if (mType >= DisplayDevice::DISPLAY_VIRTUAL) {
// reset virtual display buffer format.
// because it is changed by eglCreateWindowSurface().
native_window_set_buffers_format(window, format);
window->setSwapInterval(window, 0);
}
}
=> 可以看到這邊又生成了一個 Surface 對象,
把 producer 帶入, 保存在 mGraphicBufferProducer 內
Surface::Surface(
const sp<IGraphicBufferProducer>& bufferProducer,
bool controlledByApp)
: mGraphicBufferProducer(bufferProducer),
mGenerationNumber(0)
{
// Initialize the ANativeWindow function pointers.
ANativeWindow::setSwapInterval = hook_setSwapInterval;
ANativeWindow::dequeueBuffer = hook_dequeueBuffer;
ANativeWindow::cancelBuffer = hook_cancelBuffer;
...
}
=> 之後會透過 Surface 對象來呼叫 BufferQueueProducer 的 allocateBuffers / dequeueBuffer 等動作
=> 取得剛剛設定好的 Surface 對象, 在 Constructor 裡面已經完成了一些指定 ANativeWindow* const window = mNativeWindow.get();
生成 EGL 用的 surface, display 等對象
/*
* Create our display's surface
*/
EGLSurface surface;
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (config == EGL_NO_CONFIG) {
config = RenderEngine::chooseEglConfig(display, format);
}
surface = eglCreateWindowSurface(display, config, window, NULL);
mSurface = surface;
mDisplay = display;
=> 先總結一下, 現在的 producer 藉由 DisplayDevice 的 mNativeWindow 傳遞給了 EGL
而 consumer 則是給了 FramebufferSurface, 等收到了 onFrameAvailable 之後, 就會呼叫 HWComposer 的 fbPost 函數開始輸出
void FramebufferSurface::onFrameAvailable(const BufferItem& /* item */) {
sp<GraphicBuffer> buf;
sp<Fence> acquireFence;
status_t err = nextBuffer(buf, acquireFence);
if (err != NO_ERROR) {
ALOGE("error latching nnext FramebufferSurface buffer: %s (%d)",
strerror(-err), err);
return;
}
err = mHwc.fbPost(mDisplayType, acquireFence, buf);
if (err != NO_ERROR) {
ALOGE("error posting framebuffer: %d", err);
}
}
=> 啟動 EventControlThread, 並呼叫一次 eventControl (一開始 mVsyncEnabled 是 false)
mFlinger->eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC,
mVsyncEnabled);
=> 這個 eventControl 最終會呼叫到 HWComposer 的 HAL 的 eventControl, 以 mx6 為例,
它會呼叫 hwc_eventControl, 並設定 VSyncThread 的 mEnabled 值
ctx->m_vsync_thread->setEnabled(enabled);
=> mEnabled = false 的時候會讓 threadLoop 卡在這邊等 mCondition
bool VSyncThread::threadLoop()
{
{ // scope for lock
Mutex::Autolock _l(mLock);
while (!mEnabled) {
mCondition.wait(mLock);
}
}
if (mFakeVSync) {
performFakeVSync();
}
else {
performVSync();
}
return true;
}
=> 呼叫 initializeDisplays(); 送出一個 Async 的 command (MessageScreenInitialized)
=> 前面追過了, 收到之後會執行 handler, 所以會呼叫 onInitializeDisplays
=> SurfaceFlinger 啟動完成, 呼叫 property_set 來啟動 bootAnimation