Android Graphics 显示系统 - BufferQueue的状态监测

“ BufferQueue作为连接生产者和消费者的桥梁,时刻掌握队列中每一块Buffer的状态,对于解决一些卡死卡顿问题很有帮助,辨别是否有生产者或消费者长期持有大量Buffer不放导致运行不畅的情况。

01

前言

在Android系统中,应用UI的显示、播放器解码后画面的显示、Camera预览画面的显示最终都是要送到Graphics系统的流程完成最终的合成送显,所以在出现画面卡顿卡死问题时Graphics系统往往成为"背锅侠"。

因此,我们要学会如何快速精准地理清问题(甩锅)。

最近遇到一些播放相关的问题:

player的小伙伴认为是decode时dequeue不出新的buffer导致解码流程卡住;

graphics的小伙伴认为是decoder长期持有大量的buffer,导致显示合成卡住;

那有没有办法可以实时监测下当前BufferQueue的状态呢?我简单研究了下,有点发现,但未必完美,在此分享下供大家讨论!

建议小伙伴们先阅读下早前BufferQueue的讲解文章:

Android Graphics 显示系统 - BufferQueue的工作流程(十二)

Android Graphics 显示系统 - BufferQueue的工作流程(十三)

Android Graphics 显示系统 - BufferQueue的工作流程(十四)

Android Graphics 显示系统 - BufferQueue的工作流程(十五)

在正常的显示流程中,每一块buffer的状态会进行转换

FREE -> DEQUEUED -> QUEUED -> ACQUIRED -> FREE

图片

监测下当前BufferQueue的状态,目标就是获取当下队列中分配了多少了块Buffer?以及每一块Buffer所处的状态是什么?

02

演示效果

使用原生gallery3d app播放视频时,抓到的BufferQueue的状态信息

