android display之VSync和线程处理关系
目录:
0.mtk平台相关surfaceflinger线程有那些?
1 mtk采用的是:硬件VSYNC 线程
2.Mtk 通过surfaceflinger注册了3个eventthread
2.1 DispSyncThread如何区分和执行vssyncsrc和sfVsyncSrc的vs?
2.2 vssyncsrc和sfVsyncSrc的事件接受者什么创建
2.3 EventControl线程
//////////////////////////////////////////////////////////////////////////////////////
0.mtk平台相关surfaceflinger线程有:
1 mtk采用的是:硬件VSYNC 线程:
2.Mtk 通过surfaceflinger注册了3个eventthread:
每个event线程都注册:
voidEventThread::Connection::onFirstRef() {
// NOTE: mEventThread doesn't hold a strongreference on us
mEventThread->registerDisplayEventConnection(this);
}
线程 | VS信号源 | 功能 |
eventthread: | vssyncsrc硬件VS | 用于控制App UI的同步,产生sfVsyncSrc的周期:sfVsyncPhaseOffsetNs。在setVSyncEnabled()的时候mDispSync->addEventListener()来设置周期 |
Eventthread | sfVsyncSrc | 与surfaceflinger的渲染同步,产生vssyncsrc的周期是:vsyncPhaseOffsetNs。在setVSyncEnabled()的时候mDispSync->addEventListener()来设置周期 |
EventControl | 无 | 用来向VSync硬件发命令,只是使能和关闭硬件vs信号 |
DispSync线程 | vssyncsrc硬件VS | 统一处理硬件产生的vs信号,以及计算帧时间 |
理论上来说:vssyncsrc和sfVsyncSrc都是虚拟的vs。两者都是通过DispSync线程来计算发出vs的时间。
2.1 DispSyncThread如何区分和执行vssyncsrc和sfVsyncSrc的VsyncSrc?
答案:
1)首先VSyncSource对象的创建如下
// start the EventThread
sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,返回一个DispSyncSource对象给vsyncSrc
vsyncPhaseOffsetNs, true);
mEventThread = new EventThread(vsyncSrc);
sp<VSyncSource>sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,----返回一个DispSyncSource对象给sfVsyncSrc
sfVsyncPhaseOffsetNs, false);
mSFEventThread = newEventThread(sfVsyncSrc);
mEventQueue.setEventThread(mSFEventThread);
-------也就是每个EventThread都是有管理自己的对象vsyncSrc或者sfVsyncSrc;
---------EventThread::threadLoop-------
{
……...
-waitForEvent()
…...
}
//增加监听者以及设置接收到vsync的时候callbakc
waitForEvent(){
…..
// Here we figure outif we need to enable or disable vsyncs
if (timestamp && !waitForVSync){
// we received a VSYNC but we haveno clients
// don't report it, and disableVSYNC events
disableVSyncLocked();
} else if (!timestamp &&waitForVSync) {
// we have at least one client, sowe want vsync enabled
// (TODO: this function is calledright after we finish
// notifying clients of a vsync, sothis call will be made
// at the vsync rate, e.g.60fps. If we can accurately
// track the current state we couldavoid making this call
// so often.)
enableVSyncLocked();
}
………
}
void EventThread::enableVSyncLocked() {
if (!mUseSoftwareVSync) {
// never enable h/w VSYNC when screenis off
if (!mVsyncEnabled) {
mVsyncEnabled = true;
/*设置回调VSyncSource::Callback 的onVSyncEvent是纯虚函数:EventThread继承自VSyncSource::Callback。实现了onVSyncEvent()回调函数。
//classEventThread : public Thread, private VSyncSource::Callback
最终:mCallback = callback;
virtual voidsetCallback(const sp<VSyncSource::Callback>& callback) {
Mutex::Autolock lock(mMutex);
mCallback = callback;
}
*/
mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this));
mVSyncSource->setVSyncEnabled(true);-----》这侧监听者到mEventListeners
mPowerHAL.vsyncHint(true);
}
}
mDebugVsyncEnabled = true;
}
2)其次硬件常常一个VS--->通知到SurfaceFlinger::onVSyncReceived(inttype, nsecs_t timestamp)//timestamp就是用来计算这次vs的周期:mPeriod ;而mPeriod 就是DispSync线程的执行周期。
virtual bool threadLoop() {
status_t err;
nsecs_t now =systemTime(SYSTEM_TIME_MONOTONIC);
nsecs_t nextEventTime = 0;
while (true) {
Vector<CallbackInvocation>callbackInvocations;
………...
if (mPeriod == 0) {
err = mCond.wait(mMutex);//周期超时 ,则wait,直到下一次HW VS产生
if (err != NO_ERROR) {
ALOGE("errorwaiting for new events: %s (%d)",
strerror(-err),err);
return false;
}
continue;
}
。。。。。。。。。
if (isWakeup) {
mWakeupLatency =((mWakeupLatency * 63) +
(now - targetTime))/ 64;
if (mWakeupLatency >500000) {
// Don't correct bymore than 500 us
mWakeupLatency =500000;
}
if (traceDetailedInfo) {
ATRACE_INT64("DispSync:WakeupLat", now - nextEventTime);
ATRACE_INT64("DispSync:AvgWakeupLat", mWakeupLatency);
}
}
//gatherCallbackInvocationsLocked() 计算出虚拟VSync信号 要多久产生。
callbackInvocations= gatherCallbackInvocationsLocked(now);
}
if (callbackInvocations.size() >0) {
fireCallbackInvocations(callbackInvocations);
//调起监听者的回调函数DispSyncSource::onDispSyncEvent()-----》callback->onVSyncEvent(when);
}
}
return false;
}
voidfireCallbackInvocations(const Vector<CallbackInvocation>& callbacks){
for (size_t i = 0; i <callbacks.size(); i++) {
callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime);
}
}
“DispSyncThread就像乐队鼓手一样控制着大家的节奏。它在主循环中会先通过已经向DispSync注册的listener计算下一个要产生的虚拟VSync信号还要多久,等待相应时间后就会调用相应listener的callback函数。这样,对于那些注册了listener的监听者来说,就好像被真实的VSync信号控制着一样。”
小结:相对DispSyncThread而言,vssyncsrc线程和sfVsyncSrc线程是vsync监听者。
而vssyncsrc和sfVsyncSrc收到vsync之后,应用程序和surfaceflinger(两线程循环 获取Event)是vsync事件的接收者。
所以vsynv的路径就是:DispSyncThread--->vssyncsrc和sfVsyncSrc---->vsync事件的接收者:应用程序和surfaceflinger.
2.2 vssyncsrc线程和sfVsyncSrc线程的vsync事件接受者什么创建?
1)sfVsyncSrc的vsync事件接收者创建:通过mSFEventThread对象 ;
mSFEventThread= new EventThread(sfVsyncSrc);
mEventQueue.setEventThread(mSFEventThread);
voidMessageQueue::setEventThread(constsp<EventThread>& eventThread)
{
mEventThread = eventThread;
mEvents =eventThread->createEventConnection();
mEventTube = mEvents->getDataChannel();
mLooper->addFd(mEventTube->getFd(),0, ALOOPER_EVENT_INPUT,
MessageQueue::cb_eventReceiver,this);
}
2)vssyncsrc的vsync事件接收者创建:
应用层通过DisplayEventReceiver.java
--->android_view_DisplayEventReceiver.cpp
--->DisplayEventReceiver.cpp
---->EventThread.cpp
一直到mEventThread对象:
sp<IDisplayEventConnection>SurfaceFlinger::createDisplayEventConnection() {
return mEventThread->createEventConnection();
}
2.3 EventControl线程
EventControlThread::threadLoop()
---->
mFlinger->eventControl(HWC_DISPLAY_PRIMARY,
SurfaceFlinger::EVENT_VSYNC, mVsyncEnabled);
----->getHwComposer().eventControl(disp, event, enabled);----->HWComposer::eventControl()
---- mHwc->eventControl() hal层
更多相关文章
- SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
- ConditionVariable的用法
- Android(安卓)BroadcastReceiver 的生命周期及实际应用
- Android(java)学习笔记75:匿名内部类的方式实现多线程程序
- android 反纠结app开发: 在线程中更新view
- 第10章(2)---ThreadLocal
- Android的Handler常见的面试问题
- android 多线程断点续传下载 二
- Thread、Runable和Timer、TimerTask简述