網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
一 Surfaceflinger介紹
surfaceflinger作用是接受多個(gè)來(lái)源的圖形顯示數(shù)據(jù),將他們合成,然后發(fā)送到顯示設(shè)備。比如打開(kāi)應(yīng)用,常見(jiàn)的有三層顯示,頂部的statusbar底部或者側(cè)面的導(dǎo)航欄以及應(yīng)用的界面,每個(gè)層是單獨(dú)更新和渲染,這些界面都是有surfaceflinger合成一個(gè)刷新到硬件顯示。在顯示過(guò)程中使用到了bufferqueue,surfaceflinger作為consumer方,比如windwomanager管理的surface作為生產(chǎn)方產(chǎn)生頁(yè)面,交由surfaceflinger進(jìn)行合成。
二 bufferqueue 原理
bufferqueue分為生產(chǎn)者和消費(fèi)者
比如應(yīng)用通過(guò)windowsmanager分配一個(gè)surface,需要分配(dequeueBuffer)顯示空間在上面進(jìn)行繪圖,在圖形繪制完成后需要推送(queueBuffer)到surfaceflinger進(jìn)行合成顯示。
surfaceflinger作為消費(fèi)者,通過(guò)acquireBuffer()得到一個(gè)要合成的圖形,在合成完畢后再releaseBuffer()將圖形釋放。
bufferqueue類(lèi)圖關(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的連接,通過(guò)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é)這個(gè)顯示層的控制。
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; }
通過(guò)SurfaceControl::getSurface(),得到的真正的顯示層,這樣之后可以通過(guò)Lock和unlock將surface空間分配繪圖,再返回給surfaceflinger
上面只是cpp側(cè)的分析,上層比如WMS是java層,他的管理也是同底層一樣,只不過(guò)是有層JNI的封裝。
四 layer顯示內(nèi)存分配
surface創(chuàng)建后得到 mGraphicBufferProducer,通過(guò)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分配一個(gè)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中就是分配一個(gè)共享內(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)建一個(gè)surface后,surfaceflinger對(duì)應(yīng)的是一個(gè)layer,當(dāng)上層layer調(diào)用刷新后,onFrameAvailable被調(diào)用,通知surfaceflinger有l(wèi)ayer更新
void BufferLayer::onFrameAvailable(const BufferItem& item) { mFlinger->signalLayerUpdate(); }
原文鏈接:https://www.jianshu.com/p/656fb878f9ee
相關(guān)推薦
- 2023-04-29 C++數(shù)組模擬之單鏈表與雙鏈表和棧和隊(duì)列的實(shí)現(xiàn)過(guò)程_C 語(yǔ)言
- 2022-09-08 返回最大值的index?pytorch方式_python
- 2022-09-30 Python使用draw類(lèi)繪制圖形示例講解_python
- 2022-03-24 Sublime?Text3安裝Go語(yǔ)言相關(guān)插件gosublime時(shí)搜不到gosublime的解決方法
- 2022-10-12 python?time時(shí)間庫(kù)詳解_python
- 2022-08-31 Flask接收上傳圖片方法實(shí)現(xiàn)_python
- 2022-03-23 Android應(yīng)用內(nèi)懸浮窗Activity的簡(jiǎn)單實(shí)現(xiàn)_Android
- 2022-11-30 golang中的defer函數(shù)理解_Golang
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支