Android 画面显示流程二

这篇具有很好参考价值的文章主要介绍了Android 画面显示流程二。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

BufferQueue

BufferQueue要解决的是生产者的同步问题,应用程序生产画面,SurfaceFlinger消费画面,SurfaceFlinger生产画面而HWCService消费画面。用来存储这些画面的存储区我们称其为帧缓冲区buffer,下面我们以应用程序作为生产者,SurfaceFlinger作为消费者为例来了解一下BufferQueue的内部设计。

Buffer State的切换

在Buffer Queue的设计中,一个buffer有以下几种状态:
FREE:表示该buffer可以给到应用程序,由应用程序来绘画
Dequeued:表示该buffer的控制权已经交给到应用程序侧,这个状态下应用程序可以在上面绘图了
Queued:表示buffer已经由应用程序绘画完成,buffer的控制权已经回到SurfaceFlinger手上
QCQUIRED:表示该buffer已经交给HWC service去合成了,这时控制权已经到HWC Service了

Buffer初始态为FREE,当生产者通过dequeueBuffer来申请buffer成功时,buffer状态变成Dequeued状态,应用画图完成后通过queueBuffer将buffer状态变为了Queued状态,当SurfaceFlinger通过acquireBuffer操作将buffer拿去给HWC Service合成,这时buffer状态变为ACQUIRED状态,合成完成后通过releaseBuffer把buffer状态重新改为FREE状态。状态切换如下图所示:
Android 画面显示流程二,android,surfaceflinger
从时间轴上来看一个buffer的状态总是这样循环变化
FREE–>DEQUEUED–>QUEUED–>FREE
应用程序在DEQUEUED状态下绘图,而HWC Service在状态为ACQUIRED状态下合成

Android 画面显示流程二,android,surfaceflinger

BufferSlot

每一个应用程序的图层在SurfaceFlinger里称为一个Layer,而每个Layer都拥有一个独立的BufferQueue,每个BufferQueue都有多个Buffer,Android系统上目前支持每个Layer最多64个buffer,这个最大值被定义在frameworks/native/gui/BufferQueueDefs.h,每个buffer用一个结构体BufferSlot来代表。
每个BufferSlot里主要有如下重要成员:

struct BufferSlot{
   
    ......
    BufferState mBufferState;//代表当前Buffer的状态 FREE/DEQUEUED/QUEUED/ACQUIRED
    ....
    sp<GraphicBuffer> mGraphicBuffer;//代表了真正的buffer的存储空间
    ......
    uint64_t mFrameNumber;//表示这个slot被queued的编号,在应用调dequeueBuffer申请slot时会参考该值
    ......
    sp<Fence> mFence;//在Fence一章再来看它的作用
    .....
}

64个BufferSlot可以分成俩个部分,used Slots和Unused Slot就是使用未使用的,而Used Slots又可以分为Active Slots和UnActive Slots ,处在Dequeued,queued,ACQUIRED状态的被称为Active Slots,剩下FREE状态的称为UnActive Slots,所以所有Active Slots都是正在有人使用中的slot,使用者可能是生产者也可能是消费者。而FREE状态的Slot根据是否已经为其分配内存分为两个部分,一是已经分配过内存的,在Android源码中称mFreeBuffers,没有分配过内存的称为mFreeSlots, 所以如果我们在代码中看到是从mFreeSlots里拿出一个BufferSlot那说明这个BufferSlot是还没有配置GraphicBuffer的, 这个slot可能是第一次被使用到。其分类如下图所示:
Android 画面显示流程二,android,surfaceflinger我们来看一下,应用上帧时SurfaceFlinger是如何管理分配这些Slot的。
应用侧对图层buffer的操作接口如下文件:
应用第一次dequeueBuffer前会通过connect接口和SurfaceFlinger建立连接

int Surface::connect(int api, const sp<IProducerListener>&listener, bool reportBufferRemoval){
   
    ATRACE_CALL();//应用第一次上帧前可以在trace 中看到这个
    ......
    int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output);//这里通过binder调用和SurfaceFlinger建立联系
    ......
}

应用第一次dequeueBuffer时会先调用requestBuffer:

int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
   
    ATRACE_CALL();//这里可以在systrace中看到
    ......
    //这里尝试去dequeueBuffer,因为这时SurfaceFlinger对应Layer的slot还没有分配buffer,这时SurfaceFlinger会回复的flag会有BUFFER_NEEDS_REALLOCATION
    status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, reqWidth, reqHeight, 
                                       reqFormat, reqUsage, &mBufferAge, 
                                        enableFrameTimestamps?&frameTimestamps:nullptr);
    ......
    if((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == nullptr) {
   
        ......
        //这里检查到dequeueBuffer返回的结果里带有BUFFER_NEEDS_REALLOCATION标志就会发出一次requestBuffer
        result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
        ......
    }
    ......
}

在SurfaceFinger这端,第一次收到DequeueBuffer时发现分配出来的slot没有Graphic,这时会去申请对应的Buffer文章来源地址https://www.toymoban.com/news/detail-534652.html

