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

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

Merge "SurfaceFlinger: support negative phase offset" into qt-dev

parents 8b30c364 be0f948b
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -65,6 +65,13 @@ PhaseOffsets::PhaseOffsets() {
    property_get("debug.sf.high_fps_late_sf_phase_offset_ns", value, "1000000");
    const int highFpsLateSfOffsetNs = atoi(value);

    // Below defines the threshold when an offset is considered to be negative, i.e. targeting
    // for the N+2 vsync instead of N+1. This means that:
    // For offset < threshold, SF wake up (vsync_duration - offset) before HW vsync.
    // For offset >= threshold, SF wake up (2 * vsync_duration - offset) before HW vsync.
    property_get("debug.sf.phase_offset_threshold_for_next_vsync_ns", value, "-1");
    const int phaseOffsetThresholdForNextVsyncNs = atoi(value);

    mDefaultRefreshRateOffsets.early = {earlySfOffsetNs != -1 ? earlySfOffsetNs
                                                              : sfVsyncPhaseOffsetNs,
                                        earlyAppOffsetNs != -1 ? earlyAppOffsetNs
@@ -84,6 +91,10 @@ PhaseOffsets::PhaseOffsets() {
                                       highFpsEarlyGlAppOffsetNs != -1 ? highFpsEarlyGlAppOffsetNs
                                                                       : highFpsLateAppOffsetNs};
    mHighRefreshRateOffsets.late = {highFpsLateSfOffsetNs, highFpsLateAppOffsetNs};

    mOffsetThresholdForNextVsync = phaseOffsetThresholdForNextVsyncNs != -1
            ? phaseOffsetThresholdForNextVsyncNs
            : std::numeric_limits<nsecs_t>::max();
}

PhaseOffsets::Offsets PhaseOffsets::getOffsetsForRefreshRate(
+4 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ public:
            RefreshRateConfigs::RefreshRateType refreshRateType) const = 0;
    virtual Offsets getCurrentOffsets() const = 0;
    virtual void setRefreshRateType(RefreshRateConfigs::RefreshRateType refreshRateType) = 0;
    virtual nsecs_t getOffsetThresholdForNextVsync() const = 0;
    virtual void dump(std::string& result) const = 0;
};

@@ -72,6 +73,8 @@ public:
        mRefreshRateType = refreshRateType;
    }

    nsecs_t getOffsetThresholdForNextVsync() const override { return mOffsetThresholdForNextVsync; }

    // Returns current offsets in human friendly format.
    void dump(std::string& result) const override;

@@ -84,6 +87,7 @@ private:

    Offsets mDefaultRefreshRateOffsets;
    Offsets mHighRefreshRateOffsets;
    nsecs_t mOffsetThresholdForNextVsync;
};
} // namespace impl

+13 −13
Original line number Diff line number Diff line
@@ -139,6 +139,19 @@ public:
        }
    }

    Offsets getOffsets() {
        // Early offsets are used if we're in the middle of a refresh rate
        // change, or if we recently begin a transaction.
        if (mTransactionStart == Scheduler::TransactionStart::EARLY ||
            mRemainingEarlyFrameCount > 0 || mRefreshRateChangePending) {
            return mEarlyOffsets;
        } else if (mLastFrameUsedRenderEngine) {
            return mEarlyGlOffsets;
        } else {
            return mLateOffsets;
        }
    }

private:
    void updateOffsets() {
        const Offsets desired = getOffsets();
@@ -167,19 +180,6 @@ private:
        }
    }

    Offsets getOffsets() {
        // Early offsets are used if we're in the middle of a refresh rate
        // change, or if we recently begin a transaction.
        if (mTransactionStart == Scheduler::TransactionStart::EARLY ||
            mRemainingEarlyFrameCount > 0 || mRefreshRateChangePending) {
            return mEarlyOffsets;
        } else if (mLastFrameUsedRenderEngine) {
            return mEarlyGlOffsets;
        } else {
            return mLateOffsets;
        }
    }

    Offsets mLateOffsets;
    Offsets mEarlyOffsets;
    Offsets mEarlyGlOffsets;
+20 −8
Original line number Diff line number Diff line
@@ -977,8 +977,7 @@ void SurfaceFlinger::setActiveConfigInternal() {
bool SurfaceFlinger::performSetActiveConfig() {
    ATRACE_CALL();
    if (mCheckPendingFence) {
        if (mPreviousPresentFence != Fence::NO_FENCE &&
            (mPreviousPresentFence->getStatus() == Fence::Status::Unsignaled)) {
        if (previousFrameMissed()) {
            // fence has not signaled yet. wait for the next invalidate
            mEventQueue->invalidateForHWC();
            return true;
@@ -1587,12 +1586,23 @@ void SurfaceFlinger::updateVrFlinger() {
    setTransactionFlags(eDisplayTransactionNeeded);
}

bool SurfaceFlinger::previousFrameMissed() NO_THREAD_SAFETY_ANALYSIS {
    // We are storing the last 2 present fences. If sf's phase offset is to be
    // woken up before the actual vsync but targeting the next vsync, we need to check
    // fence N-2
    const sp<Fence>& fence =
            mVsyncModulator.getOffsets().sf < mPhaseOffsets->getOffsetThresholdForNextVsync()
            ? mPreviousPresentFences[0]
            : mPreviousPresentFences[1];

    return fence != Fence::NO_FENCE && (fence->getStatus() == Fence::Status::Unsignaled);
}

void SurfaceFlinger::onMessageReceived(int32_t what) NO_THREAD_SAFETY_ANALYSIS {
    ATRACE_CALL();
    switch (what) {
        case MessageQueue::INVALIDATE: {
            bool frameMissed = mPreviousPresentFence != Fence::NO_FENCE &&
                    (mPreviousPresentFence->getStatus() == Fence::Status::Unsignaled);
            bool frameMissed = previousFrameMissed();
            bool hwcFrameMissed = mHadDeviceComposition && frameMissed;
            bool gpuFrameMissed = mHadClientComposition && frameMissed;
            ATRACE_INT("FrameMissed", static_cast<int>(frameMissed));
@@ -1982,9 +1992,11 @@ void SurfaceFlinger::postComposition()
    }

    getBE().mDisplayTimeline.updateSignalTimes();
    mPreviousPresentFence = displayDevice ? getHwComposer().getPresentFence(*displayDevice->getId())
    mPreviousPresentFences[1] = mPreviousPresentFences[0];
    mPreviousPresentFences[0] = displayDevice
            ? getHwComposer().getPresentFence(*displayDevice->getId())
            : Fence::NO_FENCE;
    auto presentFenceTime = std::make_shared<FenceTime>(mPreviousPresentFence);
    auto presentFenceTime = std::make_shared<FenceTime>(mPreviousPresentFences[0]);
    getBE().mDisplayTimeline.push(presentFenceTime);

    DisplayStatInfo stats;
@@ -2075,7 +2087,7 @@ void SurfaceFlinger::postComposition()
        }
    }

    mTransactionCompletedThread.addPresentFence(mPreviousPresentFence);
    mTransactionCompletedThread.addPresentFence(mPreviousPresentFences[0]);
    mTransactionCompletedThread.sendCallbacks();

    if (mLumaSampling && mRegionSamplingThread) {
+3 −1
Original line number Diff line number Diff line
@@ -824,6 +824,8 @@ private:
        return hwcDisplayId ? getHwComposer().toPhysicalDisplayId(*hwcDisplayId) : std::nullopt;
    }

    bool previousFrameMissed();

    /*
     * Debugging & dumpsys
     */
@@ -956,7 +958,7 @@ private:
    std::vector<sp<Layer>> mLayersWithQueuedFrames;
    // Tracks layers that need to update a display's dirty region.
    std::vector<sp<Layer>> mLayersPendingRefresh;
    sp<Fence> mPreviousPresentFence = Fence::NO_FENCE;
    std::array<sp<Fence>, 2> mPreviousPresentFences = {Fence::NO_FENCE, Fence::NO_FENCE};
    // True if in the previous frame at least one layer was composed via the GPU.
    bool mHadClientComposition = false;
    // True if in the previous frame at least one layer was composed via HW Composer.
Loading