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.

0 0
原创粉丝点击