網站首頁 編程語言 正文
一 Surfaceflinger介紹
surfaceflinger作用是接受多個來源的圖形顯示數據,將他們合成,然后發送到顯示設備。比如打開應用,常見的有三層顯示,頂部的statusbar底部或者側面的導航欄以及應用的界面,每個層是單獨更新和渲染,這些界面都是有surfaceflinger合成一個刷新到硬件顯示。在顯示過程中使用到了bufferqueue,surfaceflinger作為consumer方,比如windwomanager管理的surface作為生產方產生頁面,交由surfaceflinger進行合成。
二 bufferqueue 原理
bufferqueue分為生產者和消費者
比如應用通過windowsmanager分配一個surface,需要分配(dequeueBuffer)顯示空間在上面進行繪圖,在圖形繪制完成后需要推送(queueBuffer)到surfaceflinger進行合成顯示。
surfaceflinger作為消費者,通過acquireBuffer()得到一個要合成的圖形,在合成完畢后再releaseBuffer()將圖形釋放。
bufferqueue類圖關系如下:
三 surfaceflinger 關系圖
ComposerService 為單例模式負責與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調用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負責這個顯示層的控制。
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側的分析,上層比如WMS是java層,他的管理也是同底層一樣,只不過是有層JNI的封裝。
四 layer顯示內存分配
surface創建后得到 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側,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中就是分配一個共享內存
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進行內存分配,分配完成后,得到bufferIdx 將他發給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
上面創建一個surface后,surfaceflinger對應的是一個layer,當上層layer調用刷新后,onFrameAvailable被調用,通知surfaceflinger有layer更新
void BufferLayer::onFrameAvailable(const BufferItem& item) { mFlinger->signalLayerUpdate(); }
原文鏈接:https://www.jianshu.com/p/656fb878f9ee
相關推薦
- 2022-05-15 C++11:lambda表達式詳細介紹
- 2023-06-04 Django修改端口號與地址的三種方式_python
- 2022-06-21 Android隨機給出加減乘除的四則運算算術題_Android
- 2022-07-26 ES對比兩個索引的數據差
- 2022-12-06 深入了解Rust?結構體的使用_Rust語言
- 2022-04-23 uni-app項目之商品列表的下拉刷新與上拉加載更多
- 2022-03-15 在Linux+Jexus中發布和部署Asp.Net?Core_自學過程
- 2022-09-15 C語言實現簡單的推箱子小游戲_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支