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

Commit 34157762 authored by Dominik Laskowski's avatar Dominik Laskowski
Browse files

SF: Define DisplayId as struct type

This prevents accidental mix-up with HWC display IDs, which have the
same backing type, as well as other implicitly convertible integers,
e.g. EDID manufacturer IDs. This CL also fixes misuses detected by
type checking:

1) Recycling of virtual display IDs.
2) Skipping composition for non-HWC virtual displays.
3) Unit tests for fallback/virtual display IDs.

Bug: 74619554
Bug: 119412688
Test: libsurfaceflinger_unittest
Test: vrflinger_test on walleye_xr
Change-Id: I0be41cc93c82860e859f1adf427430436c926595
parent f77adb1f
Loading
Loading
Loading
Loading
+2 −5
Original line number Diff line number Diff line
@@ -231,15 +231,12 @@ bool BufferLayer::isHdrY410() const {

void BufferLayer::setPerFrameData(DisplayId displayId, const ui::Transform& transform,
                                  const Rect& viewport, int32_t supportedPerFrameMetadata) {
    RETURN_IF_NO_HWC_LAYER(displayId);

    // Apply this display's projection's viewport to the visible region
    // before giving it to the HWC HAL.
    Region visible = transform.transform(visibleRegion.intersect(viewport));

    if (!hasHwcLayer(displayId)) {
        ALOGE("[%s] failed to setPerFrameData: no HWC layer found for display %" PRIu64,
              mName.string(), displayId);
        return;
    }
    auto& hwcInfo = getBE().mHwcLayers[displayId];
    auto& hwcLayer = hwcInfo.layer;
    auto error = hwcLayer->setVisibleRegion(visible);
+2 −5
Original line number Diff line number Diff line
@@ -59,13 +59,10 @@ bool ColorLayer::isVisible() const {

void ColorLayer::setPerFrameData(DisplayId displayId, const ui::Transform& transform,
                                 const Rect& viewport, int32_t /* supportedPerFrameMetadata */) {
    RETURN_IF_NO_HWC_LAYER(displayId);

    Region visible = transform.transform(visibleRegion.intersect(viewport));

    if (!hasHwcLayer(displayId)) {
        ALOGE("[%s] failed to setPerFrameData: no HWC layer found for display %" PRIu64,
              mName.string(), displayId);
        return;
    }
    auto& hwcInfo = getBE().mHwcLayers[displayId];
    auto& hwcLayer = hwcInfo.layer;
    auto error = hwcLayer->setVisibleRegion(visible);
+1 −1
Original line number Diff line number Diff line
@@ -647,7 +647,7 @@ uint32_t DisplayDevice::getPrimaryDisplayOrientationTransform() {
}

std::string DisplayDevice::getDebugName() const {
    const auto id = mId ? base::StringPrintf("%" PRIu64 ", ", *mId) : std::string();
    const auto id = mId ? to_string(*mId) + ", " : std::string();
    return base::StringPrintf("DisplayDevice{%s%s%s\"%s\"}", id.c_str(),
                              isPrimary() ? "primary, " : "", isVirtual() ? "virtual, " : "",
                              mDisplayName.c_str());
+15 −7
Original line number Diff line number Diff line
@@ -64,12 +64,16 @@ char getPnpLetter(uint16_t id) {
    return letter < 'A' || letter > 'Z' ? '\0' : letter;
}

DisplayId getEdidDisplayId(uint8_t port, uint16_t manufacturerId, uint32_t displayNameHash) {
    return (static_cast<DisplayId>(manufacturerId) << 40) |
            (static_cast<DisplayId>(displayNameHash) << 8) | port;
} // namespace

uint16_t DisplayId::manufacturerId() const {
    return static_cast<uint16_t>(value >> 40);
}

} // namespace
DisplayId DisplayId::fromEdid(uint8_t port, uint16_t manufacturerId, uint32_t displayNameHash) {
    return {(static_cast<Type>(manufacturerId) << 40) | (static_cast<Type>(displayNameHash) << 8) |
            port};
}

bool isEdid(const DisplayIdentificationData& data) {
    const uint8_t kMagic[] = {0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0};
@@ -168,6 +172,10 @@ std::optional<PnpId> getPnpId(uint16_t manufacturerId) {
    return a && b && c ? std::make_optional(PnpId{a, b, c}) : std::nullopt;
}

std::optional<PnpId> getPnpId(DisplayId displayId) {
    return getPnpId(displayId.manufacturerId());
}

std::optional<DisplayIdentificationInfo> parseDisplayIdentificationData(
        uint8_t port, const DisplayIdentificationData& data) {
    if (!isEdid(data)) {
@@ -183,16 +191,16 @@ std::optional<DisplayIdentificationInfo> parseDisplayIdentificationData(
    // Hash display name instead of using product code or serial number, since the latter have been
    // observed to change on some displays with multiple inputs.
    const auto hash = static_cast<uint32_t>(std::hash<std::string_view>()(edid->displayName));
    return DisplayIdentificationInfo{getEdidDisplayId(port, edid->manufacturerId, hash),
    return DisplayIdentificationInfo{DisplayId::fromEdid(port, edid->manufacturerId, hash),
                                     std::string(edid->displayName)};
}

DisplayId getFallbackDisplayId(uint8_t port) {
    return getEdidDisplayId(port, kFallbackEdidManufacturerId, 0);
    return DisplayId::fromEdid(port, kFallbackEdidManufacturerId, 0);
}

DisplayId getVirtualDisplayId(uint32_t id) {
    return getEdidDisplayId(0, kVirtualEdidManufacturerId, id);
    return DisplayId::fromEdid(0, kVirtualEdidManufacturerId, id);
}

} // namespace android
+33 −1
Original line number Diff line number Diff line
@@ -25,7 +25,27 @@

namespace android {

using DisplayId = uint64_t;
struct DisplayId {
    using Type = uint64_t;
    Type value;

    uint16_t manufacturerId() const;

    static DisplayId fromEdid(uint8_t port, uint16_t manufacturerId, uint32_t displayNameHash);
};

inline bool operator==(DisplayId lhs, DisplayId rhs) {
    return lhs.value == rhs.value;
}

inline bool operator!=(DisplayId lhs, DisplayId rhs) {
    return !(lhs == rhs);
}

inline std::string to_string(DisplayId displayId) {
    return std::to_string(displayId.value);
}

using DisplayIdentificationData = std::vector<uint8_t>;

struct DisplayIdentificationInfo {
@@ -45,6 +65,7 @@ struct Edid {
bool isEdid(const DisplayIdentificationData&);
std::optional<Edid> parseEdid(const DisplayIdentificationData&);
std::optional<PnpId> getPnpId(uint16_t manufacturerId);
std::optional<PnpId> getPnpId(DisplayId);

std::optional<DisplayIdentificationInfo> parseDisplayIdentificationData(
        uint8_t port, const DisplayIdentificationData&);
@@ -53,3 +74,14 @@ DisplayId getFallbackDisplayId(uint8_t port);
DisplayId getVirtualDisplayId(uint32_t id);

} // namespace android

namespace std {

template <>
struct hash<android::DisplayId> {
    size_t operator()(android::DisplayId displayId) const {
        return hash<android::DisplayId::Type>()(displayId.value);
    }
};

} // namespace std
Loading