Android 12(S) 圖像顯示系統 - BufferQueue的工作流程(九)



題外話

Covid-19疫情的強烈反彈,小區里檢測出了無症狀感染者。小區封閉管理,我也不得不居家辦公了。既然這么大把的時間可以光明正大的宅家里,自然要好好利用,八個字 == 努力工作,好好學習


 

一、前言


這篇文章中,將詳細講解 生產者 -- 圖形緩沖隊列 -- 消費者 這個模型的的具體工作流程。我們還是從我們的demo運行流程着手。

可以再回頭看看 Android 12(S) 圖像顯示系統 - 示例應用(二)

在demo示例中,我們獲取buffer --> 填充數據 --> 送出顯示的代碼如下所示(做了簡化):

        // 9. dequeue a buffer
        ANativeWindowBuffer *nativeBuffer = nullptr;
        int hwcFD = -1;
        err = nativeWindow->dequeueBuffer(nativeWindow, &nativeBuffer, &hwcFD);

        // 10. make sure really control the dequeued buffer
        sp<Fence> hwcFence(new Fence(hwcFD));
        int waitResult = hwcFence->waitForever("dequeueBuffer_EmptyNative");
        // 11. fill buffer
        sp<GraphicBuffer> buf(GraphicBuffer::from(nativeBuffer));
        uint8_t* img = nullptr;
        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
        fillRGBA8Buffer(img);
        err = buf->unlock();

        // 13. queue the buffer to display
        int gpuFD = -1;
        err = nativeWindow->queueBuffer(nativeWindow, buf->getNativeBuffer(), gpuFD);

獲取圖形緩沖區調用流程:

==> ANativeWindow::dequeueBuffer 

==> Surface::hook_dequeueBuffer

==> Surface::dequeueBuffer

==> BufferQueueProducer::dequeueBuffer

填充數據后返還圖形緩沖區的調用流程:

==> ANativeWindow::queueBuffer

==> Surface::hook_queueBuffer

==> Surface::queueBuffer

==> BufferQueueProducer::queueBuffer

前面文章講解中提到,BLASTBufferQueue中創建Surface對象時,初始化其成員mGraphicBufferProducer,這個就是指向了一個GraphicBufferProducer對象。

當然,demo作為客戶端僅僅是展示了生產者的工作,那消費者的工作又是如何的呢?

先用一張流程圖概述一下:

 

上圖基本展示了BufferQueue的工作邏輯以及Buffer的流轉過程和狀態變化情況。


上圖描述的流程我再重復嘮叨一遍:

  1. Producer准備繪圖時,調用dequeueBuffer向BufferQueue請求一塊buffer;
  2. BufferQueue收到dequeueBuffer的請求后會去自己的BufferSlot隊列中尋找一個FREE狀態的,然后返回它的index;
  3. Producer拿到可用的buffer后就可以准備填充數據了;
  4. Producer填充數據完畢,調用queueBuffer將bffer再返還給BufferQueue;
  5. BufferQueue收到queueBuffer請求后,將指定的buffer包裝為BufferItem對象,放入mQueue,並通知Consumer來消費;
  6. Consumer收到 frame available的通知后,調用acquireBuffer,獲取一個buffer;
  7. Consumer拿到buffer進行消費,一般是指SurfaceFlinger做渲染顯示;
  8. Consumer完成處理,調用releaseBuffer把buffer返還給BufferQueue,這個buffer之后就可以再次在新的循環中使用了。

另外一點請留意各個函數調用后,對應的BufferSlot(GraphicBuffer)的狀態變化。一般是這樣的:

FREE -> DEQUEUED -> QUEUED -> ACQUIRED -> FREE


 

二、生產者-Producer的相關邏輯


代碼位置 :/frameworks/native/libs/gui/BufferQueueProducer.cpp

 

 

關注公眾號 Android元宇宙 繼續閱讀相關文章!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM