上篇博客最后分析到MonitoredProducer对象,这个对象只是一个代理,真正实是BufferQueueProducer类,这个对象和BufferQueueCore有关联,可以管理最多达64块的缓冲区。Surface可以理解为一张画布,那么Surface为何要和一个缓冲区队列相关呢?在播放动画时,美妙至少要播放24帧画面才能形成比较真实的动画效果。而这些数据是通过cpu解码得到的,准备他们需要时间。对于图像显示设备而言,刷新周期是固定的,我们必须要在它需要数据的时候把数据准备好。视频播放的每一帧也需要在指定的时间播放,因此解码器会提前准备好一批数据,这些数据保存在解码器内存的缓冲区中,当时间到达是,解码器会把内部缓冲区的图像复制到Surface中,但是显示设备并不是立刻就把数据取走的,因此Surface也需要缓冲区来临时保存数据。
一、BufferQueueCore BufferQueueProducer BufferQueueConsumer
上篇博客在Layer的onFirstRef函数中,调用了下面函数,创建了3个对象BufferQueueCore BufferQueueProducer BufferQueueConsumer。其中BufferCore是核心,把BufferQueueProducer和BufferQueueConsumer对象连接在一起。
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));
*outProducer = producer;
*outConsumer = consumer;
}
1.1 生产者和core的联系
IGraphicBufferProducer 的大致接口如下,BufferQueueProducer类是接口IGraphicBufferProducer 的实现,使用BufferQueueProducer之前先要调用connect函数,使用结束后调用disconnect断开连接。
class IGraphicBufferProducer : public IInterface
{
public:
virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) = 0;
virtual status_t setBufferCount(int bufferCount) = 0;
virtual status_t dequeueBuffer(int* slot, sp<Fence>* fence, bool async,
uint32_t w, uint32_t h, PixelFormat format, uint32_t usage) = 0;
virtual status_t detachBuffer(int slot) = 0;
virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer,
sp<Fence>* outFence) = 0;
virtual status_t attachBuffer(int* outSlot,
const sp<GraphicBuffer>& buffer) = 0;
virtual status_t queueBuffer(int slot,
const QueueBufferInput& input, QueueBufferOutput* output) = 0;
virtual void cancelBuffer(int slot, const sp<Fence>& fence) = 0;
virtual int query(int what, int* value) = 0;
virtual status_t connect(const sp<IProducerListener>& listener,
int api, bool producerControlledByApp, QueueBufferOutput* output) = 0;
virtual status_t disconnect(int api) = 0;
virtual status_t setSidebandStream(const sp<NativeHandle>& stream) = 0;
virtual void allocateBuffers(bool async, uint32_t width, uint32_t height,
PixelFormat format, uint32_t usage) = 0;
virtual status_t allowAllocation(bool allow) = 0;
virtual status_t setGenerationNumber(uint32_t generationNumber) = 0;
virtual String8 getConsumerName() const = 0;
};
在BufferQueueCore类中定义了一个64项的数据mSlots。
BufferQueueDefs::SlotsType mSlots;