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

Commit 8a40509f authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 11220357 from b507b71c to 24Q1-release

Change-Id: I3187bdc28d220b3de2813d978684f2a2aa593140
parents 8ed6f5a3 b507b71c
Loading
Loading
Loading
Loading
+1 −2
Original line number Original line Diff line number Diff line
@@ -148,8 +148,7 @@ public:
    MOCK_METHOD(const aidl::android::hardware::graphics::composer3::OverlayProperties&,
    MOCK_METHOD(const aidl::android::hardware::graphics::composer3::OverlayProperties&,
                getOverlaySupport, (), (const, override));
                getOverlaySupport, (), (const, override));
    MOCK_METHOD(status_t, setRefreshRateChangedCallbackDebugEnabled, (PhysicalDisplayId, bool));
    MOCK_METHOD(status_t, setRefreshRateChangedCallbackDebugEnabled, (PhysicalDisplayId, bool));
    MOCK_METHOD(status_t, notifyExpectedPresentIfRequired,
    MOCK_METHOD(status_t, notifyExpectedPresent, (PhysicalDisplayId, TimePoint, Fps));
                (PhysicalDisplayId, Period, TimePoint, Fps, std::optional<Period>));
};
};


} // namespace mock
} // namespace mock
+7 −106
Original line number Original line Diff line number Diff line
@@ -15,6 +15,7 @@
 */
 */


// TODO(b/129481165): remove the #pragma below and fix conversion issues
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#include <chrono>
#pragma clang diagnostic push
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
#pragma clang diagnostic ignored "-Wconversion"


@@ -78,59 +79,6 @@ using aidl::android::hardware::graphics::composer3::Capability;
using aidl::android::hardware::graphics::composer3::DisplayCapability;
using aidl::android::hardware::graphics::composer3::DisplayCapability;
namespace hal = android::hardware::graphics::composer::hal;
namespace hal = android::hardware::graphics::composer::hal;


namespace {
bool isFrameIntervalOnCadence(android::TimePoint expectedPresentTime,
                              android::TimePoint lastExpectedPresentTimestamp,
                              android::Fps lastFrameInterval, android::Period timeout,
                              android::Duration threshold) {
    if (lastFrameInterval.getPeriodNsecs() == 0) {
        return false;
    }

    const auto expectedPresentTimeDeltaNs =
            expectedPresentTime.ns() - lastExpectedPresentTimestamp.ns();

    if (expectedPresentTimeDeltaNs > timeout.ns()) {
        return false;
    }

    const auto expectedPresentPeriods = static_cast<nsecs_t>(
            std::round(static_cast<float>(expectedPresentTimeDeltaNs) /
                       static_cast<float>(lastFrameInterval.getPeriodNsecs())));
    const auto calculatedPeriodsOutNs = lastFrameInterval.getPeriodNsecs() * expectedPresentPeriods;
    const auto calculatedExpectedPresentTimeNs =
            lastExpectedPresentTimestamp.ns() + calculatedPeriodsOutNs;
    const auto presentTimeDelta =
            std::abs(expectedPresentTime.ns() - calculatedExpectedPresentTimeNs);
    return presentTimeDelta < threshold.ns();
}

bool isExpectedPresentWithinTimeout(android::TimePoint expectedPresentTime,
                                    android::TimePoint lastExpectedPresentTimestamp,
                                    std::optional<android::Period> timeoutOpt,
                                    android::Duration threshold) {
    if (!timeoutOpt) {
        // Always within timeout if timeoutOpt is absent and don't send hint
        // for the timeout
        return true;
    }

    if (timeoutOpt->ns() == 0) {
        // Always outside timeout if timeoutOpt is 0 and always send
        // the hint for the timeout.
        return false;
    }

    if (expectedPresentTime.ns() < lastExpectedPresentTimestamp.ns() + timeoutOpt->ns()) {
        return true;
    }

    // Check if within the threshold as it can be just outside the timeout
    return std::abs(expectedPresentTime.ns() -
                    (lastExpectedPresentTimestamp.ns() + timeoutOpt->ns())) < threshold.ns();
}
} // namespace

