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

Commit 69114c7e authored by Alec Mouri's avatar Alec Mouri
Browse files

Add remaining output-relevant fields to LayerState

Also clean up unit tests to collect logically shared assertions into
helper methods.

Bug: 180638831
Test: libcompositionengine_test
Change-Id: I59b80f7ecd5c036b27d16e4e213f99a180be3fdd
parent 9737f323
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -55,6 +55,16 @@ struct GenericLayerMetadataEntry {
    std::vector<uint8_t> value;

    std::string dumpAsString() const;

    struct Hasher {
        size_t operator()(const GenericLayerMetadataEntry& entry) const {
            size_t hash = 0;
            for (const auto value : entry.value) {
                hashCombineSingleHashed(hash, value);
            }
            return hash;
        }
    };
};

inline bool operator==(const GenericLayerMetadataEntry& lhs, const GenericLayerMetadataEntry& rhs) {
@@ -70,6 +80,8 @@ using GenericLayerMetadataMap = std::unordered_map<std::string, GenericLayerMeta

/*
 * Used by LayerFE::getCompositionState
 * Note that fields that affect HW composer state may need to be mirrored into
 * android::compositionengine::impl::planner::LayerState
 */
struct LayerFECompositionState {
    // If set to true, forces client composition on all output layers until
+2 −0
Original line number Diff line number Diff line
@@ -48,6 +48,8 @@ class HWComposer;

namespace compositionengine::impl {

// Note that fields that affect HW composer state may need to be mirrored into
// android::compositionengine::impl::planner::LayerState
struct OutputLayerCompositionState {
    // The portion of the layer that is not obscured by opaque layers on top
    Region visibleRegion;
+111 −39
Original line number Diff line number Diff line
@@ -57,13 +57,16 @@ enum class LayerStateField : uint32_t {
    BufferTransform = 1u << 5,
    BlendMode       = 1u << 6,
    Alpha           = 1u << 7,
    VisibleRegion   = 1u << 8,
    Dataspace       = 1u << 9,
    ColorTransform  = 1u << 10,
    CompositionType = 1u << 11,
    SidebandStream  = 1u << 12,
    Buffer          = 1u << 13,
    SolidColor      = 1u << 14,
    LayerMetadata   = 1u << 8,
    VisibleRegion   = 1u << 9,
    Dataspace       = 1u << 10,
    PixelFormat     = 1u << 11,
    ColorTransform  = 1u << 12,
    SurfaceDamage   = 1u << 13,
    CompositionType = 1u << 14,
    SidebandStream  = 1u << 15,
    Buffer          = 1u << 16,
    SolidColor      = 1u << 17,
};
// clang-format on

@@ -95,6 +98,7 @@ public:
    using ReadFromLayerState = std::function<T(const compositionengine::OutputLayer* layer)>;
    using ToStrings = std::function<std::vector<std::string>(const T&)>;
    using Equals = std::function<bool(const T&, const T&)>;
    using Hashes = std::function<size_t(const T&)>;

    static ToStrings getDefaultToStrings() {
        return [](const T& value) {
@@ -107,14 +111,38 @@ public:
        return [](const T& value) { return std::vector<std::string>{toString(value)}; };
    }

    static ToStrings getRegionToStrings() {
        return [](const Region& region) {
            using namespace std::string_literals;
            std::string dump;
            region.dump(dump, "");
            std::vector<std::string> split = base::Split(dump, "\n"s);
            split.erase(split.begin()); // Strip the header
            split.pop_back();           // Strip the last (empty) line
            for (std::string& line : split) {
                line.erase(0, 4); // Strip leading padding before each rect
            }
            return split;
        };
    }

    static Equals getDefaultEquals() {
        return [](const T& lhs, const T& rhs) { return lhs == rhs; };
    }

    static Equals getRegionEquals() {
        return [](const Region& lhs, const Region& rhs) { return lhs.hasSameRects(rhs); };
    }

    static Hashes getDefaultHashes() {
        return [](const T& value) { return std::hash<T>{}(value); };
    }

    OutputLayerState(ReadFromLayerState reader,
                     ToStrings toStrings = OutputLayerState::getDefaultToStrings(),
                     Equals equals = OutputLayerState::getDefaultEquals())
          : mReader(reader), mToStrings(toStrings), mEquals(equals) {}
                     Equals equals = OutputLayerState::getDefaultEquals(),
                     Hashes hashes = OutputLayerState::getDefaultHashes())
          : mReader(reader), mToStrings(toStrings), mEquals(equals), mHashes(hashes) {}

    ~OutputLayerState() override = default;

@@ -138,7 +166,7 @@ public:

    size_t getHash() const override {
        if (!mHash) {
            mHash = std::hash<T>{}(mValue);
            mHash = mHashes(mValue);
        }
        return *mHash;
    }
@@ -172,6 +200,7 @@ private:
    const ReadFromLayerState mReader;
    const ToStrings mToStrings;
    const Equals mEquals;
    const Hashes mHashes;
    T mValue = {};
    mutable std::optional<size_t> mHash = {};
};
@@ -263,39 +292,80 @@ private:
    OutputLayerState<float, LayerStateField::Alpha> mAlpha{
            [](auto layer) { return layer->getLayerFE().getCompositionState()->alpha; }};

    // TODO(b/180638831): Generic layer metadata

    // Output-dependent per-frame state

    OutputLayerState<Region, LayerStateField::VisibleRegion>
            mVisibleRegion{[](auto layer) { return layer->getState().visibleRegion; },
                           [](const Region& region) {
                               using namespace std::string_literals;
                               std::string dump;
                               region.dump(dump, "");
                               std::vector<std::string> split = base::Split(dump, "\n"s);
                               split.erase(split.begin()); // Strip the header
                               split.pop_back();           // Strip the last (empty) line
                               for (std::string& line : split) {
                                   line.erase(0, 4); // Strip leading padding before each rect
    using LayerMetadataState =
            OutputLayerState<GenericLayerMetadataMap, LayerStateField::LayerMetadata>;
    LayerMetadataState
            mLayerMetadata{[](auto layer) {
                               return layer->getLayerFE().getCompositionState()->metadata;
                           },
                           [](const GenericLayerMetadataMap& metadata) {
                               std::vector<std::string> result;
                               if (metadata.empty()) {
                                   result.push_back("{}");
                                   return result;
                               }
                               return split;
                               result.push_back("{");
                               for (const auto& [key, value] : metadata) {
                                   std::string keyValueDump;
                                   keyValueDump.append("           ");
                                   keyValueDump.append(key);
                                   keyValueDump.append("=");
                                   keyValueDump.append(value.dumpAsString());
                                   result.push_back(keyValueDump);
                               }
                               result.push_back("}");
                               return result;
                           },
                           [](const Region& lhs, const Region& rhs) {
                               return lhs.hasSameRects(rhs);
                           LayerMetadataState::getDefaultEquals(),
                           [](const GenericLayerMetadataMap& metadata) {
                               size_t hash = 0;
                               for (const auto& [key, value] : metadata) {
                                   size_t entryHash = 0;
                                   hashCombineSingleHashed(entryHash,
                                                           std::hash<std::string>{}(key));
                                   hashCombineSingleHashed(entryHash,
                                                           GenericLayerMetadataEntry::Hasher{}(
                                                                   value));
                                   hash ^= entryHash;
                               }
                               return hash;
                           }};

    // Output-dependent per-frame state

    using VisibleRegionState = OutputLayerState<Region, LayerStateField::VisibleRegion>;
    VisibleRegionState mVisibleRegion{[](auto layer) { return layer->getState().visibleRegion; },
                                      VisibleRegionState::getRegionToStrings(),
                                      VisibleRegionState::getRegionEquals()};

    using DataspaceState = OutputLayerState<ui::Dataspace, LayerStateField::Dataspace>;
    DataspaceState mOutputDataspace{[](auto layer) { return layer->getState().dataspace; },
                                    DataspaceState::getHalToStrings()};

    // TODO(b/180638831): Buffer format

    // Output-independent per-frame state

    using PixelFormatState = OutputLayerState<hardware::graphics::composer::hal::PixelFormat,
                                              LayerStateField::PixelFormat>;
    PixelFormatState
            mPixelFormat{[](auto layer) {
                             return layer->getLayerFE().getCompositionState()->buffer
                                     ? static_cast<hardware::graphics::composer::hal::PixelFormat>(
                                               layer->getLayerFE()
                                                       .getCompositionState()
                                                       ->buffer->getPixelFormat())
                                     : hardware::graphics::composer::hal::PixelFormat::RGBA_8888;
                         },
                         PixelFormatState::getHalToStrings()};

    OutputLayerState<mat4, LayerStateField::ColorTransform> mColorTransform;

    // TODO(b/180638831): Surface damage
    using SurfaceDamageState = OutputLayerState<Region, LayerStateField::SurfaceDamage>;
    SurfaceDamageState
            mSurfaceDamage{[](auto layer) {
                               return layer->getLayerFE().getCompositionState()->surfaceDamage;
                           },
                           SurfaceDamageState::getRegionToStrings(),
                           SurfaceDamageState::getRegionEquals()};

    using CompositionTypeState = OutputLayerState<hardware::graphics::composer::hal::Composition,
                                                  LayerStateField::CompositionType>;
@@ -339,10 +409,12 @@ private:
                            return std::vector<std::string>{stream.str()};
                        }};

    std::array<StateInterface*, 13> getNonUniqueFields() {
        std::array<const StateInterface*, 13> constFields =
    static const constexpr size_t kNumNonUniqueFields = 16;

    std::array<StateInterface*, kNumNonUniqueFields> getNonUniqueFields() {
        std::array<const StateInterface*, kNumNonUniqueFields> constFields =
                const_cast<const LayerState*>(this)->getNonUniqueFields();
        std::array<StateInterface*, 13> fields;
        std::array<StateInterface*, kNumNonUniqueFields> fields;
        std::transform(constFields.cbegin(), constFields.cend(), fields.begin(),
                       [](const StateInterface* constField) {
                           return const_cast<StateInterface*>(constField);
@@ -350,12 +422,12 @@ private:
        return fields;
    }

    std::array<const StateInterface*, 13> getNonUniqueFields() const {
    std::array<const StateInterface*, kNumNonUniqueFields> getNonUniqueFields() const {
        return {
                &mDisplayFrame,    &mSourceCrop,     &mZOrder,         &mBufferTransform,
                &mBlendMode,      &mAlpha,           &mVisibleRegion,  &mOutputDataspace,
                &mColorTransform, &mCompositionType, &mSidebandStream, &mBuffer,
                &mSolidColor,
                &mBlendMode,       &mAlpha,          &mLayerMetadata,  &mVisibleRegion,
                &mOutputDataspace, &mPixelFormat,    &mColorTransform, &mSurfaceDamage,
                &mCompositionType, &mSidebandStream, &mBuffer,         &mSolidColor,
        };
    }
};
+4 −2
Original line number Diff line number Diff line
@@ -157,9 +157,11 @@ bool operator==(const LayerState& lhs, const LayerState& rhs) {
    return lhs.mId == rhs.mId && lhs.mName == rhs.mName && lhs.mDisplayFrame == rhs.mDisplayFrame &&
            lhs.mSourceCrop == rhs.mSourceCrop && lhs.mZOrder == rhs.mZOrder &&
            lhs.mBufferTransform == rhs.mBufferTransform && lhs.mBlendMode == rhs.mBlendMode &&
            lhs.mAlpha == rhs.mAlpha && lhs.mVisibleRegion == rhs.mVisibleRegion &&
            lhs.mOutputDataspace == rhs.mOutputDataspace &&
            lhs.mAlpha == rhs.mAlpha && lhs.mLayerMetadata == rhs.mLayerMetadata &&
            lhs.mVisibleRegion == rhs.mVisibleRegion &&
            lhs.mOutputDataspace == rhs.mOutputDataspace && lhs.mPixelFormat == rhs.mPixelFormat &&
            lhs.mColorTransform == rhs.mColorTransform &&
            lhs.mSurfaceDamage == rhs.mSurfaceDamage &&
            lhs.mCompositionType == rhs.mCompositionType &&
            lhs.mSidebandStream == rhs.mSidebandStream && lhs.mBuffer == rhs.mBuffer &&
            (lhs.mCompositionType.get() != hal::Composition::SOLID_COLOR ||
+180 −94

File changed.

Preview size limit exceeded, changes collapsed.