android graphic(5)—surfaceflinger和Vsync (简化)
来源:互联网 发布:无涯子 知乎 编辑:程序博客网 时间:2024/05/25 23:59
版权声明:本文为博主原创文章,未经博主允许不得转载。
目录(?)[+]
- surfaceflinger中类的关系
- HWC驱动DispSync
上一节分析了Vsync的多个类之间的关系,感觉非常不清晰,特地画了一张图,感觉清晰了很多。(黄色的方框是类名,绿色方框为field,联系用虚线箭头表示,如果不同线条之间有重叠,用了不同的颜色)
surfaceflinger中类的关系
下面照着这张图,梳理下Android 4.4 SF中Vsync相关类之间的联系,surfaceflinger简写为SF:
1. Vsync的硬件模型类,DispSync,其对应的thread保存在mThread中,thread是一个DispSyncThread类型;
2. DispSyncThread的mEventListeners是个EventListener类型的Vector;
3. EventListener类中的mCallback其实保存的是DispSyncSource对象,这样就将硬件模型和驱动的事件DispSyncSource类联系起来了,在上面图中我们看到了两个mCallback,一个指向了DispSyncSource,一个指向了EventThread,容易搞混,正是由于这两个mCallback把DispSyncThread类,DispSyncSource,EventThread联系了起来;
4. DispSyncSource类中的mCallback指向的其实是其对应的EventThread类,而EventThread类中的mDisplayEventConnections是个 wp 类型的SortedVector,但是所指向的Connection中的BitTube mChannel只有写fd,这样我们往这个写fd写东西,哪里会收到呢?
5. 当然是SF主线程中的MessageQueue,其中保存了另外一个BitTube mEventTube,里面保存了读fd,当Vsync信号到来时,EventThread会去往写fd中写东西,而这时候SF主线程中MessageQueue的looper的epoll会被唤醒;
6. 在looper中保存了一个KeyedVector<int, Request>mRequests键值对,其中以fd做键,Request做值,其中fd指向了读fd,而data指向了MessageQueue,callback指向了一个SimpleLooperCallback类,SimpleLooperCallback类中的mCallback则指向了最终的事件处理函数cb_eventReceiver();
下面看下Looper的pollInner函数,
int Looper::pollInner(int timeoutMillis){
struct epoll_eventeventItems[EPOLL_MAX_EVENTS];
int eventCount =epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
//epoll_wait返回,
for (int i =0; i <eventCount; i++) {
int fd =eventItems[i].data.fd;
uint32_tepollEvents = eventItems[i].events;
if (fd ==mWakeReadPipeFd) {
if (epollEvents& EPOLLIN) {
awoken();
} else {
ALOGW("Ignoringunexpected epoll events 0x%x on wake read pipe.", epollEvents);
}
} else {
//mRequests键值对前面就注册好了,这里通过fd取到mRequests中fd的index
ssize_trequestIndex = mRequests.indexOfKey(fd);
if (requestIndex>=0) {
int events =0;
if (epollEvents& EPOLLIN) events |= EVENT_INPUT;
if (epollEvents& EPOLLOUT) events |= EVENT_OUTPUT;
if (epollEvents& EPOLLERR) events |= EVENT_ERROR;
if (epollEvents& EPOLLHUP) events |= EVENT_HANGUP;
//取出mRequests相关的值,放到mResponses中
pushResponse(events, mRequests.valueAt(requestIndex));
} else {
ALOGW("Ignoringunexpected epoll events 0x%x on fd %d that is "
"no longer registered.", epollEvents,fd);
}
}
}
// Release lock.
mLock.unlock();
//前面的mResponses已经填充好了,这里取出来处理具体事件
// Invoke all response callbacks.
for (size_t i =0; i <mResponses.size(); i++) {
Response& response = mResponses.editItemAt(i);
if(response.request.ident == POLL_CALLBACK) {
int fd =response.request.fd;
int events =response.events;
void* data =response.request.data;
#ifDEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
ALOGD("%p ~ pollOnce - invoking fd eventcallback %p: fd=%d, events=0x%x, data=%p",
this,response.request.callback.get(), fd, events, data);
#endif
//这里的callbackcallback指向了一个SimpleLooperCallback类,SimpleLooperCallback类中的mCallback则指向了最终的事件处理函数cb_eventReceiver()
int callbackResult= response.request.callback->handleEvent(fd, events, data);
if (callbackResult==0) {
removeFd(fd);
}
// Clear the callback reference in theresponse structure promptly because we
// will not clear the response vectoritself until the next poll.
response.request.callback.clear();
result = POLL_CALLBACK;
}
}
return result;
}
SimpleLooperCallback的handleEvent()函数,其实执行的是mCallback(),即cb_eventReceiver()。
int SimpleLooperCallback::handleEvent(int fd,int events,void* data) {
return mCallback(fd,events, data);
}
HWC驱动DispSync
最开始的图形描述的都是SF中Vsync相关类的关系,那么HWC如何驱动DispSync?
HWC中每个Vsync信号到来时,都会调用SF的onVSyncReceived函数,
mHwc.mEventHandler.onVSyncReceived(0, next_vsync);
进而去调用mPrimaryDispSync的addResyncSample,mPrimaryDispSync就是DispSync,根据函数名,添加时间片,就相当于不停的产生时间,就把DispSync驱动起来了,
voidSurfaceFlinger::onVSyncReceived(inttype, nsecs_ttimestamp) {
boolneedsHwVsync = false;
{ // Scope for the lock
Mutex::Autolock _l(mHWVsyncLock);
if (type ==0 && mPrimaryHWVsyncEnabled) {
needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
}
}
}
进而调用DispSync的updateModelLocked()函数,
boolDispSync::addResyncSample(nsecs_t timestamp) {
updateModelLocked();
}
这里就会去驱动DispSyncThread线程工作了,后续的在图上都能看到。
void DispSync::updateModelLocked() {
if(mNumResyncSamples>= MIN_RESYNC_SAMPLES_FOR_UPDATE){
//驱动DispSyncThread线程不停工作了
mThread->updateModel(mPeriod,mPhase);
}
}
- android graphic(5)—surfaceflinger和Vsync (简化)
- android graphic(5)—surfaceflinger和Vsync (简化)
- android graphic(4)—surfaceflinger和Vsync
- android graphic(4)—surfaceflinger和Vsync
- android graphic(6)—surfaceflinger和MessageQueue
- android graphic(6)—surfaceflinger和MessageQueue
- Android Graphic SurfaceFlinger 疑难解答
- Android Graphic SurfaceFlinger分析
- 【Android】Android SurfaceFlinger之VSync
- Android 5.1 SurfaceFlinger VSYNC详解
- Android SurfaceFlinger VSync流程分析
- UNDERSTANDING ANDROID GRAPHIC- SURFACEFLINGER (IV)
- android graphic(16)—fence(简化)
- android graphic(3)—surfaceflinger的启动流程
- android graphic(3)—surfaceflinger的启动流程
- Android 5.1 SurfaceFlinger --- Dispatching VSync events
- Android surfaceflinger (4) -Vsync产生上报流程
- Android 4.2 JellyBean Graphic Component -- SurfaceFlinger 1
- hiho一下 第二十八周 #1105 : 题外话·堆 【堆】
- 用C语言实现快速排序算法
- 【HPU 1012 QAQ的区间统计】
- HDU5968 异或密码(暴力)
- 噪音放大器原理及基础知识问答
- android graphic(5)—surfaceflinger和Vsync (简化)
- bzoj 3744: Gty的妹子序列 分块+树状数组
- Struts 执行流程
- java编程思想学习之垃圾回收
- 优先队列详解priority_queue
- SVG文档的注意事项
- 重磅 | 微信应用号,小程序最新开发教程第一弹
- FZU2150 fire
- iOS 第三方JASidePanels侧滑