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…

多层感知机与CLIP在推荐系统和多模态学习中的应用

MLP多层感知机 在推荐系统中,MLP(Multi-Layer Perceptron,多层感知机)是一种常用的神经网络模型,用于捕捉用户和物品之间的复杂非线性关系,从而生成高质量的推荐结果。以下是 MLP 在推荐系统中的应用及其优势。 MLP 在推荐系统中的作用 用户和物品特征的表示: MLP 能够…

Spring Boot应用的部署与扩展

Spring Boot应用的部署与扩展 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 引言 Spring Boot作为现代化Java应用的首选框架之一,以其简化的配置…

MicroBin好用的粘贴板工具

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

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

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

大数据开发语言 Scala(二):变量和数据类型

目录 1. 变量的基本概念 1.1 不可变变量(val) 1.2 可变变量(var) 2. 数据类型详解 2.1 基本数据类型 2.1.1 数字类型 2.1.2 字符类型 2.1.3 布尔类型 2.2 复杂数据类型 2.2.1 数组 2.2.2 元组 2.2.3 列表 2.2.4 集合…

韩顺平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标…

Python 学习之面向对象(四)

面向对象编程(Object-Oriented Programming, OOP)是一种编程范式,它使用“对象”来设计应用程序和软件系统。在Python中,面向对象编程是一个核心概念,并得到了广泛的支持。 以下是Python面向对象编程的一些基本概念和特…

MySQL高可用(MHA高可用)

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

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

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

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

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

Perl正则表达式捕获组:深入探索与实战应用

🕵️‍♂️ Perl正则表达式捕获组:深入探索与实战应用 在Perl的世界里,正则表达式是其强大的文本处理能力的基石。捕获组作为正则表达式中的一个核心概念,允许我们从匹配的文本中提取子字符串。本文将深入探讨如何在Perl中使用正…

【AI应用探讨】—k-means应用场景

目录 数据挖掘 图像分析 自然语言处理 生物信息学 物流配送优化 公共安全与城市规划 社交网络分析 数据挖掘 市场分析:在市场营销中,企业可以利用K-means算法对消费者进行聚类分析,根据消费者的购买行为、消费习惯等信息将客户分成不同…

Redis缓存问题二、缓存雪崩

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

sql-语句

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

Zookeeper怎么用

ZooKeeper 的使用方式通常涉及以下几个核心方面: 1. 安装和配置 ZooKeeper 服务 首先,需要在网络中的多台服务器上安装和配置 ZooKeeper 服务。通常情况下,ZooKeeper 至少需要三台服务器来保证服务的高可用性和容错性。安装和配置可以参考 Zo…

SpringBoot实现文章点赞功能

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

python库 - tqdm

文章目录 主要特点安装基本用法1. 在 for 循环中使用2. 在 enumerate 中使用3. 自定义描述信息4. 在多线程中使用 高级用法1. 手动更新进度条2. 嵌套进度条 tqdm 是一个用于 Python 的快速、可扩展的进度条库。它可以在长循环中提供即时的进度反馈,帮助开发者了解代…

SprongBoot3整合Knife4j

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