前言
SurfaceFlinger和Choreographer是构成Android图形系统的主要部分,它们都是VSYNC信号的订阅者;SurfaceFlinger将接受到的不同数据源整合并,最终更新到帧缓冲以便显示;而Choreographer最终post给ViewRootImpl进行界面view的measure及draw等。
一、VSYNC的产生与分发
不管以何种方式启动SurfaceFlinger,创建SurfaceFlinger的实例之后都会调用init方法:
1. SurfaceFlinger.cpp
// Do not call property_set on main thread which will be blocked by init
// Use StartPropertySetThread instead.
void SurfaceFlinger::init() {
...
Mutex::Autolock _l(mStateLock);
// start the EventThread
mScheduler =
getFactory().createScheduler([this](bool enabled) { setVsyncEnabled(enabled); },
mRefreshRateConfigs);
auto resyncCallback =
mScheduler->makeResyncCallback(std::bind(&SurfaceFlinger::getVsyncPeriod, this));
mAppConnectionHandle =
mScheduler->createConnection("app", mPhaseOffsets->getCurrentAppOffset(),
resyncCallback,
impl::EventThread::InterceptVSyncsCallback());
mSfConnectionHandle = mScheduler->createConnection("sf", mPhaseOffsets->getCurrentSfOffset(),
resyncCallback, [this](nsecs_t timestamp) {
mInterceptor->saveVSyncEvent(timestamp);
});
mEventQueue->setEventConnection(mScheduler->getEventConnection(mSfConnectionHandle));
mVsyncModulator.setSchedulerAndHandles(mScheduler.get(), mAppConnectionHandle.get(),
mSfConnectionHandle.get());
mRegionSamplingThread =
new RegionSamplingThread(*this, *mScheduler,
RegionSamplingThread::EnvironmentTimingTunables());
...
// Get a RenderEngine for the given display / config (can't fail)
int32_t renderEngineFeature = 0;
renderEngineFeature |= (useColorManagement ?
renderengine::RenderEngine::USE_COLOR_MANAGEMENT : 0);
renderEngineFeature |= (useContextPriority ?
renderengine::RenderEngine::USE_HIGH_PRIORITY_CONTEXT : 0);
{
using vendor::display::config::V1_7::IDisplayConfig;
android::sp disp_config_v1_7 = IDisplayConfig::getService();
if (disp_config_v1_7 != NULL) {
disp_config_v1_7->getDebugProperty("protected_client_composition",
[&] (const ::android::hardware::hidl_string& value, int32_t error) {
if (error == 0) {
renderEngineFeature |= atoi(value.c_str()) ?
renderengine::RenderEngine::ENABLE_PROTECTED_CONTEXT : 0;
}
});
}
}
// TODO(b/77156734): We need to stop casting and use HAL types when possible.
// Sending maxFrameBufferAcquiredBuffers as the cache size is tightly tuned to single-display.
mCompositionEngine->setRenderEngine(
renderengine::RenderEngine::create(static_cast(defaultCompositionPixelFormat),
renderEngineFeature, maxFrameBufferAcquiredBuffers));
LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
"Starting with vr flinger active is not currently supported.");
mCompositionEngine->setHwComposer(getFactory().createHWComposer(getBE().mHwcServiceName));
mCompositionEngine->getHwComposer().registerCallback(this, getBE().mComposerSequenceId);
// Process any initial hotplug and resulting display changes.
processDisplayHotplugEventsLocked();
const auto display = getDefaultDisplayDeviceLocked();
LOG_ALWAYS_FATAL_IF(!display, "Missing internal display after registering composer callback.");
LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(*display->getId()),
"Internal display is disconnected.");
if (useVrFlinger) {
auto vrFlingerRequestDisplayCallback = [this](bool requestDisplay) {
// This callback is called from the vr flinger dispatch thread. We
// need to call signalTransaction(), which requires holding
// mStateLock when we're not on the main thread. Acquiring
// mStateLock from the vr flinger dispatch thread might trigger a
// deadlock in surface flinger (see b/66916578), so post a message
// to be handled on the main thread instead.
postMessageAsync(new LambdaMessage([=] {
ALOGI("VR request display mode: requestDisplay=%d", requestDisplay);
mVrFlingerRequestsDisplay = requestDisplay;
signalTransaction();
}));
};
mVrFlinger = dvr::VrFlinger::Create(getHwComposer().getComposer(),
getHwComposer()
.fromPhysicalDisplayId(*display->getId())
.value_or(0),
vrFlingerRequestDisplayCallback);
if (!mVrFlinger) {
ALOGE("Failed to start vrflinger");
}
}
// initialize our drawing state
mDrawingState = mCurrentState;
// set initial conditions (e.g. unblank default device)
initializeDisplays();
getRenderEngine().primeCache();
// Inform native graphics APIs whether the present timestamp is supported:
const bool presentFenceReliable =
!getHwComposer().hasCapability(HWC2::Capability::PresentFenceIsNotReliable);
mStartPropertySetThread = getFactory().createStartPropertySetThread(presentFenceReliable);
if (mStartPropertySetThread->Start() != NO_ERROR) {
ALOGE("Run StartPropertySetThread failed!");
}
mScheduler->setChangeRefreshRateCallback(
[this](RefreshRateType type, Scheduler::ConfigEvent event) {
Mutex::Autolock lock(mStateLock);
setRefreshRateTo(type, event);
});
mScheduler->setGetVsyncPeriodCallback([this] {
Mutex::Autolock lock(mStateLock);
return getVsyncPeriod();
});
mRefreshRateConfigs.populate(getHwComposer().getConfigs(*display->getId()));
mRefreshRateStats.setConfigMode(getHwComposer().getActiveConfigIndex(*display->getId()));
ALOGV("Done initializing");
}
2. SurfaceFlinger.h
std::unique_ptr mScheduler;
sp mAppConnectionHandle;
sp mSfConnectionHandle;
3. Scheduler.h
// Connections are stored in a map for easy retrieval.
std::unordered_map> mConnections;
...
/* The scheduler handle is a BBinder object passed to the client from which we can extract
* an ID for subsequent operations.
*/
class ConnectionHandle : public BBinder {
public:
ConnectionHandle(int64_t id) : id(id) {}
~ConnectionHandle() = default;
const int64_t id;
};
class Connection {
public:
Connection(sp handle, sp eventConnection,
std::unique_ptr eventThread)
: handle(handle), eventConnection(eventConnection), thread(std::move(eventThread)) {}
~Connection() = default;
sp handle;
sp eventConnection;
const std::unique_ptr thread;
};
4. Scheduler.cpp
sp Scheduler::createConnection(
const char* connectionName, int64_t phaseOffsetNs, ResyncCallback resyncCallback,
impl::EventThread::InterceptVSyncsCallback interceptCallback) {
const int64_t id = sNextId++;
ALOGV("Creating a connection handle with ID: %" PRId64 "\n", id);
//由第一个参数可以,总共生成两个EventThread对象,分别代表着"app"、"sf"。
std::unique_ptr eventThread =
makeEventThread(connectionName, mPrimaryDispSync.get(), phaseOffsetNs,
std::move(interceptCallback));
auto eventThreadConnection =
createConnectionInternal(eventThread.get(), std::move(resyncCallback));
//此处以id为key值,value为Connection 加入到集合mConnections中
//Connection是Scheduler的内部类
mConnections.emplace(id,
std::make_unique(new ConnectionHandle(id),
eventThreadConnection,
std::move(eventThread)));
return mConnections[id]->handle;
}
std::unique_ptr Scheduler::makeEventThread(
const char* connectionName, DispSync* dispSync, int64_t phaseOffsetNs,
impl::EventThread::InterceptVSyncsCallback interceptCallback) {
std::unique_ptr eventThreadSource =
std::make_unique(dispSync, phaseOffsetNs, true, connectionName);
//DispSyncSource持有DispSync、且DispSyncSource继承自VSyncSource
//EventThread持有DispSyncSource
return std::make_unique(std::move(eventThreadSource),
std::move(interceptCallback), connectionName);
}
init方法中会实例化两个ConnectionHandle:mAppConnectionHandle、mSfConnectionHandle。以mAppConnectionHandle为例深入分析其具体结构及获取过程。ConnectionHandle属于Scheduler的内部类,继承自BBinder,即可以跨进程通信。
mAppConnectionHandle所持有的EventThread是Choreographer所代表App层的远程SOCKET服务端,mSfConnectionHandle所持有的EventThread则对应着SurfaceFlinger自身的VSYNC处理。它们都通过各自的DispSyncSource持有mPrimaryDispSync。
mPrimaryDispSync是DispSync的实例,内部持有一个DispSyncThread。EventThread在有客户端成功订阅VSYNC后,通过DispSyncSource的setVSyncEnabled方法调用DispSync的addEventListener方法,将mPhaseOffset和callback传递DispSync。
DispSyncSource.cpp
void DispSyncSource::setVSyncEnabled(bool enable) {
std::lock_guard lock(mVsyncMutex);
if (enable) {
status_t err = mDispSync->addEventListener(mName, mPhaseOffset,
static_cast(this),
mLastCallbackTime);
if (err != NO_ERROR) {
ALOGE("error registering vsync callback: %s (%d)", strerror(-err), err);
}
// ATRACE_INT(mVsyncOnLabel.c_str(), 1);
} else {
status_t err = mDispSync->removeEventListener(static_cast(this),
&mLastCallbackTime);
if (err != NO_ERROR) {
ALOGE("error unregistering vsync callback: %s (%d)", strerror(-err), err);
}
// ATRACE_INT(mVsyncOnLabel.c_str(), 0);
}
mEnabled = enable;
}
DispSync则通过这个offset和屏幕刷新周期period,依靠DispSyncThread线程控制着回调调用的时间,最终通过SurfaceFlinger的onDispSyncEvent方法调用到EventThread的onVSyncEvent方法。
1. DispSyncSource.cpp
void DispSyncSource::setVSyncEnabled(bool enable) {
std::lock_guard lock(mVsyncMutex);
if (enable) {
status_t err = mDispSync->addEventListener(mName, mPhaseOffset,
static_cast(this),
mLastCallbackTime);
if (err != NO_ERROR) {
ALOGE("error registering vsync callback: %s (%d)", strerror(-err), err);
}
// ATRACE_INT(mVsyncOnLabel.c_str(), 1);
} else {
status_t err = mDispSync->removeEventListener(static_cast(this),
&mLastCallbackTime);
if (err != NO_ERROR) {
ALOGE("error unregistering vsync callback: %s (%d)", strerror(-err), err);
}
// ATRACE_INT(mVsyncOnLabel.c_str(), 0);
}
mEnabled = enable;
}
2. DispSync.cpp
status_t DispSync::addEventListener(const char* name, nsecs_t phase, Callback* callback,
nsecs_t lastCallbackTime) {
Mutex::Autolock lock(mMutex);
return mThread->addEventListener(name, phase, callback, lastCallbackTime);
}
3. DispSync.DispSyncThread
//DispSyncThread继承自Thread
status_t addEventListener(const char* name, nsecs_t phase, DispSync::Callback* callback,
nsecs_t lastCallbackTime) {
if (mTraceDetailedInfo) ATRACE_CALL();
Mutex::Autolock lock(mMutex);
for (size_t i = 0; i < mEventListeners.size(); i++) {
if (mEventListeners[i].mCallback == callback) {
return BAD_VALUE;
}
}
EventListener listener;
listener.mName = name;
listener.mPhase = phase;
listener.mCallback = callback;
// We want to allow the firstmost future event to fire without
// allowing any past events to fire. To do this extrapolate from
// mReferenceTime the most recent hardware vsync, and pin the
// last event time there.
const nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
if (mPeriod != 0) {
const nsecs_t baseTime = now - mReferenceTime;
const nsecs_t numPeriodsSinceReference = baseTime / mPeriod;
const nsecs_t predictedReference = mReferenceTime + numPeriodsSinceReference * mPeriod;
const nsecs_t phaseCorrection = mPhase + listener.mPhase;
const nsecs_t predictedLastEventTime = predictedReference + phaseCorrection;
if (predictedLastEventTime >= now) {
// Make sure that the last event time does not exceed the current time.
// If it would, then back the last event time by a period.
listener.mLastEventTime = predictedLastEventTime - mPeriod;
} else {
listener.mLastEventTime = predictedLastEventTime;
}
} else {
listener.mLastEventTime = now + mPhase - mWakeupLatency;
}
if (lastCallbackTime <= 0) {
// If there is no prior callback time, try to infer one based on the
// logical last event time.
listener.mLastCallbackTime = listener.mLastEventTime + mWakeupLatency;
} else {
listener.mLastCallbackTime = lastCallbackTime;
}
mEventListeners.push_back(listener);
//signal 通知
mCond.signal();
return NO_ERROR;
}
virtual bool threadLoop() {
status_t err;
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
while (true) {
std::vector callbackInvocations;
nsecs_t targetTime = 0;
{ // Scope for lock
Mutex::Autolock lock(mMutex);
if (mTraceDetailedInfo) {
ATRACE_INT64("DispSync:Frame", mFrameNumber);
}
ALOGV("[%s] Frame %" PRId64, mName, mFrameNumber);
++mFrameNumber;
if (mStop) {
return false;
}
if (mPeriod == 0) {
//wait 等待
err = mCond.wait(mMutex);
if (err != NO_ERROR) {
ALOGE("error waiting for new events: %s (%d)", strerror(-err), err);
return false;
}
continue;
}
targetTime = computeNextEventTimeLocked(now);
bool isWakeup = false;
if (now < targetTime) {
if (mTraceDetailedInfo) ATRACE_NAME("DispSync waiting");
if (targetTime == INT64_MAX) {
ALOGV("[%s] Waiting forever", mName);
//wait 等待
err = mCond.wait(mMutex);
} else {
ALOGV("[%s] Waiting until %" PRId64, mName, ns2us(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);
// Don't correct by more than 1.5 ms
static const nsecs_t kMaxWakeupLatency = us2ns(1500);
if (isWakeup) {
mWakeupLatency = ((mWakeupLatency * 63) + (now - targetTime)) / 64;
mWakeupLatency = min(mWakeupLatency, kMaxWakeupLatency);
if (mTraceDetailedInfo) {
ATRACE_INT64("DispSync:WakeupLat", now - targetTime);
ATRACE_INT64("DispSync:AvgWakeupLat", mWakeupLatency);
}
}
//从mEventListeners获取满足相应条件的回调,加入到集合callbackInvocations中
callbackInvocations = gatherCallbackInvocationsLocked(now);
}
if (callbackInvocations.size() > 0) {
//执行callback回调
fireCallbackInvocations(callbackInvocations);
}
}
return false;
}
void fireCallbackInvocations(const std::vector& callbacks) {
if (mTraceDetailedInfo) ATRACE_CALL();
for (size_t i = 0; i < callbacks.size(); i++) {
callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime);
}
}
std::vector gatherCallbackInvocationsLocked(nsecs_t now) {
if (mTraceDetailedInfo) ATRACE_CALL();
ALOGV("[%s] gatherCallbackInvocationsLocked @ %" PRId64, mName, ns2us(now));
std::vector callbackInvocations;
nsecs_t onePeriodAgo = now - mPeriod;
for (auto& eventListener : mEventListeners) {
nsecs_t t = computeListenerNextEventTimeLocked(eventListener, onePeriodAgo);
if (t < now) {
if (isCloseToPeriod(now - eventListener.mLastCallbackTime)) {
eventListener.mLastEventTime = t;
ALOGV("[%s] [%s] Skipping event due to model error", mName,
eventListener.mName);
continue;
}
if (eventListener.mHasFired && !mModelLocked) {
eventListener.mLastEventTime = t;
ALOGV("[%s] [%s] Skipping event due to already firing", mName,
eventListener.mName);
continue;
}
CallbackInvocation ci;
ci.mCallback = eventListener.mCallback;
ci.mEventTime = t;
ALOGV("[%s] [%s] Preparing to fire, latency: %" PRId64, mName, eventListener.mName,
t - eventListener.mLastEventTime);
callbackInvocations.push_back(ci);
eventListener.mLastEventTime = t;
eventListener.mLastCallbackTime = now;
eventListener.mHasFired = true;
}
}
return callbackInvocations;
}
EventThread本身继承自Thread,通过Condition唤醒当前的线程。
1. DispSync.DispSyncThread
void fireCallbackInvocations(const std::vector& callbacks) {
if (mTraceDetailedInfo) ATRACE_CALL();
for (size_t i = 0; i < callbacks.size(); i++) {
callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime);
}
}
struct CallbackInvocation {
DispSync::Callback* mCallback;
nsecs_t mEventTime;
};
2. DispSyncSource.h
class DispSyncSource final : public VSyncSource, private DispSync::Callback
3. DispSyncSource.cpp
void DispSyncSource::onDispSyncEvent(nsecs_t when) {
VSyncSource::Callback* callback;
{
std::lock_guard lock(mCallbackMutex);
callback = mCallback;
if (mTraceVsync) {
mValue = (mValue + 1) % 2;
ATRACE_INT(mVsyncEventLabel.c_str(), mValue);
}
}
if (callback != nullptr) {
callback->onVSyncEvent(when);
}
}
4. EventThread.h
class EventThread : public android::EventThread, private VSyncSource::Callback
5. EventThread.cpp
void EventThread::onVSyncEvent(nsecs_t timestamp) {
std::lock_guard lock(mMutex);
LOG_FATAL_IF(!mVSyncState);
mPendingEvents.push_back(makeVSync(mVSyncState->displayId, timestamp, ++mVSyncState->count));
mCondition.notify_all();
}
最终调用到BitTube的write方法,往mSendFd描述符send对应内容。
1. EventThread.cpp
void EventThread::threadMain(std::unique_lock& lock) {
DisplayEventConsumers consumers;
while (mState != State::Quit) {
std::optional event;
// Determine next event to dispatch.
if (!mPendingEvents.empty()) {
event = mPendingEvents.front();
mPendingEvents.pop_front();
switch (event->header.type) {
case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
if (event->hotplug.connected && !mVSyncState) {
mVSyncState.emplace(event->header.displayId);
} else if (!event->hotplug.connected && mVSyncState &&
mVSyncState->displayId == event->header.displayId) {
mVSyncState.reset();
}
break;
case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
if (mInterceptVSyncsCallback) {
mInterceptVSyncsCallback(event->header.timestamp);
}
break;
}
}
bool vsyncRequested = false;
// Find connections that should consume this event.
auto it = mDisplayEventConnections.begin();
while (it != mDisplayEventConnections.end()) {
if (const auto connection = it->promote()) {
vsyncRequested |= connection->vsyncRequest != VSyncRequest::None;
if (event && shouldConsumeEvent(*event, connection)) {
consumers.push_back(connection);
}
++it;
} else {
it = mDisplayEventConnections.erase(it);
}
}
if (!consumers.empty()) {
dispatchEvent(*event, consumers);
consumers.clear();
}
State nextState;
if (mVSyncState && vsyncRequested) {
nextState = mVSyncState->synthetic ? State::SyntheticVSync : State::VSync;
} else {
ALOGW_IF(!mVSyncState, "Ignoring VSYNC request while display is disconnected");
nextState = State::Idle;
}
if (mState != nextState) {
if (mState == State::VSync) {
mVSyncSource->setVSyncEnabled(false);
} else if (nextState == State::VSync) {
mVSyncSource->setVSyncEnabled(true);
}
mState = nextState;
}
if (event) {
continue;
}
// Wait for event or client registration/request.
if (mState == State::Idle) {
mCondition.wait(lock);
} else {
// Generate a fake VSYNC after a long timeout in case the driver stalls. When the
// display is off, keep feeding clients at 60 Hz.
const auto timeout = mState == State::SyntheticVSync ? 16ms : 1000ms;
if (mCondition.wait_for(lock, timeout) == std::cv_status::timeout) {
ALOGW_IF(mState == State::VSync, "Faking VSYNC due to driver stall");
LOG_FATAL_IF(!mVSyncState);
mPendingEvents.push_back(makeVSync(mVSyncState->displayId,
systemTime(SYSTEM_TIME_MONOTONIC),
++mVSyncState->count));
}
}
}
}
void EventThread::dispatchEvent(const DisplayEventReceiver::Event& event,
const DisplayEventConsumers& consumers) {
for (const auto& consumer : consumers) {
switch (consumer->postEvent(event)) {
case NO_ERROR:
break;
case -EAGAIN:
...
break;
default:
// Treat EPIPE and other errors as fatal.
removeDisplayEventConnectionLocked(consumer);
}
}
}
status_t EventThreadConnection::postEvent(const DisplayEventReceiver::Event& event) {
ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
return size < 0 ? status_t(size) : status_t(NO_ERROR);
}
2. EventThread.h
using DisplayEventConsumers = std::vector>
class EventThreadConnection : public BnDisplayEventConnection {
public:
EventThreadConnection(EventThread*, ResyncCallback);
virtual ~EventThreadConnection();
virtual status_t postEvent(const DisplayEventReceiver::Event& event);
status_t stealReceiveChannel(gui::BitTube* outChannel) override;
status_t setVsyncRate(uint32_t rate) override;
void requestNextVsync() override; // asynchronous
// Called in response to requestNextVsync.
const ResyncCallback resyncCallback;
VSyncRequest vsyncRequest = VSyncRequest::None;
private:
virtual void onFirstRef();
EventThread* const mEventThread;
gui::BitTube mChannel;
};
3. DisplayEventReceiver.cpp
ssize_t DisplayEventReceiver::sendEvents(gui::BitTube* dataChannel,
Event const* events, size_t count)
{
return gui::BitTube::sendObjects(dataChannel, events, count);
}
4. BitTube.cpp
ssize_t BitTube::sendObjects(BitTube* tube, void const* events, size_t count, size_t objSize) {
const char* vaddr = reinterpret_cast(events);
ssize_t size = tube->write(vaddr, count * objSize);
// should never happen because of SOCK_SEQPACKET
LOG_ALWAYS_FATAL_IF((size >= 0) && (size % static_cast(objSize)),
"BitTube::sendObjects(count=%zu, size=%zu), res=%zd (partial events were "
"sent!)",
count, objSize, size);
// ALOGE_IF(size<0, "error %d sending %d events", size, count);
return size < 0 ? size : size / static_cast(objSize);
}
ssize_t BitTube::write(void const* vaddr, size_t size) {
ssize_t err, len;
do {
len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);
// cannot return less than size, since we're using SOCK_SEQPACKET
err = len < 0 ? errno : 0;
} while (err == EINTR);
return err == 0 ? len : -err;
}
二、VSYNC的接收
在SurfaceFlinger中,首次创建实例的时候会调用到onFirstRef方法:
1. SurfaceFlinger.cpp
void SurfaceFlinger::onFirstRef()
{
mEventQueue->init(this);
}
2. SurfaceFlinger.h
// these are thread safe
std::unique_ptr mEventQueue;
3. MessageQueue.cpp
void MessageQueue::init(const sp& flinger) {
mFlinger = flinger;
mLooper = new Looper(true);
mHandler = new Handler(*this);
}
上面我们已经提到了,在SurfaceFlinger的init方法中,mSfConnectionHandle对应着SurfaceFlinger自身的VSYNC的处理,是因为调用了mEventQueue->setEventConnection(mScheduler->getEventConnection(mSfConnectionHandle))方法。
1. MessageQueue.cpp
void MessageQueue::setEventConnection(const sp& connection) {
if (mEventTube.getFd() >= 0) {
mLooper->removeFd(mEventTube.getFd());
}
mEvents = connection;
mEvents->stealReceiveChannel(&mEventTube);
mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver,
this);
}
2. MessageQueue.h
gui::BitTube mEventTube;
3. BitTube.cpp
void BitTube::init(size_t rcvbuf, size_t sndbuf) {
//BitTube通过SocketPair创建了两个Socket描述符
int sockets[2];
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) {
size_t size = DEFAULT_SOCKET_BUFFER_SIZE;
setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf));
// since we don't use the "return channel", we keep it small...
setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
fcntl(sockets[0], F_SETFL, O_NONBLOCK);
fcntl(sockets[1], F_SETFL, O_NONBLOCK);
mReceiveFd.reset(sockets[0]);
mSendFd.reset(sockets[1]);
} else {
mReceiveFd.reset();
ALOGE("BitTube: pipe creation failed (%s)", strerror(errno));
}
}
int BitTube::getFd() const {
return mReceiveFd;
}
getFd方法返回的是mReceiveFd,MessageQueue通过Looper的addFD方法将该描述符添加到Looper中,当上述的VSYNC时间分发时,当通过send方法往mSendFd写数据时,会触发Looper中的epoll机制,从而回调到MessageQueue::cb_eventReceiver方法。MessageQueue的cb_eventReceiver方法,最终通过Looper的SendMessage调用到SurfaceFlinger的onMessageReceived方法,Message类型为MessageQueue::REFRESH:
1. SurfaceFlinger.cpp
void SurfaceFlinger::onMessageReceived(int32_t what) NO_THREAD_SAFETY_ANALYSIS {
ATRACE_CALL();
switch (what) {
case MessageQueue::INVALIDATE: {
...
case MessageQueue::REFRESH: {
if (mDolphinFuncsEnabled) {
mDolphinRefresh();
}
handleMessageRefresh();
break;
}
}
}
最终通过SurfaceFlinger的handleMessageRefresh方法,将App填充的最新的Layer实现计算大小,合成到framebuffer中供显卡显示。
三、Choreographer
从创建FrameDisplayEventReceiver开始分析,调用到它的父类DisplayEventReceiver.java的构造方法。
1. DisplayEventReceiver.java
/**
* Creates a display event receiver.
*
* @param looper The looper to use when invoking callbacks.
* @param vsyncSource The source of the vsync tick. Must be on of the VSYNC_SOURCE_* values.
*/
public DisplayEventReceiver(Looper looper, int vsyncSource) {
if (looper == null) {
throw new IllegalArgumentException("looper must not be null");
}
mMessageQueue = looper.getQueue();
mReceiverPtr = nativeInit(new WeakReference(this), mMessageQueue,
vsyncSource);
mCloseGuard.open("dispose");
}
然后通过nativeInit的jni调用android_view_DisplayEventReceiver.cpp中的nativeInit方法,通过创建NativeDisplayEventReceiver调用到它的父类DisplayEventDispatcher,通过nativeInit中传递过来的MessageQueue,得到App主线程的Looper,并交给DisplayEventDispatcher,继而调用DisplayEventDispatcher的initialize方法。
1. android_view_DisplayEventReceiver.cpp
static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak,
jobject messageQueueObj, jint vsyncSource) {
sp messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
if (messageQueue == NULL) {
jniThrowRuntimeException(env, "MessageQueue is not initialized.");
return 0;
}
sp receiver = new NativeDisplayEventReceiver(env,
receiverWeak, messageQueue, vsyncSource);
status_t status = receiver->initialize();
if (status) {
String8 message;
message.appendFormat("Failed to initialize display event receiver. status=%d", status);
jniThrowRuntimeException(env, message.string());
return 0;
}
receiver->incStrong(gDisplayEventReceiverClassInfo.clazz); // retain a reference for the object
return reinterpret_cast(receiver.get());
}
class NativeDisplayEventReceiver : public DisplayEventDispatcher
2. DisplayEventDispatcher.cpp
status_t DisplayEventDispatcher::initialize() {
status_t result = mReceiver.initCheck();
if (result) {
ALOGW("Failed to initialize display event receiver, status=%d", result);
return result;
}
int rc = mLooper->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT,
this, NULL);
if (rc < 0) {
return UNKNOWN_ERROR;
}
return OK;
}
可以看到它也是通过addFd监听着VSYNC信号的到来。而mReceiver则对应着DisplayEventReceiver则可以理解成跨进程的远程对象的本地代理。DisplayEventReceiver首先通过ComposerService创建了SurfaceFlinger的本地代理,然后通过createDisplayEventConnection得到EventThread所持有的Connection,这个Connection持有的BitTube订阅的方式和上面SurfaceFlinger一样。
1. DisplayEventReceiver.cp
DisplayEventReceiver::DisplayEventReceiver(ISurfaceComposer::VsyncSource vsyncSource) {
sp sf(ComposerService::getComposerService());
if (sf != nullptr) {
mEventConnection = sf->createDisplayEventConnection(vsyncSource);
if (mEventConnection != nullptr) {
mDataChannel = std::make_unique();
mEventConnection->stealReceiveChannel(mDataChannel.get());
}
}
}
int DisplayEventReceiver::getFd() const {
if (mDataChannel == nullptr)
return NO_INIT;
return mDataChannel->getFd();
}
2. SurfaceFlinger.cpp
sp SurfaceFlinger::createDisplayEventConnection(
ISurfaceComposer::VsyncSource vsyncSource) {
auto resyncCallback = mScheduler->makeResyncCallback([this] {
Mutex::Autolock lock(mStateLock);
return getVsyncPeriod();
});
const auto& handle =
vsyncSource == eVsyncSourceSurfaceFlinger ? mSfConnectionHandle : mAppConnectionHandle;
return mScheduler->createDisplayEventConnection(handle, std::move(resyncCallback));
}
这里分析使用的是mSfConnectionHandle还是mAppConnectionHandle?
变量eVsyncSourceSurfaceFlinger的来历
1. ISurfaceComposer.h
enum VsyncSource {
eVsyncSourceApp = 0,
eVsyncSourceSurfaceFlinger = 1
};
反向追踪vsyncSource可知,其初始来源于Choreographer中,如下所示:
public final class Choreographer {
...
private final class FrameDisplayEventReceiver extends DisplayEventReceiver
implements Runnable {
...
public FrameDisplayEventReceiver(Looper looper, int vsyncSource) {
super(looper, vsyncSource);
}
}
...
private Choreographer(Looper looper, int vsyncSource) {
...
mDisplayEventReceiver = USE_VSYNC ? new FrameDisplayEventReceiver(looper, vsyncSource) : null;
...
}
...
/**
* Gets the choreographer for the calling thread. Must be called from
* a thread that already has a {@link android.os.Looper} associated with it.
*
* @return The choreographer for this thread.
* @throws IllegalStateException if the thread does not have a looper.
*/
public static Choreographer getInstance() {
return sThreadInstance.get();
}
/**
* @hide
*/
@UnsupportedAppUsage
public static Choreographer getSfInstance() {
return sSfThreadInstance.get();
}
...
// Thread local storage for the choreographer.
private static final ThreadLocal sThreadInstance =
new ThreadLocal() {
@Override
protected Choreographer initialValue() {
Looper looper = Looper.myLooper();
if (looper == null) {
throw new IllegalStateException("The current thread must have a looper!");
}
Choreographer choreographer = new Choreographer(looper, VSYNC_SOURCE_APP);
if (looper == Looper.getMainLooper()) {
mMainInstance = choreographer;
}
return choreographer;
}
};
...
// Thread local storage for the SF choreographer.
private static final ThreadLocal sSfThreadInstance =
new ThreadLocal() {
@Override
protected Choreographer initialValue() {
Looper looper = Looper.myLooper();
if (looper == null) {
throw new IllegalStateException("The current thread must have a looper!");
}
return new Choreographer(looper, VSYNC_SOURCE_SURFACE_FLINGER);
}
};
...
}
public abstract class DisplayEventReceiver {
/**
* When retrieving vsync events, this specifies that the vsync event should happen at the normal
* vsync-app tick.
*
* Needs to be kept in sync with frameworks/native/include/gui/ISurfaceComposer.h
*/
public static final int VSYNC_SOURCE_APP = 0;
/**
* When retrieving vsync events, this specifies that the vsync event should happen whenever
* Surface Flinger is processing a frame.
*
* Needs to be kept in sync with frameworks/native/include/gui/ISurfaceComposer.h
*/
public static final int VSYNC_SOURCE_SURFACE_FLINGER = 1;
...
}
在ViewRootImpl中初始化Choreographer使用的是Choreographer.getInstance()即可知,最终生成的mAppConnectionHandle。所以Choreographer通过mAppConnectionHandle所对应的EventThread建立的连接而不是mSfConnectionHandle。就这样Choreographer成功的订阅了VSYNC信号。
public final class ViewRootImpl implements ViewParent,
View.AttachInfo.Callbacks, ThreadedRenderer.DrawCallbacks {
...
public ViewRootImpl(Context context, Display display) {
...
mChoreographer = Choreographer.getInstance();
...
}
...
}
而当Vsync信号到来的时候,由于DisplayEventDispatcher继承了LooperCallback,会调用到它的handleEvent方法,继而调用到NativeDisplayEventReceiver的dispatchVsync方法:
1. android_view_DisplayEventReceiver.cpp
class NativeDisplayEventReceiver : public DisplayEventDispatcher
2. DisplayEventDispatcher.h
class DisplayEventDispatcher : public LooperCallback
3. DisplayEventDispatcher.cpp
int DisplayEventDispatcher::handleEvent(int, int events, void*) {
...
if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
...
dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount);
}
return 1; // keep the callback
}
4. android_view_DisplayEventReceiver.cpp
void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId,
uint32_t count) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
ScopedLocalRef receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
if (receiverObj.get()) {
...
env->CallVoidMethod(receiverObj.get(),
gDisplayEventReceiverClassInfo.dispatchVsync, timestamp, displayId, count);
...
}
mMessageQueue->raiseAndClearException(env, "dispatchVsync");
}
int register_android_view_DisplayEventReceiver(JNIEnv* env) {
int res = RegisterMethodsOrDie(env, "android/view/DisplayEventReceiver", gMethods,
NELEM(gMethods));
jclass clazz = FindClassOrDie(env, "android/view/DisplayEventReceiver");
gDisplayEventReceiverClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
gDisplayEventReceiverClassInfo.dispatchVsync = GetMethodIDOrDie(env,
gDisplayEventReceiverClassInfo.clazz, "dispatchVsync", "(JJI)V");
gDisplayEventReceiverClassInfo.dispatchHotplug = GetMethodIDOrDie(env,
gDisplayEventReceiverClassInfo.clazz, "dispatchHotplug", "(JJZ)V");
gDisplayEventReceiverClassInfo.dispatchConfigChanged = GetMethodIDOrDie(env,
gDisplayEventReceiverClassInfo.clazz, "dispatchConfigChanged", "(JJI)V");
return res;
}
5. DisplayEventReceiver.java
// Called from native code.
@SuppressWarnings("unused")
@UnsupportedAppUsage
private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame) {
onVsync(timestampNanos, physicalDisplayId, frame);
}
jni端会通过CallVoidMethod方法调用到java端的DisplayEventReceiver的dispatchVsync方法,继而调用到FrameDisplayEventReceiver的onVsync方法。