namespace android {
namespace android {


HWComposer::~HWComposer() = default;
HWComposer::~HWComposer() = default;
@@ -538,13 +486,6 @@ status_t HWComposer::getDeviceCompositionChanges(
    }();
    }();


    displayData.validateWasSkipped = false;
    displayData.validateWasSkipped = false;
    {
        std::scoped_lock lock{displayData.expectedPresentLock};
        if (expectedPresentTime > displayData.lastExpectedPresentTimestamp.ns()) {
            displayData.lastExpectedPresentTimestamp = TimePoint::fromNs(expectedPresentTime);
        }
    }

    ATRACE_FORMAT("NextFrameInterval %d_Hz", frameInterval.getIntValue());
    ATRACE_FORMAT("NextFrameInterval %d_Hz", frameInterval.getIntValue());
    if (canSkipValidate) {
    if (canSkipValidate) {
        sp<Fence> outPresentFence = Fence::NO_FENCE;
        sp<Fence> outPresentFence = Fence::NO_FENCE;
@@ -939,55 +880,15 @@ status_t HWComposer::setRefreshRateChangedCallbackDebugEnabled(PhysicalDisplayId
    return NO_ERROR;
    return NO_ERROR;
}
}


status_t HWComposer::notifyExpectedPresentIfRequired(PhysicalDisplayId displayId,
status_t HWComposer::notifyExpectedPresent(PhysicalDisplayId displayId,
                                                     Period vsyncPeriod,
                                           TimePoint expectedPresentTime, Fps frameInterval) {
                                                     TimePoint expectedPresentTime,
                                                     Fps frameInterval,
                                                     std::optional<Period> timeoutOpt) {
    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
    auto& displayData = mDisplayData[displayId];
    ATRACE_FORMAT("%s ExpectedPresentTime in %.2fms frameInterval %.2fms", __func__,
    if (!displayData.hwcDisplay) {
                  ticks<std::milli, float>(expectedPresentTime - TimePoint::now()),
        // Display setup has not completed yet
                  ticks<std::milli, float>(Duration::fromNs(frameInterval.getPeriodNsecs())));
        return BAD_INDEX;
    const auto error = mComposer->notifyExpectedPresent(mDisplayData[displayId].hwcDisplay->getId(),
    }
    {
        std::scoped_lock lock{displayData.expectedPresentLock};
        const auto lastExpectedPresentTimestamp = displayData.lastExpectedPresentTimestamp;
        const auto lastFrameInterval = displayData.lastFrameInterval;
        displayData.lastFrameInterval = frameInterval;
        const auto threshold = Duration::fromNs(vsyncPeriod.ns() / 2);

        const constexpr nsecs_t kOneSecondNs =
                std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count();
        const bool frameIntervalIsOnCadence =
                isFrameIntervalOnCadence(expectedPresentTime, lastExpectedPresentTimestamp,
                                         lastFrameInterval,
                                         Period::fromNs(timeoutOpt && timeoutOpt->ns() > 0
                                                                ? timeoutOpt->ns()
                                                                : kOneSecondNs),
                                         threshold);

        const bool expectedPresentWithinTimeout =
                isExpectedPresentWithinTimeout(expectedPresentTime, lastExpectedPresentTimestamp,
                                               timeoutOpt, threshold);

        using fps_approx_ops::operator!=;
        if (frameIntervalIsOnCadence && frameInterval != lastFrameInterval) {
            displayData.lastExpectedPresentTimestamp = expectedPresentTime;
        }

        if (expectedPresentWithinTimeout && frameIntervalIsOnCadence) {
            return NO_ERROR;
        }

        displayData.lastExpectedPresentTimestamp = expectedPresentTime;
    }
    ATRACE_FORMAT("%s ExpectedPresentTime %" PRId64 " frameIntervalNs %d", __func__,
                  expectedPresentTime, frameInterval.getPeriodNsecs());
    const auto error = mComposer->notifyExpectedPresent(displayData.hwcDisplay->getId(),
                                                        expectedPresentTime.ns(),
                                                        expectedPresentTime.ns(),
                                                        frameInterval.getPeriodNsecs());
                                                        frameInterval.getPeriodNsecs());

    if (error != hal::Error::NONE) {
    if (error != hal::Error::NONE) {
        ALOGE("Error in notifyExpectedPresent call %s", to_string(error).c_str());
        ALOGE("Error in notifyExpectedPresent call %s", to_string(error).c_str());
        return INVALID_OPERATION;
        return INVALID_OPERATION;
+4 −13
Original line number Original line Diff line number Diff line
@@ -303,10 +303,8 @@ public:
            aidl::android::hardware::graphics::common::HdrConversionStrategy,
            aidl::android::hardware::graphics::common::HdrConversionStrategy,
            aidl::android::hardware::graphics::common::Hdr*) = 0;
            aidl::android::hardware::graphics::common::Hdr*) = 0;
    virtual status_t setRefreshRateChangedCallbackDebugEnabled(PhysicalDisplayId, bool enabled) = 0;
    virtual status_t setRefreshRateChangedCallbackDebugEnabled(PhysicalDisplayId, bool enabled) = 0;
    virtual status_t notifyExpectedPresentIfRequired(PhysicalDisplayId, Period vsyncPeriod,
    virtual status_t notifyExpectedPresent(PhysicalDisplayId, TimePoint expectedPresentTime,
                                                     TimePoint expectedPresentTime,
                                           Fps frameInterval) = 0;
                                                     Fps frameInterval,
                                                     std::optional<Period> timeoutOpt) = 0;
};
};


static inline bool operator==(const android::HWComposer::DeviceRequestedChanges& lhs,
static inline bool operator==(const android::HWComposer::DeviceRequestedChanges& lhs,
@@ -466,9 +464,8 @@ public:
            aidl::android::hardware::graphics::common::HdrConversionStrategy,
            aidl::android::hardware::graphics::common::HdrConversionStrategy,
            aidl::android::hardware::graphics::common::Hdr*) override;
            aidl::android::hardware::graphics::common::Hdr*) override;
    status_t setRefreshRateChangedCallbackDebugEnabled(PhysicalDisplayId, bool enabled) override;
    status_t setRefreshRateChangedCallbackDebugEnabled(PhysicalDisplayId, bool enabled) override;
    status_t notifyExpectedPresentIfRequired(PhysicalDisplayId, Period vsyncPeriod,
    status_t notifyExpectedPresent(PhysicalDisplayId, TimePoint expectedPresentTime,
                                             TimePoint expectedPresentTime, Fps frameInterval,
                                   Fps frameInterval) override;
                                             std::optional<Period> timeoutOpt) override;


    // for debugging ----------------------------------------------------------
    // for debugging ----------------------------------------------------------
    void dump(std::string& out) const override;
    void dump(std::string& out) const override;
@@ -494,7 +491,6 @@ public:
private:
private:
    // For unit tests
    // For unit tests
    friend TestableSurfaceFlinger;
    friend TestableSurfaceFlinger;
    friend HWComposerTest;


    struct DisplayData {
    struct DisplayData {
        std::unique_ptr<HWC2::Display> hwcDisplay;
        std::unique_ptr<HWC2::Display> hwcDisplay;
@@ -502,11 +498,6 @@ private:
        sp<Fence> lastPresentFence = Fence::NO_FENCE; // signals when the last set op retires
        sp<Fence> lastPresentFence = Fence::NO_FENCE; // signals when the last set op retires
        nsecs_t lastPresentTimestamp = 0;
        nsecs_t lastPresentTimestamp = 0;


        std::mutex expectedPresentLock;
        TimePoint lastExpectedPresentTimestamp GUARDED_BY(expectedPresentLock) =
                TimePoint::fromNs(0);
        Fps lastFrameInterval GUARDED_BY(expectedPresentLock) = Fps::fromValue(0);

        std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
        std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;


        bool validateWasSkipped;
        bool validateWasSkipped;
+3 −1
Original line number Original line Diff line number Diff line
@@ -630,6 +630,7 @@ bool Scheduler::addResyncSample(PhysicalDisplayId id, nsecs_t timestamp,
}
}


void Scheduler::addPresentFence(PhysicalDisplayId id, std::shared_ptr<FenceTime> fence) {
void Scheduler::addPresentFence(PhysicalDisplayId id, std::shared_ptr<FenceTime> fence) {
    ATRACE_NAME(ftl::Concat(__func__, ' ', id.value).c_str());
    const auto scheduleOpt =
    const auto scheduleOpt =
            (ftl::FakeGuard(mDisplayLock), mDisplays.get(id)).and_then([](const Display& display) {
            (ftl::FakeGuard(mDisplayLock), mDisplays.get(id)).and_then([](const Display& display) {
                return display.powerMode == hal::PowerMode::OFF
                return display.powerMode == hal::PowerMode::OFF
@@ -640,7 +641,8 @@ void Scheduler::addPresentFence(PhysicalDisplayId id, std::shared_ptr<FenceTime>
    if (!scheduleOpt) return;
    if (!scheduleOpt) return;
    const auto& schedule = scheduleOpt->get();
    const auto& schedule = scheduleOpt->get();


    if (const bool needMoreSignals = schedule->getController().addPresentFence(std::move(fence))) {
    const bool needMoreSignals = schedule->getController().addPresentFence(std::move(fence));
    if (needMoreSignals) {
        schedule->enableHardwareVsync();
        schedule->enableHardwareVsync();
    } else {
    } else {
        constexpr bool kDisallow = false;
        constexpr bool kDisallow = false;
+8 −0
Original line number Original line Diff line number Diff line
@@ -88,6 +88,7 @@ bool VSyncPredictor::validate(nsecs_t timestamp) const {
            (timestamp - aValidTimestamp) % idealPeriod() * kMaxPercent / idealPeriod();
            (timestamp - aValidTimestamp) % idealPeriod() * kMaxPercent / idealPeriod();
    if (percent >= kOutlierTolerancePercent &&
    if (percent >= kOutlierTolerancePercent &&
        percent <= (kMaxPercent - kOutlierTolerancePercent)) {
        percent <= (kMaxPercent - kOutlierTolerancePercent)) {
        ATRACE_FORMAT_INSTANT("timestamp is not aligned with model");
        return false;
        return false;
    }
    }


@@ -98,6 +99,7 @@ bool VSyncPredictor::validate(nsecs_t timestamp) const {
    const auto distancePercent = std::abs(*iter - timestamp) * kMaxPercent / idealPeriod();
    const auto distancePercent = std::abs(*iter - timestamp) * kMaxPercent / idealPeriod();
    if (distancePercent < kOutlierTolerancePercent) {
    if (distancePercent < kOutlierTolerancePercent) {
        // duplicate timestamp
        // duplicate timestamp
        ATRACE_FORMAT_INSTANT("duplicate timestamp");
        return false;
        return false;
    }
    }
    return true;
    return true;
@@ -126,6 +128,8 @@ Period VSyncPredictor::minFramePeriodLocked() const {
}
}


bool VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) {
bool VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) {
    ATRACE_CALL();

    std::lock_guard lock(mMutex);
    std::lock_guard lock(mMutex);


    if (!validate(timestamp)) {
    if (!validate(timestamp)) {
@@ -144,6 +148,8 @@ bool VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) {
        } else {
        } else {
            mKnownTimestamp = timestamp;
            mKnownTimestamp = timestamp;
        }
        }
        ATRACE_FORMAT_INSTANT("timestamp rejected. mKnownTimestamp was %.2fms ago",
            (systemTime() - *mKnownTimestamp) / 1e6f);
        return false;
        return false;
    }
    }


@@ -515,6 +521,8 @@ VSyncPredictor::Model VSyncPredictor::getVSyncPredictionModelLocked() const {
}
}


void VSyncPredictor::clearTimestamps() {
void VSyncPredictor::clearTimestamps() {
    ATRACE_CALL();

    if (!mTimestamps.empty()) {
    if (!mTimestamps.empty()) {
        auto const maxRb = *std::max_element(mTimestamps.begin(), mTimestamps.end());
        auto const maxRb = *std::max_element(mTimestamps.begin(), mTimestamps.end());
        if (mKnownTimestamp) {
        if (mKnownTimestamp) {
Loading