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

Commit 9f9fb51b authored by Matt Buckley's avatar Matt Buckley Committed by Android (Google) Code Review
Browse files

Merge "Cap the maximum message queue size for reportActualWorkDuration" into main

parents e10e2e3b d02939ed
Loading
Loading
Loading
Loading
+11 −0
Original line number Original line Diff line number Diff line
@@ -13,6 +13,17 @@ flag {
    }
    }
}
}


flag {
    name: "adpf_cap_max_batch_size"
    namespace: "game"
    description: "Caps the maximum batch size of work durations that can be sent in a report"
    is_fixed_read_only: true
    bug: "406377213"
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}

flag {
flag {
    name: "adpf_gpu_report_actual_work_duration"
    name: "adpf_gpu_report_actual_work_duration"
    is_exported: true
    is_exported: true
+1 −0
Original line number Original line Diff line number Diff line
@@ -432,6 +432,7 @@ LIBANDROID_PLATFORM {
    APerformanceHint_setUseNewLoadHintBehaviorForTesting;
    APerformanceHint_setUseNewLoadHintBehaviorForTesting;
    APerformanceHint_closeSessionFromJava;
    APerformanceHint_closeSessionFromJava;
    APerformanceHint_createSessionFromJava;
    APerformanceHint_createSessionFromJava;
    APerformanceHint_setReportBatchSizeCapForTesting;
    extern "C++" {
    extern "C++" {
        ASurfaceControl_registerSurfaceStatsListener*;
        ASurfaceControl_registerSurfaceStatsListener*;
        ASurfaceControl_unregisterSurfaceStatsListener*;
        ASurfaceControl_unregisterSurfaceStatsListener*;
+21 −3
Original line number Original line Diff line number Diff line
@@ -98,6 +98,9 @@ constexpr double kReplenishRate = kMaxLoadHintsPerInterval / static_cast<double>
constexpr int64_t kSendHintTimeout = kLoadHintInterval / kMaxLoadHintsPerInterval;
constexpr int64_t kSendHintTimeout = kLoadHintInterval / kMaxLoadHintsPerInterval;
bool kForceNewHintBehavior = false;
bool kForceNewHintBehavior = false;


std::optional<size_t> kReportBatchSizeCap =
        android::os::adpf_cap_max_batch_size() ? std::make_optional(50) : std::nullopt;

template <class T>
template <class T>
constexpr int32_t enum_size() {
constexpr int32_t enum_size() {
    return static_cast<int32_t>(*(ndk::enum_range<T>().end() - 1)) + 1;
    return static_cast<int32_t>(*(ndk::enum_range<T>().end() - 1)) + 1;
@@ -783,7 +786,16 @@ int APerformanceHintSession::reportActualWorkDurationInternal(AWorkDuration* wor
    }
    }


    traceActualDuration(actualTotalDurationNanos);
    traceActualDuration(actualTotalDurationNanos);
    mActualWorkDurations.push_back(std::move(*workDuration));
    mActualWorkDurations.push_back(*workDuration);

    if (kReportBatchSizeCap.has_value()) {
        // Check if the buffer is larger than the max size, and if it is pop the oldest elements
        const int overflow = mActualWorkDurations.size() - *kReportBatchSizeCap;
        if (overflow > 0) {
            mActualWorkDurations.erase(mActualWorkDurations.begin(),
                                       mActualWorkDurations.begin() + overflow);
        }
    }


    if (actualTotalDurationNanos >= mTargetDurationNanos) {
    if (actualTotalDurationNanos >= mTargetDurationNanos) {
        // Reset timestamps if we are equal or over the target.
        // Reset timestamps if we are equal or over the target.
@@ -872,12 +884,14 @@ void APerformanceHintManager::layersFromNativeSurfaces(ANativeWindow** windows,
        std::vector<ASurfaceControl*> controlVec(controls, controls + numSurfaceControls);
        std::vector<ASurfaceControl*> controlVec(controls, controls + numSurfaceControls);
        for (auto&& aSurfaceControl : controlVec) {
        for (auto&& aSurfaceControl : controlVec) {
            SurfaceControl* control = reinterpret_cast<SurfaceControl*>(aSurfaceControl);
            SurfaceControl* control = reinterpret_cast<SurfaceControl*>(aSurfaceControl);
            if (control != nullptr) {
                if (control->isValid()) {
                if (control->isValid()) {
                    out.push_back(control->getHandle());
                    out.push_back(control->getHandle());
                }
                }
            }
            }
        }
        }
    }
    }
}


// ===================================== FMQ wrapper implementation
// ===================================== FMQ wrapper implementation


@@ -1396,6 +1410,10 @@ void APerformanceHint_setUseNewLoadHintBehaviorForTesting(bool newBehavior) {
    kForceNewHintBehavior = newBehavior;
    kForceNewHintBehavior = newBehavior;
}
}


void APerformanceHint_setReportBatchSizeCapForTesting(int cap) {
    kReportBatchSizeCap = cap > 0 ? std::make_optional(cap) : std::nullopt;
}

void ASessionCreationConfig_setNativeSurfaces(ASessionCreationConfig* config,
void ASessionCreationConfig_setNativeSurfaces(ASessionCreationConfig* config,
                                              ANativeWindow** nativeWindows,
                                              ANativeWindow** nativeWindows,
                                              size_t nativeWindowsSize,
                                              size_t nativeWindowsSize,
+57 −0
Original line number Original line Diff line number Diff line
@@ -640,6 +640,63 @@ TEST_F(PerformanceHintTest, TestSupportObject) {
    EXPECT_EQ(expectedSupportInt, actualSupportInt);
    EXPECT_EQ(expectedSupportInt, actualSupportInt);
}
}


TEST_F(PerformanceHintTest, TestReportActualOverflow) {
    mClientData.preferredRateNanos = 10000000L;
    APerformanceHintManager* manager = createManager();

    auto&& config = configFromCreator({
            .tids = mTids,
            .targetDuration = 20,
    });

    auto&& session = createSession(manager);
    hal::WorkDuration duration{.timeStampNanos = 3,
                               .durationNanos = 10,
                               .workPeriodStartTimestampNanos = 1,
                               .cpuDurationNanos = 5,
                               .gpuDurationNanos = 5};

    EXPECT_CALL(*mMockSession, reportActualWorkDuration2(_)).Times(2);

    // Report a duration under the target, to signal the start of good behavior per the rate limiter
    APerformanceHint_reportActualWorkDuration2(session.get(),
                                               reinterpret_cast<AWorkDuration*>(&duration));

    // Sleep for longer than preferredUpdateRateNanos.
    usleep(12000);

    // Report a duration under the target, to signal continued good behavior per the rate limiter
    APerformanceHint_reportActualWorkDuration2(session.get(),
                                               reinterpret_cast<AWorkDuration*>(&duration));

    EXPECT_CALL(*mMockSession, reportActualWorkDuration2(SizeIs(Eq(30)))).Times(1);

    APerformanceHint_setReportBatchSizeCapForTesting(-1);
    for (int i = 0; i < 29; ++i) {
        APerformanceHint_reportActualWorkDuration2(session.get(),
                                                   reinterpret_cast<AWorkDuration*>(&duration));
    }

    // Sleep for longer than preferredUpdateRateNanos.
    usleep(12000);
    APerformanceHint_reportActualWorkDuration2(session.get(),
                                               reinterpret_cast<AWorkDuration*>(&duration));

    // Enforce that report spam gets capped
    EXPECT_CALL(*mMockSession, reportActualWorkDuration2(SizeIs(Eq(10)))).Times(1);

    APerformanceHint_setReportBatchSizeCapForTesting(10);
    for (int i = 0; i < 29; ++i) {
        APerformanceHint_reportActualWorkDuration2(session.get(),
                                                   reinterpret_cast<AWorkDuration*>(&duration));
    }

    // Sleep for longer than preferredUpdateRateNanos.
    usleep(12000);
    APerformanceHint_reportActualWorkDuration2(session.get(),
                                               reinterpret_cast<AWorkDuration*>(&duration));
}

TEST_F(PerformanceHintTest, TestCreatingAutoSession) {
TEST_F(PerformanceHintTest, TestCreatingAutoSession) {
    // Disable GPU capability for testing
    // Disable GPU capability for testing
    mClientData.supportInfo.sessionModes &= ~(1 << (int)hal::SessionMode::AUTO_GPU);
    mClientData.supportInfo.sessionModes &= ~(1 << (int)hal::SessionMode::AUTO_GPU);