讓我們看看 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(); }
=> 下一行的 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 對象, 在 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
沒有留言:
張貼留言