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

Commit 1bc43ee3 authored by Marin Shalamanov's avatar Marin Shalamanov
Browse files

Move LayerHistoryV2 to LayerHistory

The old class LayerHistory (content detection v1) no longer exists
so LayerHisotryV2 can take its place.

Bug: 174120566
Test: presubmit
Change-Id: I84f33255b04ab082bbc5ae6e3ae4d7a793bfcd14
parent 27fa3ded
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -155,8 +155,8 @@ filegroup {
        "Scheduler/DispSyncSource.cpp",
        "Scheduler/EventThread.cpp",
        "Scheduler/OneShotTimer.cpp",
        "Scheduler/LayerHistoryV2.cpp",
        "Scheduler/LayerInfoV2.cpp",
        "Scheduler/LayerHistory.cpp",
        "Scheduler/LayerInfo.cpp",
        "Scheduler/MessageQueue.cpp",
        "Scheduler/RefreshRateConfigs.cpp",
        "Scheduler/Scheduler.cpp",
+20 −20
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@
 */

#undef LOG_TAG
#define LOG_TAG "LayerHistoryV2"
#define LOG_TAG "LayerHistory"
#define ATRACE_TAG ATRACE_TAG_GRAPHICS

#include "LayerHistory.h"
@@ -32,14 +32,14 @@
#include <utility>

#include "../Layer.h"
#include "LayerInfoV2.h"
#include "LayerInfo.h"
#include "SchedulerUtils.h"

namespace android::scheduler::impl {
namespace android::scheduler {

namespace {

bool isLayerActive(const Layer& layer, const LayerInfoV2& info, nsecs_t threshold) {
bool isLayerActive(const Layer& layer, const LayerInfo& info, nsecs_t threshold) {
    // Layers with an explicit vote are always kept active
    if (layer.getFrameRateForLayerTree().rate > 0) {
        return true;
@@ -58,7 +58,7 @@ bool useFrameRatePriority() {
    return atoi(value);
}

void trace(const wp<Layer>& weak, const LayerInfoV2& info, LayerHistory::LayerVoteType type,
void trace(const wp<Layer>& weak, const LayerInfo& info, LayerHistory::LayerVoteType type,
           int fps) {
    const auto layer = weak.promote();
    if (!layer) return;
@@ -78,23 +78,23 @@ void trace(const wp<Layer>& weak, const LayerInfoV2& info, LayerHistory::LayerVo
}
} // namespace

LayerHistoryV2::LayerHistoryV2(const scheduler::RefreshRateConfigs& refreshRateConfigs)
LayerHistory::LayerHistory(const RefreshRateConfigs& refreshRateConfigs)
      : mTraceEnabled(traceEnabled()), mUseFrameRatePriority(useFrameRatePriority()) {
    LayerInfoV2::setTraceEnabled(mTraceEnabled);
    LayerInfoV2::setRefreshRateConfigs(refreshRateConfigs);
    LayerInfo::setTraceEnabled(mTraceEnabled);
    LayerInfo::setRefreshRateConfigs(refreshRateConfigs);
}

LayerHistoryV2::~LayerHistoryV2() = default;
LayerHistory::~LayerHistory() = default;

void LayerHistoryV2::registerLayer(Layer* layer, float /*lowRefreshRate*/, float highRefreshRate,
void LayerHistory::registerLayer(Layer* layer, float /*lowRefreshRate*/, float highRefreshRate,
                                 LayerVoteType type) {
    const nsecs_t highRefreshRatePeriod = static_cast<nsecs_t>(1e9f / highRefreshRate);
    auto info = std::make_unique<LayerInfoV2>(layer->getName(), highRefreshRatePeriod, type);
    auto info = std::make_unique<LayerInfo>(layer->getName(), highRefreshRatePeriod, type);
    std::lock_guard lock(mLock);
    mLayerInfos.emplace_back(layer, std::move(info));
}

void LayerHistoryV2::record(Layer* layer, nsecs_t presentTime, nsecs_t now,
void LayerHistory::record(Layer* layer, nsecs_t presentTime, nsecs_t now,
                          LayerUpdateType updateType) {
    std::lock_guard lock(mLock);

@@ -112,7 +112,7 @@ void LayerHistoryV2::record(Layer* layer, nsecs_t presentTime, nsecs_t now,
    }
}

LayerHistoryV2::Summary LayerHistoryV2::summarize(nsecs_t now) {
LayerHistory::Summary LayerHistory::summarize(nsecs_t now) {
    LayerHistory::Summary summary;

    std::lock_guard lock(mLock);
@@ -155,7 +155,7 @@ LayerHistoryV2::Summary LayerHistoryV2::summarize(nsecs_t now) {
    return summary;
}

void LayerHistoryV2::partitionLayers(nsecs_t now) {
void LayerHistory::partitionLayers(nsecs_t now) {
    const nsecs_t threshold = getActiveLayerThreshold(now);

    // Collect expired and inactive layers after active layers.
@@ -207,7 +207,7 @@ void LayerHistoryV2::partitionLayers(nsecs_t now) {
    mLayerInfos.erase(mLayerInfos.begin() + static_cast<long>(end), mLayerInfos.end());
}

void LayerHistoryV2::clear() {
void LayerHistory::clear() {
    std::lock_guard lock(mLock);

    for (const auto& [layer, info] : activeLayers()) {
@@ -215,10 +215,10 @@ void LayerHistoryV2::clear() {
    }
}

std::string LayerHistoryV2::dump() const {
std::string LayerHistory::dump() const {
    std::lock_guard lock(mLock);
    return base::StringPrintf("LayerHistoryV2{size=%zu, active=%zu}", mLayerInfos.size(),
    return base::StringPrintf("LayerHistory{size=%zu, active=%zu}", mLayerInfos.size(),
                              mActiveLayersEnd);
}

} // namespace android::scheduler::impl
} // namespace android::scheduler
+11 −40
Original line number Diff line number Diff line
@@ -36,25 +36,23 @@ class TestableScheduler;
namespace scheduler {

class LayerHistoryTest;
class LayerHistoryTestV2;
class LayerInfo;
class LayerInfoV2;

class LayerHistory {
public:
    using LayerVoteType = RefreshRateConfigs::LayerVoteType;

    virtual ~LayerHistory() = default;
    LayerHistory(const RefreshRateConfigs&);
    ~LayerHistory();

    // Layers are unregistered when the weak reference expires.
    virtual void registerLayer(Layer*, float lowRefreshRate, float highRefreshRate,
                               LayerVoteType type) = 0;
    void registerLayer(Layer*, float lowRefreshRate, float highRefreshRate, LayerVoteType type);

    // Sets the display size. Client is responsible for synchronization.
    virtual void setDisplayArea(uint32_t displayArea) = 0;
    void setDisplayArea(uint32_t displayArea) { mDisplayArea = displayArea; }

    // Sets whether a config change is pending to be applied
    virtual void setConfigChangePending(bool pending) = 0;
    void setConfigChangePending(bool pending) { mConfigChangePending = pending; }

    // Represents which layer activity is recorded
    enum class LayerUpdateType {
@@ -64,47 +62,21 @@ public:
    };

    // Marks the layer as active, and records the given state to its history.
    virtual void record(Layer*, nsecs_t presentTime, nsecs_t now, LayerUpdateType updateType) = 0;
    void record(Layer*, nsecs_t presentTime, nsecs_t now, LayerUpdateType updateType);

    using Summary = std::vector<RefreshRateConfigs::LayerRequirement>;

    // Rebuilds sets of active/inactive layers, and accumulates stats for active layers.
    virtual Summary summarize(nsecs_t now) = 0;
    Summary summarize(nsecs_t now);

    virtual void clear() = 0;
    virtual std::string dump() const = 0;
};

namespace impl {

class LayerHistoryV2 : public android::scheduler::LayerHistory {
public:
    LayerHistoryV2(const scheduler::RefreshRateConfigs&);
    virtual ~LayerHistoryV2();

    // Layers are unregistered when the weak reference expires.
    void registerLayer(Layer*, float lowRefreshRate, float highRefreshRate,
                       LayerVoteType type) override;

    // Sets the display size. Client is responsible for synchronization.
    void setDisplayArea(uint32_t displayArea) override { mDisplayArea = displayArea; }

    void setConfigChangePending(bool pending) override { mConfigChangePending = pending; }

    // Marks the layer as active, and records the given state to its history.
    void record(Layer*, nsecs_t presentTime, nsecs_t now, LayerUpdateType updateType) override;

    // Rebuilds sets of active/inactive layers, and accumulates stats for active layers.
    android::scheduler::LayerHistory::Summary summarize(nsecs_t /*now*/) override;

    void clear() override;
    std::string dump() const override;
    void clear();
    std::string dump() const;

private:
    friend android::scheduler::LayerHistoryTestV2;
    friend LayerHistoryTest;
    friend TestableScheduler;

    using LayerPair = std::pair<wp<Layer>, std::unique_ptr<LayerInfoV2>>;
    using LayerPair = std::pair<wp<Layer>, std::unique_ptr<LayerInfo>>;
    using LayerInfos = std::vector<LayerPair>;

    struct ActiveLayers {
@@ -141,6 +113,5 @@ private:
    std::atomic<bool> mConfigChangePending = false;
};

} // namespace impl
} // namespace scheduler
} // namespace android
+21 −21
Original line number Diff line number Diff line
@@ -17,7 +17,7 @@
// #define LOG_NDEBUG 0
#define ATRACE_TAG ATRACE_TAG_GRAPHICS

#include "LayerInfoV2.h"
#include "LayerInfo.h"

#include <algorithm>
#include <utility>
@@ -26,14 +26,14 @@
#include <cutils/trace.h>

#undef LOG_TAG
#define LOG_TAG "LayerInfoV2"
#define LOG_TAG "LayerInfo"

namespace android::scheduler {

const RefreshRateConfigs* LayerInfoV2::sRefreshRateConfigs = nullptr;
bool LayerInfoV2::sTraceEnabled = false;
const RefreshRateConfigs* LayerInfo::sRefreshRateConfigs = nullptr;
bool LayerInfo::sTraceEnabled = false;

LayerInfoV2::LayerInfoV2(const std::string& name, nsecs_t highRefreshRatePeriod,
LayerInfo::LayerInfo(const std::string& name, nsecs_t highRefreshRatePeriod,
                     LayerHistory::LayerVoteType defaultVote)
      : mName(name),
        mHighRefreshRatePeriod(highRefreshRatePeriod),
@@ -41,8 +41,8 @@ LayerInfoV2::LayerInfoV2(const std::string& name, nsecs_t highRefreshRatePeriod,
        mLayerVote({defaultVote, 0.0f}),
        mRefreshRateHistory(name) {}

void LayerInfoV2::setLastPresentTime(nsecs_t lastPresentTime, nsecs_t now,
                                     LayerUpdateType updateType, bool pendingConfigChange) {
void LayerInfo::setLastPresentTime(nsecs_t lastPresentTime, nsecs_t now, LayerUpdateType updateType,
                                   bool pendingConfigChange) {
    lastPresentTime = std::max(lastPresentTime, static_cast<nsecs_t>(0));

    mLastUpdatedTime = std::max(lastPresentTime, now);
@@ -63,13 +63,13 @@ void LayerInfoV2::setLastPresentTime(nsecs_t lastPresentTime, nsecs_t now,
    }
}

bool LayerInfoV2::isFrameTimeValid(const FrameTimeData& frameTime) const {
bool LayerInfo::isFrameTimeValid(const FrameTimeData& frameTime) const {
    return frameTime.queueTime >= std::chrono::duration_cast<std::chrono::nanoseconds>(
                                          mFrameTimeValidSince.time_since_epoch())
                                          .count();
}

bool LayerInfoV2::isFrequent(nsecs_t now) const {
bool LayerInfo::isFrequent(nsecs_t now) const {
    // If we know nothing about this layer we consider it as frequent as it might be the start
    // of an animation.
    if (mFrameTimes.size() < FREQUENT_LAYER_WINDOW_SIZE) {
@@ -94,11 +94,11 @@ bool LayerInfoV2::isFrequent(nsecs_t now) const {
    return (1e9f * (numFrames - 1)) / totalTime >= MIN_FPS_FOR_FREQUENT_LAYER;
}

bool LayerInfoV2::isAnimating(nsecs_t now) const {
bool LayerInfo::isAnimating(nsecs_t now) const {
    return mLastAnimationTime >= getActiveLayerThreshold(now);
}

bool LayerInfoV2::hasEnoughDataForHeuristic() const {
bool LayerInfo::hasEnoughDataForHeuristic() const {
    // The layer had to publish at least HISTORY_SIZE or HISTORY_DURATION of updates
    if (mFrameTimes.size() < 2) {
        ALOGV("fewer than 2 frames recorded: %zu", mFrameTimes.size());
@@ -120,7 +120,7 @@ bool LayerInfoV2::hasEnoughDataForHeuristic() const {
    return true;
}

std::optional<nsecs_t> LayerInfoV2::calculateAverageFrameTime() const {
std::optional<nsecs_t> LayerInfo::calculateAverageFrameTime() const {
    nsecs_t totalPresentTimeDeltas = 0;
    nsecs_t totalQueueTimeDeltas = 0;
    bool missingPresentTime = false;
@@ -163,7 +163,7 @@ std::optional<nsecs_t> LayerInfoV2::calculateAverageFrameTime() const {
    return static_cast<nsecs_t>(averageFrameTime);
}

std::optional<float> LayerInfoV2::calculateRefreshRateIfPossible(nsecs_t now) {
std::optional<float> LayerInfo::calculateRefreshRateIfPossible(nsecs_t now) {
    static constexpr float MARGIN = 1.0f; // 1Hz
    if (!hasEnoughDataForHeuristic()) {
        ALOGV("Not enough data");
@@ -198,7 +198,7 @@ std::optional<float> LayerInfoV2::calculateRefreshRateIfPossible(nsecs_t now) {
                                          : std::make_optional(mLastRefreshRate.reported);
}

LayerInfoV2::LayerVote LayerInfoV2::getRefreshRateVote(nsecs_t now) {
LayerInfo::LayerVote LayerInfo::getRefreshRateVote(nsecs_t now) {
    if (mLayerVote.type != LayerHistory::LayerVoteType::Heuristic) {
        ALOGV("%s voted %d ", mName.c_str(), static_cast<int>(mLayerVote.type));
        return mLayerVote;
@@ -233,7 +233,7 @@ LayerInfoV2::LayerVote LayerInfoV2::getRefreshRateVote(nsecs_t now) {
    return {LayerHistory::LayerVoteType::Max, 0};
}

const char* LayerInfoV2::getTraceTag(android::scheduler::LayerHistory::LayerVoteType type) const {
const char* LayerInfo::getTraceTag(android::scheduler::LayerHistory::LayerVoteType type) const {
    if (mTraceTags.count(type) == 0) {
        const auto tag = "LFPS " + mName + " " + RefreshRateConfigs::layerVoteTypeString(type);
        mTraceTags.emplace(type, tag);
@@ -242,8 +242,8 @@ const char* LayerInfoV2::getTraceTag(android::scheduler::LayerHistory::LayerVote
    return mTraceTags.at(type).c_str();
}

LayerInfoV2::RefreshRateHistory::HeuristicTraceTagData
LayerInfoV2::RefreshRateHistory::makeHeuristicTraceTagData() const {
LayerInfo::RefreshRateHistory::HeuristicTraceTagData
LayerInfo::RefreshRateHistory::makeHeuristicTraceTagData() const {
    const std::string prefix = "LFPS ";
    const std::string suffix = "Heuristic ";
    return {.min = prefix + mName + suffix + "min",
@@ -252,11 +252,11 @@ LayerInfoV2::RefreshRateHistory::makeHeuristicTraceTagData() const {
            .average = prefix + mName + suffix + "average"};
}

void LayerInfoV2::RefreshRateHistory::clear() {
void LayerInfo::RefreshRateHistory::clear() {
    mRefreshRates.clear();
}

bool LayerInfoV2::RefreshRateHistory::add(float refreshRate, nsecs_t now) {
bool LayerInfo::RefreshRateHistory::add(float refreshRate, nsecs_t now) {
    mRefreshRates.push_back({refreshRate, now});
    while (mRefreshRates.size() >= HISTORY_SIZE ||
           now - mRefreshRates.front().timestamp > HISTORY_DURATION.count()) {
@@ -274,7 +274,7 @@ bool LayerInfoV2::RefreshRateHistory::add(float refreshRate, nsecs_t now) {
    return isConsistent();
}

bool LayerInfoV2::RefreshRateHistory::isConsistent() const {
bool LayerInfo::RefreshRateHistory::isConsistent() const {
    if (mRefreshRates.empty()) return true;

    const auto max = std::max_element(mRefreshRates.begin(), mRefreshRates.end());
+9 −9
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@ constexpr nsecs_t getActiveLayerThreshold(nsecs_t now) {
}

// Stores history of present times and refresh rates for a layer.
class LayerInfoV2 {
class LayerInfo {
    using LayerUpdateType = LayerHistory::LayerUpdateType;

    // Layer is considered frequent if the earliest value in the window of most recent present times
@@ -54,7 +54,7 @@ class LayerInfoV2 {
    static constexpr auto MAX_FREQUENT_LAYER_PERIOD_NS =
            std::chrono::nanoseconds(static_cast<nsecs_t>(1e9f / MIN_FPS_FOR_FREQUENT_LAYER)) + 1ms;

    friend class LayerHistoryTestV2;
    friend class LayerHistoryTest;

public:
    // Holds information about the layer vote
@@ -70,11 +70,11 @@ public:
        sRefreshRateConfigs = &refreshRateConfigs;
    }

    LayerInfoV2(const std::string& name, nsecs_t highRefreshRatePeriod,
    LayerInfo(const std::string& name, nsecs_t highRefreshRatePeriod,
              LayerHistory::LayerVoteType defaultVote);

    LayerInfoV2(const LayerInfo&) = delete;
    LayerInfoV2& operator=(const LayerInfoV2&) = delete;
    LayerInfo(const LayerInfo&) = delete;
    LayerInfo& operator=(const LayerInfo&) = delete;

    // Records the last requested present time. It also stores information about when
    // the layer was last updated. If the present time is farther in the future than the
@@ -131,9 +131,9 @@ private:
    struct RefreshRateHeuristicData {
        // Rate calculated on the layer
        float calculated = 0.0f;
        // Last reported rate for LayerInfoV2::getRefreshRate()
        // Last reported rate for LayerInfo::getRefreshRate()
        float reported = 0.0f;
        // Whether the last reported rate for LayerInfoV2::getRefreshRate()
        // Whether the last reported rate for LayerInfo::getRefreshRate()
        // was due to animation or infrequent updates
        bool animatingOrInfrequent = false;
    };
@@ -154,7 +154,7 @@ private:
        bool add(float refreshRate, nsecs_t now);

    private:
        friend class LayerHistoryTestV2;
        friend class LayerHistoryTest;

        // Holds the refresh rate when it was calculated
        struct RefreshRateData {
Loading