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
status_t DisplayEventDispatcher::initialize() {
status_t result = mReceiver.initCheck();
int rc = mLooper->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT,
this, NULL);
return OK;
}
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
}
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
sp<IDisplayEventConnection> mEventConnection;
std::unique_ptr<gui::BitTube> mDataChannel;
/*
* 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());
}
}
}
int DisplayEventReceiver::getFd() const {
if (mDataChannel == NULL)
return NO_INIT;
return mDataChannel->getFd();
}
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);
}
status_t DisplayEventReceiver::requestNextVsync() {
if (mEventConnection != NULL) {
mEventConnection->requestNextVsync();
return NO_ERROR;
}
return NO_INIT;
}
frameworks/native/libs/gui/BitTube.cpp
int BitTube::getFd() const {
return mReceiveFd;
}
frameworks/native/libs/gui/SurfaceComposerClient.cpp
frameworks/native/libs/gui/include/private/gui/ComposerService.h
// 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;
}
// 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;
}
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);
}
void ComposerService::composerServiceDied()
{
Mutex::Autolock _l(mLock);
mComposerService = NULL;
mDeathObserver = NULL;
}
frameworks/native/libs/binder/include/binder/IServiceManager.h
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;
}