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的状态监测

  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值