总体上是图像生产者,如应用的一个窗口(activity)的绘制、程序调用OpenGL的各种”draw”函数等,把图像数据传给相应的处理接口。2D的一般使用Canvas,3D的可以直接调用OpenGL ES。但是两种方法图像都绘制到一个surface上,关于绘制操作,如OpenGL的图形库有一个graphics pipeline的流程,主要为从把点的坐标转换到normalized device coordinate,即x,y,z是-1.0到正1.0的坐标系中,再裁剪可视区域,进而以Z坐标确定可视图层顺序,rasterization,即像素化,这样一个流程。OpenGL中的framebuffer(帧缓存)已经是像素化之后的位图了,这说明以效果为主要目的的处理图像已经GPU端完成,在Linux内核的framebuffer层之上。但这个“graphics pipeline”的概念不仅仅是OpenGL独有的,操作系统如安卓等在传输和处理图像时也与此相近,只是最终把图像绘制到surface上。

此时的问题是如何把图像传给屏幕端。一般的应用产生的所有图像都会传给surfaceflinger,后者再选择性的把图像传给显示控制器。显示控制器一般是芯片上的一个硬件,它的驱动软件和安卓框架层的接口是HWComposer,由该库与之交互。

安卓通用的模型大致如此,对于我们使用的MTK的芯片,因为很多模块是闭源的或者完全没有说明,我只能作推测。应该是HWCompser接收到surfaceflinger的事件后通过HWC的库调用内核的fb接口,然后显控以DMA的方式读取帧缓存,进行”overlay”的处理,最终在驱动层的overlay处理图像后通过DSI传给屏幕。

现在介绍我理解的一些模块的工作方式:

由于应用传输图像给surfaceflinger的操作不涉及内核,在此不作分析。Surfaceflinger初始化时会创建一个HWComposer实例,等开始上层通过BufferQueue把缓存传给Surfaceflinger,SF会调用hwc的方法prepare来决定哪些图层需要给显示控制器处理,然后把这些图层收集起来通过postFramebuffer方法更新帧缓存,这里的帧缓存并非立即就更新到屏幕上,而是调用mHwc->commit(hwcId)把数据给HWComposer;其余的图层由surfaceflinger调用OpenGL来合成。SF会设置一个“Fence“(围栏)来表示对每一帧操作的开始与完成。AOSP文档(source.android.com)上指出,surfaceflinger曾经直接把帧缓存往比如/dev/graphics/fb0里写,但很久前就不再这么做了。内核里有drivers/gpu/drm/mediatek,里面有mtk_drm_drv,mtk_drm_fb等,但Linux的DRM(direct rendering manager)在安卓里应该用不到,因为计算机上的XWindow或者Wayland用的协议没有Fence的概念,所以这些代码应该没什么作用,但我不很确定是干什么用的,于是从SF到内核层至少有两个通路:

1) surfaceflinger -> HWComposer-> graphics/fb0(mtkfb)->overlay

2) surfaceflinger->GPU->overlay

第一条通路显然是2D绘制。大多数安卓设备都有/dev/graphics/fb0这个framebuffer设备,经分析我们的MTK的系统中fb0最终就是mtkfb.c在驱动,图像设备有major number 29,adb shell执行ls –l /dev/graphics/fb0可知minor number 为0,在对应/sys/dev/char/29:0/device/driver中可以找到该设备的驱动,再通过readlink该驱动发现是bus/platform/drivers/mtkfb的链接。Mtkfb.c中并没有指定具体路径,这说明/dev/graphics/应该是安卓内核图像设备的默认位置。

然而直接写mtkfb(比如cat image > fb0)并没有作用,读(cp fb0 /sdcard/fb)可以得到1个帧(3个图层),通过ffmpeg等解码器转换为常用图片格式后发现所得往往并不是“截图“时屏幕所显示的内容,这已知有几种原因,首先有很多图层不是走的这条通路,第二是图像缓存不是一直更新,比如空闲时primary_display会切换到decouple mode。查看mtkfb.c可知,fb_ops结构并没有read和write的操作,但fb设备和内存设备类似,所以对其进行读操作应该可以复制出它内存中的数据,对其写就不会触发fb驱动的刷屏操作。除了跟primary_display、ddp*等内部互相调用的接口外,mtkfb主要以ioctl来操作,在mtkfb.h中有相应ioctl操作的定义。如果在root shell下以用户层的ioctl来操作mtkfb(dev/graphics/fb0),比如ioctl(fd, MTKFB_META_SHOW_BOOTLOGO),我们会发现屏幕会显示随机的缓存然后恢复,通过日志可知它的调用顺序为mtkfb_ioctl->primary_display_config_input_multiple ,primary_display_trigger,而primary_display_config_input_multiple调用了_config_ovl_input,其中关于”帧“的数据结构为disp_session_input_config,该结构包含了帧大小和地址等信息,进而调用_config_ovl_input,由此可见,2D绘制的调用路径是从mtkfb到ovl。观察fb_info结构,注意到mtkfb.c中对该结构使用的最多的成员是”par”,一个自定义的指针,它指向一个mtkfb_device结构的实例,而后者携带framebuffer的内存地址。

