Vsync信号的产生,都有那些类需要接收vsync信号

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));
	}	
}

DispSyncSourceonDispSyncEvent方法


    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::ConnectionpostEvent

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::ConnectionpostEvent,会往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

其他类通过调用ChoreographerpostFrameCallbackpostCallback来请求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.javaFrameDisplayEventReceiveronVsync函数。

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();










你可能感兴趣的:(Vsync信号的产生,都有那些类需要接收vsync信号)