Android Surfaceflinger Service (vi) Distribution of-----vsync signals

Source: Internet
Author: User

Tag: Star remove generates ref rate mask turned CTO disable

The Hwcomposer module generates a VSYNC signal to be distributed before it can be sent to the module concerned with the VSync event. The VSYNC signal distribution process is hwcomposer->surfaceflinger->dispsync->dispsyncsource-> each specific module. The following is a detailed analysis of the process.

In the previous article, when analyzing a hardware or software vsync signal generation, the Surfaceflinger onvsyncreceived function is called back to see this function:

void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {    bool needsHwVsync = false;    { // Scope for the lock        Mutex::Autolock _l(mHWVsyncLock);         if (type == 0 && mPrimaryHWVsyncEnabled) {            needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);        }    }      if (needsHwVsync) {        enableHardwareVsync();    } else {        disableHardwareVsync(false);    }  }
    • The Mprimarydispsync type is Dispsync, which is created when constructed Dispsyncthread
DispSync::DispSync() :        mRefreshSkipCount(0),        mThread(new DispSyncThread()) {    mThread->run("DispSync", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);    reset();    beginResync();    if (kTraceDetailedInfo) {        // If we‘re not getting present fences then the ZeroPhaseTracer        // would prevent HW vsync event from ever being turned off.        // Even if we‘re just ignoring the fences, the zero-phase tracing is        // not needed because any time there is an event registered we will        // turn on the HW vsync events.        if (!kIgnorePresentFences) {               addEventListener(0, new ZeroPhaseTracer());        }    }}
    • Calling Dispsync's Addresyncsample method will eventually wake up the Dispsyncthread thread
  bool Dispsync::addresyncsample (nsecs_t timestamp) {Mutex::autolock lock (Mmutex);    size_t idx = (mfirstresyncsample + mnumresyncsamples)% Max_resync_samples;    MRESYNCSAMPLES[IDX] = timestamp;    if (Mnumresyncsamples < max_resync_samples) {mnumresyncsamples++;    } else {mfirstresyncsample = (mfirstresyncsample + 1)% Max_resync_samples;    } updatemodellocked ();    if (mnumresyncsamplessincepresent++ > Max_resync_samples_without_present) {reseterrorlocked (); } if (kignorepresentfences) {//If we don ' t have the sync framework we'll never have//Addpresentfenc  E called.        This means we have no-to-know whether//or not we ' re synchronized with the HW Vsyncs, so we just request        That the HW vsync events is turned on whenever we need to generate//SW VSync events.    return Mthread->hasanyeventlisteners (); } return Mperiod = = 0 | | Merror > Kerrorthreshold;}  
    • Call the updatemodellocked function
    • Calculate if you need to turn on hardware vsync for synchronization
void DispSync::updateModelLocked() {    if (mNumResyncSamples >= MIN_RESYNC_SAMPLES_FOR_UPDATE) {                ......                mThread->updateModel(mPeriod, mPhase);    }}
    • The member variable mthread is an object of the Dispsyncthread class
    • Call the Dispsyncthread class Pdatemodel method
void updateModel(nsecs_t period, nsecs_t phase) {        Mutex::Autolock lock(mMutex);        mPeriod = period;        mPhase = phase;        mCond.signal();    }
    • This method mainly sets member variables Mperiod, mphase
    • Then in the wake thread loop
virtual bool threadLoop() {        status_t err;        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);        nsecs_t nextEventTime = 0;        while (true) {            Vector<CallbackInvocation> callbackInvocations;            nsecs_t targetTime = 0;            { // Scope for lock                Mutex::Autolock lock(mMutex);                ......                callbackInvocations = gatherCallbackInvocationsLocked(now);            }            if (callbackInvocations.size() > 0) {                fireCallbackInvocations(callbackInvocations);            }        }        return false;    }
    • Get Listener Collection by gathercallbackinvocationslocked
    • Call Listener callback function via Firecallbackinvocations

Where Dispsync's callback function is registered, we're looking at Dispsyncsource's setvsyncenabled function

virtual void setvsyncenabled (bool enable) {Mutex::autolock lock (Mvsyncmutex); if (enable) {status_t err = Mdispsync->addeventlistener (Mphaseoffset, Static_cast<dis            Psync::callback*> (this));                        if (err! = No_error) {aloge ("ERROR registering VSync callback:%s (%d)",                                                                                                                                                            Strerror (-err), err);                                                                                                                                   }//atrace_int (Mvsynconlabel.string (), 1); } else {status_t err = Mdispsync->removeeventlistener (static_cast<disp            Sync::callback*> (this)); if (err! = No_error) {aloge ("ERROR unregistering VSync callback:%s (%d) ", Strerror (-err), err); }//atrace_int (Mvsynconlab                                                                                                                                                 El.string (), 0);    } menabled = enable; }
    • Dispsyncsource class inherits from Dispsync::callback
    • Call Dispsync->addeventlistener to register the callback, and when Dispsyncsource receives the Dispsync vsync signal, the Ondispsyncevent function is adjusted back
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);        }    }
    • This function eventually calls Vsyncsource::callback's Onvsyncevent function.
    • The registration of the Vsyncsource::callback function is registered by calling the Setcallback of Dispsyncsource.

Dispsyncsource the Setcallback function where to call, to answer this question, or to go back to the Surfaceflinger init function, take sfvsyncsrc as an example.

void SurfaceFlinger::init() {        ......        // start the EventThread    sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,            vsyncPhaseOffsetNs, true, "app");    mEventThread = new EventThread(vsyncSrc);    sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,            sfVsyncPhaseOffsetNs, true, "sf");    mSFEventThread = new EventThread(sfVsyncSrc);    mEventQueue.setEventThread(mSFEventThread);    ......}
    • Creating Eventthread objects with SFVSYNCSRC as parameters
    • The enablevsynclocked function is called in the thread loop of Eventthread
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();}
    • Eventthread inherits the Vsyncsource::callback interface, implements the Onvsyncevent function
    • Call Mvsyncsource's Setcallback function to set the callback
    • Call Mvsyncsource's setvsyncenabled function to enable the monitoring of the vsync signal.
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();}
    • Eventthread receive VSYNC signal, send broadcast message, Wake up related thread
    • The final eventthread transmits the VSNC signal to the MessageQueue

Android Surfaceflinger Service (vi) Distribution of-----vsync signals

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.