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

Commit c0b7016a authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "[SF] Introduce VirtualDisplayId"

parents aa4bbda7 7cee53e6
Loading
Loading
Loading
Loading
+96 −4
Original line number Diff line number Diff line
@@ -17,13 +17,20 @@
#pragma once

#include <cstdint>
#include <functional>
#include <optional>
#include <string>

namespace android {

// ID of a physical or a virtual display. This class acts as a type safe wrapper around uint64_t.
// The encoding of the ID is type-specific for bits 0 to 61.
struct DisplayId {
    // Flag indicating that the display is virtual.
    static constexpr uint64_t FLAG_VIRTUAL = 1ULL << 63;

    // Flag indicating that the ID is stable across reboots.
    static constexpr uint64_t FLAG_STABLE = 1ULL << 62;

    // TODO(b/162612135) Remove default constructor
    DisplayId() = default;
    constexpr DisplayId(const DisplayId&) = default;
@@ -51,8 +58,12 @@ inline std::string to_string(DisplayId displayId) {

// DisplayId of a physical display, such as the internal display or externally connected display.
struct PhysicalDisplayId : DisplayId {
    // Flag indicating that the ID is stable across reboots.
    static constexpr uint64_t FLAG_STABLE = 1ULL << 62;
    static constexpr std::optional<PhysicalDisplayId> tryCast(DisplayId id) {
        if (id.value & FLAG_VIRTUAL) {
            return std::nullopt;
        }
        return {PhysicalDisplayId(id)};
    }

    // Returns a stable ID based on EDID information.
    static constexpr PhysicalDisplayId fromEdid(uint8_t port, uint16_t manufacturerId,
@@ -69,8 +80,8 @@ struct PhysicalDisplayId : DisplayId {

    // TODO(b/162612135) Remove default constructor
    PhysicalDisplayId() = default;
    // TODO(b/162612135) Remove constructor
    explicit constexpr PhysicalDisplayId(uint64_t id) : DisplayId(id) {}
    explicit constexpr PhysicalDisplayId(DisplayId other) : DisplayId(other.value) {}

    constexpr uint16_t getManufacturerId() const { return static_cast<uint16_t>(value >> 40); }

@@ -81,10 +92,82 @@ private:
                                uint32_t modelHash)
          : DisplayId(flags | (static_cast<uint64_t>(manufacturerId) << 40) |
                      (static_cast<uint64_t>(modelHash) << 8) | port) {}

    explicit constexpr PhysicalDisplayId(DisplayId other) : DisplayId(other) {}
};

static_assert(sizeof(PhysicalDisplayId) == sizeof(uint64_t));

struct VirtualDisplayId : DisplayId {
    using BaseId = uint32_t;
    // Flag indicating that this virtual display is backed by the GPU.
    static constexpr uint64_t FLAG_GPU = 1ULL << 61;

    static constexpr std::optional<VirtualDisplayId> tryCast(DisplayId id) {
        if (id.value & FLAG_VIRTUAL) {
            return {VirtualDisplayId(id)};
        }
        return std::nullopt;
    }

protected:
    constexpr VirtualDisplayId(uint64_t flags, BaseId baseId)
          : DisplayId(DisplayId::FLAG_VIRTUAL | flags | baseId) {}

    explicit constexpr VirtualDisplayId(DisplayId other) : DisplayId(other) {}
};

struct HalVirtualDisplayId : VirtualDisplayId {
    explicit constexpr HalVirtualDisplayId(BaseId baseId) : VirtualDisplayId(0, baseId) {}

    static constexpr std::optional<HalVirtualDisplayId> tryCast(DisplayId id) {
        if ((id.value & FLAG_VIRTUAL) && !(id.value & VirtualDisplayId::FLAG_GPU)) {
            return {HalVirtualDisplayId(id)};
        }
        return std::nullopt;
    }

private:
    explicit constexpr HalVirtualDisplayId(DisplayId other) : VirtualDisplayId(other) {}
};

struct GpuVirtualDisplayId : VirtualDisplayId {
    explicit constexpr GpuVirtualDisplayId(BaseId baseId)
          : VirtualDisplayId(VirtualDisplayId::FLAG_GPU, baseId) {}

    static constexpr std::optional<GpuVirtualDisplayId> tryCast(DisplayId id) {
        if ((id.value & FLAG_VIRTUAL) && (id.value & VirtualDisplayId::FLAG_GPU)) {
            return {GpuVirtualDisplayId(id)};
        }
        return std::nullopt;
    }

private:
    explicit constexpr GpuVirtualDisplayId(DisplayId other) : VirtualDisplayId(other) {}
};

// HalDisplayId is the ID of a display which is managed by HWC.
// PhysicalDisplayId and HalVirtualDisplayId are implicitly convertible to HalDisplayId.
struct HalDisplayId : DisplayId {
    constexpr HalDisplayId(HalVirtualDisplayId other) : DisplayId(other) {}
    constexpr HalDisplayId(PhysicalDisplayId other) : DisplayId(other) {}

    static constexpr std::optional<HalDisplayId> tryCast(DisplayId id) {
        if (GpuVirtualDisplayId::tryCast(id)) {
            return std::nullopt;
        }
        return {HalDisplayId(id)};
    }

private:
    explicit constexpr HalDisplayId(DisplayId other) : DisplayId(other) {}
};

static_assert(sizeof(VirtualDisplayId) == sizeof(uint64_t));
static_assert(sizeof(HalVirtualDisplayId) == sizeof(uint64_t));
static_assert(sizeof(GpuVirtualDisplayId) == sizeof(uint64_t));
static_assert(sizeof(HalDisplayId) == sizeof(uint64_t));

} // namespace android

namespace std {
@@ -99,4 +182,13 @@ struct hash<android::DisplayId> {
template <>
struct hash<android::PhysicalDisplayId> : hash<android::DisplayId> {};

template <>
struct hash<android::HalVirtualDisplayId> : hash<android::DisplayId> {};

template <>
struct hash<android::GpuVirtualDisplayId> : hash<android::DisplayId> {};

template <>
struct hash<android::HalDisplayId> : hash<android::DisplayId> {};

} // namespace std
+7 −0
Original line number Diff line number Diff line
@@ -28,6 +28,13 @@ cc_test {
    cflags: ["-Wall", "-Werror"],
}

cc_test {
    name: "DisplayId_test",
    shared_libs: ["libui"],
    srcs: ["DisplayId_test.cpp"],
    cflags: ["-Wall", "-Werror"],
}

cc_test {
    name: "FlattenableHelpers_test",
    shared_libs: ["libui"],
+66 −0
Original line number Diff line number Diff line
/*
 * Copyright 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <ui/DisplayId.h>

#include <gtest/gtest.h>

namespace android::ui {

TEST(DisplayIdTest, createPhysicalIdFromEdid) {
    constexpr uint8_t port = 1;
    constexpr uint16_t manufacturerId = 13;
    constexpr uint32_t modelHash = 42;
    PhysicalDisplayId id = PhysicalDisplayId::fromEdid(port, manufacturerId, modelHash);
    EXPECT_EQ(port, id.getPort());
    EXPECT_EQ(manufacturerId, id.getManufacturerId());
    EXPECT_FALSE(VirtualDisplayId::tryCast(id));
    EXPECT_FALSE(HalVirtualDisplayId::tryCast(id));
    EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id));
    EXPECT_TRUE(PhysicalDisplayId::tryCast(id));
    EXPECT_TRUE(HalDisplayId::tryCast(id));
}

TEST(DisplayIdTest, createPhysicalIdFromPort) {
    constexpr uint8_t port = 3;
    PhysicalDisplayId id = PhysicalDisplayId::fromPort(port);
    EXPECT_EQ(port, id.getPort());
    EXPECT_FALSE(VirtualDisplayId::tryCast(id));
    EXPECT_FALSE(HalVirtualDisplayId::tryCast(id));
    EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id));
    EXPECT_TRUE(PhysicalDisplayId::tryCast(id));
    EXPECT_TRUE(HalDisplayId::tryCast(id));
}

TEST(DisplayIdTest, createGpuVirtualId) {
    GpuVirtualDisplayId id(42);
    EXPECT_TRUE(VirtualDisplayId::tryCast(id));
    EXPECT_TRUE(GpuVirtualDisplayId::tryCast(id));
    EXPECT_FALSE(HalVirtualDisplayId::tryCast(id));
    EXPECT_FALSE(PhysicalDisplayId::tryCast(id));
    EXPECT_FALSE(HalDisplayId::tryCast(id));
}

TEST(DisplayIdTest, createHalVirtualId) {
    HalVirtualDisplayId id(42);
    EXPECT_TRUE(VirtualDisplayId::tryCast(id));
    EXPECT_TRUE(HalVirtualDisplayId::tryCast(id));
    EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id));
    EXPECT_FALSE(PhysicalDisplayId::tryCast(id));
    EXPECT_TRUE(HalDisplayId::tryCast(id));
}

} // namespace android::ui
+1 −1
Original line number Diff line number Diff line
@@ -366,7 +366,7 @@ bool BufferLayer::onPostComposition(const DisplayDevice* display,
        mFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence));
    } else if (!display) {
        // Do nothing.
    } else if (const auto displayId = display->getId();
    } else if (const auto displayId = PhysicalDisplayId::tryCast(display->getId());
               displayId && mFlinger->getHwComposer().isConnected(*displayId)) {
        // The HWC doesn't support present fences, so use the refresh
        // timestamp instead.
+2 −2
Original line number Diff line number Diff line
@@ -34,8 +34,8 @@ struct DisplayColorProfileCreationArgs;
 */
class Display : public virtual Output {
public:
    // Gets the HWC DisplayId for the display if there is one
    virtual const std::optional<DisplayId>& getId() const = 0;
    // Gets the DisplayId for the display
    virtual DisplayId getId() const = 0;

    // True if the display is secure
    virtual bool isSecure() const = 0;
Loading