06-22 10:14:04.297  3400  3427 E BufferQueue: State: [SurfaceView[com.android.gallery3d/com.android.gallery3d.app.MovieActivity]#11(BLAST Consumer)11]
06-22 10:14:04.297  3400  3427 E BufferQueue: - BufferQueue mMaxAcquiredBufferCount=1 mMaxDequeuedBufferCount=15
06-22 10:14:04.297  3400  3427 E BufferQueue:   mDequeueBufferCannotBlock=0 mAsyncMode=0
06-22 10:14:04.297  3400  3427 E BufferQueue:   mQueueBufferCanDrop=0 mLegacyBufferDrop=1
06-22 10:14:04.297  3400  3427 E BufferQueue:   default-size=[720x1280] default-format=4   transform-hint=00 frame-counter=84
06-22 10:14:04.297  3400  3427 E BufferQueue:   mTransformHintInUse=00 mAutoPrerotation=0
06-22 10:14:04.297  3400  3427 E BufferQueue: FIFO(1):
06-22 10:14:04.297  3400  3427 E BufferQueue: (mConsumerName=SurfaceView[com.android.gallery3d/com.android.gallery3d.app.MovieActivity]#11(BLAST Consumer)11, mConnectedApi=3, mConsumerUsageBits=2304, mId=d480000000b, producer=[532:???], consumer=[3400:com.android.gallery3d])
06-22 10:14:04.297  3400  3427 E BufferQueue:   15:0x7756e78afd10 crop=[0,0,720,1280] xform=0x00 time=1049.6518 scale=SCALE_TO_WINDOW
06-22 10:14:04.297  3400  3427 E BufferQueue: Slots:
06-22 10:14:04.297  3400  3427 E BufferQueue:   [00:0x7756e78ad490] state=DEQUEUED 0x7756278c19d0 frame=75 [ 768x1280: 768,32315659]
06-22 10:14:04.297  3400  3427 E BufferQueue:   [01:0x7756e78c2190] state=DEQUEUED 0x7756278d0230 frame=71 [ 768x1280: 768,32315659]
06-22 10:14:04.297  3400  3427 E BufferQueue:   [02:0x7756e78bf010] state=DEQUEUED 0x7756278c5de0 frame=74 [ 768x1280: 768,32315659]
06-22 10:14:04.297  3400  3427 E BufferQueue:   [03:0x7756e78c2df0] state=DEQUEUED 0x7756278c4680 frame=80 [ 768x1280: 768,32315659]
06-22 10:14:04.297  3400  3427 E BufferQueue:   [04:0x7756e78b0df0] state=DEQUEUED 0x7756278d02e0 frame=70 [ 768x1280: 768,32315659]
06-22 10:14:04.297  3400  3427 E BufferQueue:   [05:0x7756e78c4e90] state=DEQUEUED 0x7756278cf310 frame=72 [ 768x1280: 768,32315659]
06-22 10:14:04.297  3400  3427 E BufferQueue:   [06:0x7756e78b82f0] state=DEQUEUED 0x7756278d7030 frame=73 [ 768x1280: 768,32315659]
06-22 10:14:04.297  3400  3427 E BufferQueue:   [07:0x7756e78c10b0] state=DEQUEUED 0x7756278d6e20 frame=76 [ 768x1280: 768,32315659]
06-22 10:14:04.297  3400  3427 E BufferQueue:   [08:0x7756e78c7950] state=DEQUEUED 0x7756278cfcb0 frame=77 [ 768x1280: 768,32315659]
06-22 10:14:04.297  3400  3427 E BufferQueue:   [09:0x7756e78c61b0] state=DEQUEUED 0x7756278d4f30 frame=78 [ 768x1280: 768,32315659]
06-22 10:14:04.297  3400  3427 E BufferQueue:   [10:0x7756e78bf910] state=DEQUEUED 0x7756278d5980 frame=79 [ 768x1280: 768,32315659]
06-22 10:14:04.297  3400  3427 E BufferQueue:  >[11:0x7756e78af890] state=ACQUIRED 0x7756278c6570 frame=81 [ 768x1280: 768,32315659]
06-22 10:14:04.297  3400  3427 E BufferQueue:   [13:0x7756e78b7d50] state=DEQUEUED 0x7756278c94e0 frame=67 [ 768x1280: 768,32315659]
06-22 10:14:04.297  3400  3427 E BufferQueue:  >[14:0x7756e78c22b0] state=ACQUIRED 0x7756278c54f0 frame=83 [ 768x1280: 768,32315659]
06-22 10:14:04.297  3400  3427 E BufferQueue:   [15:0x7756e78afd10] state=QUEUED   0x7756278c9590 frame=84 [ 768x1280: 768,32315659]
06-22 10:14:04.297  3400  3427 E BufferQueue:   [12:0x7756e78ad370] state=FREE     0x7756278d7b30 frame=82 [ 768x1280: 768,32315659]

可以看到:

  • 一共分配了16块buffer;

  • 2块buffer处于ACQUIRED状态,说明已被消费者拿去准备合成显示了;

  • 1块buffer处于QUEUED状态,说明生产者已经queueBuffer返还了;

  • 1块buffer处于FREE状态;

  • 12块buffer处于DEQUEUED状态,说明生产者dequeueBuffer准备填充数据;

  • 还可以看到每一块buffer的width/height/stride/format 

  • frame=xx,代表了该buffer被queueBuffer的顺序,即为BufferSlot中的

        // mFrameNumber is the number of the queued frame for this slot.  This// is used to dequeue buffers in LRU order (useful because buffers// may be released before their release fence is signaled).uint64_t mFrameNumber;
    
  • 另外还有BufferQueue的配置信息;

使用原生gallery3d app展示图片时,抓到的BufferQueue的状态信息

06-22 11:24:40.224  3400  9472 E BufferQueue: State: [SurfaceView[com.android.gallery3d/com.android.gallery3d.app.GalleryActivity]#29(BLAST Consumer)29]
06-22 11:24:40.224  3400  9472 E BufferQueue: - BufferQueue mMaxAcquiredBufferCount=1 mMaxDequeuedBufferCount=2
06-22 11:24:40.224  3400  9472 E BufferQueue:   mDequeueBufferCannotBlock=0 mAsyncMode=0
06-22 11:24:40.224  3400  9472 E BufferQueue:   mQueueBufferCanDrop=0 mLegacyBufferDrop=1
06-22 11:24:40.224  3400  9472 E BufferQueue:   default-size=[1080x1776] default-format=3   transform-hint=00 frame-counter=414
06-22 11:24:40.224  3400  9472 E BufferQueue:   mTransformHintInUse=00 mAutoPrerotation=0
06-22 11:24:40.224  3400  9472 E BufferQueue: FIFO(1):
06-22 11:24:40.224  3400  9472 E BufferQueue: (mConsumerName=SurfaceView[com.android.gallery3d/com.android.gallery3d.app.GalleryActivity]#29(BLAST Consumer)29, mConnectedApi=1, mConsumerUsageBits=2304, mId=d480000001d, producer=[3400:com.android.gallery3d], consumer=[3400:com.android.gallery3d])
06-22 11:24:40.224  3400  9472 E BufferQueue:   02:0x7756e78c73b0 crop=[0,0,0,0] xform=0x00 time=5285.5555 scale=SCALE_TO_WINDOW
06-22 11:24:40.224  3400  9472 E BufferQueue: Slots:
06-22 11:24:40.224  3400  9472 E BufferQueue:  >[00:0x7756e78b7210] state=ACQUIRED 0x7756278cf050 frame=412 [1080x1776:1088,  1]
06-22 11:24:40.224  3400  9472 E BufferQueue:  >[01:0x7756e78c0210] state=ACQUIRED 0x7756278c3ad0 frame=413 [1080x1776:1088,  1]
06-22 11:24:40.224  3400  9472 E BufferQueue:   [02:0x7756e78c73b0] state=QUEUED   0x7756278d0e90 frame=414 [1080x1776:1088,  1]

03

方法及源码

现在的方法是把BufferQueue的状态信息直接打印到logcat中,通过设置一个属性值来指定需要打印哪一个BufferQueue的信息。

源码

阅读原文获取

Android Graphics 显示系统 - BufferQueue的状态监测

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/864033.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis基础教程(四):redis键(key)

💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝你生活愉快! 💝&#x1f49…

MicroBin好用的粘贴板工具

有时候你可能想从一台电脑上粘贴文本到另一台电脑上,或者是你想要分享一张图片或者是一些文件,某些设备上登陆qq和微信有不太方便,那么就可以使用MicroBin,它不但可以实现跨设备复制粘贴的功能,还支持文件上传等功能 …

微信小程序的在线客服系统源码 附带完整的源代码包以及搭建部署教程

系统概述 微信小程序的在线客服系统源码是一套专门为微信小程序开发的客服解决方案。它通过与微信小程序的紧密集成,为用户提供了便捷、高效的客服沟通渠道。该系统源码采用先进的技术架构,具备良好的稳定性和扩展性,能够满足不同规模企业的…

韩顺平0基础学java——第34天

p675-689 UDP网络编程 1.类 DatagramSocket和 DatagramPacket[数据包/数据报]实现了基于UDP协议网络程序。 2.UDP数据报通过数据报套接字DatagramSocket发送和接收,系统不保证UDP数据报一定能够安全送到目的地,也不能确定什么时候可以抵达。 3.DatagramPacket对象…

【前端】从零开始学习编写HTML

目录 一、什么是前端 二、什么是HTML 三、HTML文件的基本结构 四、HTML常见标签 4.1 注释标签 4.2 标题标签 4.3 段落标签 4.4 换行标签 4.5 格式化标签 4.6 图片标签 4.7 超链接标签 4.8 表格标签 4.9 列表标签 4.10 表单标签 (1)form标…

MySQL高可用(MHA高可用)

什么是 MHA MHA(MasterHigh Availability)是一套优秀的MySQL高可用环境下故障切换和主从复制的软件。 MHA 的出现就是解决MySQL 单点的问题。 MySQL故障切换过程中,MHA能做到0-30秒内自动完成故障切换操作。 MHA能在故障切换的过程中最大…

内容营销专家刘鑫炜:如何撰写一篇吸睛又能转化的医疗推广软文?

在我每天要处理的稿件中,有1/3以上是医疗软文,但稿件质量情况不容乐观,大部分医疗软文甚至用极其糟糕来形容都为过,互联网都到下半场了,很多医疗机构营销人员的营销思维还是停留在二十几年前,投放的软文还是…

SpringMVC系列八: 手动实现SpringMVC底层机制-第三阶段

手动实现SpringMVC底层机制 实现任务阶段六🍍完成控制器方法获取参数-RequestParam1.🥦将 方法的 HttpServletRequest 和 HttpServletResponse 参数封装到数组, 进行反射调用2.🥦在方法形参处, 指定 RequestParam, 将对应的实参封装到参数数组…

Redis缓存问题二、缓存雪崩

缓存雪崩 缓存雪崩:是指在同一时段大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库,带来巨大压力。 缓存雪崩的解决方案: 给不同的Key的TTL添加随机值利用Redis集群提高服务的可用性给缓存业务添加降级限流策略…

sql-语句

文章目录 SQL语句的学习sql是什么sql的内置命令sql的种类sql mode库,表属性介绍:字符集,存储引擎列的数据类型:数字,字符串,时间列的约束DDL: 数据定义语言库表 Online DDL(ALGORITHM) *DML :数据操纵语言资…

SpringBoot实现文章点赞功能

提示:今日是2024年的6月30日,未来的你看到这篇文章,希望你依旧快乐 文章目录 前言 首先在这里前缀部分我就不做要求了,比如说登录信息什么的 数据库表格 这里实现点赞功能,主要是围绕论坛项目完成的 user_info代表用户信息表 for…

SprongBoot3整合Knife4j

大家好,我是晓凡。 写在前面 在上一篇文章,我们详细介绍了SpringBoot3 怎么整合SpringDoc实现在线接口文档。但是,有不少小伙伴 都觉得接口界面太丑了。有没有什么更美观一点的UI界面呢? 当然是有的了,毕竟这是一…

抖音直播自动点赞脚本:让点赞变得简单

抖音直播自动点赞脚本:让点赞变得简单 简介 点赞是社交媒体上表达喜爱的一种方式,尤其在抖音这样的平台上,点赞不仅能够增加主播的人气,还能鼓励他们创作更多优质内容。然而,手动点赞往往既耗时又费力。为了解决这个…

云服务出现故障这样处理

无法连接云服务器 服务器远程无法连接时,可通过7ECloud控制台进行连接。 常见故障现象 1、ping不通 2、ping丢包 3、部分端口telnet不通 4、全部端口telnet不通 5、广告、弹窗植入 6、域名无法访问IP访问正常 常见故障原因 1、云服务器过期、关机或者EIP被…

深度学习基准模型Transformer

深度学习基准模型Transformer 深度学习基准模型Transformer,最初由Vaswani等人在2017年的论文《Attention is All You Need》中提出,是自然语言处理(NLP)领域的一个里程碑式模型。它在许多序列到序列(seq2seq&#xf…

恭喜了!全体前端彻底狂欢吧!这个好消息来得太及时!

在这个快速变化的科技时代,作为独立开发者,你是否常常被繁琐的开发任务压得喘不过气?前端开发要操心后端的各种服务搭建和接口开发,这些琐碎而耗时的工作常常让人头大。但现在,你可以松一口气了,因为MemFir…

【ARM-Linux篇】项目:智能家居

一、项目概述 •项目功能 通过语音控制客厅灯、卧室灯、风扇、人脸识别开门等,可以进行火灾险情监测,可以并且实现Sockect发送指令远程控制各类家电等 •项目描述 全志H616通过串口连接各模块硬件,检测语音的识别结果,分析语音识别的结果来对家电设备进行控制。摄像头拍…

视频上面怎样编辑文字?4种视频编辑文字方法分享

视频已成为我们日常生活中不可或缺的一部分。无论是社交分享、商业宣传还是个人记录,视频都以其直观、生动的特点吸引着观众的眼球。然而,一个优质的视频,除了画面和音效,文字编辑也是提升观看体验的关键。那么,如何在…

Webpack: 并行构建

概述 受限于 Node.js 的单线程架构,原生 Webpack 对所有资源文件做的所有解析、转译、合并操作本质上都是在同一个线程内串行执行,CPU 利用率极低,因此,理所当然地,社区出现了一些以多进程方式运行 Webpack&#xff0…

Redis学习——Redisson 分布式锁集成及其简单使用

文章目录 引言1. Redisson概述1.1 Redisson的基本概念1.2 Redisson的主要功能1.3 Redisson的优点 2. 开发环境3. Redisson的安装与配置3.1 添加依赖3.2 配置Redisson 4. 使用Redisson4.1 可重入锁4.1.1 可重入锁的概念4.1.2 可重入锁的实现原理4.1.3 简单使用锁的获取和释放 4.…