Android SurfaceFlinger VSync流程分析
2017-09-08 17:33
627 查看
一,VSync机制的作用及VSync在SurfaceFlinger服务中的位置:
VSync信号通常都来自硬件控制器,在Android中也可以采用软件模拟;
VSync的作用,如下图(以双缓冲为例,为了提高流畅性有时也采用triple三缓冲):LCD控制器在读取每一帧数据的开始都会产生一个VSync信号(垂直同步信号或帧同步信号);
LCD的频率是60Hz,显示每一帧的间隔是16ms,所以每一个VSync信号的时间间隔是16ms,上图中的A和B都是帧缓冲区framebuffer,每一个framebuffer由CPU和GPU共同完成;
在硬件芯片中,晶振产生的时钟脉冲驱动整个硬件电路连续运行;在Surfaceflinger中,VSync信号就好像晶振电路产生的时钟信号一样驱动Surfaceflinger中所有模块和谐的运行,如下图;
二,VSync流程及重要代码:
1,整体流程概览,如下图:
重点介绍如下过程:
2,App绘制请求发送流程(过程1(App)):
App进程调用invalidate或postinvalidate方法发送绘制请求;
invalidate方法最终会调用的BpDisplayEventConnection的requestNextVsync方法,在该方法中通过Binder IPC访问服务端的requestNextSync方法;
BpDisplayEventConnection方法的实例化过程如下:
1>,在ViewRootImpl的构造函数中会实例化Choreographer对象,
2>,在mChoreographer 的构造函数中实例化FrameDisplayEventReceiver对象:
3>,在FrameDisplayEventReceiver的父类构造函数中会调用到,android_view_DisplayEventReceiver.cpp中的nativeInit方法,
4>,在nativeInit方法中有如下过程:
在NativeDisplayEventReceiver的构造函数中会调用DisplayEventReceiver类的无参构造函数实例化成员mReceiver;
在这段代码中获取Surfaceflinger服务的代理对象,然后通过Binder IPC创建BpDisplayEventConnection对象,然后mEventConnection->getDataChannel()方法再次通过Binder IPC创建 BitTube对象mDataChannel ,在Binder IPC创建mDataChannel 过程中会从服务端EventThread::Connection::Connection中(在EventThread类中定义)接收一个socketpair创建的FIFO文件描述符;
EventThread::Connection::Connection创建描述符的代码:
Connection构造函数调用BitTube的无参构造函数,在BitTube的构造函数中调用init函数;
3,Vsync信号驱动App进程绘制流程(过程4(App)):
4,Surfaceflinger图册合成请求发送流程(过程1(sf)):
5,Vsync信号驱动Surfaceflinger合成流程(过程4(sf)):
VSync信号通常都来自硬件控制器,在Android中也可以采用软件模拟;
VSync的作用,如下图(以双缓冲为例,为了提高流畅性有时也采用triple三缓冲):LCD控制器在读取每一帧数据的开始都会产生一个VSync信号(垂直同步信号或帧同步信号);
LCD的频率是60Hz,显示每一帧的间隔是16ms,所以每一个VSync信号的时间间隔是16ms,上图中的A和B都是帧缓冲区framebuffer,每一个framebuffer由CPU和GPU共同完成;
在硬件芯片中,晶振产生的时钟脉冲驱动整个硬件电路连续运行;在Surfaceflinger中,VSync信号就好像晶振电路产生的时钟信号一样驱动Surfaceflinger中所有模块和谐的运行,如下图;
二,VSync流程及重要代码:
1,整体流程概览,如下图:
重点介绍如下过程:
2,App绘制请求发送流程(过程1(App)):
App进程调用invalidate或postinvalidate方法发送绘制请求;
invalidate方法最终会调用的BpDisplayEventConnection的requestNextVsync方法,在该方法中通过Binder IPC访问服务端的requestNextSync方法;
BpDisplayEventConnection方法的实例化过程如下:
1>,在ViewRootImpl的构造函数中会实例化Choreographer对象,
public ViewRootImpl(Context context, Display display) { . . . . . mChoreographer = Choreographer.getInstance(); }
2>,在mChoreographer 的构造函数中实例化FrameDisplayEventReceiver对象:
private Choreographer(Looper looper) { . . . . . . mDisplayEventReceiver = USE_VSYNC ? new FrameDisplayEventReceiver(looper) : null; }
3>,在FrameDisplayEventReceiver的父类构造函数中会调用到,android_view_DisplayEventReceiver.cpp中的nativeInit方法,
4>,在nativeInit方法中有如下过程:
static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject messageQueueObj) { . . . . . . sp<NativeDisplayEventReceiver> receiver = new NativeDisplayEventReceiver(env, receiverWeak, messageQueue); status_t status = receiver->initialize(); . . . . . .
1),创建NativeDisplayEventReceiver类类型指针,
在NativeDisplayEventReceiver的构造函数中会调用DisplayEventReceiver类的无参构造函数实例化成员mReceiver;
DisplayEventReceiver::DisplayEventReceiver() { sp<ISurfaceComposer> sf(ComposerService::getComposerService()); if (sf != NULL) { mEventConnection = sf->createDisplayEventConnection(); if (mEventConnection != NULL) { mDataChannel = mEventConnection->getDataChannel(); } } }
在这段代码中获取Surfaceflinger服务的代理对象,然后通过Binder IPC创建BpDisplayEventConnection对象,然后mEventConnection->getDataChannel()方法再次通过Binder IPC创建 BitTube对象mDataChannel ,在Binder IPC创建mDataChannel 过程中会从服务端EventThread::Connection::Connection中(在EventThread类中定义)接收一个socketpair创建的FIFO文件描述符;
EventThread::Connection::Connection创建描述符的代码:
Connection构造函数调用BitTube的无参构造函数,在BitTube的构造函数中调用init函数;
void BitTube::init(size_t rcvbuf, size_t sndbuf) { int sockets[2]; if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) { size_t size = DEFAULT_SOCKET_BUFFER_SIZE; setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)); setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)); // sine we don't use the "return channel", we keep it small... setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)); setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); fcntl(sockets[0], F_SETFL, O_NONBLOCK); fcntl(sockets[1], F_SETFL, O_NONBLOCK); mReceiveFd = sockets[0]; mSendFd = sockets[1]; } else { mReceiveFd = -errno; ALOGE("BitTube: pipe creation failed (%s)", strerror(-mReceiveFd)); } }
2)调用到NativeDisplayEventReceiver类的父类DisplayEventDispatcher中的initialize()方法, 将BpDisplayEventConnection对象获取到的mDataChannel (BitTube类型)中的文件描述符添加到UI主线程Looper的epoll中, 当文件描述符中被写入数据时,该epoll_wait会被唤醒;
3,Vsync信号驱动App进程绘制流程(过程4(App)):
4,Surfaceflinger图册合成请求发送流程(过程1(sf)):
5,Vsync信号驱动Surfaceflinger合成流程(过程4(sf)):
相关文章推荐
- Android display架构分析七-Surfaceflinger process流程分析
- Android SurfaceFlinger process 流程分析
- Android display架构分析七-Surfaceflinger process流程分析
- 【Android】Android SurfaceFlinger之VSync
- android Gui系统之SurfaceFlinger(5)---Vsync(2)
- 通过 dumpsys SurfaceFlinger 分析Android 系统图层
- SurfaceFlinger旋转流程分析
- Android surfaceflinger 源代码分析
- Android系统Surface机制的SurfaceFlinger服务的启动过程分析 JellyBean
- Android核心分析(27)-----Android GDI 之SurfaceFlinger之动态结构示意图
- android L 的surfaceflinger服务启动分析
- android从init到开机动画启动关闭流程一简易图(surfaceflinger启动的位置)
- Android SurfaceFlinger服务的消息循环过程源码分析
- Android核心分析(27)-----Android GDI 之SurfaceFlinger之动态结构示意图
- Android系统Surface机制的SurfaceFlinger服务的启动过程分析
- Android SurfaceFlinger服务启动过程源码分析1
- Android 4.4KitKat AudioFlinger 流程分析
- Android核心分析(26)-----Android GDI之SurfaceFlinger
- android从init到开机动画启动关闭流程一简易图(surfaceflinger启动的位置)
- Android系统Surface机制的SurfaceFlinger服务的启动过程分析