概述
3.数据
BufferQueue
BufferSlot mSlots[32];
Vector mQueue;
工作原理
数据部分:(共享内存)
struct BufferSlot {
//图像缓冲区
sp mGraphicBuffer;
//buffer的状态,表示当的状态,是否可以dequue,queue,acquire等
BufferState mBufferState;
}
class BufferItem : public Flattenable {
//图像缓冲区
sp mGraphicBuffer;
//在slot数组中的索引
int mBuf;
…
}
BufferQueue中的 mSlots[32],mQueue都是指向GraphicBuffer的,只是应用的地方不一样
mQueue:是加工好的数据,Consumer可以消耗了
mSlots:所有的缓冲 Producer在里面找合适的空闲buffer,其实我感觉也可以用一个freeQueue.
生产者(app端)
//要缓冲区,
BufferQueue ::dequeueBuffer()从mSlots中获取一段空闲的buffer
{
//统计一下正在dequeue中 正acquired中的
for (int i = 0; i < maxBufferCount; i++) {
const int state = mSlots[i].mBufferState;
switch (state) {
case BufferSlot::DEQUEUED:
dequeuedCount++;
break;
case BufferSlot::ACQUIRED:
acquiredCount++;
break;
case BufferSlot::FREE:
//选择最早(mFrameNumber最小)queue的buffer,这种buffer其他硬件已经用完的可能性最大了
i
《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享
f ((found < 0) || mSlots[i].mFrameNumber < mSlots[found].mFrameNumber) {
found = i;
}
break;
}
if(found<0){ 可能找不到buffer需要等待空闲buffer
DequeueCondition.wait(mMutex)
}
}
}
//数据填充进去了,通知consumer消费把
BufferQueue :: queueBuffer 把加工好的buffer推到mQueue中
{
找到buf索引位置的buffer,以前dequeue出的索引
BufferItem item;
item.mAcquireCalled = mSlots[buf].mAcquireCalled;
item.mGraphicBuffer = mSlots[buf].mGraphicBuffer;
item.mFrameNumber = mFrameCounter; //每次加1,最小的肯定是最早推进去的
item.mBuf = buf;
if (mQueue.empty()) {
mQueue.push_back(item);
}
//通知dequeue中等待的,dequeue可能没有缓存了,在等待呢
mDequeueCondition.broadcast();
//通知Consumer数据准备好了
listener->onFrameAvailable();
}
消费者 (SurfaceFlinger服务)
//要数据
BufferQueue :: acquireBuffer(BufferItem *buffer, nsecs_t expectedPresent) 从mQueue中获取一段加工好的buffer
{
//获取队列头的,别设置一系列状态
Fifo::iterator front(mQueue.begin());
int buf = front->mBuf; //solt中的索引
*buffer = *front;
mQueue.erase(front);
mDequeueCondition.broadcast();
}
//数据用完了,归还回去
BufferQueue::releaseBuffer( int buf, const sp& fence,…) {
if (mSlots[buf].mBufferState == BufferSlot::ACQUIRED) {//验证一下状态,然后归还,就是修改写一下slot的状态
mSlots[buf].mFence = fence; //这个是为了与其他硬件同步的
mSlots[buf].mBufferState = BufferSlot::FREE;
}
mDequeueCondition.broadcast();
return NO_ERROR;
}
BufferQueue对谁的生死那么关心呢
IBinder::DeathRecipient
void BufferQueue::binderDied(const wp& who) {//binder死掉后回调这个的
int api = mConnectedApi;
this->disconnect(api);
}
disconnect(){
//把所有的buffer全清掉
freeAllBuffersLocked();
sp token = mConnectedProducerToken;
token->unlinkToDeath(static_castIBinder::DeathRecipient*(this));
最后
以上就是想人陪蜜粉为你收集整理的Android BufferQueue生产消费原理(八),Android基础面试常常死在这几个问题上的全部内容,希望文章能够帮你解决Android BufferQueue生产消费原理(八),Android基础面试常常死在这几个问题上所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复