Android GraphicBuffer-Fence

少年乘勇气,百战过乌孙。这篇文章主要讲述Android GraphicBuffer-Fence相关的知识,希望能为你提供帮助。
这里需要介绍一个伴随着GraphicBuffer的Fence,包括Fence的诞生,Fence的处理。
在前面介绍Surface的时候,提到过Surface会通过BufferQueueProducer申请GraphicBuffer,用作显存,所以我们这里看一下BufferQueueProducer/Consumer是怎么管理GraphicBuffer的。(这里有一个问题,是否可以脱离BufferQueueProducer/Consumer去使用GraphicBuffer?)
BufferQueueProducer(简称producer)和BufferQueueConsumer(简称consumer)公用BufferQueueCore(简称core);core里面有一个mSlots = struct BufferSlot[64]; 同时mMaxAcquiredBufferCount=1,mMaxDequeuedBufferCount=1,同时getMaxBufferCountLocked 为3或者2:

int BufferQueueCore::getMaxBufferCountLocked() const { int maxBufferCount = mMaxAcquiredBufferCount + mMaxDequeuedBufferCount + ((mAsyncMode || mDequeueBufferCannotBlock) ? 1 : 0); // limit maxBufferCount by mMaxBufferCount always maxBufferCount = std::min(mMaxBufferCount, maxBufferCount); return maxBufferCount; }
//BufferQueueCore创建的时候会初始化mFreeSlots(最多3个元素), mUnusedSlots有64-3个元素

    int numStartingBuffers = getMaxBufferCountLocked();
    for (int s = 0; s < numStartingBuffers; s++) {
      mFreeSlots.insert(s);
    }
    for (int s = numStartingBuffers; s < BufferQueueDefs::NUM_BUFFER_SLOTS;   s++){
      mUnusedSlots.push_front(s);
    }
在APP拿到BufferQueueProducer的时候,在绘制之前,会调用BufferQueueProducer.allocateBuffers,预先分配足够的GraphicBuffer,防止在draw的时候分配造成delay;
分配Buffer的数量和mFreeSlots元素数目相同,也就是3个:
void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height, PixelFormat format, uint64_t usage) { newBufferCount = mCore-> mFreeSlots.size(); 。。。。。。
//创建3个GraphicBuffer for (size_t i = 0; i < newBufferCount; ++i) { sp< GraphicBuffer> graphicBuffer = new GraphicBuffer( allocWidth, allocHeight, allocFormat, BQ_LAYER_COUNT, allocUsage, allocName); status_t result = graphicBuffer-> initCheck(); if (result != NO_ERROR) { BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format" " %u, usage %#" PRIx64 ")", width, height, format, usage); Mutex::Autolock lock(mCore-> mMutex); mCore-> mIsAllocating = false; mCore-> mIsAllocatingCondition.broadcast(); return; } buffers.push_back(graphicBuffer); } 。。。。。
//将新创建的GraphicBuffer添加到mSlots数组中。注意mSlots的index,这个index很重要,mSlots中的数据是和index绑定的,类似于ID;其中的graphicBuffer可能会发生变化。 for (size_t i = 0; i < newBufferCount; ++i) { if (mCore-> mFreeSlots.empty()) { BQ_LOGV("allocateBuffers: a slot was occupied while " "allocating. Dropping allocated buffer."); continue; } auto slot = mCore-> mFreeSlots.begin(); mCore-> clearBufferSlotLocked(*slot); // Clean up the slot first mSlots[*slot].mGraphicBuffer = buffers[i]; mSlots[*slot].mFence = Fence::NO_FENCE; // freeBufferLocked puts this slot on the free slots list. Since // we then attached a buffer, move the slot to free buffer list. mCore-> mFreeBuffers.push_front(*slot); BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d", *slot); // Make sure the erase is done after all uses of the slot // iterator since it will be invalid after this point. mCore-> mFreeSlots.erase(slot); }}

下面看一下GraphicBuffer的创建流程:
Android GraphicBuffer-Fence

文章图片

GraphicBuffer经过GrallocService-> GrallocHal,在libgralloc里面分配;其中比较常见的方式是使用ION驱动进行分配,分配完毕之后还要为buffer分配Fence。
【Android GraphicBuffer-Fence】 

    推荐阅读