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

Commit 40973b96 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 8736075 from d1424dea to tm-qpr1-release

Change-Id: I85816d0da725a5624544814bb006a2f982e219f9
parents 5d089931 d1424dea
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -261,7 +261,7 @@ bool Display::chooseCompositionStrategy(
    }

    if (isPowerHintSessionEnabled()) {
        mPowerAdvisor->setValidateTiming(mId, startTime, systemTime());
        mPowerAdvisor->setHwcValidateTiming(mId, startTime, systemTime());
        mPowerAdvisor->setRequiresClientComposition(mId, requiresClientComposition);
    }

@@ -371,7 +371,7 @@ compositionengine::Output::FrameFences Display::presentAndGetFrameFences() {
        if (!getCompositionEngine().getHwComposer().getComposer()->isSupported(
                    Hwc2::Composer::OptionalFeature::ExpectedPresentTime) &&
            getState().previousPresentFence->getSignalTime() != Fence::SIGNAL_TIME_PENDING) {
            mPowerAdvisor->setPresentDelayedTime(mId, getState().earliestPresentTime);
            mPowerAdvisor->setHwcPresentDelayedTime(mId, getState().earliestPresentTime);
        }
    }

@@ -379,7 +379,7 @@ compositionengine::Output::FrameFences Display::presentAndGetFrameFences() {
                                   getState().previousPresentFence);

    if (isPowerHintSessionEnabled()) {
        mPowerAdvisor->setPresentTiming(mId, startTime, systemTime());
        mPowerAdvisor->setHwcPresentTiming(mId, startTime, systemTime());
    }

    fences.presentFence = hwc.getPresentFence(*halDisplayIdOpt);