但mtkfb_ioctl有一个疑点,执行MTKFB_CAPTURE_FRAMEBUFFER的操作并没有得到有效数据,目前还不清楚是什么原因。另外关于”decouple mode”,据说该模式类似command屏,有专门的内存用于本地刷新屏幕。在primary_display_idlemgr_*函数中可以找到在空闲时切换到decouplemode的机制。稍微联想一下我们可以发现,这decouple mode、“command”屏和OpenGL提交、更新图像的模式十分相近,都是”客户端“提交数据和指令来指示如何处理,而”服务端“有自己的内存和响应指令的机制,两者间通过某种方式交互,OpenGL commands、mtk cmdq、mipi dsi等等。

GPU这条通路有很多机制尚不清楚,首先安卓的gralloc负责分配GPU使用的显存,但我们用的厂商实现是MTK提供的gralloc库,HWComposer也是如此(在hardware.c里dlopen加载的这些库),MTK的显示控制器如何工作也未知,只知道在内核中驱动是使用中断和DMA,在ddp_irq加上日志可看到,平时图像更新disp_irq_handler函数都会不断响应,紧接着就是RDMA的函数(ddp_ovl_get_cur_addr等),这些是在primary_display_switch_mode里一路往下调用的,由于HWComposer上层是以event(事件)的形式交互,所以primary_display的dpmgr_map_event_to_irq应该是把事件和中断对应起来,DMA是把数据读到”overlay”;

关于显示控制器和overlay:

”overlay”在计算机显示中的作用是图像直接送到显示控制器进行简单的缩放、裁剪、组合等,没有诸如OpenGL的texture mapping、blending等功能。安卓使用“overlay”的意义是有的操作简单,若调用OpenGL用GPU处理占内存多,通常在嵌入式设备和手机中GPU没有独立显存,是共用主内存的,另外GPU一次只能作一个用途,让显控来分担一些GPU的负担,可提升性能。具体哪些帧需要GPU合成哪些需要overlay来处理是由HWComposer对帧来标记决定的,MTK的平台应该是在它的HWC库里实现的算法。MTK的“ovl“有点迷惑,它既有overlay的硬件,也有最后把所有的帧送到屏幕IC的作用。所以所有的图层在两个地方有汇总过,一是surfaceflinger,另一是最后的overlay层,这也就解释了为什么虽然有的图层是用GPU合成的,但如果在MTK的overlay里(定义PHYSICAL_ROTATION_HW的宏)旋转帧缓存,所有的图像都会旋转。现在的截图和录屏无法通过framebuffer接口来实现,都是调用surfaceflinger的接口把图层处理到一个”virtual display”上,通过BufferQueue传输给调用软件。

最后是VSYNC信号和fence,屏幕硬件和surfaceflinger是有关联的,IC会由DSI给primary_display发vsync信号,表示一帧已显示完毕,最后这个信号会给surfaceflinger,后者只在此时进行新的绘制操作,因而vsync、porch值除了和屏幕玻璃有关外,也会影响到surfaceflinger的绘制;fence的作用和mutex的目的接近,但更灵活。其内核接口为sw_sync.h,我们可以看到mtkfb.h中包含了该头文件,底层的fence以文件描述符的形式使用,可以”poll”,检查是否可读写等,以此表示和该fence关联的图像内存是否可用,这些功能在mtkfb_fence.c中实现。

