我是靠谱客的博主 搞怪大雁,最近开发中收集的这篇文章主要介绍Android BufferQueue生产消费原理(八),flutter消息推送方案,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

//图像缓冲区

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其他硬件已经用完的可能性最大了

if ((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));

最后

为了方便有学习需要的朋友,我把资料都整理成了视频教程(实际上比预期多花了不少精力),由于篇幅有限,都放在了我的GitHub上,点击即可免费获取!

Androidndroid架构视频+BAT面试专题PDF+学习笔记

当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。

  • 无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,这四个字就是我的建议!!
  • 我希望每一个努力生活的IT工程师,都会得到自己想要的,因为我们很辛苦,我们应得的。

当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。

无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,没有人能随随便便成功。

加油,共勉。

最后

以上就是搞怪大雁为你收集整理的Android BufferQueue生产消费原理(八),flutter消息推送方案的全部内容,希望文章能够帮你解决Android BufferQueue生产消费原理(八),flutter消息推送方案所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部