[surfaceflinger] Vsync流程

Android11 记录Vsync的流程 只截取了部分代码

SurfaceFlinger.cpp

void SurfaceFlinger::onVsyncReceived(int32_t sequenceId, hal::HWDisplayId hwcDisplayId,
                                     int64_t timestamp,
                                     std::optional<hal::VsyncPeriodNanos> vsyncPeriod) {
    
    
    ...
    ...
    bool periodFlushed = false;
    mScheduler->addResyncSample(timestamp, vsyncPeriod, &periodFlushed); 
    ...
    ...
}

Schedule.cpp

void Scheduler::addResyncSample(nsecs_t timestamp, std::optional<nsecs_t> hwcVsyncPeriod,
                                bool* periodFlushed) {
    
    
    ...
    {
    
     // Scope for the lock
        std::lock_guard<std::mutex> lock(mHWVsyncLock);
        if (mPrimaryHWVsyncEnabled) {
    
    
            needsHwVsync =
                    mPrimaryDispSync->addResyncSample(timestamp, hwcVsyncPeriod, periodFlushed);
        }
    }
    ...
}

DispSync.cpp

bool DispSync::addResyncSample(nsecs_t timestamp, std::optional<nsecs_t> /*hwcVsyncPeriod*/,
                               bool* periodFlushed) {
    
    
    ...
    ...
    // Always update the reference time with the most recent timestamp.
    mReferenceTime = timestamp;
    mThread->updateModel(mPeriod, mPhase, mReferenceTime);

    if (mNumResyncSamples < MAX_RESYNC_SAMPLES) {
    
    
        mNumResyncSamples++;
    } else {
    
    
        mFirstResyncSample = (mFirstResyncSample + 1) % MAX_RESYNC_SAMPLES;
    }

    updateModelLocked();
    ...
    ...
}

DispSync.cpp

DispSyncThread::

 void updateModel(nsecs_t period, nsecs_t phase, nsecs_t referenceTime) {
    
    
        ...
        ...
        // 给等待中的线程发送信号
        mCond.signal();  // -> threadloop()
    }

一直在循环的 threadloop 收到信号

virtual bool threadLoop() {
    
    
        status_t err;
        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);

        while (true) {
    
    
            std::vector<CallbackInvocation> callbackInvocations;

            nsecs_t targetTime = 0;

            {
    
     // Scope for lock
                Mutex::Autolock lock(mMutex);
                ...
                ...
               // 取出eventListener 放入 callbackInvocations,等待后面的调用
                callbackInvocations =
                        gatherCallbackInvocationsLocked(now, computeNextRefreshLocked(0, now));
            }

            if (callbackInvocations.size() > 0) {
    
    
                fireCallbackInvocations(callbackInvocations);
            }
        }

        return false;
    }
std::vector<CallbackInvocation> gatherCallbackInvocationsLocked(nsecs_t now,
                                                                    nsecs_t expectedVSyncTime) {
    
    
        if (mTraceDetailedInfo) ATRACE_CALL();
        ALOGV("[%s] gatherCallbackInvocationsLocked @ %" PRId64, mName, ns2us(now));

        std::vector<CallbackInvocation> callbackInvocations;
        nsecs_t onePeriodAgo = now - mPeriod;

        for (auto& eventListener : mEventListeners) {
    
    
            nsecs_t t = computeListenerNextEventTimeLocked(eventListener, onePeriodAgo);

            if (t < now) {
    
    
                if (isCloseToPeriod(now - eventListener.mLastCallbackTime)) {
    
    
                    eventListener.mLastEventTime = t;
                    ALOGV("[%s] [%s] Skipping event due to model error", mName,
                          eventListener.mName);
                    continue;
                }

                CallbackInvocation ci;
                ci.mCallback = eventListener.mCallback;
                ci.mEventTime = t;
                ci.mExpectedVSyncTime = expectedVSyncTime;
                if (eventListener.mPhase < 0) {
    
    
                    ci.mExpectedVSyncTime += mPeriod;
                }
                ALOGV("[%s] [%s] Preparing to fire, latency: %" PRId64, mName, eventListener.mName,
                      t - eventListener.mLastEventTime);
                callbackInvocations.push_back(ci);
                eventListener.mLastEventTime = t;
                eventListener.mLastCallbackTime = now;
            }
        }
void fireCallbackInvocations(const std::vector<CallbackInvocation>& callbacks) {
    
    
        if (mTraceDetailedInfo) ATRACE_CALL();
        for (size_t i = 0; i < callbacks.size(); i++) {
    
    
            callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime,
                                                    callbacks[i].mExpectedVSyncTime);
        }
    }

DispSyncSource.cpp

void DispSyncSource::onDispSyncEvent(nsecs_t when, nsecs_t expectedVSyncTimestamp) {
    
    
   ...
   ...
    if (callback != nullptr) {
    
    
        callback->onVSyncEvent(when, expectedVSyncTimestamp);
    }
}

EventThread.cpp

notify_all() 告知等待的进程

void EventThread::onVSyncEvent(nsecs_t timestamp, nsecs_t expectedVSyncTimestamp) {
    
    
    std::lock_guard<std::mutex> lock(mMutex);

    LOG_FATAL_IF(!mVSyncState);
    mPendingEvents.push_back(makeVSync(mVSyncState->displayId, timestamp, ++mVSyncState->count,
                                       expectedVSyncTimestamp));
    mCondition.notify_all();
}

EventThread.cpp

EventThreadConnection::

status_t EventThreadConnection::postEvent(const DisplayEventReceiver::Event& event) {
    
    
    ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
    return size < 0 ? status_t(size) : status_t(NO_ERROR);
}

frameworks/native/libs/gui/DisplayEventReceiver.cpp

ssize_t DisplayEventReceiver::sendEvents(gui::BitTube* dataChannel,
        Event const* events, size_t count)
{
    
    
    return gui::BitTube::sendObjects(dataChannel, events, count);
}

frameworks/native/libs/gui/BitTube.cpp

ssize_t BitTube::sendObjects(BitTube* tube, void const* events, size_t count, size_t objSize) {
    
    
    const char* vaddr = reinterpret_cast<const char*>(events);
    ssize_t size = tube->write(vaddr, count * objSize);

    // should never happen because of SOCK_SEQPACKET
    LOG_ALWAYS_FATAL_IF((size >= 0) && (size % static_cast<ssize_t>(objSize)),
                        "BitTube::sendObjects(count=%zu, size=%zu), res=%zd (partial events were "
                        "sent!)",
                        count, objSize, size);

    // ALOGE_IF(size<0, "error %d sending %d events", size, count);
    return size < 0 ? size : size / static_cast<ssize_t>(objSize);

最后这个消息会由MessageQueue获取进行绘制,绘制完成由surfaceflinger进行显示

猜你喜欢

转载自blog.csdn.net/weixin_45460140/article/details/119758017