status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* outFence,
                                            uint32_t width, uint32_t height, PixelFormat format,
                                            uint64_t usage, uint64_t* outBufferAge,
                                            FrameEventHistoryDelta* outTimestamps) {
   
    if ((buffer == NULL) ||
        buffer->needsReallocation(width, height, format, BQ_LAYER_COUNT,

到了这里,关于Android 画面显示流程二的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android Studio新功能-设备镜像Device mirroring-在电脑侧显示手机实时画面并可控制

    下载最新的灰测版本-蜥蜴 成功运行到真机后,点击右侧Running Devices选项卡,再点击+号 选中当前设备; 非常丝滑同步,在电脑侧也可以顺畅控制真机 该功能大大方便了我们视线保持在显示器上专注开发,并且便于与UI视觉进行校准与比对。 Device mirroring You can now mirror your p

    2024年02月08日
    浏览(41)
  • Android14 SurfaceFlinger-BLASTBufferQueue的创建

    如果mWindowSession.relayout之后,mSurfaceControl将会变成有效的,此时会判断blast是否开启(blast特性时12新推出的,它默认开启的),所以进入到getOrCreateBLASTSurface,在这里将会生成一个BLASTBufferQueue, 而原来的 mSurface.copyFrom(mSurfaceControl)  分为两步 BBQ主要核心逻辑的初始化都放在了N

    2024年02月22日
    浏览(41)
  • Android GUI系统之SurfaceFlinger(16)MessageBase解读

    该系列文章总纲链接:Android GUI系统之SurfaceFlinger 系列文章目录 说明: 关于导读:导读部分主要是方便初学者理解SurfaceFlinger代码中的机制,为后面分析代码打下一个更好的基础,这样就可以把更多的精力放在surfaceFlinger的业务逻辑分析上。 关于代码分支:以下代码分析均在

    2024年02月09日
    浏览(36)
  • 【Android车载系列】第12章 车载渲染-SurfaceFlinger单独绘制到界面

    车载的 倒车影像 同学们知道是怎么实现的吗?等待Android设备开机再打开倒车影像App?车子挂到R档倒车如果等待这个流程实在太久,是否还有其它办法可以让车子挂R档直接展示倒车影像呢?大家思考一下。 我们从Android渲染的基础上思考,Android图像渲染到屏幕上通过 Surfac

    2024年02月04日
    浏览(87)
  • Android T 远程动画显示流程其二——系统侧动画启动流程

    接着上篇文章分析 Android T 远程动画显示流程其一 下面,我们以从桌面点击一个应用启动的场景来分析远程动画的流程,窗口添加的流程见Android T WMS窗口相关流程 这里我们从AppTransitionController.handleAppTransitionReady方法开始跟踪代码流程 代码路径:framework/services/core/java/com/and

    2024年03月28日
    浏览(46)
  • Android T 远程动画显示流程其一——整体流程以及堆栈介绍

    本地动画和远程动画区别是什么? 本地动画:自给自足。对自身SurfaceControl矢量动画进行控制。 远程动画:拿来吧你!一个app A对另一个app B通过binder跨进程通信,控制app B的SurfaceControl矢量动画。 无论是本地动画还是远程动画,都仅仅只是对SurfaceControl动画图层控制,而无法控

    2024年04月11日
    浏览(96)
  • Android Studio基础工作流程-xml布局文件如何调用显示

    说起安卓开发,很多小伙伴在刚开始入门的时候会有些云里雾里,觉得很混乱,这很正常,大多数是因为不太清楚安卓开发的基本流程,以及各个文件之间是怎样去相互作用的。我会在这篇文章里面向你介绍一下Android studio工作的基本流程,很基础很基础的那种。 一个完整的

    2024年02月03日
    浏览(42)
  • Android 12.0 系统systemui状态栏下拉左滑显示通知栏右滑显示控制中心模块的流程分析

      在android12.0的系统rom定制化开发中,在系统原生systemui进行自定义下拉状态栏布局的定制的时候,需要在systemui下拉状态栏下滑的时候,根据下滑坐标来 判断当前是滑出通知栏还是滑出控制中心模块,所以就需要根据屏幕宽度,来区分x坐标值为多少是左滑出通知栏或者右滑

    2024年02月09日
    浏览(94)
  • Android 10.0 系统systemui状态栏下拉左滑显示通知栏右滑显示控制中心模块的流程分析

      在android10.0的系统rom定制化开发中,在系统原生systemui进行自定义下拉状态栏布局的定制的时候,需要在systemui下拉状态栏下滑的时候,根据下滑坐标来 判断当前是滑出通知栏还是滑出控制中心模块,所以就需要根据屏幕宽度,来区分x坐标值为多少是左滑出通知栏或者右滑

    2023年04月09日
    浏览(66)
  • Android Camera预览画面变形问题

    csdn 安卓camera1在预览时,预览画面看起来被拉伸了. 如图,圆形的盖子,变成椭圆形了. 默认流程,如下为大致的打开摄像头并进行预览显示的代码 网上大部分的解决方法(实测不一定有效) 原理是遍历摄像头分辨率,找到与当前屏幕契合的分辨率,并设置为预览大小. 如下

    2024年02月13日
    浏览(75)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包