Android 5.1 SurfaceFlinger --- Dispatching VSync events
来源:互联网 发布:财经新闻数据 编辑:程序博客网 时间:2024/05/06 04:06
surfaceflinger进程由init.rc启动:
service surfaceflinger /system/bin/surfaceflinger
接下来进到surfaceflinger的main()函数:
frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
int main(int, char**) { // When SF is launched in its own process, limit the number of // binder threads to 4. ProcessState::self()->setThreadPoolMaxThreadCount(4); // start the thread pool sp<ProcessState> ps(ProcessState::self()); ps->startThreadPool(); // instantiate surfaceflinger sp<SurfaceFlinger> flinger = new SurfaceFlinger();#if defined(HAVE_PTHREADS) setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);#endif set_sched_policy(0, SP_FOREGROUND); // initialize before clients can connect flinger->init(); // publish surface flinger sp<IServiceManager> sm(defaultServiceManager()); sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false); // run in this thread flinger->run(); return 0;}
首先设置surfaceflinger进程的Binder线程数量为4,进程优先级是PRIORITY_URGENT_DISPLAY,这个优先级的设置在Display系统的很多地方都能看到。与此同时,创建了一个SurfaceFlinger对象,调用了对应的init()函数,将surfaceflinger注册到ServiceManager中去,并启动surfaceflinger线程。
其中的初始化操作在init()中:
void SurfaceFlinger::init() { ALOGI( "SurfaceFlinger's main thread ready to run. " "Initializing graphics H/W..."); status_t err; Mutex::Autolock _l(mStateLock); /* Set the mask bit of the sigset to block the SIGPIPE signal */ sigset_t sigMask; sigemptyset (&sigMask); sigaddset(&sigMask, SIGPIPE); sigprocmask(SIG_BLOCK, &sigMask, NULL); // initialize EGL for the default display mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(mEGLDisplay, NULL, NULL); // Initialize the H/W composer object. There may or may not be an // actual hardware composer underneath. mHwc = new HWComposer(this, *static_cast<HWComposer::EventHandler *>(this)); // get a RenderEngine for the given display / config (can't fail) mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID()); // retrieve the EGL context that was selected/created mEGLContext = mRenderEngine->getEGLContext(); LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT, "couldn't create EGLContext"); // initialize our non-virtual displays for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) { DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i); // set-up the displays that are already connected if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) { // query from hwc if the non-virtual display is secure. bool isSecure = mHwc->isSecure(i);; createBuiltinDisplayLocked(type, isSecure); wp<IBinder> token = mBuiltinDisplays[i]; sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer, new GraphicBufferAlloc()); sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i, consumer); int32_t hwcId = allocateHwcDisplayId(type); sp<DisplayDevice> hw = new DisplayDevice(this, type, hwcId, mHwc->getFormat(hwcId), isSecure, token, fbs, producer, mRenderEngine->getEGLConfig()); if (i > DisplayDevice::DISPLAY_PRIMARY) { // FIXME: currently we don't get blank/unblank requests // for displays other than the main display, so we always // assume a connected display is unblanked. ALOGD("marking display %zu as acquired/unblanked", i); hw->setPowerMode(HWC_POWER_MODE_NORMAL); } mDisplays.add(token, hw); } } // make the GLContext current so that we can create textures when creating Layers // (which may happens before we render something) getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext); // start the EventThread sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync, vsyncPhaseOffsetNs, true, "app"); mEventThread = new EventThread(vsyncSrc); sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync, sfVsyncPhaseOffsetNs, true, "sf"); mSFEventThread = new EventThread(sfVsyncSrc); mEventQueue.setEventThread(mSFEventThread); mEventControlThread = new EventControlThread(this); mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY); // set a fake vsync period if there is no HWComposer if (mHwc->initCheck() != NO_ERROR) { mPrimaryDispSync.setPeriod(16666667); } // initialize our drawing state mDrawingState = mCurrentState; // set initial conditions (e.g. unblank default device) initializeDisplays(); // start boot animation startBootAnim();}
一步步来看:
// Initialize the H/W composer object. There may or may not be an // actual hardware composer underneath. mHwc = new HWComposer(this, *static_cast<HWComposer::EventHandler *>(this));
初始化HWComposer,封装了厂商的HAL层实现,来看看它的构造函数:
frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp
HWComposer::HWComposer( const sp<SurfaceFlinger>& flinger, EventHandler& handler) : mFlinger(flinger), mFbDev(0), mHwc(0), mNumDisplays(1), mCBContext(new cb_context), mEventHandler(handler), mDebugForceFakeVSync(false), mVDSEnabled(false){ for (size_t i =0 ; i<MAX_HWC_DISPLAYS ; i++) { mLists[i] = 0; } for (size_t i=0 ; i<HWC_NUM_PHYSICAL_DISPLAY_TYPES ; i++) { mLastHwVSync[i] = 0; mVSyncCounts[i] = 0; } char value[PROPERTY_VALUE_MAX]; property_get("debug.sf.no_hw_vsync", value, "0"); mDebugForceFakeVSync = atoi(value); bool needVSyncThread = true; // Note: some devices may insist that the FB HAL be opened before HWC. int fberr = loadFbHalModule(); loadHwcModule(); if (mFbDev && mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { // close FB HAL if we don't needed it. // FIXME: this is temporary until we're not forced to open FB HAL // before HWC. framebuffer_close(mFbDev); mFbDev = NULL; } // If we have no HWC, or a pre-1.1 HWC, an FB dev is mandatory. if ((!mHwc || !hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) && !mFbDev) { ALOGE("ERROR: failed to open framebuffer (%s), aborting", strerror(-fberr)); abort(); } // these display IDs are always reserved for (size_t i=0 ; i<NUM_BUILTIN_DISPLAYS ; i++) { mAllocatedDisplayIDs.markBit(i); } if (mHwc) { ALOGI("Using %s version %u.%u", HWC_HARDWARE_COMPOSER, (hwcApiVersion(mHwc) >> 24) & 0xff, (hwcApiVersion(mHwc) >> 16) & 0xff); if (mHwc->registerProcs) { mCBContext->hwc = this; mCBContext->procs.invalidate = &hook_invalidate; mCBContext->procs.vsync = &hook_vsync; if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) mCBContext->procs.hotplug = &hook_hotplug; else mCBContext->procs.hotplug = NULL; memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero)); mHwc->registerProcs(mHwc, &mCBContext->procs); } // don't need a vsync thread if we have a hardware composer needVSyncThread = false; // always turn vsync off when we start eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0); // the number of displays we actually have depends on the // hw composer version if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) { // 1.3 adds support for virtual displays mNumDisplays = MAX_HWC_DISPLAYS; } else if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { // 1.1 adds support for multiple displays mNumDisplays = NUM_BUILTIN_DISPLAYS; } else { mNumDisplays = 1; } } if (mFbDev) { ALOG_ASSERT(!(mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)), "should only have fbdev if no hwc or hwc is 1.0"); DisplayData& disp(mDisplayData[HWC_DISPLAY_PRIMARY]); disp.connected = true; disp.format = mFbDev->format; DisplayConfig config = DisplayConfig(); config.width = mFbDev->width; config.height = mFbDev->height; config.xdpi = mFbDev->xdpi; config.ydpi = mFbDev->ydpi; config.secure = true; //XXX: Assuming primary is always true config.refresh = nsecs_t(1e9 / mFbDev->fps); disp.configs.push_back(config); disp.currentConfig = 0; } else if (mHwc) { // here we're guaranteed to have at least HWC 1.1 for (size_t i =0 ; i<NUM_BUILTIN_DISPLAYS ; i++) { queryDisplayProperties(i); } } // read system property for VDS solution // This property is expected to be setup once during bootup if( (property_get("persist.hwc.enable_vds", value, NULL) > 0) && ((!strncmp(value, "1", strlen("1"))) || !strncasecmp(value, "true", strlen("true")))) { //HAL virtual display is using VDS based implementation mVDSEnabled = true; } if (needVSyncThread) { // we don't have VSYNC support, we need to fake it mVSyncThread = new VSyncThread(*this); }#ifdef QCOM_BSP // Threshold Area to enable GPU Tiled Rect. property_get("debug.hwc.gpuTiledThreshold", value, "1.9"); mDynThreshold = atof(value);#endif}
一开始做了一些初始化操作,然后加载对应的HAL,对应函数loadHwcModule():
// Load and prepare the hardware composer module. Sets mHwc.void HWComposer::loadHwcModule(){ hw_module_t const* module; if (hw_get_module(HWC_HARDWARE_MODULE_ID, &module) != 0) { ALOGE("%s module not found", HWC_HARDWARE_MODULE_ID); return; } int err = hwc_open_1(module, &mHwc); if (err) { ALOGE("%s device failed to initialize (%s)", HWC_HARDWARE_COMPOSER, strerror(-err)); return; } if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0) || hwcHeaderVersion(mHwc) < MIN_HWC_HEADER_VERSION || hwcHeaderVersion(mHwc) > HWC_HEADER_VERSION) { ALOGE("%s device version %#x unsupported, will not be used", HWC_HARDWARE_COMPOSER, mHwc->common.version); hwc_close_1(mHwc); mHwc = NULL; return; }}
实现并不复杂,只是获取到HWComposer对应的hw_module_t结构体,并对老版本做了兼容,mHwc保存真正的HWComposer对象,作为返回结果供接下来的调用使用。
回到SurfaceFlinger的init()函数,继续往下走:
if (mHwc) { ALOGI("Using %s version %u.%u", HWC_HARDWARE_COMPOSER, (hwcApiVersion(mHwc) >> 24) & 0xff, (hwcApiVersion(mHwc) >> 16) & 0xff); if (mHwc->registerProcs) { mCBContext->hwc = this; mCBContext->procs.invalidate = &hook_invalidate; mCBContext->procs.vsync = &hook_vsync; if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) mCBContext->procs.hotplug = &hook_hotplug; else mCBContext->procs.hotplug = NULL; memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero)); mHwc->registerProcs(mHwc, &mCBContext->procs); } ......}
首先判断mHwc->registerProcs是否为空,这是一个函数指针,可以到HAL层的实现里去查找:
hardware/qcom/display/msm8974/libhwcomposer/hwc.cpp(cm-12.1)
static int hwc_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device){ int status = -EINVAL; if (!strcmp(name, HWC_HARDWARE_COMPOSER)) { struct hwc_context_t *dev; dev = (hwc_context_t*)malloc(sizeof(*dev)); if(dev == NULL) return status; memset(dev, 0, sizeof(*dev)); //Initialize hwc context status = initContext(dev); if (status < 0) { free(dev); return status; } //Setup HWC methods dev->device.common.tag = HARDWARE_DEVICE_TAG; dev->device.common.version = HWC_DEVICE_API_VERSION_1_4; dev->device.common.module = const_cast<hw_module_t*>(module); dev->device.common.close = hwc_device_close; dev->device.prepare = hwc_prepare; dev->device.set = hwc_set; dev->device.eventControl = hwc_eventControl; dev->device.setPowerMode = hwc_setPowerMode; dev->device.query = hwc_query; dev->device.registerProcs = hwc_registerProcs; dev->device.dump = hwc_dump; dev->device.getDisplayConfigs = hwc_getDisplayConfigs; dev->device.getDisplayAttributes = hwc_getDisplayAttributes; dev->device.getActiveConfig = hwc_getActiveConfig; dev->device.setActiveConfig = hwc_setActiveConfig; *device = &dev->device.common; status = 0; } return status;}
可以看到hwc_composer_device_1里定义了很多函数指针,有eventControl,registerProcs,getDisplayConfigs等等,这样可以SurfaceFlinger可以通过预先规定好的接口,调用HAL层里的具体实现。
回到HWComposer::init(),很显然这里mHwc->registerProcs不为空,实际上指向了HAL层的hwc_registerProcs():
if (mHwc) { ALOGI("Using %s version %u.%u", HWC_HARDWARE_COMPOSER, (hwcApiVersion(mHwc) >> 24) & 0xff, (hwcApiVersion(mHwc) >> 16) & 0xff); if (mHwc->registerProcs) { mCBContext->hwc = this; mCBContext->procs.invalidate = &hook_invalidate; mCBContext->procs.vsync = &hook_vsync; if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) mCBContext->procs.hotplug = &hook_hotplug; else mCBContext->procs.hotplug = NULL; memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero)); mHwc->registerProcs(mHwc, &mCBContext->procs); } ......}
这两句比较有意思,看到后面可以发现这其实就是注册了vsync发生时的回调,在hwcomposer得到硬件发来的vsync,然后做进一步处理:
mCBContext->procs.vsync = &hook_vsync;mHwc->registerProcs(mHwc, &mCBContext->procs);
那我们去hwc_registerProcs()里看看:
hardware/qcom/display/msm8974/libhwcomposer/hwc.cpp(cm-12.1)
/* * Save callback functions registered to HWC */static void hwc_registerProcs(struct hwc_composer_device_1* dev, hwc_procs_t const* procs){ ALOGI("%s", __FUNCTION__); hwc_context_t* ctx = (hwc_context_t*)(dev); if(!ctx) { ALOGE("%s: Invalid context", __FUNCTION__); return; } ctx->proc = procs; // Now that we have the functions needed, kick off // the uevent & vsync threads init_uevent_thread(ctx); init_vsync_thread(ctx);}
先看看init_vsync_thread()函数:
hardware/qcom/display/msm8974/libhwcomposer/hwc_vsync.cpp
void init_vsync_thread(hwc_context_t* ctx){ int ret; pthread_t vsync_thread; ALOGI("Initializing VSYNC Thread"); ret = pthread_create(&vsync_thread, NULL, vsync_loop, (void*) ctx); if (ret) { ALOGE("%s: failed to create %s: %s", __FUNCTION__, HWC_VSYNC_THREAD_NAME, strerror(ret)); }}
逻辑也比较简单,vsync_loop函数指针作为参数,创建了一个新的pthread,可以想到这个线程应该就是vsync发送线程,那就看看vsync_loop()函数:
hardware/qcom/display/msm8974/libhwcomposer/hwc_vsync.cpp
static void *vsync_loop(void *param){ hwc_context_t * ctx = reinterpret_cast<hwc_context_t *>(param); char thread_name[64] = HWC_VSYNC_THREAD_NAME; prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0); setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY + android::PRIORITY_MORE_FAVORABLE); const int MAX_DATA = 64; char vdata[MAX_DATA]; bool logvsync = false; struct pollfd pfd[2]; int fb_fd[2]; uint64_t timestamp[2]; int num_displays; char property[PROPERTY_VALUE_MAX]; if(property_get("debug.hwc.fakevsync", property, NULL) > 0) { if(atoi(property) == 1) ctx->vstate.fakevsync = true; } if(property_get("debug.hwc.logvsync", property, 0) > 0) { if(atoi(property) == 1) logvsync = true; } if (ctx->mExtDisplay->getHDMIIndex() > 0) num_displays = 2; else num_displays = 1; char vsync_node_path[MAX_SYSFS_FILE_PATH]; for (int dpy = HWC_DISPLAY_PRIMARY; dpy < num_displays; dpy++) { snprintf(vsync_node_path, sizeof(vsync_node_path), "/sys/class/graphics/fb%d/vsync_event", dpy == HWC_DISPLAY_PRIMARY ? 0 : ctx->mExtDisplay->getHDMIIndex()); ALOGI("%s: Reading vsync for dpy=%d from %s", __FUNCTION__, dpy, vsync_node_path); fb_fd[dpy] = open(vsync_node_path, O_RDONLY); if (fb_fd[dpy] < 0) { // Make sure fb device is opened before starting this thread so this // never happens. ALOGE ("%s:not able to open vsync node for dpy=%d, %s", __FUNCTION__, dpy, strerror(errno)); if (dpy == HWC_DISPLAY_PRIMARY) { ctx->vstate.fakevsync = true; break; } } // Read once from the fds to clear the first notify pread(fb_fd[dpy], vdata , MAX_DATA, 0); pfd[dpy].fd = fb_fd[dpy]; if (pfd[dpy].fd >= 0) pfd[dpy].events = POLLPRI | POLLERR; } if (LIKELY(!ctx->vstate.fakevsync)) { do { int err = poll(pfd, num_displays, -1); if(err > 0) { for (int dpy = HWC_DISPLAY_PRIMARY; dpy < num_displays; dpy++) { if (pfd[dpy].revents & POLLPRI) { int len = pread(pfd[dpy].fd, vdata, MAX_DATA, 0); if (UNLIKELY(len < 0)) { // If the read was just interrupted - it is not a // fatal error. Just continue in this case ALOGE ("%s: Unable to read vsync for dpy=%d : %s", __FUNCTION__, dpy, strerror(errno)); continue; } // extract timestamp if (!strncmp(vdata, "VSYNC=", strlen("VSYNC="))) { timestamp[dpy] = strtoull(vdata + strlen("VSYNC="), NULL, 0); } // send timestamp to SurfaceFlinger ALOGD_IF (logvsync, "%s: timestamp %llu sent to SF for dpy=%d", __FUNCTION__, timestamp[dpy], dpy); ctx->proc->vsync(ctx->proc, dpy, timestamp[dpy]); } } } else { ALOGE("%s: vsync poll failed errno: %s", __FUNCTION__, strerror(errno)); continue; } } while (true); } else { //Fake vsync is used only when set explicitly through a property or when //the vsync timestamp node cannot be opened at bootup. There is no //fallback to fake vsync from the true vsync loop, ever, as the //condition can easily escape detection. //Also, fake vsync is delivered only for the primary display. do { usleep(16666); timestamp[HWC_DISPLAY_PRIMARY] = systemTime(); ctx->proc->vsync(ctx->proc, HWC_DISPLAY_PRIMARY, timestamp[HWC_DISPLAY_PRIMARY]); } while (true); } for (int dpy = HWC_DISPLAY_PRIMARY; dpy <= HWC_DISPLAY_EXTERNAL; dpy++ ) { if(fb_fd[dpy] >= 0) close (fb_fd[dpy]); } return NULL;}
值得一提的是,这个loop线程同样设置了线程的优先级:
setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY + android::PRIORITY_MORE_FAVORABLE);
这个函数的逻辑也很清晰:等待vsync消息然后分发给每个display,调用callback:
for (int dpy = HWC_DISPLAY_PRIMARY; dpy < num_displays; dpy++) { if (pfd[dpy].revents & POLLPRI) { int len = pread(pfd[dpy].fd, vdata, MAX_DATA, 0); if (UNLIKELY(len < 0)) { // If the read was just interrupted - it is not a // fatal error. Just continue in this case ALOGE ("%s: Unable to read vsync for dpy=%d : %s", __FUNCTION__, dpy, strerror(errno)); continue; } // extract timestamp if (!strncmp(vdata, "VSYNC=", strlen("VSYNC="))) { timestamp[dpy] = strtoull(vdata + strlen("VSYNC="), NULL, 0); } // send timestamp to SurfaceFlinger ALOGD_IF (logvsync, "%s: timestamp %llu sent to SF for dpy=%d", __FUNCTION__, timestamp[dpy], dpy); ctx->proc->vsync(ctx->proc, dpy, timestamp[dpy]); } }
也就是在vsync event到来的时候,通过HAL层把事件传递给了hwcomposer对象。
于是我们回到HWComposer里,看看ctx->proc->vsync()也就是hook_vsync()的实现:
void HWComposer::hook_vsync(const struct hwc_procs* procs, int disp, int64_t timestamp) { cb_context* ctx = reinterpret_cast<cb_context*>( const_cast<hwc_procs_t*>(procs)); ctx->hwc->vsync(disp, timestamp);}void HWComposer::vsync(int disp, int64_t timestamp) { if (uint32_t(disp) < HWC_NUM_PHYSICAL_DISPLAY_TYPES) { { Mutex::Autolock _l(mLock); // There have been reports of HWCs that signal several vsync events // with the same timestamp when turning the display off and on. This // is a bug in the HWC implementation, but filter the extra events // out here so they don't cause havoc downstream. if (timestamp == mLastHwVSync[disp]) { ALOGW("Ignoring duplicate VSYNC event from HWC (t=%" PRId64 ")", timestamp); return; } mLastHwVSync[disp] = timestamp; } char tag[16]; snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", disp); ATRACE_INT(tag, ++mVSyncCounts[disp] & 1); mEventHandler.onVSyncReceived(disp, timestamp); }}
最关键的还是最后一句,mEventHandler其实就是HWComposer构造时候传进来的SurfaceFlinger对象,SurfaceFlinger继承了HWComposer::EventHandler,实现了onVsyncReceived()接口:
mEventHandler.onVSyncReceived(disp, timestamp);
void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) { bool needsHwVsync = false; { // Scope for the lock Mutex::Autolock _l(mHWVsyncLock); if (type == 0 && mPrimaryHWVsyncEnabled) { needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp); } } if (needsHwVsync) { enableHardwareVsync(); } else { disableHardwareVsync(false); }}
SurfaceFlinger::onVSyncReceived对vsync事件做出响应,这里先不继续讨论。创建完HWComposer对象,回到SurfaceFlinger的init()函数,接下来创建一系列显示设备对象,并启动了两个EventThread:
// start the EventThread sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync, vsyncPhaseOffsetNs, true, "app"); mEventThread = new EventThread(vsyncSrc); sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync, sfVsyncPhaseOffsetNs, true, "sf"); mSFEventThread = new EventThread(sfVsyncSrc); mEventQueue.setEventThread(mSFEventThread);
这里传入参数mPrimaryDispSync创建了两个虚拟的vsync源,分别名叫”VSYNC-app”和”VSYNC-sf”,其实不用查看代码,从systrace里我们就能很直观地看到这两个名称的线程。
先看看mPrimaryDispSync是起什么作用的,它是SurfaceFlinger的一个成员变量:
DispSync mPrimaryDispSync;
创建SurfaceFlinger对象的时候没有对mPrimaryDispSync进行显式初始化,因此调用默认的构造函数:
DispSync::DispSync() : mRefreshSkipCount(0), mThread(new DispSyncThread()) { mThread->run("DispSync", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE); reset(); beginResync(); if (kTraceDetailedInfo) { // If we're not getting present fences then the ZeroPhaseTracer // would prevent HW vsync event from ever being turned off. // Even if we're just ignoring the fences, the zero-phase tracing is // not needed because any time there is an event registered we will // turn on the HW vsync events. if (!kIgnorePresentFences) { addEventListener(0, new ZeroPhaseTracer()); } }}
很显然,在它构造的时候就会启动一个类型为DispSyncThread的新的线程mThread,调用mThread->run()实际上是创建了一个新的进程,并在这个线程内执行DispSyncThread的threadLoop()函数:
virtual bool threadLoop() { status_t err; nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); nsecs_t nextEventTime = 0; while (true) { Vector<CallbackInvocation> callbackInvocations; nsecs_t targetTime = 0; { // Scope for lock Mutex::Autolock lock(mMutex); if (mStop) { return false; } if (mPeriod == 0) { err = mCond.wait(mMutex); if (err != NO_ERROR) { ALOGE("error waiting for new events: %s (%d)", strerror(-err), err); return false; } continue; } nextEventTime = computeNextEventTimeLocked(now); targetTime = nextEventTime; bool isWakeup = false; if (now < targetTime) { err = mCond.waitRelative(mMutex, targetTime - now); if (err == TIMED_OUT) { isWakeup = true; } else if (err != NO_ERROR) { ALOGE("error waiting for next event: %s (%d)", strerror(-err), err); return false; } } now = systemTime(SYSTEM_TIME_MONOTONIC); if (isWakeup) { mWakeupLatency = ((mWakeupLatency * 63) + (now - targetTime)) / 64; if (mWakeupLatency > 500000) { // Don't correct by more than 500 us mWakeupLatency = 500000; } if (kTraceDetailedInfo) { ATRACE_INT64("DispSync:WakeupLat", now - nextEventTime); ATRACE_INT64("DispSync:AvgWakeupLat", mWakeupLatency); } } callbackInvocations = gatherCallbackInvocationsLocked(now); } if (callbackInvocations.size() > 0) { fireCallbackInvocations(callbackInvocations); } } return false; }
其中的主要内容是在计算时间,决定信号是否到来,该进行下一步操作,否则就在mCond上等待:
err = mCond.waitRelative(mMutex, targetTime - now);
那什么时候唤醒它呢?这就是前面提到的SurfaceFlinger::onVSyncReceived():
void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) { bool needsHwVsync = false; { // Scope for the lock Mutex::Autolock _l(mHWVsyncLock); if (type == 0 && mPrimaryHWVsyncEnabled) { needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp); } } if (needsHwVsync) { enableHardwareVsync(); } else { disableHardwareVsync(false); }}
其中mPrimaryDispSync.addResyncSample()在满足特定条件下会调用updateModelLocked():
frameworks/native/services/surfaceflinger/DispSync.cpp
bool DispSync::addResyncSample(nsecs_t timestamp) { ... updateModelLocked(); ...}
并调用DispSync::updateModelLocked():
frameworks/native/services/surfaceflinger/DispSync.cpp
void DispSync::updateModelLocked() { ... mThread->updateModel(mPeriod, mPhase); ...}
最终DispSyncThread:updateModel(),唤醒线程:
void updateModel(nsecs_t period, nsecs_t phase) { Mutex::Autolock lock(mMutex); mPeriod = period; mPhase = phase; mCond.signal();}
唤醒后,获取需要所有Listeners的回调列表
callbackInvocations = gatherCallbackInvocationsLocked(now);
frameworks/native/services/surfaceflinger/DispSync.cpp
Vector<CallbackInvocation> gatherCallbackInvocationsLocked(nsecs_t now) { Vector<CallbackInvocation> callbackInvocations; nsecs_t ref = now - mPeriod; for (size_t i = 0; i < mEventListeners.size(); i++) { nsecs_t t = computeListenerNextEventTimeLocked(mEventListeners[i], ref); if (t < now) { CallbackInvocation ci; ci.mCallback = mEventListeners[i].mCallback; ci.mEventTime = t; callbackInvocations.push(ci); mEventListeners.editItemAt(i).mLastEventTime = t; } } return callbackInvocations; }
从这段代码里不难看出,从mEventListeners里找出合适的listener,封装成CallbackInvocation对象并作为返回值返回。
这时候有一个疑问,这些listener是什么时候加到mEventListeners里去的。答案是创建EventThread的时候。
// start the EventThread sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync, vsyncPhaseOffsetNs, true, "app"); mEventThread = new EventThread(vsyncSrc); sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync, sfVsyncPhaseOffsetNs, true, "sf"); mSFEventThread = new EventThread(sfVsyncSrc); mEventQueue.setEventThread(mSFEventThread);
mEventThread和mSFEventThread均是强指针,因此在第一次引用的时候会调用:
void EventThread::onFirstRef() { run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);}
新启动一个名为EventThread的线程:
bool EventThread::threadLoop() { DisplayEventReceiver::Event event; Vector< sp<EventThread::Connection> > signalConnections; signalConnections = waitForEvent(&event); // dispatch events to listeners... const size_t count = signalConnections.size(); for (size_t i=0 ; i<count ; i++) { const sp<Connection>& conn(signalConnections[i]); // now see if we still need to report this event status_t err = conn->postEvent(event); if (err == -EAGAIN || err == -EWOULDBLOCK) { // The destination doesn't accept events anymore, it's probably // full. For now, we just drop the events on the floor. // FIXME: Note that some events cannot be dropped and would have // to be re-sent later. // Right-now we don't have the ability to do this. ALOGW("EventThread: dropping event (%08x) for connection %p", event.header.type, conn.get()); } else if (err < 0) { // handle any other error on the pipe as fatal. the only // reasonable thing to do is to clean-up this connection. // The most common error we'll get here is -EPIPE. removeDisplayEventConnection(signalConnections[i]); } } return true;}
EventThread::waitForEvent()函数:
// Here we figure out if we need to enable or disable vsyncs if (timestamp && !waitForVSync) { // we received a VSYNC but we have no clients // don't report it, and disable VSYNC events disableVSyncLocked(); } else if (!timestamp && waitForVSync) { // we have at least one client, so we want vsync enabled // (TODO: this function is called right after we finish // notifying clients of a vsync, so this call will be made // at the vsync rate, e.g. 60fps. If we can accurately // track the current state we could avoid making this call // so often.) enableVSyncLocked(); }
timestamp表示上一次某一个display获取到的vsync的时间,在EventThread第一次执行到这里的时候,一切都还没有准备就绪,于是timestamp为0,执行这一个代码段:
else if (!timestamp && waitForVSync) { // we have at least one client, so we want vsync enabled // (TODO: this function is called right after we finish // notifying clients of a vsync, so this call will be made // at the vsync rate, e.g. 60fps. If we can accurately // track the current state we could avoid making this call // so often.) enableVSyncLocked(); }
enableVSyncLocked()最终会调用setVSyncEnabled()把当前这个DispSyncSource注册成DispSync的listener。
void EventThread::enableVSyncLocked() { if (!mUseSoftwareVSync) { // never enable h/w VSYNC when screen is off if (!mVsyncEnabled) { mVsyncEnabled = true; mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this)); mVSyncSource->setVSyncEnabled(true); } } mDebugVsyncEnabled = true; sendVsyncHintOnLocked();} virtual void SurfaceFlinger::setVSyncEnabled(bool enable) { // Do NOT lock the mutex here so as to avoid any mutex ordering issues // with locking it in the onDispSyncEvent callback. if (enable) { status_t err = mDispSync->addEventListener(mPhaseOffset, static_cast<DispSync::Callback*>(this)); if (err != NO_ERROR) { ALOGE("error registering vsync callback: %s (%d)", strerror(-err), err); } //ATRACE_INT(mVsyncOnLabel.string(), 1); } else { status_t err = mDispSync->removeEventListener( static_cast<DispSync::Callback*>(this)); if (err != NO_ERROR) { ALOGE("error unregistering vsync callback: %s (%d)", strerror(-err), err); } //ATRACE_INT(mVsyncOnLabel.string(), 0); } }
就这样,DispSync线程在收到VSync消息的时候就能回调两个虚拟vsync源DispSyncSource的onVSyncEvent()
void fireCallbackInvocations(const Vector<CallbackInvocation>& callbacks) { for (size_t i = 0; i < callbacks.size(); i++) { callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime); } }
virtual void DispSyncSource::onDispSyncEvent(nsecs_t when) { sp<VSyncSource::Callback> callback; { Mutex::Autolock lock(mMutex); callback = mCallback; if (mTraceVsync) { mValue = (mValue + 1) % 2; ATRACE_INT(mVsyncEventLabel.string(), mValue); } } if (callback != NULL) { callback->onVSyncEvent(when); } }
最后调用EventThread::onVSyncEvent():
void EventThread::onVSyncEvent(nsecs_t timestamp) { Mutex::Autolock _l(mLock); mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC; mVSyncEvent[0].header.id = 0; mVSyncEvent[0].header.timestamp = timestamp; mVSyncEvent[0].vsync.count++; mCondition.broadcast();}
唤醒EventThread(),并通过conn->postEvent()发送消息:
bool EventThread::threadLoop() { DisplayEventReceiver::Event event; Vector< sp<EventThread::Connection> > signalConnections; signalConnections = waitForEvent(&event); // dispatch events to listeners... const size_t count = signalConnections.size(); for (size_t i=0 ; i<count ; i++) { const sp<Connection>& conn(signalConnections[i]); // now see if we still need to report this event status_t err = conn->postEvent(event); … } return true;}
因为我们在main(),也就是SurfaceFlinger中调用了SurfaceFlinger::run():
void SurfaceFlinger::run() { do { waitForEvent(); } while (true);}void SurfaceFlinger::waitForEvent() { mEventQueue.waitMessage();}
事实上,最后EventThread::onVSyncEvent()就是通过MessageQueue(socket)把消息发给了SurfaceFlinger主线程。
void MessageQueue::Handler::handleMessage(const Message& message) { switch (message.what) {... case REFRESH: android_atomic_and(~eventMaskRefresh, &mEventMask); mQueue.mFlinger->onMessageReceived(message.what); break;...}void SurfaceFlinger::onMessageReceived(int32_t what) { ATRACE_CALL(); switch (what) {... case MessageQueue::REFRESH: { handleMessageRefresh(); break; } }}
就这样,VSync消息一步步传递回了SurfaceFlinger的主线程,接下来就是对vsync进行响应,刷新系统的显示了。值得注意的是,surfaceflinger的刷新是跟着mSFEventThread这个虚拟的VsyncSource走的,因为前面是这么设置的:
mEventQueue.setEventThread(mSFEventThread)
所以vsync事件在线程中的传递流程大致如下:
HAL Thread-DispSyncThread - EventThread - SurfaceFlinger main Thread.
- Android 5.1 SurfaceFlinger --- Dispatching VSync events
- Android 5.1 SurfaceFlinger VSYNC详解
- 【Android】Android SurfaceFlinger之VSync
- Android SurfaceFlinger VSync流程分析
- android graphic(4)—surfaceflinger和Vsync
- android graphic(4)—surfaceflinger和Vsync
- Android surfaceflinger (4) -Vsync产生上报流程
- Android SurfaceFlinger对VSync信号的处理过程分析
- android graphic(5)—surfaceflinger和Vsync (简化)
- android graphic(5)—surfaceflinger和Vsync (简化)
- Android SurfaceFlinger 学习之路(五)----VSync 工作原理
- Observers and Dispatching Events
- android vsync
- Manually dispatching events手动触发事件
- Android Input Event Dispatching
- Android Input Event Dispatching
- Android Input Event Dispatching
- GUI系统之SurfaceFlinger(13)VSync信号的处理
- 22次会战,你们省有几个?
- C ++的this指针
- [Leetcode]Symmetric Tree
- Gulp--Less
- Libev使用
- Android 5.1 SurfaceFlinger --- Dispatching VSync events
- 解决spring quartz定时任务执行2次的问题
- Http响应码
- HDOJ 5375 Gray code
- Android percent-support-lib
- 用Java实现调用WebService的客户端程序
- JavaScript 函数 对象 数组
- 浏览器端Less
- URLClassLoader类加载器