八. WMS原理分析

WMS帧缓冲区

屏幕刷新率(HZ):代表屏幕在1秒内刷新的次数,Android手机一般是60Hz(也即是1s刷新60帧,大约16.67ms刷新1帧)
系统帧速率(FPS):代表系统在1秒内合成的帧数,这个值的大小由系统算法和硬件决定.

分析屏幕卡顿的原因

当我们的系统帧速率跟不上屏幕刷新率的速度时,假如屏幕刷新率时候60HZ,但是系统帧速率是10PFS,也就是说屏幕原本1秒中可以刷新60帧,但是现在只提供给了10帧给屏幕刷新,就会造成刷新完10帧后,最终停留在第10帧画面上,1s-1s/6=5/6s的剩余时间都卡在了第10帧画面上,给用户带来的视觉体验就是卡顿.

VSync

全称是Vertical Synchronize,垂直同步,保证屏幕刷新率和系统帧速率一致性,防止卡顿、屏幕撕裂和丢帧.

扩展:
在显示当前这一帧数据的时候,会同时生成下一帧的数据;当显示下一帧数据的时候,直接把生成的数据拿来展示即可.

GPU作用举例
  1. 将颜色值(如:#FF000000)转换成屏幕LED灯可以可以识别的红、绿、蓝RGB色值
  2. 将我们的图像进行放大和缩小
SurfaceFlinger

负责图像的合成.
一个Window对应3个Buffer缓冲(比如:Navigation导航栏、StatusBar状态栏和我们的应用程序窗口都分别表示一个Window),一个Window表示一个Surface,由SurfaceFlinger将我们的一个个Surface合成,然后在通过HWC(Hardware Compose)经过硬件合成或者软件整体合成,最终构成了我们整个手机屏幕.

  1. 一个Window有三个Buffer的好处:
  1. 复用
  2. 减少资源浪费
  1. 整体流程

每一个Window(比如:Navigation导航栏)都对应一个Surface,而一个Suface对应SurfaceFlinger中的一个图层(BufferQueueLayer),一个图层(BufferQueueLayer)中包含了生产者、BufferQueue和消费者,通过生产者将Surface写入BufferQueue,然后通过消费者从BufferQueue中读出数据,通过HWC硬件设备经过硬件合成或者是软件合成称为我们的图像,然后将合成的图像展示在手机屏幕上.

  1. BufferQueue

BufferQueue里面了一个BufferQueueCore,而BufferQueueCore包含了一个个卡槽(BufferSlot),一个BufferQueue最多可以包含64个卡槽,每一个卡槽BufferSlot包含了Buffer的状态mBufferState,Buffer包含了如下4中状态:

  • Free:可被上层使用
  • Dequeue:出列,正在被上层使用
  • Queued:入列,已完成上层绘制,等待SurfaceFlinger绘制
  • Acquired:被获取,SurfaceFlinger正持有该Buffer进行合成

状态的变化:
Free->Dequeued->Queued->Acquired->Free

  1. Surface

Surface包含了lockCanvas和unlockCanvasAndPost(canvas)方法,分别对应了dequeue出列和queue入列两种状态,lockCanvas方法会返回一个Canvas画布对象,接着调用我们View的draw方法通过拿到的Canvas进行View的绘制,绘制完成后,交给unlockCanvasAndPost方法进行处理,处理完成后,再将我们的数据通过生产者添加到BufferQueue队列中去.

面试题
  1. 什么是SurfaceView?

是一个View控件,他单独拥有一个画布Canvas,正常情况下是一个窗口Window(比如:我们的应用程序窗口,也就是是一个Activity中的PhoneWindow窗口)拥有一个画布Canvas;而SurfaceView这个View却拥有一个Canvas画布对象,我们可以通过lockCanvas获取到这个Canvas画布对象,然后通过这个画布对象进行View绘制,绘制完成后调用unlockCanvasAndPost方法,将绘制后的数据写入到BufferQueue队列,然后通过SufaceFlinger组合Surface给HWC合成图像交给屏幕展示.
我们可以把SurfaceView理解成是一个精简版的窗口Window;他可以同时在主线程和子线程中刷新UI.
使用场景:
摄像、播放视频、帧动画的优化等.

  1. View和SurfaceView的区别?
  • View是属于一个Window的(一个Window中可以包含很多的View),一个Window对应了一个Surface,也就是一个Window中的所有View公用一个Surface的画布对象;而SurfaceView单独拥有一个Surface的画布对象.
    因此,SurfaceView拥有更高的效率.
  • 正常情况下,View只能在主线程中更新UI,而SurfaceView可以同时在主线程和子线程中更新UI.
  • 正常情况下,View的屏幕刷新率是60HZ,但是SurfaceView可以更高屏幕的刷新率,可以增大屏幕刷新率的值.
    因此,SurfaceView可以通过更改屏幕刷新率,让屏幕的画面更流畅.
  1. 应用程序是如何与SurfaceFlinger进行通信的,View的绘制是如何把数据传递给SurfaceFlinger的?
  • 首先,我们通过Surface的lockCanvas()方法,通过生产者从SurfaceFling中的缓冲队列(BufferQueue)中拿到数据,数据会被转换成Canvas画布对象;
  • 然后调用View的draw方法通过拿到Canvas画布对象进行View的绘制,绘制完成后,调用Surface的unlockCanvasAndPost(canvas)方法,通过生产者将绘制后的数据,添加到缓冲队列(BufferQueue)中去.
  1. relayout是如何向SurfaceFlinger申请Surface的?
  • App进程:
    ViewRootImpl.performTranversal()
    ->ViewRootImpl.relayoutWindow()
    ->mWindowSession.relayout(…,mSurface)

  • SystemServer进程的WMS服务:
    WindowManagerService.relayoutWindow()
    ->createSurfaceControl(Surface outSurface)
    ->winAnimator.createSurfaceLocked
    ->mSurfaceControl.Builder.build()
    ->new SurfaceControl()
    ->nativeCreate()
    ->SurfaceComposerClient::createSurfaceChecked(…,&surface,…)

  • SurfaceFlinger进程:
    Client::createSurface
    ->mFlinger->createLayer

  • SystemServer进程的WMS服务:
    surfaceControl.getSurface(outSurface) @WindowManagerService.java
    ->outSurface.copyFrom(mSurfaceControl)

  • App进程:
    ViewRootImpl.relayoutWindow()//这个时候App就可以拿到创建的Surface.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值