SurfaceFlinger模块下的HWComposer,其中一个功能就是产生硬件的vsync。
SurfaceFlinger_hwc1.cpp
初始化HWComposer对象,同时传入参数SurfaceFlinger本身,作为回调事件的接收方。
void SurfaceFlinger::init() { mHwc.reset(new HWComposer(this, *static_cast<HWComposer::EventHandler *>(this))); }
HWComposer_hwc1.cpp
HWComposer::HWComposer( const sp<SurfaceFlinger>& flinger, EventHandler& handler) : mFlinger(flinger), mFbDev(0), mHwc(0), mNumDisplays(1), mCBContext(new cb_context),...{ loadHwcModule(); HWC模块加载成功,先给一些函数指针赋值,然后注册硬件回调registerProcs。 if (mHwc) { if (mHwc->registerProcs) { mCBContext->hwc = this; mCBContext->procs.invalidate = &hook_invalidate; mCBContext->procs.vsync = &hook_vsync; mHwc->registerProcs(mHwc, &mCBContext->procs); } } }
HWComposer_hwc1.cpp
void HWComposer::loadHwcModule(){ hw_module_t const* module; if (hw_get_module(HWC_HARDWARE_MODULE_ID, &module) != 0) {} int err = hwc_open_1(module, &mHwc); }
注册的硬件回调类型(其中的procs,类型是hwc_procs_t):
struct HWComposer::cb_context { struct callbacks : public hwc_procs_t { // these are here to facilitate the transition when adding // new callbacks (an implementation can check for NULL before // calling a new callback). void (*zero[4])(void); }; callbacks procs; HWComposer* hwc; };
打开的HWComposer硬件模块类型是structhwc_composer_device_1* mHwc;
hardware/libhardware/include/hardware/Hwcomposer.h
typedef struct hwc_composer_device_1 { /* * (*registerProcs)() registers callbacks that the h/w composer HAL can * later use. It will be called immediately after the composer device is * opened with non-NULL procs. It is FORBIDDEN to call any of the callbacks * from within registerProcs(). registerProcs() must save the hwc_procs_t * pointer which is needed when calling a registered callback. */ void (*registerProcs)(struct hwc_composer_device_1* dev, hwc_procs_t const* procs); }hwc_composer_device_1_t;
hwc_composer_device_1_t的具体实现类hwc_session.h
hardware/qcom/display/sdm/libs/hwc/hwc_session.h class HWCSession : hwc_composer_device_1_t, public qClient::BnQClient {}
把注册的回调实例surfaceflinger中的&mCBContext->procs赋值给hwc_session->hwc_procs_
void HWCSession::RegisterProcs(hwc_composer_device_1 *device, hwc_procs_t const *procs) { SCOPE_LOCK(locker_); if (!device || !procs) { return; } HWCSession *hwc_session = static_cast<HWCSession *>(device); hwc_session->hwc_procs_ = procs; }
hardware/qcom/display/sdm/libs/hwc/hwc_session.h
hwc_session->hwc_procs_跟&mCBContext->procs的类型一致,都是hwc_procs_t,所以可以直接赋值。
hwc_procs_t const*hwc_procs_ = &hwc_procs_default_;
hwc_procs_thwc_procs_default_;
hwc_session构造时,会创建显示设备,同时把回调实例&hwc_procs_,传递给显示硬件。
hwc_session.cpp
int HWCSession::Init() { status = HWCDisplayPrimary::Create(core_intf_, &buffer_allocator_, &hwc_procs_, qservice_, &hwc_display_[HWC_DISPLAY_PRIMARY]); }
hwc_display_primary.cpp
int HWCDisplayPrimary::Create(CoreInterface *core_intf, BufferAllocator *buffer_allocator, hwc_procs_t const **hwc_procs, qService::QService *qservice, HWCDisplay **hwc_display) { HWCDisplay *hwc_display_primary = new HWCDisplayPrimary(core_intf, buffer_allocator, hwc_procs, qservice); }
HWCDisplayPrimary::HWCDisplayPrimary(CoreInterface *core_intf, BufferAllocator *buffer_allocator, hwc_procs_t const **hwc_procs, qService::QService *qservice) : HWCDisplay(core_intf, hwc_procs, kPrimary, HWC_DISPLAY_PRIMARY, true, qservice, DISPLAY_CLASS_PRIMARY), buffer_allocator_(buffer_allocator) { }
hwc_display.cpp
hwc_display是最初vsync信号产生的地方。回调实例保存在hwc_procs_变量中。
HWCDisplay::HWCDisplay(CoreInterface *core_intf, hwc_procs_t const **hwc_procs, DisplayType type, int id, bool needs_blit, qService::QService *qservice, DisplayClass display_class) : core_intf_(core_intf), hwc_procs_(hwc_procs), type_(type), id_(id), needs_blit_(needs_blit), qservice_(qservice), display_class_(display_class) { }
当有硬件vsync信号产生时,一路回调到HWComposer_hwc1.cpp中的vsync函数(实际执行的hook_vsync,因为:mCBContext->procs.vsync= &hook_vsync;)
DisplayError HWCDisplay::VSync(const DisplayEventVSync &vsync) { const hwc_procs_t *hwc_procs = *hwc_procs_; if (!hwc_procs) { return kErrorParameters; } hwc_procs->vsync(hwc_procs, id_, vsync.timestamp); return kErrorNone; }
再次回到HWComposer_hwc1.cpp
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); }
hook_vsync直接调用了vsync函数。通过mEventHandler也即是SurfaceFlinger实例把vsync传递到了Surfaceflinger中的onVSyncReceived。
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(this, disp, timestamp); } }
vsync信号的接收
SurfaceFlinger_hwc1.cpp
void SurfaceFlinger::onVSyncReceived(HWComposer* /*composer*/, int type, nsecs_t timestamp) { needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp); enableHardwareVsync(); }
DispSync.cpp
bool DispSync::addResyncSample(nsecs_t timestamp) { 唤醒DispSync中的DispSyncThread线程 mThread->updateModel(mPeriod, mPhase, mReferenceTime); }
class DispSyncThread: public Thread { virtual bool threadLoop() { 收集需要回调的监听者,执行回调。 callbackInvocations = gatherCallbackInvocationsLocked(now); if (callbackInvocations.size() > 0) { fireCallbackInvocations(callbackInvocations); } } }
回调其 onDispSyncEvent函数。 void fireCallbackInvocations(const Vector<CallbackInvocation>& callbacks) { if (kTraceDetailedInfo) ATRACE_CALL(); for (size_t i = 0; i < callbacks.size(); i++) { callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime); } }
都有哪些对vsync感兴趣的监听者呢?
回到SurfaceFlinger_hwc1.cpp
这里会注册一个对vsync的监听到DispSync中。
void SurfaceFlinger::init() { mSFEventThread = new EventThread(sfVsyncSrc, *this, true); mEventQueue.setEventThread(mSFEventThread); }
EventThread.cpp bool EventThread::threadLoop() { signalConnections = waitForEvent(&event); }
Vector< sp<EventThread::Connection> > EventThread::waitForEvent( DisplayEventReceiver::Event* event){ enableVSyncLocked(); }
void EventThread::enableVSyncLocked() { mVSyncSource->setVSyncEnabled(true); }
SurfaceFlinger_hwc1.cpp
class DispSyncSource : public VSyncSource, private DispSync::Callback { 往DisySync中添加一个对vsync感兴趣的监听者,就是DispSyncSource实例。所以vsync信号回调时会传递到 DispSyncSource的onDispSyncEvent方法中。 virtual void setVSyncEnabled(bool enable) { status_t err = mDispSync->addEventListener(mName, mPhaseOffset, static_cast<DispSync::Callback*>(this)); } }
DispSyncSource的onDispSyncEvent方法
virtual void onDispSyncEvent(nsecs_t when) { sp<VSyncSource::Callback> callback; { Mutex::Autolock lock(mCallbackMutex); callback = mCallback; if (mTraceVsync) { mValue = (mValue + 1) % 2; ATRACE_INT(mVsyncEventLabel.string(), mValue); } } if (callback != NULL) { callback->onVSyncEvent(when); } }
那么onDispSyncEvent这里的回调callback= mCallback;又是谁呢?
回到EventThread.cpp,通过mVSyncSource->setCallback设置的回调就是onDispSyncEvent的中mCallback。
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(); }
所以vsync信号又被传递到了EventThread.cpp中的onVSyncEvent。
EventThread.cpp 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(); }
这里把vsync包装成一个event事件,然后mCondition.broadcast();唤醒一个线程,也就是EventThread::threadLoop()。
EventThread.cpp bool EventThread::threadLoop() { 将会调用 signalConnections中的listener的postEvent方法。 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); } }
EventThread.cpp Vector< sp<EventThread::Connection> > EventThread::waitForEvent( DisplayEventReceiver::Event* event){ signalConnections中的listener来自 mDisplayEventConnections。 // find out connections waiting for events size_t count = mDisplayEventConnections.size(); for (size_t i=0 ; i<count ; i++) { sp<Connection> connection(mDisplayEventConnections[i].promote()); signalConnections.add(connection); } }
mDisplayEventConnections中的元素来源:
EventThread.cpp status_t EventThread::registerDisplayEventConnection( const sp<EventThread::Connection>& connection) { Mutex::Autolock _l(mLock); mDisplayEventConnections.add(connection); if (!mFirstConnectionInited) { // additional external displays can't be enumerated by default, // need to report additional hotplug to listeners for (int32_t type = DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES; type < (int32_t)mHotplugEvent.size(); type++) { if (mHotplugEvent[type].hotplug.connected) { connection->postEvent(mHotplugEvent[type]); } } mFirstConnectionInited = true; } mCondition.broadcast(); return NO_ERROR; }
void EventThread::Connection::onFirstRef() { // NOTE: mEventThread doesn't hold a strong reference on us mEventThread->registerDisplayEventConnection(this); }
mDisplayEventConnections中的元素,其中一个就是EventThread.cpp中的内部类Connection。
所以包装着vsync信号的事件,被传递到了EventThread::Connection的postEvent。
status_t EventThread::Connection::postEvent( const DisplayEventReceiver::Event& event) { ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1); return size < 0 ? status_t(size) : status_t(NO_ERROR); }
上面的函数DisplayEventReceiver::sendEvents,将把事件写入到socket中的输入端。其中&mChannel的类型gui::BitTubemChannel;本质是一个socket。
Frameworks/native/libs/gui/DisplayEventReceiver.cpp
EventThread::Connection的postEvent,会往socket中写入事件
ssize_t DisplayEventReceiver::sendEvents(gui::BitTube* dataChannel, Event const* events, size_t count) { return gui::BitTube::sendObjects(dataChannel, events, count); }
从socket中读取事件
ssize_t DisplayEventReceiver::getEvents(DisplayEventReceiver::Event* events, size_t count) { return DisplayEventReceiver::getEvents(mDataChannel.get(), events, count); }
那么都有谁是这个socket的接收端,或者读取端呢?
首先看EventThread.cpp中,mChannel变量是在其构造时创建的
mChannel(gui::BitTube::DefaultSize)。
EventThread::Connection::Connection( const sp<EventThread>& eventThread) : count(-1), mEventThread(eventThread), mChannel(gui::BitTube::DefaultSize){}
其中函数
stealReceiveChannel
用来设置socket 的接收端。status_t EventThread::Connection::stealReceiveChannel(gui::BitTube* outChannel) { outChannel->setReceiveFd(mChannel.moveReceiveFd()); return NO_ERROR; }
都有那些类会希望接收vsync信号呢?
一,SurfaceFigner,通过其中的MessageQueue来接收vsync信号。
MessageQueue.cpp
void MessageQueue::setEventThread(const sp<EventThread>& eventThread) { if (mEventThread == eventThread) { return; } if (mEventTube.getFd() >= 0) { mLooper->removeFd(mEventTube.getFd()); } 调用 stealReceiveChannel设置socket的接收端为 mEventTube, mEventThread = eventThread; mEvents = eventThread->createEventConnection(); mEvents->stealReceiveChannel(&mEventTube); 在socket有数据写入时,执行回调 cb_eventReceiver,然后调用eventReceiver,通过mHandler->dispatchInvalidate()把事件放入消息队列, 具体是MessageQueue的looper带有的消息队列。 mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver, this); }
void MessageQueue::Handler::dispatchInvalidate() { if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) { mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE)); } }
void MessageQueue::Handler::handleMessage(const Message& message) { switch (message.what) { case INVALIDATE: android_atomic_and(~eventMaskInvalidate, &mEventMask); mQueue.mFlinger->onMessageReceived(message.what); break; case REFRESH: android_atomic_and(~eventMaskRefresh, &mEventMask); mQueue.mFlinger->onMessageReceived(message.what); break; } }
最终通过mQueue.mFlinger->onMessageReceived(message.what);把vsync信号,作为msg传到Surfacefligner中的onMessageReceived函数。
二,RenderThread.cpp也需要接收vsync,
RenderThread.cpp
void RenderThread::initializeDisplayEventReceiver() { LOG_ALWAYS_FATAL_IF(mDisplayEventReceiver, "Initializing a second DisplayEventReceiver?"); mDisplayEventReceiver = new DisplayEventReceiver(); status_t status = mDisplayEventReceiver->initCheck(); LOG_ALWAYS_FATAL_IF(status != NO_ERROR, "Initialization of DisplayEventReceiver " "failed with status: %d", status); // Register the FD mLooper->addFd(mDisplayEventReceiver->getFd(), 0, Looper::EVENT_INPUT, RenderThread::displayEventReceiverCallback, this); }
在有vsync信号时,执行设置的回调enderThread::displayEventReceiverCallback:
int RenderThread::displayEventReceiverCallback(int fd, int events, void* data) { if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) { ALOGE("Display event receiver pipe was closed or an error occurred. " "events=0x%x", events); return 0; // remove the callback } if (!(events & Looper::EVENT_INPUT)) { ALOGW("Received spurious callback for unhandled poll event. " "events=0x%x", events); return 1; // keep the callback } reinterpret_cast<RenderThread*>(data)->drainDisplayEventQueue(); return 1; // keep the callback }
三,前面都是native层对vsync信号的接收,java层也需要接收vsync信号,比如动画的执行,UI的填充,他们是通过Choreographer.java的来接收的,然后回调动画的执行,UI的填充。
Choreographer.java
其他类通过调用Choreographer的postFrameCallback,postCallback来请求vsync。会调用到scheduleVsyncLocked函数。
Choreographer 内部类FrameDisplayEventReceiver,
private finalclass FrameDisplayEventReceiver extends DisplayEventReceiver{}
间接调用到:
private void scheduleVsyncLocked() { mDisplayEventReceiver.scheduleVsync(); }
scheduleVsync调用的父类DisplayEventReceiver的方法。
DisplayEventReceiver.java /** * Schedules a single vertical sync pulse to be delivered when the next * display frame begins. */ public void scheduleVsync() { if (mReceiverPtr == 0) { Log.w(TAG, "Attempted to schedule a vertical sync pulse but the display event " + "receiver has already been disposed."); } else { nativeScheduleVsync(mReceiverPtr); } }
转到native层
nativeScheduleVsync
:android_view_DisplayEventReceiver.cpp static void nativeScheduleVsync(JNIEnv* env, jclass clazz, jlong receiverPtr) { sp<NativeDisplayEventReceiver> receiver = reinterpret_cast<NativeDisplayEventReceiver*>(receiverPtr); status_t status = receiver->scheduleVsync(); if (status) { String8 message; message.appendFormat("Failed to schedule next vertical sync pulse. status=%d", status); jniThrowRuntimeException(env, message.string()); } }
jni中的receiver->scheduleVsync(),将调用NativeDisplayEventReceiver的父类DisplayEventDispatcher中的scheduleVsync函数。
DisplayEventDispatcher.cpp
DisplayEventDispatcher类中的成员变量DisplayEventReceivermReceiver就是前面的Frameworks/native/libs/gui/DisplayEventReceiver.cpp。
DisplayEventReceivermReceiver;
DisplayEventDispatcher.cpp
在DisplayEventDispatcher执行初始化时,通过mReceiver.getFd()获取到socket的描述符号,getFd获取的是接收文件描述符。同时把当前类设置为事件的接收回调函数,DisplayEventDispatcher继承了 publicLooperCallback ,所以相应执行的回调函数就是LooperCallback中的handleEvent。
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; }
DisplayEventDispatcher.cpp int DisplayEventDispatcher::handleEvent(int, int events, void*) { dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount); }
从native层通过jni回调到java层,
android_view_DisplayEventReceiver.cpp void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count) { env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchVsync, timestamp, id, count); }
DisplayEventReceiver.java
private void dispatchVsync(long timestampNanos, int builtInDisplayId, int frame) { onVsync(timestampNanos, builtInDisplayId, frame); }
最后调用了Choreographer.java的FrameDisplayEventReceiver的onVsync函数。
Choreographer.java
private final class FrameDisplayEventReceiver extends DisplayEventReceiver{ public void onVsync(long timestampNanos, int builtInDisplayId, int frame) { FrameDisplayEventReceiver 实现了Runnable接口,所以可以通过post msg的形式,执行其run(),也就是说 FrameDisplayEventReceiver将 作为Runnable类型,封装成msg的回调函数,当把这个msg从消息队列取出时,会优先执行这个msg的回调函数(也即是其runnable的方法), 如果msg没有设置回调函数,才会通过handler的handlemessage方法执行。 Message msg = Message.obtain(mHandler, this); msg.setAsynchronous(true); mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS); } public void run() { mHavePendingVsync = false; doFrame(mTimestampNanos, mFrame); } }
doFrame执行相应的回调:
void doFrame(long frameTimeNanos, int frame) { AnimationUtils.lockAnimationClock(frameTimeNanos / TimeUtils.NANOS_PER_MS); mFrameInfo.markInputHandlingStart(); doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos); mFrameInfo.markAnimationsStart(); doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos); mFrameInfo.markPerformTraversalsStart(); doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos); doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos); }
DisplayEventReceiver有两个函数值得注意一下,这两个函数最终作用到IDisplayEventConnection.cpp中
DisplayEventReceiver.h
设置vsync的传递频率,参数值为1表示每个vsync事件都传递,参数值为2表示每隔一个vsync产地一次,参数值为0表示不传递,除非主动调用requestNextVsync。
status_tsetVsyncRate(uint32_t count);
requestNextVsync函数要想起作用,需要上一个函数设置vsyncrate为0.
status_trequestNextVsync();