乐趣区

关于android:MTK-Camera-冷启动前后摄切换性能优化分析

和你一起一生学习,这里是程序员 Android

本篇文章次要介绍 Android 开发中的局部知识点,通过浏览本篇文章,您将播种以下内容:

一、背景
二、问题合成
三、工具剖析
四、traceView 教程
五、surface create 优化
六、systrace 的教程
七、优化计划
八、前后切换速度优化
九、优化计划
十、热启动优化
十一、解决方案:
十二、驱动优化

一、背景

id5a、id6 平台咱们的相机,比照雷同平台红米 6a 和 6 的相机,冷热启动,前后摄切换性能要差,比照竞品,咱们冀望优化的比红米 6a 和 6 的相机快 10%.

二、问题合成

性能优化的外围就是找到影响性能的 hotspot, 查找 hotspot 也是有套路的,首先要把相机启动流程合成进去,一个阶段一个阶段剖析。

相机的冷启动,能够合成如下几步:

1.AMS 启动相机的 Activity -> 相机的 Activity 收到 onCreated 音讯 (可体现零碎的性能)。
2.onCreate begin -> onCreate end(次要是 ui 的加载)
3.openCamera -> CameraOpened
4.TextureView add -> SurfaceTexture created (Surface 的创立工夫)
5.startPreview -> PreviewStarted
6.setWindow -> PreviewCallback

Log 如下:

01-01 12:01:57.099   794  3012 I ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.mediatek.camera/.CameraLauncher bnds=[150,976][290,1202] (has extras)} from uid 10064
01-01 12:01:57.169  8261  8261 D CamAp_QuickActivity: [0.000ms][BEGIN] onCreate
01-01 12:01:57.196  8261  8295 I CamAp_API1-Handler-0: [openCamera]+
01-01 12:01:57.217   532  2586 I mtkcam-dev1: [createSpecificCameraDevice1] dlopen libmtkcam_device1.so +
01-01 12:01:57.224   532  2586 I mtkcam-dev1: [createSpecificCameraDevice1] dlopen libmtkcam_device1.so -
01-01 12:01:57.259   532  2586 I mtkcam-dev1: [createSpecificCameraDevice1] - 0xe6a0ec00
01-01 12:01:57.260   532  2586 I mtkcam-dev1: 0[CameraDevice1Base::open] +
01-01 12:01:57.419   532  2586 I mtkcam-dev1: 0[CameraDevice1Base::open] Add new cameraId 0 - 0xe6a0ec00
01-01 12:01:57.419   532  2586 I mtkcam-dev1: 0[CameraDevice1Base::open] -

01-01 12:01:57.424  8261  8295 I CamAp_API1-Handler-0: [openCamera]-, executing time = 228ms.
01-01 12:01:57.537  8261  8261 D CamAp_QuickActivity: [367.294ms]  [END] onCreate
01-01 12:01:57.542  8261  8261 D CamAp_QuickActivity: [0.000ms][BEGIN] onStart
01-01 12:01:57.546  8261  8261 D CamAp_QuickActivity: [3.762ms]  [END] onStart
01-01 12:01:57.549  8261  8261 D CamAp_QuickActivity: [0.000ms][BEGIN] onResume
01-01 12:01:57.552  8261  8261 D CamAp_QuickActivity: isKeyguardLocked = false
01-01 12:01:57.552  8261  8261 D CamAp_QuickActivity: onResume --> onPermissionResumeTasks()
01-01 12:01:57.600  8261  8261 D CamAp_QuickActivity: [50.774ms]  [END] onResume

01-01 12:01:57.685  8261  8294 I CamAp_API1-Handler-0: [setPreviewDisplay]+, pending time = 0ms.
01-01 12:01:57.686  8261  8294 I CamAp_API1-Handler-0: [setPreviewDisplay]-, executing time = 1ms.

01-01 12:01:57.700  8261  8294 I CamAp_API1-Handler-0: [startPreview]+, pending time = 0ms.
01-01 12:01:57.701   532  2586 W mtkcam-dev1: 0[CameraDevice1Base::initDisplayClient] NULL window is passed into...
01-01 12:01:57.701   532  2586 I mtkcam-dev1: 0[CameraDevice1Base::startPreview] +

01-01 12:01:57.720  8261  8261 I CamAp_TextureViewController: updatePreviewSize: new size (960 , 720) current size (0 , 0),mIsSurfaceCreated = false listener = com.mediatek.camera.common.mode.photo.PhotoMode$SurfaceChangeListener@a79ec89

