surfaceflinger 合成過程解析
阿新 • • 發佈:2018-11-10
用 [TOC]
來生成目錄:
整體流程
我們知道,當VSync訊號到來時,SurfaceFlinger最主要是通過處理INVALIDATE和REFRESH訊息來做合併渲染和輸出的工作的。這裡的核心思想是能少處理一點是一點,所以在渲染前有很多髒區域的計算工作,這樣後面只要處理那些區域的更新就可以了。
這樣是有現實意義的,一方面由於圖層間的遮蓋,有些不可見圖層不需要渲染。另一方面,因為我們的應用程式中前後幀一般只有一小部分變化,要是每幀都全變估計人都要看吐了。這裡主要是呼叫了這幾個函式:
handleMessageTransaction
handleMessageInvalidate()主要呼叫handlePageFlip()函式。這裡Page Flip是指從BufferQueue中取下一個圖形緩衝區內容,就好像是“翻頁”一樣。該函式主要是從各Layer對應的BufferQueue中拿圖形緩衝區資料,並根據內容更新髒區域。
handleMessageRefresh()就是合併和渲染輸出了。
handleMessageInvalidate
如上所說,這個主要是把所有可見的layer的buffer拿出來。
handleMessageInvalidate只調用了handlePageFlip
bool SurfaceFlinger::handlePageFlip()
{
Region dirtyRegion;
bool visibleRegions = false;
const LayerVector& layers(mDrawingState.layersSortedByZ);//拿出所有的layer
bool frameQueued = false;
Vector<Layer*> layersWithQueuedFrames;
for (size_t i = 0, count = layers.size(); i<count ; i++) {
const sp<Layer>& layer(layers[i]);
if (layer->hasQueuedFrame()) {//看Layer的mQueuedFrames > 0?
frameQueued = true;
if (layer->shouldPresentNow(mPrimaryDispSync)) {
layersWithQueuedFrames.push_back(layer.get());
}
}
}
//如果layersWithQueuedFrames.size()>0,說明有更新
for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) {
Layer* layer = layersWithQueuedFrames[i];
const Region dirty(layer->latchBuffer(visibleRegions));//呼叫latchBuffer,該函式會拿出BufferQueue的新buffer
const Layer::State& s(layer->getDrawingState());
invalidateLayerStack(s.layerStack, dirty);
}
mVisibleRegionsDirty |= visibleRegions;
if (frameQueued && layersWithQueuedFrames.empty()) {
signalLayerUpdate();//如果沒有任何layer更新,那就呼叫signalLayerUpdate->requestNextVsync,等待下一個vsync
}
return !layersWithQueuedFrames.empty();//有新幀,就返回true
}
handleMessageRefresh
前一步,已經把各個layer的buffer更新了,接著就是要合成並輸出了,這個函式就幹這個事情。
且看其定義。
void SurfaceFlinger::handleMessageRefresh() {
ATRACE_CALL();
preComposition();
rebuildLayerStacks();
setUpHWComposer();
doDebugFlashRegions();
doComposition();
postComposition();
}
1. preComposition
void SurfaceFlinger::preComposition()
{
bool needExtraInvalidate = false;
const LayerVector& layers(mDrawingState.layersSortedByZ);
const size_t count = layers.size();
for (size_t i=0 ; i<count ; i++) {
if (layers[i]->onPreComposition()) {//判斷mQueuedFrames > 0
needExtraInvalidate = true;
}
}
if (needExtraInvalidate) {
signalLayerUpdate();//一旦有某一個layer有更新,就呼叫signalLayerUpdate->requestNextVsync
}
}
signalLayerUpdate主要呼叫
mEvents->requestNextVsync();
2. rebuildLayerStacks
根據函式名字就可以知道,他主要是對所有的layer過濾一遍,拿出可見的layer,等待下一步處理。
函式比較簡單,這裡不詳說。
3. setUpHWComposer
void SurfaceFlinger::setUpHWComposer() {
//省略。。。
HWComposer& hwc(getHwComposer());
if (hwc.initCheck() == NO_ERROR) {
// build the h/w work list
if (CC_UNLIKELY(mHwWorkListDirty)) {
mHwWorkListDirty = false;
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {//其實大部分情況,只有一個DisplayDevice
sp<const DisplayDevice> hw(mDisplays[dpy]);
const int32_t id = hw->getHwcDisplayId();//DisplayDevice的id
if (id >= 0) {
const Vector< sp<Layer> >& currentLayers(
hw->getVisibleLayersSortedByZ());//rebuildLayerStacks時,把可見的layer存在DisplayDevice了
const size_t count = currentLayers.size();//可見的layer
if (hwc.createWorkList(id, count) == NO_ERROR) {//HWC的createWorkList很重要。
HWComposer::LayerListIterator cur = hwc.begin(id);
const HWComposer::LayerListIterator end = hwc.end(id);
for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
const sp<Layer>& layer(currentLayers[i]);
layer->setGeometry(hw, *cur);
if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix) {
cur->setSkip(true);
}
}
}
}
}
}
}