Android顯示系統(tǒng)SurfaceFlinger分析
一 Surfaceflinger介紹
surfaceflinger作用是接受多個(gè)來源的圖形顯示數(shù)據(jù),將他們合成,然后發(fā)送到顯示設(shè)備。比如打開應(yīng)用,常見的有三層顯示,頂部的statusbar底部或者側(cè)面的導(dǎo)航欄以及應(yīng)用的界面,每個(gè)層是單獨(dú)更新和渲染,這些界面都是有surfaceflinger合成一個(gè)刷新到硬件顯示。在顯示過程中使用到了bufferqueue,surfaceflinger作為consumer方,比如windwomanager管理的surface作為生產(chǎn)方產(chǎn)生頁面,交由surfaceflinger進(jìn)行合成。
二 bufferqueue 原理

bufferqueue分為生產(chǎn)者和消費(fèi)者
比如應(yīng)用通過windowsmanager分配一個(gè)surface,需要分配(dequeueBuffer)顯示空間在上面進(jìn)行繪圖,在圖形繪制完成后需要推送(queueBuffer)到surfaceflinger進(jìn)行合成顯示。
surfaceflinger作為消費(fèi)者,通過acquireBuffer()得到一個(gè)要合成的圖形,在合成完畢后再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é)這個(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;
}
通過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分配一個(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();
}
到此這篇關(guān)于Android顯示系統(tǒng)SurfaceFlinger分析的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android編程中出現(xiàn)The connection to adb is down問題的解決方法
這篇文章主要介紹了Android編程中出現(xiàn)The connection to adb is down問題的解決方法,涉及Android進(jìn)程與服務(wù)的相關(guān)操作技巧,需要的朋友可以參考下2015-12-12
ViewPager實(shí)現(xiàn)輪播圖引導(dǎo)頁
這篇文章主要為大家詳細(xì)介紹了ViewPager實(shí)現(xiàn)輪播圖引導(dǎo)頁,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-09-09
Android UI系列-----ScrollView和HorizontalScrollView的詳解
本篇文章主要是介紹的Android UI系列-----ScrollView和HorizontalScrollView,ScrollView和HorizontalScrollView都是布局容器,有需要的可以了解一下。2016-11-11
Android.mk引入第三方j(luò)ar包和so庫文件的方法
這篇文章主要介紹了Android.mk引入第三方j(luò)ar包和so庫文件的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-05-05
Android開發(fā)-之環(huán)境的搭建(圖文詳解)
這篇文章主要介紹了Android開發(fā)-之環(huán)境的搭建(圖文詳解),具有一定的參考價(jià)值,有興趣的可以了解一下。2016-11-11
android自定義滾動(dòng)上下回彈scollView
這篇文章主要為大家詳細(xì)介紹了android自定義滾動(dòng)上下回彈scollView,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04