01-01 12:01:57.735   532  2586 I mtkcam-dev1: 0[CameraDevice1Base::startPreview] - status(0)

01-01 12:01:57.736  8261  8294 I CamAp_API1-Handler-0: [startPreview]-, executing time = 36ms.
01-01 12:01:57.948   532  8363 I MtkCam/DCNode: [0::waitPreviewReady]wait for start preview done +
01-01 12:01:58.087   532  8363 I MtkCam/DCNode: [0::waitPreviewReady]wait for start preview done - , use 130 ms

01-01 12:01:58.053  8261  8261 D CamAp_TextureViewController: onSurfaceTextureAvailable surface  = android.graphics.SurfaceTexture@2d48d1c width 720 height 960

01-01 12:01:58.056  8261  8294 I CamAp_API1-Handler-0: [setPreviewTexture]+, pending time = 0ms.
01-01 12:01:58.087   532  8363 I MtkCam/CamAdapter: (8363)[transitState] StateIdle --> StatePreview
01-01 12:01:58.089   532  2586 I MtkCam/DisplayClient: [setWindow] + window(0xe6a0ecf0), WxH=960x720, count(6), iNativeWindowConsumerUsage(256)

01-01 12:01:58.093  8261  8294 I CamAp_API1-Handler-0: [setPreviewTexture]-, executing time = 37ms.

01-01 12:01:58.279  8261  8295 D CamAp_PhotoDeviceController: [onPreviewFrame] mModeDeviceCallback = com.mediatek.camera.common.mode.photo.PhotoMode@feb2273

其中 OnCreate begin -> onCreate end: 花了 367ms

01-01 12:01:57.169  8261  8261 D CamAp_QuickActivity: [0.000ms][BEGIN] onCreate
01-01 12:01:57.537  8261  8261 D CamAp_QuickActivity: [367.294ms]  [END] onCreate

其中 openCamera: 花了 238ms


01-01 12:01:57.196  8261  8295 I CamAp_API1-Handler-0: [openCamera]+
01-01 12:01:57.424  8261  8295 I CamAp_API1-Handler-0: [openCamera]-, executing time = 228ms.

其中 Surface Create: 花了 333ms

01-01 12:01:57.720  8261  8261 I CamAp_TextureViewController: updatePreviewSize: new size (960 , 720) current size (0 , 0),mIsSurfaceCreated = false listener = com.mediatek.camera.common.mode.photo.PhotoMode$SurfaceChangeListener@a79ec89
01-01 12:01:58.053  8261  8261 D CamAp_TextureViewController: onSurfaceTextureAvailable surface  = android.graphics.SurfaceTexture@2d48d1c width 720 height 960

其中 startPreview: 花 386ms

01-01 12:01:57.701   532  2586 I mtkcam-dev1: 0[CameraDevice1Base::startPreview] +
01-01 12:01:58.087   532  8363 I MtkCam/CamAdapter: (8363)[transitState] StateIdle --> StatePreview

其中 startWindow -> PreveiwCallback: 花 87ms

01-01 12:01:58.093  8261  8294 I CamAp_API1-Handler-0: [setPreviewTexture]-, executing time = 37ms.

01-01 12:01:58.279  8261  8295 D CamAp_PhotoDeviceController: [onPreviewFrame] mModeDeviceCallback = com.mediatek.camera.common.mode.photo.PhotoMode@feb2273

其中花工夫的步骤,是 2、3、4、5, 次要 ui 加载,openCamera,surfaceCreated、startPreview。openCamera 和 startPreview 花工夫须要驱动优化。ui 加载和 surfaceCreate 须要下层看。

三、工具剖析

traceView 剖析 ui 加载,发现没有可优化的,当初加载的 ui 都是须要一进去就要看见的,不须要进去看见的 view,都应用 viewStub 延时加载解决了,并且对于 ui 也优化了好几波。优化空间比拟小。不过针对冷启动,能够应用内存常驻的计划,这样实际上冷启动就是热启动。次要起因是相机在手机启动时,收到启动播送会启动一个服务,用于检测是否温度过高,服务拉起了相机利用。内存常驻后,此利用就不被杀掉了。这样启动速度优化很大。
目前的计划:2G 以上我的项目默认应用内存常驻计划。

四、traceView 教程

https://www.jianshu.com/p/f81b20b9a7e2
https://developer.android.com/studio/profile/traceview

五、surface create 优化

当初次要的大头就是 Surface create 优化了。systrace 剖析创立 surface 过程,发现 ArcFilter HandleThread 始终在 wait。

六、systrace 的教程

https://developer.android.google.cn/studio/command-line/systrace

