題外話
你有沒有聽見,心里有一聲咆哮,那一聲咆哮,它好像在說:我就是要從后面追上去!
寫文章真的好痛苦,特別是自己對這方面的知識也一知半解就更加痛苦了。這已經是這個系列的第六篇了,很多次都想放棄了,但最終還是堅持下來了,因為我真的好像搞懂這一塊。
1 前言
前面一篇文章中,我們已經介紹了createSurface的流程,也在SurfaceFlinger中去創建了圖層layer,但一直沒有看到buffer queue的蹤影。其實,據我觀察 Android 12 將BufferQueue的相關邏輯移出了SurfaceFlinger。這一篇文章中我們就會跟隨之前寫的應用的代碼邏輯,看看BufferQueue的相關邏輯是如何引入的?又是如何工作的?
2 創建BufferQueue/BLASTBufferQueue
接着從我們的示例應用講起,代碼在文章:Android 12(S) 圖形顯示系統 - 示例應用(二)
創建native surface后接下下就是要准備去繪圖了,流程就走到了 drawNativeSurface()這個方法中,先看內容:
int drawNativeSurface(sp<NativeSurfaceWrapper> nativeSurface) {
status_t err = NO_ERROR;
int countFrame = 0;
ANativeWindowBuffer *nativeBuffer = nullptr;
ANativeWindow* nativeWindow = nativeSurface->getSurface().get();
...
}
drawNativeSurface這個方法中首先去調用了我們定義的NativeSurfaceWrapper::getSurface方法:
sp<ANativeWindow> NativeSurfaceWrapper::getSurface() const {
sp<ANativeWindow> anw = mSurfaceControl->getSurface();
return anw;
}
getSurface方法中,mSurfaceControl就是上一篇中Android 12(S) 圖形顯示系統 - createSurface的流程(五)創建得到的,它封裝了SurfaceFlinger創建的BufferStateLayer的信息。接着來到了SurfaceControl::getSurface()
* /frameworks/native/libs/gui/SurfaceControl.cpp
sp<Surface> SurfaceControl::getSurface()
{
Mutex::Autolock _l(mLock);
if (mSurfaceData == nullptr) {
return generateSurfaceLocked();
}
return mSurfaceData;
}
其中 mSurfaceData定義如下:
* /frameworks/native/libs/gui/include/gui/SurfaceControl.h
mutable sp<Surface> mSurfaceData;
因為 SurfaceControl::getSurface() 第一次被調用,此時 mSurfaceData為null,進而會執行 SurfaceControl::generateSurfaceLocked()
sp<Surface> SurfaceControl::generateSurfaceLocked()
{
uint32_t ignore;
auto flags = mCreateFlags & (ISurfaceComposerClient::eCursorWindow |
ISurfaceComposerClient::eOpaque);
mBbqChild = mClient->createSurface(String8("bbq-wrapper"), 0, 0, mFormat,
flags, mHandle, {}, &ignore);
mBbq = sp<BLASTBufferQueue>::make("bbq-adapter", mBbqChild, mWidth, mHeight, mFormat);
// This surface is always consumed by SurfaceFlinger, so the
// producerControlledByApp value doesn't matter; using false.
mSurfaceData = mBbq->getSurface(true);
return mSurfaceData;
}
看到了沒,我們念念不忘,朝思暮想 ,魂牽夢繞的BufferQueue的邏輯 ==> BLASTBufferQueue <== 終於千呼萬喚始出來!!!
class SurfaceControl : public RefBase
...
private:
sp<SurfaceComposerClient> mClient; // 應用創建的SurfaceComposerClient對象指針,里面封裝了和SurfaceFlinger通信的Binder客戶端
sp<IBinder> mHandle; // 應用中顯式創建的layer handle,這是個BufferStateLayer 它作為parent
sp<IGraphicBufferProducer> mGraphicBufferProducer; // 這個貌似沒有實際用了?
mutable Mutex mLock;
mutable sp<Surface> mSurfaceData; //
mutable sp<BLASTBufferQueue> mBbq; // BLASTBufferQueue對象實例
mutable sp<SurfaceControl> mBbqChild; // child layer,它會和mBbq相關聯
int32_t mLayerId; // layer id
uint32_t mTransformHint; // 方向
uint32_t mWidth; // surface 寬
uint32_t mHeight; // surface 高
PixelFormat mFormat;
uint32_t mCreateFlags; // createSurface的標志信息
};
SurfaceControl中一些成員和類圖,下圖可能並不完全准確
我們看看generateSurfaceLocked都干了什么:
♦ mCreateFlags是一個uint32_t類型的變量,表示createSurface的一些屬性標識,這個值其實就是我們調用surfaceComposerClient->createSurface時new SurfaceControl傳遞下來的
♦ mClient,類型是sp<SurfaceComposerClient> 這個值也是我們調用surfaceComposerClient->createSurface時new SurfaceControl傳遞下來的
♦ mClient->createSurface 流程和我們上一章的流程是一樣的,傳遞的參數有點差異
>> surface/layer的名字為“bbq-wrapper”
>> 待創建的surface/layer設置其parent是mHandle所指向的layer,,mHandle也即是我們應用中顯示創建的那個名字為"NativeSFDemo"的layer
♦ 新創建的這個 child surface 或叫做 child layer的信息同樣被封裝到一個SurfceControl對象中,保存在 mBbqChild
我們在Android 12(S) 圖形顯示系統 - 示例應用(二)文章最后曾留下一個問題,看到這里你是不是就明白了🤩
主角登場
mBbq = sp<BLASTBufferQueue>::make("bbq-adapter", mBbqChild, mWidth, mHeight, mFormat);
♦ 創建一個BLASTBufferQueue對象,保存在mBbq中
♦ 最后調用BLASTBufferQueue::getSurface函數,返回一個sp<Surface>給應用,之后應用就可以通過這個Surface操做BufferQueue了。