SurfaceFlinger在前面的篇幅了,多有涉及。android
SurfaceFlinger是GUI刷新UI的核心,因此任何關於SurfaceFlinger的改進都會對android UI系統有重大影響。app
SurfaceFlinger主要分爲4個部分函數
1)黃油計劃---project butteroop
2)啓動過程post
3)SurfaceFlinger & BufferQueue的關係性能
4)Vsync信號的處理ui
就是給android系統,圖上一層「黃油」。咱們來看看andorid是怎麼給SurfaceFlinger塗上這層黃油的。this
butter 由2個組成部分,Vsync & Triple buffer。spa
Triple buffer:設計
上面講到雙緩衝區技術,也提到FrameBufferNativeWindow 在申請buffer的時候,能夠是2,或者是3.
這個3 就是立刻要講到的Triple Buffer技術。
咱們先會過來看看雙緩衝技術。
以前說 雙緩衝,是把一個buffer放在bitmap上,等到這個全部元素都準備好之後,在把bitmap刷到屏幕上。
這樣會解決卡頓的感受。
咱們考慮一種狀況,假設屏幕刷新頻率是66Hz,CPU頻率是100Hz.
以前已經講了雙緩衝技術,這裏簡單過一下。
如上面的假設,UI的刷新是0.015s,而buffer的準備是0.01s
一個Frame Buffer表明一幀圖像。
0.01s:
此時,buffer已經準備好數據,而顯示器只顯示了圖像的2/3
0.015s
顯示器顯示了第一幀圖像,而buffer已經填充了第二幀的1/3
0.02s
Buffer已經準備好了第二幀,而顯示器出現了問題,1/3的內容屬於第二幀,2/3的內容屬於第一幀。
這就是android引入雙緩衝技術的緣由。
若是buffer準備的時間,比屏幕刷新圖像的速度慢呢?
顯示屏的每一次刷新,就是對顯示器屏幕的掃描,可是它是有間隔的(物理設備嘛,確定有這個間隔)。
典型的PC顯示器屏幕刷新頻率是60Hz,這是由於一秒60幀,從人的角度看,就會以爲很流暢。
因此間隔1/60秒,也就是16ms 若是咱們準備時間<=16ms,那就能夠作到「無縫鏈接」。畫面就很流程。
這段空隙稱爲VBI。 這個時間就是交換緩衝區最佳的時間。而這個交換的動做就是Vsync 也是SurfaceFlinger的重點。
若是咱們圖像準備時間<=16ms. OK,畫面是很流暢的,可是咱們沒法保證設備性能必定很very good。因此也有可能畫面準備時間超過16ms
咱們看看這張圖。
SurfaceFlinger 咱們前面已經說了,它其實就是一個service。
void SurfaceFlinger::onFirstRef() { mEventQueue.init(this); }
初始化事件隊列。
void MessageQueue::init(const sp<SurfaceFlinger>& flinger) { mFlinger = flinger; mLooper = new Looper(true); mHandler = new Handler(*this); }
建立了looper & Handler
可是這個looper何時起來的呢?
void MessageQueue::waitMessage() { 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"); case Looper::POLL_TIMEOUT: // timeout (should not happen) continue; default: // should not happen ALOGE("Looper::pollOnce() returned unknown status %d", ret); continue; } } while (true); }
能夠看到最終會調用looper啓動函數。能夠看到Looper::POLL_TIMEOUT: android什麼都沒作,儘管它們不該該發生。
其實handler兜了一圈,發現最後仍是回到surfaceflinger來處理:
void SurfaceFlinger::onMessageReceived(int32_t what) { ATRACE_CALL(); switch (what) { case MessageQueue::TRANSACTION: { handleMessageTransaction(); break; } case MessageQueue::INVALIDATE: { bool refreshNeeded = handleMessageTransaction(); refreshNeeded |= handleMessageInvalidate(); refreshNeeded |= mRepaintEverything; if (refreshNeeded) { // Signal a refresh if a transaction modified the window state, // a new buffer was latched, or if HWC has requested a full // repaint signalRefresh(); } break; } case MessageQueue::REFRESH: { handleMessageRefresh(); break; } } }
任何有UI界面App都在surfaceflinger裏面有client。
因此是一個app對應一個surfaceflinger裏面的client(ISurfaceComposerClient)。
下面咱們來分析surfaceflinger的2個重要函數:
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() { sp<ISurfaceComposerClient> bclient; sp<Client> client(new Client(this)); status_t err = client->initCheck(); if (err == NO_ERROR) { bclient = client; } return bclient; }
返回ISurfaceComposerClient,也就是client的bind對象實體。
其實就上面標紅的一句,進行必要的有效性檢查,如今代碼:
status_t Client::initCheck() const { return NO_ERROR; }
有了clinet之後,看下surface的產生。
status_t Client::createSurface( const String8& name, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, sp<IBinder>* handle, sp<IGraphicBufferProducer>* 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<IBinder>* handle; sp<IGraphicBufferProducer>* 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<IBinder>* handle, sp<IGraphicBufferProducer>* 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<MessageBase> msg = new MessageCreateLayer(mFlinger.get(), name, this, w, h, format, flags, handle, gbp); mFlinger->postMessageSync(msg); return static_cast<MessageCreateLayer*>( msg.get() )->getResult(); }
到來到去,其實就2句話:
postMessageSync,其實就是一開始不會直接建立surface,而後放入surfaceflinger隊列裏,這樣不會打斷如今的操做。
而後啓動createlayer方法。這個方法以前已經分析過了。
參考:
《深刻理解android內核設計思想》 林學森