<span style="color:#FF6666;">文章都是通过阅读源码分析出来的,还在不断完善与改进中,其中难免有些地方理解得不对,欢迎大家批评指正。<br>转载请注明:From LXS. http://blog.csdn.net/uiop78uiop78/<br><br>GUI系统之SurfaceFlinger章节目录:<br>blog.csdn.net/uiop78uiop78/article/details/8954508</span>
<br>
<p><br></p>
<p></p>
<h2><a name="_Toc356900114">1.1 VSync</a>的产生和处理</h2>
<p></p>
<p>前面小节ProjectButter中我们学习了Android 4.1显示系统中的新特性,其中一个就是加入了VSync同步。我们从理论的角度分析了采用这一机制的必要性和运作机理,那么SurfaceFlinger具体是如何实施的呢?</p>
<p>先来想一下有哪些东西要考虑:</p>
<p>· VSync信号的产生和分发</p>
<p>如果有硬件主动发出这一信号,那是最好的了;否则就得通过软件定时模拟来产生</p>
<p>· VSync信号的处理</p>
<p>当信号产生后,SurfaceFlinger如何在最短的时间内响应,具体处理流程是怎么样子的</p>
<h3><a name="_Toc356900115">1.1.1 VSync</a>信号的产生和分发</h3>
<p>在Android源码surfaceflinger目录下有一个displayhardware文件夹,其中HWComposer的主要职责之一,就是用于产生VSync信号。</p>
<div style="background:#BFBFBF;">
<p>/*frameworks/native/services/surfaceflinger/displayhardware/HWComposer.cpp*/</p>
<p>HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger,EventHandler& handler, nsecs_t refreshPeriod)</p>
<p style="background:#BFBFBF;">: mFlinger(flinger), <span style="background:gray;">mModule</span>(0), <span style="background:gray;">mHwc</span>(0), mList(0), mCapacity(0),mNumOVLayers(0),</p>
<p style="background:#BFBFBF;"> mNumFBLayers(0), mDpy(EGL_NO_DISPLAY),mSur(EGL_NO_SURFACE),</p>
<p> <span style="background:gray;">mEventHandler</span>(handler),mRefreshPeriod(refreshPeriod),</p>
<p> mVSyncCount(0),mDebugForceFakeVSync(false)</p>
<p>{<!-- --></p>
<p> charvalue[PROPERTY_VALUE_MAX];</p>
<p> property_get("debug.sf.no_hw_vsync", value, "0"); //系统属性</p>
<p> mDebugForceFakeVSync =atoi(value);</p>
<p> bool needVSyncThread =false;//是否需要软件模拟VSync</p>
<p> int err = <span style="background:gray;">hw_get_module</span>(HWC_HARDWARE_MODULE_ID, &mModule);//加载HAL模块</p>
<p> if (err == 0) {<!-- --></p>
<p> err = <span style="background:gray;">hwc_open</span>(mModule, &mHwc);//打开module</p>
<p> if (err == 0) {<!-- --></p>
<p style="background:#BFBFBF;">if(mHwc->registerProcs) { //注册硬件设备事件回调</p>
<p> mCBContext.hwc= this;</p>
<p> mCBContext.procs.invalidate = &hook_invalidate;</p>
<p> mCBContext.procs.vsync = &hook_vsync;</p>
<p> mHwc-><span style="background:gray;">registerProcs</span>(mHwc, &mCBContext.procs);</p>
<p> memset(mCBContext.procs.zero, 0, sizeof(mCBContext.procs.zero));</p>
<p> }</p>
<p> if(mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) {<!-- --></p>
<p> if(mDebugForceFakeVSync) {//用于调试</p>
<p> mHwc->methods->eventControl(mHwc, HWC_EVENT_VSYNC, 0);</p>
<p> }</p>
<p> } else {//有可能支持VSync的硬件模块是这个版本以后才加入的,老版本仍然需要软件模拟</p>
<p> needVSyncThread = true;</p>
<p> }</p>
<p> }</p>
<p> } else {<!-- --></p>
<p> needVSyncThread =true; //硬件模块打开失败,只能用软件模拟</p>
<p> }</p>
<p> if (needVSyncThread) {<!-- --></p>
<p> mVSyncThread = new <span style="background:gray;">VSyncThread</span>(*this);//创建一个产生VSync信号的线程</p>
<p> }</p>
<p>}</p>
</div>
<p>这个函数的核心就是决定VSync的“信号发生源”——硬件或者软件模拟。</p>
<p>假如当前系统可以成功加载HWC_HARDWARE_MODULE_ID=“hwcomposer”,并且通过这个库模块能顺利打开设备(hwc_composer_device_t),其版本号又大于HWC_DEVICE_API_VERSION_0_3的话,我们就采用“硬件源”(此时needVSyncThread为false),否则需要创建一个新的VSync线程来模拟产生信号。</p>
<p>(1)硬件源</p>
<p>如果mHwc->registerProcs不为空的话,我们注册硬件回调mCBContext.procs。定义如下:</p>
<p> struct cb_context{<!-- --></p>
<p> callbacksprocs;</p>
<p> HWComposer*hwc;</p>
<p> };</p>
<p>调用registerProcs()时,传入的参数是&mCBContext.procs。后期当有事件产生时,比如vsync或者invalidate,硬件模块将分别通过procs.vsync和procs.invalidate来通知HWComposer。</p>
<div style="background:#BFBFBF;">
<p>void HWComposer::hook_vsync(struct hwc_procs* procs, int dpy,int64_t timestamp) {<!-- --></p>
<p> reinterpret_cast<cb_context *>(procs)->hwc->vsync(dpy,timestamp);</p>
<p>}</p>
</div>
<p>上面这个函数中,procs即前面的&mCBContext.procs,从指针地址上看它和&mC |
|