Android顯示系統(tǒng)SurfaceFlinger分析
一 Surfaceflinger介紹
surfaceflinger作用是接受多個來源的圖形顯示數(shù)據(jù),將他們合成,然后發(fā)送到顯示設(shè)備。比如打開應(yīng)用,常見的有三層顯示,頂部的statusbar底部或者側(cè)面的導(dǎo)航欄以及應(yīng)用的界面,每個層是單獨更新和渲染,這些界面都是有surfaceflinger合成一個刷新到硬件顯示。在顯示過程中使用到了bufferqueue,surfaceflinger作為consumer方,比如windwomanager管理的surface作為生產(chǎn)方產(chǎn)生頁面,交由surfaceflinger進(jìn)行合成。
二 bufferqueue 原理
bufferqueue分為生產(chǎn)者和消費者
比如應(yīng)用通過windowsmanager分配一個surface,需要分配(dequeueBuffer)顯示空間在上面進(jìn)行繪圖,在圖形繪制完成后需要推送(queueBuffer)到surfaceflinger進(jìn)行合成顯示。
surfaceflinger作為消費者,通過acquireBuffer()得到一個要合成的圖形,在合成完畢后再releaseBuffer()將圖形釋放。
bufferqueue類圖關(guān)系如下:
三 surfaceflinger 關(guān)系圖
ComposerService 為單例模式負(fù)責(zé)與surfaceflinger建立binder連接代碼如下:
class ComposerService : public Singleton<ComposerService> { sp<ISurfaceComposer> mComposerService; sp<IBinder::DeathRecipient> mDeathObserver; Mutex mLock; ComposerService(); void connectLocked(); void composerServiceDied(); friend class Singleton<ComposerService>; public: // Get a connection to the Composer Service. This will block until // a connection is established. static sp<ISurfaceComposer> getComposerService(); }; void ComposerService::connectLocked() { const String16 name("SurfaceFlinger"); while (getService(name, &mComposerService) != NO_ERROR) { usleep(250000); } assert(mComposerService != NULL); // Create the death listener. class DeathObserver : public IBinder::DeathRecipient { ComposerService& mComposerService; virtual void binderDied(const wp<IBinder>& who) { ALOGW("ComposerService remote (surfaceflinger) died [%p]", who.unsafe_get()); mComposerService.composerServiceDied(); } public: DeathObserver(ComposerService& mgr) : mComposerService(mgr) { } }; mDeathObserver = new DeathObserver(*const_cast<ComposerService*>(this)); mComposerService->asBinder()->linkToDeath(mDeathObserver); } /*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() { ComposerService& instance = ComposerService::getInstance(); Mutex::Autolock _l(instance.mLock); if (instance.mComposerService == NULL) { ComposerService::getInstance().connectLocked(); assert(instance.mComposerService != NULL); ALOGD("ComposerService reconnected"); } return instance.mComposerService; }
SurfaceComposerClient則在于surfaceflinger建立連接后建立與Client的連接,通過client調(diào)用createSurface,然后返回SurfaceControl
sp<SurfaceControl> SurfaceComposerClient::createSurface( const String8& name, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { sp<SurfaceControl> sur; if (mStatus == NO_ERROR) { sp<IBinder> handle; sp<IGraphicBufferProducer> gbp; status_t err = mClient->createSurface(name, w, h, format, flags, &handle, &gbp); ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err)); if (err == NO_ERROR) { sur = new SurfaceControl(this, handle, gbp); } } return sur; }
SurfaceControl負(fù)責(zé)這個顯示層的控制。
sp<Surface> SurfaceControl::getSurface() const { Mutex::Autolock _l(mLock); if (mSurfaceData == 0) { // This surface is always consumed by SurfaceFlinger, so the // producerControlledByApp value doesn't matter; using false. mSurfaceData = new Surface(mGraphicBufferProducer, false); } return mSurfaceData; }
通過SurfaceControl::getSurface(),得到的真正的顯示層,這樣之后可以通過Lock和unlock將surface空間分配繪圖,再返回給surfaceflinger
上面只是cpp側(cè)的分析,上層比如WMS是java層,他的管理也是同底層一樣,只不過是有層JNI的封裝。
四 layer顯示內(nèi)存分配
surface創(chuàng)建后得到 mGraphicBufferProducer,通過mGraphicBufferProducer dequeubuffer在surfaceflinger的BnGraphicBufferProducer dequeuebuffer
int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) { status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, mSwapIntervalZero, reqW, reqH, mReqFormat, mReqUsage); sp<GraphicBuffer>& gbuf(mSlots[buf].buffer); if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) { result = mGraphicBufferProducer->requestBuffer(buf, &gbuf); if (result != NO_ERROR) { ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result); return result; } *buffer = gbuf.get(); } }
在producer的server側(cè),new GraphicBuffer分配一個GraphicBuffer
if (returnFlags & BUFFER_NEEDS_REALLOCATION) { BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot); sp<GraphicBuffer> graphicBuffer = new GraphicBuffer( width, height, format, BQ_LAYER_COUNT, usage, {mConsumerName.string(), mConsumerName.size()});
在graphicbuffer中就是分配一個共享內(nèi)存
GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, uint32_t inLayerCount, uint64_t usage, std::string requestorName) : GraphicBuffer() { mInitCheck = initWithSize(inWidth, inHeight, inFormat, inLayerCount, usage, std::move(requestorName)); } status_t GraphicBuffer::initWithSize(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, uint32_t inLayerCount, uint64_t inUsage, std::string requestorName) { GraphicBufferAllocator& allocator = GraphicBufferAllocator::get(); uint32_t outStride = 0; status_t err = allocator.allocate(inWidth, inHeight, inFormat, inLayerCount, inUsage, &handle, &outStride, mId, std::move(requestorName)); if (err == NO_ERROR) { mBufferMapper.getTransportSize(handle, &mTransportNumFds, &mTransportNumInts); width = static_cast<int>(inWidth); height = static_cast<int>(inHeight); format = inFormat; layerCount = inLayerCount; usage = inUsage; usage_deprecated = int(usage); stride = static_cast<int>(outStride); } return err; }
GraphicBufferAllocator::get() 使用gralloc進(jìn)行內(nèi)存分配,分配完成后,得到bufferIdx 將他發(fā)給client端也就是surface端
virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) { Parcel data, reply; data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); data.writeInt32(bufferIdx); status_t result =remote()->transact(REQUEST_BUFFER, data, &reply); if (result != NO_ERROR) { return result; } bool nonNull = reply.readInt32(); if (nonNull) { *buf = new GraphicBuffer(); result = reply.read(**buf); if(result != NO_ERROR) { (*buf).clear(); return result; } } result = reply.readInt32(); return result;
返回虛擬地址給上層
void* vaddr; status_t res = backBuffer->lockAsync( GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, newDirtyRegion.bounds(), &vaddr, fenceFd);
五 surfaceflinger Layer
上面創(chuàng)建一個surface后,surfaceflinger對應(yīng)的是一個layer,當(dāng)上層layer調(diào)用刷新后,onFrameAvailable被調(diào)用,通知surfaceflinger有l(wèi)ayer更新
void BufferLayer::onFrameAvailable(const BufferItem& item) { mFlinger->signalLayerUpdate(); }
到此這篇關(guān)于Android顯示系統(tǒng)SurfaceFlinger分析的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android調(diào)用系統(tǒng)照相機(jī)拍照與攝像的方法
這篇文章主要為大家詳細(xì)介紹了Android如何調(diào)用系統(tǒng)現(xiàn)有的照相機(jī)拍照與攝像,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-04-04Android NDK開發(fā)的環(huán)境搭建與簡單示例
本文主要介紹Android NDK的知識,這里整理了相關(guān)資料,來說明如何搭建相應(yīng)環(huán)境和簡單實例,幫助大家理解,有興趣的小伙伴可以參考下2016-09-09Flutter啟動頁(閃屏頁)的具體實現(xiàn)及原理詳析
這篇文章主要給大家介紹了關(guān)于Flutter啟動頁(閃屏頁)的具體實現(xiàn)及原理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Flutter具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04詳解Android app自動更新總結(jié)(已適配9.0)
這篇文章主要介紹了詳解Android app自動更新總結(jié)(已適配9.0),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04Android WaveView實現(xiàn)水流波動效果
這篇文章主要介紹了 Android自定義控件 WaveView實現(xiàn)水流波動效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-03-03RecyclerView嵌套RecyclerView滑動卡頓的解決方法
這篇文章主要為大家詳細(xì)介紹了RecyclerView嵌套RecyclerView滑動卡頓的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-12-12