SurfaceFlinger模块下的HWComposer,其中一个功能就是产生硬件的vsync。
SurfaceFlinger_hwc1.cpp
初始化HWComposer对象,同时传入参数SurfaceFlinger本身,作为回调事件的接收方。
void SurfaceFlinger::init() {
mHwc.reset(new HWComposer(this,
*static_cast(this)));
}
HWComposer_hwc1.cpp
HWComposer::HWComposer(
const sp& 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(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(
const_cast(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& 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::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(this));
}
}
DispSyncSource的onDispSyncEvent方法
virtual void onDispSyncEvent(nsecs_t when) {
sp 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(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 > signalConnections;
signalConnections = waitForEvent(&event);
// dispatch events to listeners...
const size_t count = signalConnections.size();
for (size_t i=0 ; i& conn(signalConnections[i]);
// now see if we still need to report this event
status_t err = conn->postEvent(event);
}
}
EventThread.cpp
Vector< sp > 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 connection(mDisplayEventConnections[i].promote());
signalConnections.add(connection);
}
}
mDisplayEventConnections中的元素来源:
EventThread.cpp
status_t EventThread::registerDisplayEventConnection(
const sp& 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)
: 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)
{
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(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 receiver =
reinterpret_cast(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();