Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3d6cc993 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add pending period to DispSync." into qt-dev

parents be35e6e9 754c98a5
Loading
Loading
Loading
Loading
+30 −12
Original line number Diff line number Diff line
@@ -210,8 +210,7 @@ public:
            const nsecs_t baseTime = now - mReferenceTime;
            const nsecs_t numPeriodsSinceReference = baseTime / mPeriod;
            const nsecs_t predictedReference = mReferenceTime + numPeriodsSinceReference * mPeriod;
            const nsecs_t phaseCorrection = mPhase + listener.mPhase;
            listener.mLastEventTime = predictedReference + phaseCorrection;
            listener.mLastEventTime = predictedReference + mPhase + listener.mPhase;
            // If we're very close in time to the predicted last event time,
            // then we need to back up the last event time so that we can
            // attempt to fire an event immediately.
@@ -279,7 +278,6 @@ public:
                return NO_ERROR;
            }
        }

        return BAD_VALUE;
    }

@@ -525,21 +523,40 @@ void DispSync::beginResync() {
    mNumResyncSamples = 0;
}

bool DispSync::addResyncSample(nsecs_t timestamp) {
bool DispSync::addResyncSample(nsecs_t timestamp, bool* periodChanged) {
    Mutex::Autolock lock(mMutex);

    ALOGV("[%s] addResyncSample(%" PRId64 ")", mName, ns2us(timestamp));

    size_t idx = (mFirstResyncSample + mNumResyncSamples) % MAX_RESYNC_SAMPLES;
    *periodChanged = false;
    const size_t idx = (mFirstResyncSample + mNumResyncSamples) % MAX_RESYNC_SAMPLES;
    mResyncSamples[idx] = timestamp;
    if (mNumResyncSamples == 0) {
        mPhase = 0;
        mReferenceTime = timestamp;
        ALOGV("[%s] First resync sample: mPeriod = %" PRId64 ", mPhase = 0, "
              "mReferenceTime = %" PRId64,
              mName, ns2us(mPeriod), ns2us(mReferenceTime));
        mThread->updateModel(mPeriod, mPhase, mReferenceTime);
              mName, ns2us(mPeriod), ns2us(timestamp));
    } else if (mPendingPeriod > 0) {
        // mNumResyncSamples > 0, so priorIdx won't overflow
        const size_t priorIdx = (mFirstResyncSample + mNumResyncSamples - 1) % MAX_RESYNC_SAMPLES;
        const nsecs_t lastTimestamp = mResyncSamples[priorIdx];

        const nsecs_t observedVsync = std::abs(timestamp - lastTimestamp);
        if (std::abs(observedVsync - mPendingPeriod) < std::abs(observedVsync - mPeriod)) {
            // Observed vsync is closer to the pending period, so reset the
            // model and flush the pending period.
            resetLocked();
            mPeriod = mPendingPeriod;
            mPendingPeriod = 0;
            if (mTraceDetailedInfo) {
                ATRACE_INT("DispSync:PendingPeriod", mPendingPeriod);
            }
            *periodChanged = true;
        }
    }
    // Always update the reference time with the most recent timestamp.
    mReferenceTime = timestamp;
    mThread->updateModel(mPeriod, mPhase, mReferenceTime);

    if (mNumResyncSamples < MAX_RESYNC_SAMPLES) {
        mNumResyncSamples++;
@@ -562,7 +579,7 @@ bool DispSync::addResyncSample(nsecs_t timestamp) {

    // Check against kErrorThreshold / 2 to add some hysteresis before having to
    // resync again
    bool modelLocked = mModelUpdated && mError < (kErrorThreshold / 2);
    bool modelLocked = mModelUpdated && mError < (kErrorThreshold / 2) && mPendingPeriod == 0;
    ALOGV("[%s] addResyncSample returning %s", mName, modelLocked ? "locked" : "unlocked");
    return !modelLocked;
}
@@ -594,9 +611,10 @@ status_t DispSync::changePhaseOffset(Callback* callback, nsecs_t phase) {

void DispSync::setPeriod(nsecs_t period) {
    Mutex::Autolock lock(mMutex);
    mPeriod = period;
    mPhase = 0;
    mThread->updateModel(mPeriod, mPhase, mReferenceTime);
    if (mTraceDetailedInfo) {
        ATRACE_INT("DispSync:PendingPeriod", period);
    }
    mPendingPeriod = period;
}

nsecs_t DispSync::getPeriod() {
+14 −2
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ public:
    virtual void reset() = 0;
    virtual bool addPresentFence(const std::shared_ptr<FenceTime>&) = 0;
    virtual void beginResync() = 0;
    virtual bool addResyncSample(nsecs_t timestamp) = 0;
    virtual bool addResyncSample(nsecs_t timestamp, bool* periodChanged) = 0;
    virtual void endResync() = 0;
    virtual void setPeriod(nsecs_t period) = 0;
    virtual nsecs_t getPeriod() = 0;
@@ -119,7 +119,13 @@ public:
    // addPresentFence returns true indicating that the model has drifted away
    // from the hardware vsync events.
    void beginResync() override;
    bool addResyncSample(nsecs_t timestamp) override;
    // Adds a vsync sample to the dispsync model. The timestamp is the time
    // of the vsync event that fired. periodChanged will return true if the
    // vsync period was detected to have changed to mPendingPeriod.
    //
    // This method will return true if more vsync samples are needed to lock
    // down the DispSync model, and false otherwise.
    bool addResyncSample(nsecs_t timestamp, bool* periodChanged) override;
    void endResync() override;

    // The setPeriod method sets the vsync event model's period to a specific
@@ -199,6 +205,12 @@ private:
    // nanoseconds.
    nsecs_t mPeriod;

    // mPendingPeriod is the proposed period change in nanoseconds.
    // If mPendingPeriod differs from mPeriod and is nonzero, it will
    // be flushed to mPeriod when we detect that the hardware switched
    // vsync frequency.
    nsecs_t mPendingPeriod = 0;

    // mPhase is the phase offset of the modeled vsync events.  It is the
    // number of nanoseconds from time 0 to the first vsync event.
    nsecs_t mPhase;
+2 −2
Original line number Diff line number Diff line
@@ -68,8 +68,8 @@ public:
    void dump(std::string& result) const override;

private:
    Offsets getmDefaultRefreshRateOffsets() { return mDefaultRefreshRateOffsets; }
    Offsets getmHighRefreshRateOffsets() { return mHighRefreshRateOffsets; }
    Offsets getDefaultRefreshRateOffsets() { return mDefaultRefreshRateOffsets; }
    Offsets getHighRefreshRateOffsets() { return mHighRefreshRateOffsets; }

    std::atomic<RefreshRateConfigs::RefreshRateType> mRefreshRateType =
            RefreshRateConfigs::RefreshRateType::DEFAULT;
+3 −3
Original line number Diff line number Diff line
@@ -249,7 +249,6 @@ void Scheduler::setRefreshSkipCount(int count) {

void Scheduler::setVsyncPeriod(const nsecs_t period) {
    std::lock_guard<std::mutex> lock(mHWVsyncLock);
    mPrimaryDispSync->reset();
    mPrimaryDispSync->setPeriod(period);

    if (!mPrimaryHWVsyncEnabled) {
@@ -259,12 +258,13 @@ void Scheduler::setVsyncPeriod(const nsecs_t period) {
    }
}

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

+3 −1
Original line number Diff line number Diff line
@@ -139,7 +139,9 @@ public:
    // Creates a callback for resyncing.
    ResyncCallback makeResyncCallback(GetVsyncPeriod&& getVsyncPeriod);
    void setRefreshSkipCount(int count);
    void addResyncSample(const nsecs_t timestamp);
    // Passes a vsync sample to DispSync. periodChange will be true if DipSync
    // detected that the vsync period changed, and false otherwise.
    void addResyncSample(const nsecs_t timestamp, bool* periodChanged);
    void addPresentFence(const std::shared_ptr<FenceTime>& fenceTime);
    void setIgnorePresentFences(bool ignore);
    nsecs_t expectedPresentTime();
Loading