+3 −3
Original line number Diff line number Diff line
@@ -45,17 +45,17 @@ public:
    MOCK_METHOD(bool, startPowerHintSession, (const std::vector<int32_t>& threadIds), (override));
    MOCK_METHOD(void, setGpuFenceTime,
                (DisplayId displayId, std::unique_ptr<FenceTime>&& fenceTime), (override));
    MOCK_METHOD(void, setValidateTiming,
    MOCK_METHOD(void, setHwcValidateTiming,
                (DisplayId displayId, nsecs_t valiateStartTime, nsecs_t validateEndTime),
                (override));
    MOCK_METHOD(void, setPresentTiming,
    MOCK_METHOD(void, setHwcPresentTiming,
                (DisplayId displayId, nsecs_t presentStartTime, nsecs_t presentEndTime),
                (override));
    MOCK_METHOD(void, setSkippedValidate, (DisplayId displayId, bool skipped), (override));
    MOCK_METHOD(void, setRequiresClientComposition,
                (DisplayId displayId, bool requiresClientComposition), (override));
    MOCK_METHOD(void, setExpectedPresentTime, (nsecs_t expectedPresentTime), (override));
    MOCK_METHOD(void, setPresentDelayedTime,
    MOCK_METHOD(void, setHwcPresentDelayedTime,
                (DisplayId displayId,
                 std::chrono::steady_clock::time_point earliestFrameStartTime));
    MOCK_METHOD(void, setFrameDelay, (nsecs_t frameDelayDuration), (override));
+57 −50
Original line number Diff line number Diff line
@@ -287,18 +287,18 @@ void PowerAdvisor::setGpuFenceTime(DisplayId displayId, std::unique_ptr<FenceTim
    displayData.gpuStartTime = systemTime();
}

void PowerAdvisor::setValidateTiming(DisplayId displayId, nsecs_t validateStartTime,
void PowerAdvisor::setHwcValidateTiming(DisplayId displayId, nsecs_t validateStartTime,
                                        nsecs_t validateEndTime) {
    DisplayTimingData& displayData = mDisplayTimingData[displayId];
    displayData.validateStartTime = validateStartTime;
    displayData.validateEndTime = validateEndTime;
    displayData.hwcValidateStartTime = validateStartTime;
    displayData.hwcValidateEndTime = validateEndTime;
}

void PowerAdvisor::setPresentTiming(DisplayId displayId, nsecs_t presentStartTime,
void PowerAdvisor::setHwcPresentTiming(DisplayId displayId, nsecs_t presentStartTime,
                                       nsecs_t presentEndTime) {
    DisplayTimingData& displayData = mDisplayTimingData[displayId];
    displayData.presentStartTime = presentStartTime;
    displayData.presentEndTime = presentEndTime;
    displayData.hwcPresentStartTime = presentStartTime;
    displayData.hwcPresentEndTime = presentEndTime;
}

void PowerAdvisor::setSkippedValidate(DisplayId displayId, bool skipped) {
@@ -318,9 +318,9 @@ void PowerAdvisor::setFrameDelay(nsecs_t frameDelayDuration) {
    mFrameDelayDuration = frameDelayDuration;
}

void PowerAdvisor::setPresentDelayedTime(
void PowerAdvisor::setHwcPresentDelayedTime(
        DisplayId displayId, std::chrono::steady_clock::time_point earliestFrameStartTime) {
    mDisplayTimingData[displayId].presentDelayedTime =
    mDisplayTimingData[displayId].hwcPresentDelayedTime =
            (earliestFrameStartTime - std::chrono::steady_clock::now()).count() + systemTime();
}

@@ -331,10 +331,11 @@ void PowerAdvisor::setCommitStart(nsecs_t commitStartTime) {
void PowerAdvisor::setCompositeEnd(nsecs_t compositeEnd) {
    mLastCompositeEndTime = compositeEnd;
    // calculate the postcomp time here as well
    std::vector<DisplayId>&& displays = getOrderedDisplayIds(&DisplayTimingData::presentEndTime);
    std::vector<DisplayId>&& displays = getOrderedDisplayIds(&DisplayTimingData::hwcPresentEndTime);
    DisplayTimingData& timingData = mDisplayTimingData[displays.back()];
    mLastPostcompDuration = compositeEnd -
            (timingData.skippedValidate ? *timingData.validateEndTime : *timingData.presentEndTime);
            (timingData.skippedValidate ? *timingData.hwcValidateEndTime
                                        : *timingData.hwcPresentEndTime);
}

void PowerAdvisor::setDisplays(std::vector<DisplayId>& displayIds) {
@@ -390,7 +391,7 @@ std::optional<nsecs_t> PowerAdvisor::estimateWorkDuration(bool earlyHint) {
    // The timing info for the previously calculated display, if there was one
    std::optional<DisplayTimeline> previousDisplayReferenceTiming;
    std::vector<DisplayId>&& displayIds =
            getOrderedDisplayIds(&DisplayTimingData::presentStartTime);
            getOrderedDisplayIds(&DisplayTimingData::hwcPresentStartTime);
    DisplayTimeline referenceTiming, estimatedTiming;

    // Iterate over the displays in the same order they are presented
@@ -402,27 +403,26 @@ std::optional<nsecs_t> PowerAdvisor::estimateWorkDuration(bool earlyHint) {
        auto& displayData = mDisplayTimingData.at(displayId);
        referenceTiming = displayData.calculateDisplayTimeline(referenceFenceTime);

        // If this is the first display, add the pre-present time to the total
        // If this is the first display, include the duration before hwc present starts
        if (!previousDisplayReferenceTiming.has_value()) {
            estimatedEndTime += referenceTiming.prePresentTime - referenceFrameStartTime;
        } else { // Otherwise add last display's postprocessing time to the total
            estimatedEndTime += referenceTiming.prePresentTime -
                    previousDisplayReferenceTiming->postPresentTime;
            estimatedEndTime += referenceTiming.hwcPresentStartTime - referenceFrameStartTime;
        } else { // Otherwise add the time since last display's hwc present finished
            estimatedEndTime += referenceTiming.hwcPresentStartTime -
                    previousDisplayReferenceTiming->hwcPresentEndTime;
        }

        estimatedTiming = referenceTiming.estimateTimelineFromReference(mExpectedPresentTimes[-1],
                                                                        estimatedEndTime);
        // Update predicted present finish time with this display's present time
        estimatedEndTime = estimatedTiming.postPresentTime;
        estimatedEndTime = estimatedTiming.hwcPresentEndTime;

        // Track how long we spent waiting for the fence, can be excluded from the timing estimate
        idleDuration += estimatedTiming.probablyWaitsForFence
                ? mExpectedPresentTimes[-1] - estimatedTiming.preFenceWaitTime
        idleDuration += estimatedTiming.probablyWaitsForReleaseFence
                ? mExpectedPresentTimes[-1] - estimatedTiming.releaseFenceWaitStartTime
                : 0;

        // Track how long we spent waiting to present, can be excluded from the timing estimate
        idleDuration +=
                !earlyHint ? referenceTiming.presentStartTime - referenceTiming.prePresentTime : 0;
        idleDuration += earlyHint ? 0 : referenceTiming.hwcPresentDelayDuration;

        // Estimate the reference frame's gpu timing
        auto gpuTiming = displayData.estimateGpuTiming(previousValidGpuEndTime);
@@ -431,7 +431,7 @@ std::optional<nsecs_t> PowerAdvisor::estimateWorkDuration(bool earlyHint) {

            // Estimate the prediction frame's gpu end time from the reference frame
            estimatedGpuEndTime =
                    std::max(estimatedTiming.prePresentTime, estimatedGpuEndTime.value_or(0)) +
                    std::max(estimatedTiming.hwcPresentStartTime, estimatedGpuEndTime.value_or(0)) +
                    gpuTiming->duration;
        }
        previousDisplayReferenceTiming = referenceTiming;
@@ -470,48 +470,55 @@ nsecs_t PowerAdvisor::combineTimingEstimates(nsecs_t totalDuration, nsecs_t flin
PowerAdvisor::DisplayTimeline PowerAdvisor::DisplayTimeline::estimateTimelineFromReference(
        nsecs_t fenceTime, nsecs_t displayStartTime) {
    DisplayTimeline estimated;
    estimated.prePresentTime = displayStartTime;
    estimated.hwcPresentStartTime = displayStartTime;

    // We don't predict waiting for vsync alignment yet
    estimated.presentStartTime = estimated.prePresentTime;
    estimated.hwcPresentDelayDuration = 0;

    // For now just re-use last frame's post-present duration and assume it will not change much
    // How long we expect to run before we start waiting for the fence
    estimated.preFenceWaitTime = estimated.presentStartTime + (preFenceWaitTime - presentStartTime);
    estimated.probablyWaitsForFence = fenceTime > estimated.preFenceWaitTime;
    estimated.postPresentTime = postFenceDuration +
            (estimated.probablyWaitsForFence ? fenceTime : estimated.preFenceWaitTime);
    // If it's the early hint we exclude time we spent waiting for a vsync, otherwise don't
    estimated.releaseFenceWaitStartTime = estimated.hwcPresentStartTime +
            (releaseFenceWaitStartTime - (hwcPresentStartTime + hwcPresentDelayDuration));
    estimated.probablyWaitsForReleaseFence = fenceTime > estimated.releaseFenceWaitStartTime;
    estimated.hwcPresentEndTime = postReleaseFenceHwcPresentDuration +
            (estimated.probablyWaitsForReleaseFence ? fenceTime
                                                    : estimated.releaseFenceWaitStartTime);
    return estimated;
}

PowerAdvisor::DisplayTimeline PowerAdvisor::DisplayTimingData::calculateDisplayTimeline(
        nsecs_t fenceTime) {
    DisplayTimeline timeline;
    // How long between calling present from flinger and trying to wait on the fence in HWC
    const nsecs_t preFenceWaitDelay =
            (skippedValidate ? kPrefenceDelaySkippedValidate : kPrefenceDelayValidated).count();
    // How long between calling hwc present and trying to wait on the fence
    const nsecs_t fenceWaitStartDelay =
            (skippedValidate ? kFenceWaitStartDelaySkippedValidate : kFenceWaitStartDelayValidated)
                    .count();

    // Did our reference frame wait for an earliest present time before calling the HWC
    const bool waitedOnPresentTime = presentDelayedTime.has_value() &&
            *presentDelayedTime > *presentStartTime && *presentDelayedTime < *presentEndTime;
    // Did our reference frame wait for an appropriate vsync before calling into hwc
    const bool waitedOnHwcPresentTime = hwcPresentDelayedTime.has_value() &&
            *hwcPresentDelayedTime > *hwcPresentStartTime &&
            *hwcPresentDelayedTime < *hwcPresentEndTime;

    // Use validate start here if we skipped it because we did validate + present together
    timeline.prePresentTime = skippedValidate ? *validateStartTime : *presentStartTime;
    timeline.hwcPresentStartTime = skippedValidate ? *hwcValidateStartTime : *hwcPresentStartTime;

    // Use validate end here if we skipped it because we did validate + present together
    timeline.postPresentTime = skippedValidate ? *validateEndTime : *presentEndTime;

    // When we think we started waiting for the fence after calling into present
    // This is after any time spent waiting for the earliest present time
    timeline.presentStartTime =
            (waitedOnPresentTime ? *presentDelayedTime : timeline.prePresentTime);
    timeline.preFenceWaitTime = timeline.presentStartTime + preFenceWaitDelay;
    timeline.probablyWaitsForFence =
            fenceTime > timeline.preFenceWaitTime && fenceTime < timeline.postPresentTime;

    // How long we ran after we finished waiting for the fence but before present happened
    timeline.postFenceDuration = timeline.postPresentTime -
            (timeline.probablyWaitsForFence ? fenceTime : timeline.preFenceWaitTime);
    timeline.hwcPresentEndTime = skippedValidate ? *hwcValidateEndTime : *hwcPresentEndTime;

    // How long hwc present was delayed waiting for the next appropriate vsync
    timeline.hwcPresentDelayDuration =
            (waitedOnHwcPresentTime ? *hwcPresentDelayedTime - *hwcPresentStartTime : 0);
    // When we started waiting for the release fence after calling into hwc present
    timeline.releaseFenceWaitStartTime =
            timeline.hwcPresentStartTime + timeline.hwcPresentDelayDuration + fenceWaitStartDelay;
    timeline.probablyWaitsForReleaseFence = fenceTime > timeline.releaseFenceWaitStartTime &&
            fenceTime < timeline.hwcPresentEndTime;

    // How long we ran after we finished waiting for the fence but before hwc present finished
    timeline.postReleaseFenceHwcPresentDuration = timeline.hwcPresentEndTime -
            (timeline.probablyWaitsForReleaseFence ? fenceTime
                                                   : timeline.releaseFenceWaitStartTime);
    return timeline;
}

+32 −30
Original line number Diff line number Diff line
@@ -64,11 +64,11 @@ public:
    virtual bool startPowerHintSession(const std::vector<int32_t>& threadIds) = 0;
    // Provides PowerAdvisor with a copy of the gpu fence so it can determine the gpu end time
    virtual void setGpuFenceTime(DisplayId displayId, std::unique_ptr<FenceTime>&& fenceTime) = 0;
    // Reports the start and end times of a present call this frame for a given display
    virtual void setValidateTiming(DisplayId displayId, nsecs_t validateStartTime,
    // Reports the start and end times of a hwc validate call this frame for a given display
    virtual void setHwcValidateTiming(DisplayId displayId, nsecs_t validateStartTime,
                                      nsecs_t validateEndTime) = 0;
    // Reports the start and end times of a present call this frame for a given display
    virtual void setPresentTiming(DisplayId displayId, nsecs_t presentStartTime,
    // Reports the start and end times of a hwc present call this frame for a given display
    virtual void setHwcPresentTiming(DisplayId displayId, nsecs_t presentStartTime,
                                     nsecs_t presentEndTime) = 0;
    virtual void setExpectedPresentTime(nsecs_t expectedPresentTime) = 0;
    // Reports whether a display used client composition this frame
@@ -76,8 +76,8 @@ public:
                                              bool requiresClientComposition) = 0;
    // Reports whether a given display skipped validation this frame
    virtual void setSkippedValidate(DisplayId displayId, bool skipped) = 0;
    // Reports how much a given display delayed its present call this frame
    virtual void setPresentDelayedTime(
    // Reports when a hwc present is delayed, and the time that it will resume
    virtual void setHwcPresentDelayedTime(
            DisplayId displayId, std::chrono::steady_clock::time_point earliestFrameStartTime) = 0;
    // Reports the start delay for SurfaceFlinger this frame
    virtual void setFrameDelay(nsecs_t frameDelayDuration) = 0;
@@ -132,14 +132,14 @@ public:
    void enablePowerHint(bool enabled) override;
    bool startPowerHintSession(const std::vector<int32_t>& threadIds) override;
    void setGpuFenceTime(DisplayId displayId, std::unique_ptr<FenceTime>&& fenceTime);
    void setValidateTiming(DisplayId displayId, nsecs_t valiateStartTime,
    void setHwcValidateTiming(DisplayId displayId, nsecs_t valiateStartTime,
                              nsecs_t validateEndTime) override;
    void setPresentTiming(DisplayId displayId, nsecs_t presentStartTime,
    void setHwcPresentTiming(DisplayId displayId, nsecs_t presentStartTime,
                             nsecs_t presentEndTime) override;
    void setSkippedValidate(DisplayId displayId, bool skipped) override;
    void setRequiresClientComposition(DisplayId displayId, bool requiresClientComposition) override;
    void setExpectedPresentTime(nsecs_t expectedPresentTime) override;
    void setPresentDelayedTime(
    void setHwcPresentDelayedTime(
            DisplayId displayId,
            std::chrono::steady_clock::time_point earliestFrameStartTime) override;

@@ -166,17 +166,19 @@ private:

    // Higher-level timing data used for estimation
    struct DisplayTimeline {
        nsecs_t prePresentTime = -1;
        nsecs_t postPresentTime = -1;
        // Usually equals prePresentTime but can be delayed if we wait for the next valid vsync
        nsecs_t presentStartTime = -1;
        // When we think we started waiting for the fence after calling into present and
        // The start of hwc present, or the start of validate if it happened there instead
        nsecs_t hwcPresentStartTime = -1;
        // The end of hwc present or validate, whichever one actually presented
        nsecs_t hwcPresentEndTime = -1;
        // How long the actual hwc present was delayed after hwcPresentStartTime
        nsecs_t hwcPresentDelayDuration = 0;
        // When we think we started waiting for the release fence after calling into hwc present and
        // after potentially waiting for the earliest present time
        nsecs_t preFenceWaitTime = -1;
        // How long we ran after we finished waiting for the fence but before present happened
        nsecs_t postFenceDuration = 0;
        nsecs_t releaseFenceWaitStartTime = -1;
        // How long we ran after we finished waiting for the fence but before hwc present finished
        nsecs_t postReleaseFenceHwcPresentDuration = 0;
        // Are we likely to have waited for the present fence during composition
        bool probablyWaitsForFence = false;
        bool probablyWaitsForReleaseFence = false;
        // Estimate one frame's timeline from that of a previous frame
        DisplayTimeline estimateTimelineFromReference(nsecs_t fenceTime, nsecs_t displayStartTime);
    };
@@ -192,11 +194,11 @@ private:
        std::optional<nsecs_t> gpuStartTime;
        std::optional<nsecs_t> lastValidGpuEndTime;
        std::optional<nsecs_t> lastValidGpuStartTime;
        std::optional<nsecs_t> presentStartTime;
        std::optional<nsecs_t> presentEndTime;
        std::optional<nsecs_t> validateStartTime;
        std::optional<nsecs_t> validateEndTime;
        std::optional<nsecs_t> presentDelayedTime;
        std::optional<nsecs_t> hwcPresentStartTime;
        std::optional<nsecs_t> hwcPresentEndTime;
        std::optional<nsecs_t> hwcValidateStartTime;
        std::optional<nsecs_t> hwcValidateEndTime;
        std::optional<nsecs_t> hwcPresentDelayedTime;
        bool usedClientComposition = false;
        bool skippedValidate = false;
        // Calculate high-level timing milestones from more granular display timing data
@@ -258,13 +260,13 @@ private:

    // An adjustable safety margin which moves the "target" earlier to allow flinger to
    // go a bit over without dropping a frame, especially since we can't measure
    // the exact time HWC finishes composition so "actual" durations are measured
    // the exact time hwc finishes composition so "actual" durations are measured
    // from the end of present() instead, which is a bit later.
    static constexpr const std::chrono::nanoseconds kTargetSafetyMargin = 1ms;

    // How long we expect hwc to run after the present call until it waits for the fence
    static constexpr const std::chrono::nanoseconds kPrefenceDelayValidated = 150us;
    static constexpr const std::chrono::nanoseconds kPrefenceDelaySkippedValidate = 250us;
    static constexpr const std::chrono::nanoseconds kFenceWaitStartDelayValidated = 150us;
    static constexpr const std::chrono::nanoseconds kFenceWaitStartDelaySkippedValidate = 250us;
};

class AidlPowerHalWrapper : public PowerAdvisor::HalWrapper {
+3 −3
Original line number Diff line number Diff line
@@ -43,17 +43,17 @@ public:
    MOCK_METHOD(bool, startPowerHintSession, (const std::vector<int32_t>& threadIds), (override));
    MOCK_METHOD(void, setGpuFenceTime,
                (DisplayId displayId, std::unique_ptr<FenceTime>&& fenceTime), (override));
    MOCK_METHOD(void, setValidateTiming,
    MOCK_METHOD(void, setHwcValidateTiming,
                (DisplayId displayId, nsecs_t valiateStartTime, nsecs_t validateEndTime),
                (override));
    MOCK_METHOD(void, setPresentTiming,
    MOCK_METHOD(void, setHwcPresentTiming,
                (DisplayId displayId, nsecs_t presentStartTime, nsecs_t presentEndTime),
                (override));
    MOCK_METHOD(void, setSkippedValidate, (DisplayId displayId, bool skipped), (override));
    MOCK_METHOD(void, setRequiresClientComposition,
                (DisplayId displayId, bool requiresClientComposition), (override));
    MOCK_METHOD(void, setExpectedPresentTime, (nsecs_t expectedPresentTime), (override));
    MOCK_METHOD(void, setPresentDelayedTime,
    MOCK_METHOD(void, setHwcPresentDelayedTime,
                (DisplayId displayId,
                 std::chrono::steady_clock::time_point earliestFrameStartTime));
    MOCK_METHOD(void, setFrameDelay, (nsecs_t frameDelayDuration), (override));