Graphic 學(xué)習(xí)筆記

發(fā)現(xiàn)一個(gè)比較好的介紹graphic帖子, 后面會(huì)跟著帖子來(lái)梳理下graphic相關(guān)知識(shí)點(diǎn)
http://blog.csdn.net/u014409795/article/details/51276468

  • BufferQueue

  • ?????? class BufferQueue {
    ???????????? ?class ProxyConsumerListener : public BnConsumerListener;
    ????????????? static void createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
    ??????????????????????? sp<IGraphicBufferConsumer>* outConsumer,
    ????????????????????????const sp<IGraphicBufferAlloc>& allocator = NULL);
    ????????private:
    ???????????? BufferQueue(); // Create through createBufferQueue

    ???? }

    ???? //看起來(lái)只有consumer一個(gè)角色败京?


    ??? void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
    ??????? sp<IGraphicBufferConsumer>* outConsumer,
    ??????? const sp<IGraphicBufferAlloc>& allocator) {

    ??????? sp<BufferQueueCore> core(new BufferQueueCore(allocator));
    ??????? sp<IGraphicBufferProducer> producer(new BufferQueueProducer(core));

    ??????? sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core));

    ? BufferQueue核心是BufferQueueCore,

    ??看BufferQueueCore里面是管理什么的?

    ? class BufferQueueCore : public virtual RefBase {

    ??????????friend class BufferQueueProducer;
    ??????????friend class BufferQueueConsumer;

    ????????? ?typedef Vector<BufferItem> Fifo;? //一個(gè)BufferItem Vector

    ???????? private:

    ???????? // mAllocator is the connection to SurfaceFlinger that is used to allocate
    ???????? // new GraphicBuffer objects.
    ??????? sp<IGraphicBufferAlloc> mAllocator;
    ???????? // mSlots is an array of buffer slots that must be mirrored on the producer
    ??????? // side. This allows buffer ownership to be transferred between the producer
    ??????? // and consumer without sending a GraphicBuffer over Binder. The entire
    ?????? // array is initialized to NULL at construction time, and buffers are
    ?????? // allocated for a slot when requestBuffer is called with that slot's index.
    ??????? BufferQueueDefs::SlotsType mSlots;?? //


    ??????? BufferSlot()
    ??? : mEglDisplay(EGL_NO_DISPLAY),
    ????? mBufferState(BufferSlot::FREE),???//state
    ????? mRequestBufferCalled(false),
    ????? mFrameNumber(0),
    ????? mEglFence(EGL_NO_SYNC_KHR),
    ????? mAcquireCalled(false),
    ????? mNeedsCleanupOnRelease(false),
    ????? mAttachedByConsumer(false) {
    ??? }

    ??? // mGraphicBuffer points to the buffer allocated for this slot or is NULL
    ??? // if no buffer has been allocated.
    ??? sp<GraphicBuffer> mGraphicBuffer;?? //bufferslot中指向GraphicBuffer

    ?? ?enum BufferState { // state?表示buffer?state

    ??? ?FREE = 0,??//FREE indicates that the buffer is available to be dequeued by the producer.
    ?????//?允許produce獲取該buffer,填充數(shù)據(jù)惋戏,狀態(tài)變?yōu)閐equeue??? free 時(shí)表示該buffer還被bufferqueue 所有

    ?? DEQUEUED = 1,//?DEQUEUED indicates that the buffer has been dequeued by the ?producer, but has not yet been queued or canceled. The slot is "owned" by the producer.? 處于待填充數(shù)據(jù)狀態(tài),被producer所有

    ? QUEUED = 2,//QUEUED indicates that the buffer has been filled by the producer and queued for use by the consumer; producer填充完數(shù)據(jù)春贸,準(zhǔn)備提供給consumer消費(fèi),被bufferqueue所有

    ? ?ACQUIRED = 3//ACQUIRED indicates that the buffer has been acquired by the ?consumer.

    ?? buffer被consumer獲取到狱杰,消費(fèi)完后轉(zhuǎn)為free

    ?? 在bufferqueuecore中bufferItem又是什么
    ?? class BufferItem : public Flattenable<BufferItem> {

    ?? // mGraphicBuffer points to the buffer allocated for this slot, or is NULL
    ??? // if the buffer in this slot has been acquired in the past (see
    ??? // BufferSlot.mAcquireCalled).
    ??? sp<GraphicBuffer> mGraphicBuffer; //也有GraphicBuffer指針?

    ??? ?union {
    ??????? // mSlot is the slot index of this buffer (default INVALID_BUFFER_SLOT).
    ??????? int mSlot; // slot數(shù)組中索引

    ??????? // mBuf is the former name for mSlot
    ??????? int mBuf;? //?舊名字
    ??? };

    ?? BufferSlot 與 BufferItem 都指向GraphicBuffer,然后又 通過(guò)mSlot下標(biāo)關(guān)聯(lián)起來(lái)差凹,至于兩者使用場(chǎng)景再看期奔,至于GraphicBuffer是如何再通過(guò)GraphicBufferAlloc分配的,待進(jìn)一步trace,目前繼續(xù)聚焦于BufferQueue使用

    在SurfaceMediaSource::read()就是一個(gè)consumer acquire場(chǎng)景
    SurfaceMediaSource::signalBufferReturned()是consumer release場(chǎng)景危尿,但什么時(shí)候調(diào)用的呢呐萌?是通過(guò)mediaBuffer自身的observer來(lái)通知consumer release該buffer

    void MediaBuffer::release() {

    mObserver->signalBufferReturned(this);


    struct VideoNativeMetadata {
    ??? MetadataBufferType eType;?????????????? // must be kMetadataBufferTypeANWBuffer
    #ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
    ??? OMX_PTR pBuffer;
    #else
    ??? struct ANativeWindowBuffer* pBuffer;
    #endif
    ??? int nFenceFd;?????????????????????????? // -1 if unused
    };

    下面聚焦BufferQueue使用過(guò)程

    ?BufferQueue::createBufferQueue(&mProducer, &mConsumer);

    可以跳轉(zhuǎn)到文章開(kāi)頭看CreateBufferQueue, Producer與Consumer 實(shí)際是共用bufferslot,然后通過(guò)不同的BufferState 來(lái)判斷實(shí)際空間上數(shù)據(jù)是歸屬于誰(shuí),正被誰(shuí)使用

    mConsumer->setDefaultBufferSize(bufferWidth, bufferHeight); //這個(gè)寬和高是codec要編解碼的寬和高

    至于producer是如何跟surfaceview關(guān)聯(lián)起來(lái)的谊娇?
    base/core/jni/android_view_Surface.cpp:jobject android_view_Surface_createFromIGraphicBufferProducer(JNIEnv* env

    ?sp<Surface> surface(new Surface(bufferProducer, true))搁胆;這樣關(guān)聯(lián)起來(lái)了

    生產(chǎn)者

    status_t BufferQueueProducer::dequeueBuffer(){

    while (found == BufferItem::INVALID_BUFFER_SLOT) {
    ??????????? status_t status = waitForFreeSlotThenRelock("dequeueBuffer", async,
    ??????????????????? &found, &returnFlags);} //得到一個(gè)空閑的slot 號(hào) found

    ?const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
    ??????? if ((buffer == NULL) ||?buffer->needsReallocation(width, height, format, usage)){}else{}

    判斷graphic buffer是否需要重新分配

    if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
    sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
    ??????????????? width, height, format, usage, &error)); }

    return returnFlags;}

    填充數(shù)據(jù)完成

    status_t BufferQueueProducer::queueBuffer(){

    input.deflate(&timestamp, &isAutoTimestamp, &dataSpace, &crop, &scalingMode,
    ??????????? &transform, &async, &fence, &stickyTransform);

    mSlots[slot].mBufferState = BufferSlot::QUEUED;

    BufferItem item;

    ?mCore->mQueue.push_back(item);// 將buffer 放入bufferqueuecore隊(duì)列,供consumer到時(shí)acquire

    ?mCore->mDequeueCondition.broadcast();? }

    BufferQueueProducer::cancelBuffer(){

    ??? mCore->mFreeBuffers.push_front(slot);
    ??? mSlots[slot].mBufferState = BufferSlot::FREE; }


    BufferQueueProducer::connect(){}

    BufferQueueProducer::disconnect(int api){}? //BufferQueue跟app的生死綁定到了一起邮绿,當(dāng)app莫名其妙的死掉以后,flinger服務(wù)中的BufferQueue就知道攀例,會(huì)做一些清理工作

    void BufferQueueProducer::allocateBuffers(){

    newBufferCount =
    ??????????????????? static_cast<size_t>(maxBufferCount - currentBufferCount);

    for (size_t i = 0; i <? newBufferCount; ++i) {

    sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
    ??????????????????? allocWidth, allocHeight, allocFormat, allocUsage, &result));?}? }//這個(gè)buffer分配被void Surface::allocateBuffers()調(diào)用

    消費(fèi)者
    status_t BufferQueueConsumer::acquireBuffer(){

    ?BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin());
    ??int slot = front->mSlot;
    ??*outBuffer = *front;
    ???mSlots[slot].mBufferState = BufferSlot::ACQUIRED;
    ?? mCore->mQueue.erase(front);??? }

    status_t BufferQueueConsumer::releaseBuffer(int slot..){
    ??????? if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) {
    ??????????? mSlots[slot].mBufferState = BufferSlot::FREE;
    ??????????? mCore->mFreeBuffers.push_back(slot); }??//acquire, release?只是簡(jiǎn)單的狀態(tài)改變和插入對(duì)應(yīng)隊(duì)列?}

    最后編輯于
    ?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
    • 序言:七十年代末船逮,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子粤铭,更是在濱河造成了極大的恐慌挖胃,老刑警劉巖,帶你破解...
      沈念sama閱讀 218,386評(píng)論 6 506
    • 序言:濱河連續(xù)發(fā)生了三起死亡事件梆惯,死亡現(xiàn)場(chǎng)離奇詭異酱鸭,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)垛吗,發(fā)現(xiàn)死者居然都...
      沈念sama閱讀 93,142評(píng)論 3 394
    • 文/潘曉璐 我一進(jìn)店門(mén)凹髓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人怯屉,你說(shuō)我怎么就攤上這事蔚舀《祝” “怎么了?”我有些...
      開(kāi)封第一講書(shū)人閱讀 164,704評(píng)論 0 353
    • 文/不壞的土叔 我叫張陵赌躺,是天一觀的道長(zhǎng)狼牺。 經(jīng)常有香客問(wèn)我,道長(zhǎng)礼患,這世上最難降的妖魔是什么是钥? 我笑而不...
      開(kāi)封第一講書(shū)人閱讀 58,702評(píng)論 1 294
    • 正文 為了忘掉前任,我火速辦了婚禮缅叠,結(jié)果婚禮上悄泥,老公的妹妹穿的比我還像新娘。我一直安慰自己痪署,他們只是感情好码泞,可當(dāng)我...
      茶點(diǎn)故事閱讀 67,716評(píng)論 6 392
    • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著狼犯,像睡著了一般余寥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上悯森,一...
      開(kāi)封第一講書(shū)人閱讀 51,573評(píng)論 1 305
    • 那天宋舷,我揣著相機(jī)與錄音,去河邊找鬼瓢姻。 笑死祝蝠,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的幻碱。 我是一名探鬼主播绎狭,決...
      沈念sama閱讀 40,314評(píng)論 3 418
    • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼褥傍!你這毒婦竟也來(lái)了儡嘶?” 一聲冷哼從身側(cè)響起,我...
      開(kāi)封第一講書(shū)人閱讀 39,230評(píng)論 0 276
    • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤恍风,失蹤者是張志新(化名)和其女友劉穎蹦狂,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體朋贬,經(jīng)...
      沈念sama閱讀 45,680評(píng)論 1 314
    • 正文 獨(dú)居荒郊野嶺守林人離奇死亡凯楔,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
      茶點(diǎn)故事閱讀 37,873評(píng)論 3 336
    • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了锦募。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片摆屯。...
      茶點(diǎn)故事閱讀 39,991評(píng)論 1 348
    • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖御滩,靈堂內(nèi)的尸體忽然破棺而出鸥拧,到底是詐尸還是另有隱情党远,我是刑警寧澤,帶...
      沈念sama閱讀 35,706評(píng)論 5 346
    • 正文 年R本政府宣布富弦,位于F島的核電站沟娱,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏腕柜。R本人自食惡果不足惜济似,卻給世界環(huán)境...
      茶點(diǎn)故事閱讀 41,329評(píng)論 3 330
    • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望盏缤。 院中可真熱鬧砰蠢,春花似錦、人聲如沸唉铜。這莊子的主人今日做“春日...
      開(kāi)封第一講書(shū)人閱讀 31,910評(píng)論 0 22
    • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)潭流。三九已至竞惋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間灰嫉,已是汗流浹背拆宛。 一陣腳步聲響...
      開(kāi)封第一講書(shū)人閱讀 33,038評(píng)論 1 270
    • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留讼撒,地道東北人浑厚。 一個(gè)月前我還...
      沈念sama閱讀 48,158評(píng)論 3 370
    • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像根盒,于是被迫代替她去往敵國(guó)和親钳幅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
      茶點(diǎn)故事閱讀 44,941評(píng)論 2 355

    推薦閱讀更多精彩內(nèi)容

    • 本篇文章是基于谷歌有關(guān)Graphic的一篇概覽文章的翻譯:http://source.android.com/de...
      lee_3do閱讀 7,123評(píng)論 2 21
    • **2014真題Directions:Read the following text. Choose the be...
      又是夜半驚坐起閱讀 9,505評(píng)論 0 23
    • 財(cái)富的定義:‘當(dāng)你完全不工作’(或者你家里的所有人都完全不工作)時(shí)炎滞,在你現(xiàn)有的生活水平之下你所能生存的天數(shù)贡这。財(cái)富是...
      王潔敏閱讀 211評(píng)論 0 0
    • 畢業(yè)4年,同學(xué)見(jiàn)面的時(shí)候聊得最多的莫過(guò)于誰(shuí)誰(shuí)誰(shuí)結(jié)婚了厂榛,誰(shuí)誰(shuí)誰(shuí)生小孩了±霾眩可能是因?yàn)槲覀兌际桥髂蹋急容^關(guān)...
      未雨_綢繆閱讀 272評(píng)論 0 0