查看代码,是滤镜期待 arc 算法引擎初始化和 GL 引擎初始化。这里的设计是有争议的,其实相机启动的时候并没有开启滤镜,然而要初始化滤镜的引擎。做耗时 benchmark:

01-02 01:22:07.991 23458-23554/? I/CamAp_TextureEnvExt: handleGlEnvInit(): Enter
01-02 01:22:07.991 23458-23458/? V/CamAp_TextureEnvExt: getCamSurfaceTexture:: in  -1
01-02 01:22:08.090 23458-23554/? I/CamAp_TextureEnvExt: handleGlEnvInit(): Exit with bRet = EGL_SUCCESS
01-02 01:22:08.091 23458-23554/? I/CamAp_TextureEnvExt: handleArcFilterEngine(): init begin 
01-02 01:22:08.095 23458-23458/? V/CamAp_TextureEnvExt: getCamSurfaceTexture:: ID=1
01-02 01:22:08.211 23458-23554/? I/CamAp_TextureEnvExt: handleArcFilterEngine(): init end engine = 0,prepareEngine=0

能够看出:初始化 GLEnv 须要 99ms, 初始引擎须要 120ms.

七、优化计划

这有两种优化计划:

  1. 启动时,不加载滤镜引擎,切换到滤镜时加载。结果是切换滤镜时会卡一下,须要批改整个流程,代码批改量大。
  2. 分步初始化 GLEnv 和滤镜引擎,实践上能够优化 120ms+, 创立 Surface 和 startPreview 并行执行。代码改变小,并且能达到优化成果。

目前应用第二种计划,代码提交记录:

http://192.168.10.10/#/c/213235/

八、前后切换速度优化

前后切换速度对下层来说,次要有两个方面影响,一是翻转动画,一是高斯含糊。翻转动画应用高速相机测量,只有 9 帧,平台性能限度,有一种带不动的感觉,对标机也没有,和产品沟通去掉。能优化的就是高斯含糊了。

高斯含糊的耗时 benchmark:

01-02 02:00:21.636 8089-8089/? I/CamAp_GaussianBlur: GaussianBlur,create render:42
01-02 02:00:21.636 8089-8089/? D/CamAp_GaussianBlur: preview width 750 height 1500
01-02 02:00:21.731 8089-8089/? I/CamAp_GaussianBlur: getPreview bitmap spent time: 125
01-02 02:00:21.821 8089-8089/? I/CamAp_GaussianBlur: blurBitmap,render bitmap:112

整个高斯含糊流程大略须要花 279ms,次要耗时是 getPreview 和 blurBitmap,还有 init 每次都要做。

九、优化计划

init 须要花 40 多少 ms,只做一次。getPreview,对于高斯含糊,咱们不须要一张清晰的图片,反正前面也要做含糊。getPreview 时,咱们设置一个采样率,采样品质升高 16 倍,做高斯含糊时,咱们设置一个较小含糊半径因子,目前为 5,这样做含糊的速度快,含糊成果好。

优化后的耗时 benchmark:

01-02 02:14:15.628 20947-20947/? D/CamAp_GaussianBlur: preview width 750 height 1500
01-02 02:14:15.632 20947-20947/? I/CamAp_GaussianBlur: getPreview bitmap spent time: 4
01-02 02:14:15.636 20947-20947/? I/CamAp_GaussianBlur: blurBitmap,render bitmap:4

代码提交记录:

http://192.168.10.10/#/c/213235/

十、热启动优化

热启动优化,和比照机不同的是,在预览没有进去之前,咱们做了一个高斯含糊的盖板。和产品沟通须要去掉,去掉盖板比拟容易。引发两个问题须要解决。

  1. TextureView 没有被销毁,会保留上一帧。次要体现热启动会闪上一帧。
  2. framework 会有一个 screenshot 界面,同样会闪上帧。

十一、解决方案:

  1. 在 pause 时,把 TextureView 的 alpha 设置为 0, 第一帧上来,再把 alpha 设置 1,让其显示。
  2. 应用层关掉 screenshot.

代码提交记录:

http://192.168.10.10/#/c/215036/
http://192.168.10.10/#/c/214142/

十二、驱动优化

对于 openCamera 和 startPreview 优化,底层优化了 3a 算法、退出了 fastae 和应用 speed mode 模式。详情能够征询彭叶斌同学。

原文链接:https://www.jianshu.com/p/77d…

情谊举荐:
Android 干货分享

至此,本篇已完结,如有不对的中央,欢迎您的倡议与斧正。同时期待您的关注,感谢您的浏览,谢谢!

退出移动版