安卓图像更新学习总结相关推荐

  1. android10新功能,三星A80升级安卓10 更新One UI 2.0内容新功能介绍

    三星A80升级安卓10 更新One UI 2.0内容新功能介绍 据网友反馈,三星现已面向Galaxy A80用户推送One UI 2.0更新,升级Android 10. 此外,三星Galaxy A80 ...

  2. 项目“恶意APK检测系统”——安卓逆向部分学习

    项目"恶意APK检测系统"--安卓逆向部分学习 交流逆向工程相关知识 +Q1906661021 以下内容按笔者的浏览和学习顺序为序,并无难易之分 1.proguard progua ...

  3. 一种水下鱼类图像特征学习与目标识别框架

    摘要 活鱼识别是快速获取大量数据的渔业调查应用中最关键的元素之一.与一般场景不同,水下图像识别面临的挑战是图像质量差.目标和环境不可控以及难以获取代表性样本.此外,大多数现有的特征提取技术由于涉及人的 ...

  4. 消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法

    消除安卓SDK更新时的"https://dl-ssl.google.com refused"异常的方法 消除安卓SDK更新时的"https://dl-ssl.google ...

  5. 基于单幅图像一致性学习的弱光视频增强(CVPR2021)

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 作者丨图灵智库 来源丨 泡泡机器人SLAM 编辑丨3D视觉工坊 标题: Learning Tempor ...

  6. 解决安卓SDK更新dl-ssl.google.com无法连接的方法

    解决安卓SDK更新dl-ssl.google.com无法连接的方法 参考文章: (1)解决安卓SDK更新dl-ssl.google.com无法连接的方法 (2)https://www.cnblogs. ...

  7. 每周更新学习进度表--第九周

    每周更新学习进度表:   学习时间 新增代码行 博客量(篇) 知识总结 第一周  7h  80  2  对于软件工程这门课有个大致的了解,并在学习代码上步入正轨. 第二周  8h  100  4  四 ...

  8. 无人机图像深度学习的大豆害虫检测与分类

    无人机图像深度学习的大豆害虫检测与分类 1.研究内容 实验比较了Inception-v3, Resnet-50, VGG-16, VGG-19 and Xception ,用了微调和迁移学习. 2.创 ...

  9. android 使用系统下载并更新版本,安卓系统更新升级的种方法

    最近有网友问小编"安卓系统怎么升级?",针对该问题,笔者也在网上查找了下相关资料,不过并没有找到什么有价值的相关介绍,多数都是介绍如何自动升级.或者下载升级版包等等方法,对于一些常 ...

最新文章

  1. python比较好的书籍推荐-推荐几本2019年初学者学习Python最佳书籍!
  2. ZStack中的编程技巧
  3. POJ 1269 Intersecting Lines(求直线交点)
  4. 使用vue控制元素显示隐藏
  5. 我写的几篇技术文章之一:Windows消息拦截技术的应用
  6. java httpclient 跨域_13、HttpClient服务器跨域请求
  7. Linux基本命令解析(1)
  8. java画一个小车_小轿车简笔画怎么画
  9. python max_Python max()
  10. http之url和uri
  11. 接口自动化测试框架搭建(4、公用方法之url的拼接)--python+HTMLTestRunnerCN+request+unittest+mock+db
  12. Windows下配置安装Git(一)
  13. 微信支付“下单账号和支付账号不一致,请核实后再支付”
  14. c++直角空心三角形_2019秋人教版八年级数学上册三角形教材全解读
  15. java共享文件夹SMB1服务报错jcifs.smb.SmbException: Failed to connect: 0.0.0.0<00>/122.168.23.26
  16. vs2017python配置opencv_[opencv +VS2017] opencv、vs2017安装配置,环境搭建
  17. WhatsApp是啥软件?WhatsApp是什么意思?
  18. DRE6-1X/210MG24K4M比例减压阀配套US-DAS1放大器
  19. 2023年最新前端面试题
  20. 八年级计算机教案下册,信息技术八年级下册教案全册.doc

热门文章

  1. 【洛谷】 P1424 小鱼的航程(改进版)(详细代码)
  2. Android原生h5互跳控制,Android原生与H5交互方式
  3. 如何下载知网上的论文?
  4. 2021年危险化学品经营单位主要负责人考试及危险化学品经营单位主要负责人考试试卷
  5. 后端存储课程笔记(大量实战经验)
  6. 02自定义面板区附加功能模块及清单编写
  7. CVPR 2022 论文列表(持续更新)
  8. CHROME插件 by stormzhang
  9. html图片左右无缝循环滚动示例
  10. JavaDay27 HTML