标签:
vsync信号源产生地
1.硬件支持
2.软件模拟
SurfaceFlinger创建的init会初始创建HWComposer
void SurfaceFlinger::init() {
mHwc = new HWComposer(this,*static_cast<HWComposer::EventHandler *>(this));
}
HWComposer::HWComposer(
const sp<SurfaceFlinger>& flinger,
EventHandler& handler)
{
bool needVSyncThread = true;
loadHwcModule();
if (mHwc) {//存在加载成功composer硬件抽象层,则用硬件支持的vSync信号
if (mHwc->registerProcs) {
mCBContext->hwc = this;
mCBContext->procs.invalidate = &hook_invalidate;
mCBContext->procs.vsync = &hook_vsync;//硬件回调的vsync信号处理函数
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
mCBContext->procs.hotplug = &hook_hotplug;
else
mCBContext->procs.hotplug = NULL;
memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
mHwc->registerProcs(mHwc, &mCBContext->procs);
}
//先关闭vsync信号
needVSyncThread = false;
eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);
}
//软件模拟的vsync信号
if (needVSyncThread) {
mVSyncThread = new VSyncThread(*this);
}
}
void HWComposer::hook_vsync(const struct hwc_procs* procs, int disp,int64_t timestamp) {
//procs是我们传过去的,根据这个指针我们可以转化成外部的我们自己用的指针
//硬件层总是用这种技巧 一般procs作为另一个struct结构的第一成员,类似与c++中的继承关系了
cb_context* ctx = reinterpret_cast<cb_context*>(const_cast<hwc_procs_t*>(procs));
ctx->hwc->vsync(disp, timestamp);
}
void HWComposer::vsync(int disp, int64_t timestamp) {
if (uint32_t(disp) < HWC_NUM_PHYSICAL_DISPLAY_TYPES) {
//记录一下最后一次产生的vsync信号的时间值
if (timestamp == mLastHwVSync[disp]) {
return;
}
mLastHwVSync[disp] = timestamp;
//通知外面 ,mEventHandler是构造函数初始化的,就是SurfaceFlinger
//查看一下应用这个函数的地方还会找到bool HWComposer::VSyncThread::threadLoop() 这个就是
//软件模拟的vsync.
//所以不管软件还是硬件的vsync信号最后都有mEventHandler.onVSyncReceived进行处理
mEventHandler.onVSyncReceived(disp, timestamp);
}
}
HWComposer初始化后,vsync信号的输出地就是mEventHandler.onVSyncReceived (SurfaceFlinger::onVSyncReceived)
void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
bool needsHwVsync = false;
{
Mutex::Autolock _l(mHWVsyncLock);
if (type == 0 && mPrimaryHWVsyncEnabled) {
//添加采样时间点 mPrimaryDispSync通过采样点计算出vsync信号的触发间隔和波动范围
//然后通过软件模拟出vsync信号,如果不需要采样点了就返回false,这样外部根据返回值
//开启和关闭硬件(HWComposer中产生的)vsync信号,据说可以省电
needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
}
}
//开启关闭HWComposer的vsync
if (needsHwVsync) {
enableHardwareVsync();
} else {
disableHardwareVsync(false);
}
}
//关闭vsync
void SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) {
Mutex::Autolock _l(mHWVsyncLock);
if (mPrimaryHWVsyncEnabled) {
//eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false);
//又是一个控制线程,线程中会调用eventControl(HWC_DISPLAY_PRIMARY
//setVsyncEnabled设置变量后激活线程
mEventControlThread->setVsyncEnabled(false);
mPrimaryDispSync.endResync();
mPrimaryHWVsyncEnabled = false;
}
if (makeUnavailable) {
mHWVsyncAvailable = false;
}
}
//开启vsync
void SurfaceFlinger::enableHardwareVsync() {
mEventControlThread->setVsyncEnabled(true);
}
//添加采样点
bool DispSync::addResyncSample(nsecs_t timestamp) {
Mutex::Autolock lock(mMutex);
//timerstamp添加到一个固定大小的queue中,
size_t idx = (mFirstResyncSample + mNumResyncSamples) % MAX_RESYNC_SAMPLES;
mResyncSamples[idx] = timestamp;
if (mNumResyncSamples < MAX_RESYNC_SAMPLES) {
mNumResyncSamples++;
} else {
mFirstResyncSample = (mFirstResyncSample + 1) % MAX_RESYNC_SAMPLES;
}
//通过采样点计算mPeriod
updateModelLocked();
//如果计算出的间隔不是0就返回false,外部就关闭了硬件vsync
return mPeriod == 0 || mError > errorThreshold;
}
void DispSync::updateModelLocked() {
//采样点大于MIN_RESYNC_SAMPLES_FOR_UPDATE后才能计算mPeriod
if (mNumResyncSamples >= MIN_RESYNC_SAMPLES_FOR_UPDATE) {
nsecs_t durationSum = 0;
for (size_t i = 1; i < mNumResyncSamples; i++) {
size_t idx = (mFirstResyncSample + i) % MAX_RESYNC_SAMPLES;
size_t prev = (idx + MAX_RESYNC_SAMPLES - 1) % MAX_RESYNC_SAMPLES;
durationSum += mResyncSamples[idx] - mResyncSamples[prev];
}
//计算一下vsync间隔
mPeriod = durationSum / (mNumResyncSamples - 1);
//下面这一段搞这么复杂就是计算一个vsync偏差(mPhase相位),我感觉可以简单点处理,没必要sin,cos等
// 下面意思是 把mPeriod转成弧度(2pi),然后计算每次采样间隔跟mPeriod差出的弧度值
//根据弧度转成x,y ,累加x,y然后取平局偏差 ,然后计算平均的偏差弧度,然后转成mPeriod对应的长度单位
double sampleAvgX = 0;
double sampleAvgY = 0;
double scale = 2.0 * M_PI / double(mPeriod);
for (size_t i = 0; i < mNumResyncSamples; i++) {
size_t idx = (mFirstResyncSample + i) % MAX_RESYNC_SAMPLES;
nsecs_t sample = mResyncSamples[idx];
double samplePhase = double(sample % mPeriod) * scale;
sampleAvgX += cos(samplePhase);
sampleAvgY += sin(samplePhase);
}
sampleAvgX /= double(mNumResyncSamples);
sampleAvgY /= double(mNumResyncSamples);
mPhase = nsecs_t(atan2(sampleAvgY, sampleAvgX) / scale);
if (mPhase < 0) {
mPhase += mPeriod;
}
//更新模拟线程的数据
mThread->updateModel(mPeriod, mPhase);
}
}
//产生外部用的vsync信号
virtual bool DispSyncThread::threadLoop() {
status_t err;
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
nsecs_t nextEventTime = 0;
while (true) {
Vector<CallbackInvocation> callbackInvocations;
nsecs_t targetTime = 0;
{ //等待设置新的mPeriod
Mutex::Autolock lock(mMutex);
if (mPeriod == 0) {
err = mCond.wait(mMutex);
continue;
}
//根据当前时间计算下一次什么时候醒过来
nextEventTime = computeNextEventTimeLocked(now);
targetTime = nextEventTime;
err = mCond.waitRelative(mMutex, targetTime - now);
//计算需要通知的callback
now = systemTime(SYSTEM_TIME_MONOTONIC);
callbackInvocations = gatherCallbackInvocationsLocked(now);
}
//通知监听vsync信号的connect
if (callbackInvocations.size() > 0) {
fireCallbackInvocations(callbackInvocations);
}
}
return false;
}
//添加监听sync信号的callback
status_t DispSyncThread::addEventListener(nsecs_t phase, const sp<DispSync::Callback>& callback) {
EventListener listener;
listener.mPhase = phase;
listener.mCallback = callback;
listener.mLastEventTime = systemTime(SYSTEM_TIME_MONOTONIC);
mEventListeners.push(listener);
mCond.signal();
return NO_ERROR;
}
status_t DispSync::addEventListener(nsecs_t phase,const sp<Callback>& callback) {
Mutex::Autolock lock(mMutex);
return mThread->addEventListener(phase, callback);
}
SurfaceFlinger::init(){
// DispSyncSource ,设置成mPrimaryDispSync的回调,控制mPrimaryDispSync模拟的vsync开启关闭
sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,vsyncPhaseOffsetNs, true);
//需要监听vsync,plugin信号的connenct,调用SurfaceFlinger::createDisplayEventConnection就创建一个connect
mEventThread = new EventThread(vsyncSrc);
//驱动刷新vsync信号处理,
sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,sfVsyncPhaseOffsetNs, false);
mSFEventThread = new EventThread(sfVsyncSrc);
//MessageQueue.setEventThread后会监听socketpair的另一端,当有vsync信号后MessageQueue就知道了
mEventQueue.setEventThread(mSFEventThread);
//控制HWSComposer中的VSYNC开启关闭
mEventControlThread = new EventControlThread(this);
mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
}
bool EventThread::threadLoop() {
DisplayEventReceiver::Event event;
//等待有事件发生的connect
Vector< sp<EventThread::Connection> > signalConnections;
signalConnections = waitForEvent(&event);
//消息转发出去,postEvent内部通过sockpair传递数据
const size_t count = signalConnections.size();
for (size_t i=0 ; i<count ; i++) {
const sp<Connection>& conn(signalConnections[i]);
status_t err = conn->postEvent(event);
}
return true;
}
Vector< sp<EventThread::Connection> > EventThread::waitForEvent(
DisplayEventReceiver::Event* event)
{
do {
bool eventPending = false;
bool waitForVSync = false;
size_t vsyncCount = 0;
//是否有vSYNC信号
nsecs_t timestamp = 0;
for (int32_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
timestamp = mVSyncEvent[i].header.timestamp;
if (timestamp) {
*event = mVSyncEvent[i];
mVSyncEvent[i].header.timestamp = 0;
vsyncCount = mVSyncEvent[i].vsync.count;
break;
}
}
//是否有plugin信号
if (!timestamp) {
eventPending = !mPendingEvents.isEmpty();
if (eventPending) {
// we have some other event to dispatch
*event = mPendingEvents[0];
mPendingEvents.removeAt(0);
}
}
//查找对vSYnc有兴趣的connnect,如果没有找plugin信号,移除无效的connect
size_t count = mDisplayEventConnections.size();
for (size_t i=0 ; i<count ; i++) {
sp<Connection> connection(mDisplayEventConnections[i].promote());
if (connection != NULL) {
bool added = false;
if (connection->count >= 0) {
waitForVSync = true;
if (timestamp) {
if (connection->count == 0) {
connection->count = -1;
signalConnections.add(connection);
added = true;
} else if (connection->count == 1 ||
(vsyncCount % connection->count) == 0) {
signalConnections.add(connection);
added = true;
}
}
}
if (eventPending && !timestamp && !added) {
signalConnections.add(connection);
}
} else {
mDisplayEventConnections.removeAt(i);
--i; --count;
}
}
//是否需要关闭vsync ,如果没有关心vsync的connect
if (timestamp && !waitForVSync) {
disableVSyncLocked();
} else if (!timestamp && waitForVSync) {
enableVSyncLocked();
}
//如果没有了则等待一段时间
if (!timestamp && !eventPending) {
if (waitForVSync) {
bool softwareSync = mUseSoftwareVSync;
nsecs_t timeout = softwareSync ? ms2ns(16) : ms2ns(1000);
if (mCondition.waitRelative(mLock, timeout) == TIMED_OUT) {
if (!softwareSync) {
ALOGW("Timed out waiting for hw vsync; faking it");
}
mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
mVSyncEvent[0].header.id = DisplayDevice::DISPLAY_PRIMARY;
mVSyncEvent[0].header.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
mVSyncEvent[0].vsync.count++;
}
} else {
mCondition.wait(mLock);
}
}
} while (signalConnections.isEmpty());
return signalConnections;
}
当有vsync信号后会触发激活线程
void EventThread::onVSyncEvent(nsecs_t timestamp);
当有plugin信号后会触发激活线程
void EventThread::onHotplugReceived(int type, bool connected);
调用connect创建一个对事件感兴趣的connect
sp<Connection> EventThread::createEventConnection();
class Connection : public BnDisplayEventConnection {
//触发事件,在 EventThread::threadLoop中
status_t postEvent(const DisplayEventReceiver::Event& event);
//内部包装了一个socke_pair的句柄,当postEvent会向里面写数据
//如果又兴趣则需要取出句柄监听读
virtual sp<BitTube> getDataChannel() const;
};
//MessageQueue
class MessageQueue {
}
void MessageQueue::setEventThread(const sp<EventThread>& eventThread)
{
mEventThread = eventThread;
mEvents = eventThread->createEventConnection();
mEventTube = mEvents->getDataChannel();
//监听socketpair的另一端
mLooper->addFd(mEventTube->getFd(), 0, ALOOPER_EVENT_INPUT,
MessageQueue::cb_eventReceiver, this);
}
//vsync回调
int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
MessageQueue* queue = reinterpret_cast<MessageQueue *>(data);
return queue->eventReceiver(fd, events);
}
//
int MessageQueue::eventReceiver(int fd, int events) {
ssize_t n;
DisplayEventReceiver::Event buffer[8];
//socketpair读出消息来
while ((n = DisplayEventReceiver::getEvents(mEventTube, buffer, 8)) > 0) {
for (int i=0 ; i<n ; i++) {
if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
//如果vsync信号则派发出去
#if INVALIDATE_ON_VSYNC
mHandler->dispatchInvalidate();
#else
mHandler->dispatchRefresh();
#endif
break;
}
}
}
return 1;
}
//消息派发
void MessageQueue::Handler::dispatchRefresh() {
if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) {
mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));
}
}
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:
//转发到surfaceflinger
android_atomic_and(~eventMaskInvalidate, &mEventMask);
mQueue.mFlinger->onMessageReceived(message.what);
break;
case REFRESH:
//转发到surfaceflinger
android_atomic_and(~eventMaskRefresh, &mEventMask);
mQueue.mFlinger->onMessageReceived(message.what);
break;
case TRANSACTION:
//转发到surfaceflinger
android_atomic_and(~eventMaskTransaction, &mEventMask);
mQueue.mFlinger->onMessageReceived(message.what);
break;
}
}
//处理消息把,刷新界面
void SurfaceFlinger::onMessageReceived(int32_t what) {
ATRACE_CALL();
switch (what) {
case MessageQueue::TRANSACTION:
handleMessageTransaction();
break;
case MessageQueue::INVALIDATE:
handleMessageTransaction();
handleMessageInvalidate();
signalRefresh();
break;
case MessageQueue::REFRESH:
handleMessageRefresh();
break;
}
}
总结:
当SurfaceFlinger.init以后,就会定时收到onMessageReceived消息,驱动则刷新界面
void SurfaceFlinger::init() {
//硬件抽象层,vsync信号发源地,通过SurfaceFlinger加到mPrimaryDispSync中
mHwc = new HWComposer(this,*static_cast<HWComposer::EventHandler *>(this));
// 其他需要vsync信号的,通过mEventThread建立,不影响刷新的
sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
vsyncPhaseOffsetNs, true);
mEventThread = new EventThread(vsyncSrc);
//界面刷新vsync信号,在一个单独线程中转发,可能为了提交刷新效率
sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
sfVsyncPhaseOffsetNs, false);
mSFEventThread = new EventThread(sfVsyncSrc);
mEventQueue.setEventThread(mSFEventThread);
//控制HWComposer 中vsync信号开启关闭
mEventControlThread = new EventControlThread(this);
mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
}
//处理vsync信号上来的刷新等消息
void SurfaceFlinger::onMessageReceived(int32_t what) {
....
}
VSYNC信号传递流向
标签:
原文地址:http://blog.csdn.net/u014409795/article/details/51330642