Loading libs/ui/include/ui/DisplayId.h +96 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading @@ -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); } Loading @@ -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 { Loading @@ -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 libs/ui/tests/Android.bp +7 −0 Original line number Diff line number Diff line Loading @@ -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"], Loading libs/ui/tests/DisplayId_test.cpp 0 → 100644 +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 services/surfaceflinger/BufferLayer.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -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. Loading services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h +2 −2 Original line number Diff line number Diff line Loading @@ -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 Loading
libs/ui/include/ui/DisplayId.h +96 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading @@ -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); } Loading @@ -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 { Loading @@ -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
libs/ui/tests/Android.bp +7 −0 Original line number Diff line number Diff line Loading @@ -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"], Loading
libs/ui/tests/DisplayId_test.cpp 0 → 100644 +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
services/surfaceflinger/BufferLayer.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -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. Loading
services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h +2 −2 Original line number Diff line number Diff line Loading @@ -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