blob: 3a31fa084878920116a4ff47d47925dda800d0d5 [file] [log] [blame]
Marin Shalamanova524a092020-07-27 21:39:55 +02001/*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <cstdint>
Dominik Laskowski530d6bd2022-10-10 16:55:54 -040020#include <ostream>
Marin Shalamanova524a092020-07-27 21:39:55 +020021#include <string>
22
Dominik Laskowskib363c4c2022-08-02 14:03:41 -070023#include <ftl/optional.h>
24
Marin Shalamanova524a092020-07-27 21:39:55 +020025namespace android {
26
27// ID of a physical or a virtual display. This class acts as a type safe wrapper around uint64_t.
Marin Shalamanov0f10d0d2020-08-06 20:04:06 +020028// The encoding of the ID is type-specific for bits 0 to 61.
Marin Shalamanova524a092020-07-27 21:39:55 +020029struct DisplayId {
Marin Shalamanov0f10d0d2020-08-06 20:04:06 +020030 // Flag indicating that the display is virtual.
31 static constexpr uint64_t FLAG_VIRTUAL = 1ULL << 63;
32
33 // Flag indicating that the ID is stable across reboots.
34 static constexpr uint64_t FLAG_STABLE = 1ULL << 62;
35
Marin Shalamanova524a092020-07-27 21:39:55 +020036 // TODO(b/162612135) Remove default constructor
37 DisplayId() = default;
38 constexpr DisplayId(const DisplayId&) = default;
39 DisplayId& operator=(const DisplayId&) = default;
40
41 uint64_t value;
42
Dominik Laskowskif1833852021-03-23 15:06:50 -070043 // For deserialization.
44 static constexpr std::optional<DisplayId> fromValue(uint64_t);
45
46 // As above, but also upcast to Id.
47 template <typename Id>
48 static constexpr std::optional<Id> fromValue(uint64_t value) {
49 if (const auto id = Id::tryCast(DisplayId(value))) {
50 return id;
51 }
52 return {};
53 }
54
Marin Shalamanova524a092020-07-27 21:39:55 +020055protected:
56 explicit constexpr DisplayId(uint64_t id) : value(id) {}
57};
58
Marin Shalamanova524a092020-07-27 21:39:55 +020059inline bool operator==(DisplayId lhs, DisplayId rhs) {
60 return lhs.value == rhs.value;
61}
62
63inline bool operator!=(DisplayId lhs, DisplayId rhs) {
64 return !(lhs == rhs);
65}
66
67inline std::string to_string(DisplayId displayId) {
68 return std::to_string(displayId.value);
69}
70
Dominik Laskowski530d6bd2022-10-10 16:55:54 -040071// For tests.
72inline std::ostream& operator<<(std::ostream& stream, DisplayId displayId) {
73 return stream << "DisplayId{" << displayId.value << '}';
74}
75
Marin Shalamanova524a092020-07-27 21:39:55 +020076// DisplayId of a physical display, such as the internal display or externally connected display.
77struct PhysicalDisplayId : DisplayId {
Dominik Laskowskib363c4c2022-08-02 14:03:41 -070078 static constexpr ftl::Optional<PhysicalDisplayId> tryCast(DisplayId id) {
Marin Shalamanov0f10d0d2020-08-06 20:04:06 +020079 if (id.value & FLAG_VIRTUAL) {
80 return std::nullopt;
81 }
82 return {PhysicalDisplayId(id)};
83 }
Marin Shalamanova524a092020-07-27 21:39:55 +020084
85 // Returns a stable ID based on EDID information.
86 static constexpr PhysicalDisplayId fromEdid(uint8_t port, uint16_t manufacturerId,
87 uint32_t modelHash) {
88 return PhysicalDisplayId(FLAG_STABLE, port, manufacturerId, modelHash);
89 }
90
91 // Returns an unstable ID. If EDID is available using "fromEdid" is preferred.
92 static constexpr PhysicalDisplayId fromPort(uint8_t port) {
93 constexpr uint16_t kManufacturerId = 0;
94 constexpr uint32_t kModelHash = 0;
95 return PhysicalDisplayId(0, port, kManufacturerId, kModelHash);
96 }
97
98 // TODO(b/162612135) Remove default constructor
99 PhysicalDisplayId() = default;
Marin Shalamanova524a092020-07-27 21:39:55 +0200100
101 constexpr uint16_t getManufacturerId() const { return static_cast<uint16_t>(value >> 40); }
Marin Shalamanova524a092020-07-27 21:39:55 +0200102 constexpr uint8_t getPort() const { return static_cast<uint8_t>(value); }
103
104private:
105 constexpr PhysicalDisplayId(uint64_t flags, uint8_t port, uint16_t manufacturerId,
106 uint32_t modelHash)
107 : DisplayId(flags | (static_cast<uint64_t>(manufacturerId) << 40) |
108 (static_cast<uint64_t>(modelHash) << 8) | port) {}
Marin Shalamanov0f10d0d2020-08-06 20:04:06 +0200109
110 explicit constexpr PhysicalDisplayId(DisplayId other) : DisplayId(other) {}
Marin Shalamanova524a092020-07-27 21:39:55 +0200111};
112
Marin Shalamanov0f10d0d2020-08-06 20:04:06 +0200113struct VirtualDisplayId : DisplayId {
114 using BaseId = uint32_t;
Dominik Laskowskif1833852021-03-23 15:06:50 -0700115
Marin Shalamanov0f10d0d2020-08-06 20:04:06 +0200116 // Flag indicating that this virtual display is backed by the GPU.
117 static constexpr uint64_t FLAG_GPU = 1ULL << 61;
118
119 static constexpr std::optional<VirtualDisplayId> tryCast(DisplayId id) {
120 if (id.value & FLAG_VIRTUAL) {
121 return {VirtualDisplayId(id)};
122 }
123 return std::nullopt;
124 }
125
126protected:
127 constexpr VirtualDisplayId(uint64_t flags, BaseId baseId)
128 : DisplayId(DisplayId::FLAG_VIRTUAL | flags | baseId) {}
129
130 explicit constexpr VirtualDisplayId(DisplayId other) : DisplayId(other) {}
131};
132
133struct HalVirtualDisplayId : VirtualDisplayId {
134 explicit constexpr HalVirtualDisplayId(BaseId baseId) : VirtualDisplayId(0, baseId) {}
135
136 static constexpr std::optional<HalVirtualDisplayId> tryCast(DisplayId id) {
137 if ((id.value & FLAG_VIRTUAL) && !(id.value & VirtualDisplayId::FLAG_GPU)) {
138 return {HalVirtualDisplayId(id)};
139 }
140 return std::nullopt;
141 }
142
143private:
144 explicit constexpr HalVirtualDisplayId(DisplayId other) : VirtualDisplayId(other) {}
145};
146
147struct GpuVirtualDisplayId : VirtualDisplayId {
148 explicit constexpr GpuVirtualDisplayId(BaseId baseId)
149 : VirtualDisplayId(VirtualDisplayId::FLAG_GPU, baseId) {}
150
151 static constexpr std::optional<GpuVirtualDisplayId> tryCast(DisplayId id) {
152 if ((id.value & FLAG_VIRTUAL) && (id.value & VirtualDisplayId::FLAG_GPU)) {
153 return {GpuVirtualDisplayId(id)};
154 }
155 return std::nullopt;
156 }
157
158private:
159 explicit constexpr GpuVirtualDisplayId(DisplayId other) : VirtualDisplayId(other) {}
160};
161
162// HalDisplayId is the ID of a display which is managed by HWC.
163// PhysicalDisplayId and HalVirtualDisplayId are implicitly convertible to HalDisplayId.
164struct HalDisplayId : DisplayId {
165 constexpr HalDisplayId(HalVirtualDisplayId other) : DisplayId(other) {}
166 constexpr HalDisplayId(PhysicalDisplayId other) : DisplayId(other) {}
167
168 static constexpr std::optional<HalDisplayId> tryCast(DisplayId id) {
169 if (GpuVirtualDisplayId::tryCast(id)) {
170 return std::nullopt;
171 }
172 return {HalDisplayId(id)};
173 }
174
175private:
176 explicit constexpr HalDisplayId(DisplayId other) : DisplayId(other) {}
177};
178
Dominik Laskowskif1833852021-03-23 15:06:50 -0700179constexpr std::optional<DisplayId> DisplayId::fromValue(uint64_t value) {
180 if (const auto id = fromValue<PhysicalDisplayId>(value)) {
181 return id;
182 }
183 if (const auto id = fromValue<VirtualDisplayId>(value)) {
184 return id;
185 }
186 return {};
187}
188
189static_assert(sizeof(DisplayId) == sizeof(uint64_t));
190static_assert(sizeof(HalDisplayId) == sizeof(uint64_t));
Marin Shalamanov0f10d0d2020-08-06 20:04:06 +0200191static_assert(sizeof(VirtualDisplayId) == sizeof(uint64_t));
Dominik Laskowskif1833852021-03-23 15:06:50 -0700192
193static_assert(sizeof(PhysicalDisplayId) == sizeof(uint64_t));
Marin Shalamanov0f10d0d2020-08-06 20:04:06 +0200194static_assert(sizeof(HalVirtualDisplayId) == sizeof(uint64_t));
195static_assert(sizeof(GpuVirtualDisplayId) == sizeof(uint64_t));
Marin Shalamanov0f10d0d2020-08-06 20:04:06 +0200196
Marin Shalamanova524a092020-07-27 21:39:55 +0200197} // namespace android
198
199namespace std {
200
201template <>
202struct hash<android::DisplayId> {
203 size_t operator()(android::DisplayId displayId) const {
204 return hash<uint64_t>()(displayId.value);
205 }
206};
207
208template <>
209struct hash<android::PhysicalDisplayId> : hash<android::DisplayId> {};
210
Marin Shalamanov0f10d0d2020-08-06 20:04:06 +0200211template <>
212struct hash<android::HalVirtualDisplayId> : hash<android::DisplayId> {};
213
214template <>
215struct hash<android::GpuVirtualDisplayId> : hash<android::DisplayId> {};
216
217template <>
218struct hash<android::HalDisplayId> : hash<android::DisplayId> {};
219
Marin Shalamanova524a092020-07-27 21:39:55 +0200220} // namespace std