发现一个比较好的介绍graphic帖子, 后面会跟着帖子来梳理下graphic相关知识点
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
}
//看起来只有consumer一个角色?
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; //一个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,填充数据,状态变为dequeue free 时表示该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. 处于待填充数据状态,被producer所有
QUEUED = 2,//QUEUED indicates that the buffer has been filled by the producer and queued for use by the consumer; producer填充完数据,准备提供给consumer消费,被bufferqueue所有
ACQUIRED = 3//ACQUIRED indicates that the buffer has been acquired by the consumer.
buffer被consumer获取到,消费完后转为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数组中索引
// mBuf is the former name for mSlot
int mBuf; // 旧名字
};
BufferSlot 与 BufferItem 都指向GraphicBuffer,然后又 通过mSlot下标关联起来,至于两者使用场景再看,至于GraphicBuffer是如何再通过GraphicBufferAlloc分配的,待进一步trace,目前继续聚焦于BufferQueue使用
在SurfaceMediaSource::read()就是一个consumer acquire场景
SurfaceMediaSource::signalBufferReturned()是consumer release场景,但什么时候调用的呢?是通过mediaBuffer自身的observer来通知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使用过程
BufferQueue::createBufferQueue(&mProducer, &mConsumer);
可以跳转到文章开头看CreateBufferQueue, Producer与Consumer 实际是共用bufferslot,然后通过不同的BufferState 来判断实际空间上数据是归属于谁,正被谁使用
mConsumer->setDefaultBufferSize(bufferWidth, bufferHeight); //这个宽和高是codec要编解码的宽和高
至于producer是如何跟surfaceview关联起来的?
base/core/jni/android_view_Surface.cpp:jobject android_view_Surface_createFromIGraphicBufferProducer(JNIEnv* env
sp<Surface> surface(new Surface(bufferProducer, true));这样关联起来了
生产者
status_t BufferQueueProducer::dequeueBuffer(){
while (found == BufferItem::INVALID_BUFFER_SLOT) {
status_t status = waitForFreeSlotThenRelock("dequeueBuffer", async,
&found, &returnFlags);} //得到一个空闲的slot 号 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;}
填充数据完成
status_t BufferQueueProducer::queueBuffer(){
input.deflate(×tamp, &isAutoTimestamp, &dataSpace, &crop, &scalingMode,
&transform, &async, &fence, &stickyTransform);
mSlots[slot].mBufferState = BufferSlot::QUEUED;
BufferItem item;
mCore->mQueue.push_back(item);// 将buffer 放入bufferqueuecore队列,供consumer到时acquire
mCore->mDequeueCondition.broadcast(); }
BufferQueueProducer::cancelBuffer(){
mCore->mFreeBuffers.push_front(slot);
mSlots[slot].mBufferState = BufferSlot::FREE; }
BufferQueueProducer::connect(){}
BufferQueueProducer::disconnect(int api){} //BufferQueue跟app的生死绑定到了一起,当app莫名其妙的死掉以后,flinger服务中的BufferQueue就知道,会做一些清理工作
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)); } }//这个buffer分配被void Surface::allocateBuffers()调用
消费者
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 只是简单的状态改变和插入对应队列 }