Vsync

原理图

Vsync App进程

graph TB
DisplayEventDispatcher::scheduleVsync-->eventConnection.requestNextVsync
sequenceDiagram
participant JavaDispalyEventReveiver
participant NativeDisplayEventReceiver
participant Looper
participant BitTube

NativeDisplayEventReceiver->>+Looper: looper.addFd
Looper-->>-NativeDisplayEventReceiver: fd可读
NativeDisplayEventReceiver->>+NativeDisplayEventReceiver: handleEvent

NativeDisplayEventReceiver->>-BitTube: recvObjects
BitTube-->>NativeDisplayEventReceiver: return
NativeDisplayEventReceiver->>JavaDispalyEventReveiver:dispatchVsnc

frameworks/base/libs/androidfw/DisplayEventDispatcher.cpp

DisplayEventDispatcher.cpp

initialize

status_t DisplayEventDispatcher::initialize() {
    status_t result = mReceiver.initCheck();

    int rc = mLooper->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT,
            this, NULL);
    return OK;
}

handleEvent

int DisplayEventDispatcher::handleEvent(int, int events, void*) {
    // Drain all pending events, keep the last vsync.
    nsecs_t vsyncTimestamp;
    int32_t vsyncDisplayId;
    uint32_t vsyncCount;
    if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
        dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount);
    }
    return 1; // keep the callback
}

scheduleVsync

status_t DisplayEventDispatcher::scheduleVsync() {
    if (!mWaitingForVsync) {
        // Drain all pending events.
        if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
                    this, ns2ms(static_cast<nsecs_t>(vsyncTimestamp)));
        }

        status_t status = mReceiver.requestNextVsync();
        mWaitingForVsync = true;
    }
    return OK;
}

frameworks/native/libs/gui/DisplayEventReceiver.cpp

DisplayEventReceiver.cpp

    sp<IDisplayEventConnection> mEventConnection;
    std::unique_ptr<gui::BitTube> mDataChannel;

DisplayEventReceiver()

    /*
     * DisplayEventReceiver creates and registers an event connection with
     * SurfaceFlinger. VSync events are disabled by default. Call setVSyncRate
     * or requestNextVsync to receive them.
     * Other events start being delivered immediately.
     */
DisplayEventReceiver::DisplayEventReceiver(ISurfaceComposer::VsyncSource vsyncSource) {
    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
    if (sf != NULL) {
        mEventConnection = sf->createDisplayEventConnection(vsyncSource);
        if (mEventConnection != NULL) {
            mDataChannel = std::make_unique<gui::BitTube>();
            mEventConnection->stealReceiveChannel(mDataChannel.get());
        }
    }
}

getFd

int DisplayEventReceiver::getFd() const {
    if (mDataChannel == NULL)
        return NO_INIT;

    return mDataChannel->getFd();
}

getEvents

ssize_t DisplayEventReceiver::getEvents(DisplayEventReceiver::Event* events,
        size_t count) {
    return DisplayEventReceiver::getEvents(mDataChannel.get(), events, count);
}

ssize_t DisplayEventReceiver::getEvents(gui::BitTube* dataChannel,
        Event* events, size_t count)
{
    return gui::BitTube::recvObjects(dataChannel, events, count);
}

requestNextVsync

status_t DisplayEventReceiver::requestNextVsync() {
    if (mEventConnection != NULL) {
        mEventConnection->requestNextVsync();
        return NO_ERROR;
    }
    return NO_INIT;
}

frameworks/native/libs/gui/BitTube.cpp

BitTube

getFd

int BitTube::getFd() const {
    return mReceiveFd;
}

frameworks/native/libs/gui/SurfaceComposerClient.cpp

frameworks/native/libs/gui/include/private/gui/ComposerService.h

ComposerService

// This holds our connection to the composer service (i.e. SurfaceFlinger).
// If the remote side goes away, we will re-establish the connection.
// Users of this class should not retain the value from
// getComposerService() for an extended period.
class ComposerService : public Singleton<ComposerService>
{
    sp<ISurfaceComposer> mComposerService;
    sp<IBinder::DeathRecipient> mDeathObserver;
}

getComposerService

    // Get a connection to the Composer Service.  This will block until
    // a connection is established.
/*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() {
    ComposerService& instance = ComposerService::getInstance();
    Mutex::Autolock _l(instance.mLock);
    if (instance.mComposerService == NULL) {
        ComposerService::getInstance().connectLocked();
        assert(instance.mComposerService != NULL);
    }
    return instance.mComposerService;
}

connectLocked

void ComposerService::connectLocked() {
    const String16 name("SurfaceFlinger");
    while (getService(name, &mComposerService) != NO_ERROR) {//get SurfaceFlinger Service
        usleep(250000);
    }
    assert(mComposerService != NULL);

    // Create the death listener.
    class DeathObserver : public IBinder::DeathRecipient {
        ComposerService& mComposerService;
        virtual void binderDied(const wp<IBinder>& who) {
            ALOGW("ComposerService remote (surfaceflinger) died [%p]", who.unsafe_get());
            mComposerService.composerServiceDied();
        }
     public:
        explicit DeathObserver(ComposerService& mgr) : mComposerService(mgr) { }
    };

    mDeathObserver = new DeathObserver(*const_cast<ComposerService*>(this));
    IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver);
}

composerServiceDied

void ComposerService::composerServiceDied()
{
    Mutex::Autolock _l(mLock);
    mComposerService = NULL;
    mDeathObserver = NULL;
}

frameworks/native/libs/binder/include/binder/IServiceManager.h

IServiceManager

getService

template<typename INTERFACE>
status_t getService(const String16& name, sp<INTERFACE>* outService)
{
    const sp<IServiceManager> sm = defaultServiceManager();
    if (sm != NULL) {
        *outService = interface_cast<INTERFACE>(sm->getService(name));
        if ((*outService) != NULL) return NO_ERROR;
    }
    return NAME_NOT_FOUND;
}