1 #ifndef ANDROID_LIBVRFLINGER_HWCTYPES_H 2 #define ANDROID_LIBVRFLINGER_HWCTYPES_H 3 4 // General HWC type support. Hardware composer type support is a bit of a mess 5 // between HWC1, HWC2 C/C++11, and HIDL types. Particularly bothersome is the 6 // use of enum classes, which make analogous types between versions much 7 // harder to deal with in a uniform way. 8 // 9 // These utilities help address some of these pains by providing a type-safe, 10 // flexible interface to translate between different type spaces. 11 12 #define HWC2_INCLUDE_STRINGIFICATION 13 #define HWC2_USE_CPP11 14 #include <hardware/hwcomposer2.h> 15 #undef HWC2_INCLUDE_STRINGIFICATION 16 #undef HWC2_USE_CPP11 17 18 #include <string> 19 #include <type_traits> 20 21 namespace HWC { 22 23 // Value types derived from HWC HAL types. Some of these are stand-alone, 24 // while others are also wrapped in translator classes below. 25 using ColorMode = int32_t; // android_color_mode_t; 26 using Config = hwc2_config_t; 27 using ColorTransform = 28 std::underlying_type<android_color_transform_t>::type; // int32_t; 29 using Dataspace = std::underlying_type<android_dataspace_t>::type; // int32_t; 30 using DisplayId = hwc2_display_t; 31 using DisplayRequest = std::underlying_type<HWC2::DisplayRequest>::type; 32 using Hdr = std::underlying_type<android_hdr_t>::type; // int32_t; 33 using Layer = hwc2_layer_t; 34 using PixelFormat = 35 std::underlying_type<android_pixel_format_t>::type; // int32_t; 36 37 // Type traits and casting utilities. 38 39 // SFINAE utility to evaluate type expressions. 40 template <typename...> 41 using TestTypeExpression = void; 42 43 // Traits type to determine the underlying type of an enum, integer, 44 // or wrapper class. 45 template <typename T, typename = typename std::is_enum<T>::type, 46 typename = typename std::is_integral<T>::type, typename = void> 47 struct UnderlyingType { 48 using Type = T; 49 }; 50 // Partial specialization that matches enum types. Captures the underlying type 51 // of the enum in member type Type. 52 template <typename T> 53 struct UnderlyingType<T, std::true_type, std::false_type> { 54 using Type = typename std::underlying_type<T>::type; 55 }; 56 // Partial specialization that matches integral types. Captures the type of the 57 // integer in member type Type. 58 template <typename T> 59 struct UnderlyingType<T, std::false_type, std::true_type> { 60 using Type = T; 61 }; 62 // Partial specialization that matches the wrapper types below. Captures 63 // wrapper member type ValueType in member type Type. 64 template <typename T> 65 struct UnderlyingType<T, std::false_type, std::false_type, 66 TestTypeExpression<typename T::ValueType>> { 67 using Type = typename T::ValueType; 68 }; 69 70 // Enable if T is an enum with underlying type U. 71 template <typename T, typename U, typename ReturnType = void> 72 using EnableIfMatchingEnum = typename std::enable_if< 73 std::is_enum<T>::value && 74 std::is_same<U, typename UnderlyingType<T>::Type>::value, 75 ReturnType>::type; 76 77 // Enable if T and U are the same size/alignment and have the same underlying 78 // type. Handles enum, integral, and wrapper classes below. 79 template <typename T, typename U, typename Return = void> 80 using EnableIfSafeCast = typename std::enable_if< 81 sizeof(T) == sizeof(U) && alignof(T) == alignof(U) && 82 std::is_same<typename UnderlyingType<T>::Type, 83 typename UnderlyingType<U>::Type>::value, 84 Return>::type; 85 86 // Safely cast between std::vectors of matching enum/integer/wraper types. 87 // Normally this is not possible with pendantic compiler type checks. However, 88 // given the same size, alignment, and underlying type this is safe due to 89 // allocator requirements and array-like element access guarantees. 90 template <typename T, typename U> 91 EnableIfSafeCast<T, U, std::vector<T>*> VectorCast(std::vector<U>* in) { 92 return reinterpret_cast<std::vector<T>*>(in); 93 } 94 95 // Translator classes that wrap specific HWC types to make translating 96 // between different types (especially enum class) in code cleaner. 97 98 // Base type for the enum wrappers below. This type provides type definitions 99 // and implicit conversion logic common to each wrapper type. 100 template <typename EnumType> 101 struct Wrapper { 102 // Alias type of this instantiantion of Wrapper. Useful for inheriting 103 // constructors in subclasses via "using Base::Base;" statements. 104 using Base = Wrapper<EnumType>; 105 106 // The enum type wrapped by this instantiation of Wrapper. 107 using BaseType = EnumType; 108 109 // The underlying type of the base enum type. 110 using ValueType = typename UnderlyingType<BaseType>::Type; 111 112 // A default constructor is not defined here. Subclasses should define one 113 // as appropriate to define the correct inital value for the enum type. 114 115 // Default copy constructor. 116 Wrapper(const Wrapper&) = default; 117 118 // Implicit conversion from ValueType. 119 // NOLINTNEXTLINE(google-explicit-constructor) 120 Wrapper(ValueType value) : value(value) {} 121 122 // Implicit conversion from BaseType. 123 // NOLINTNEXTLINE(google-explicit-constructor) 124 Wrapper(BaseType value) : value(static_cast<ValueType>(value)) {} 125 126 // Implicit conversion from an enum type of the same underlying type. 127 template <typename T, typename = EnableIfMatchingEnum<T, ValueType>> 128 // NOLINTNEXTLINE(google-explicit-constructor) 129 Wrapper(const T& value) : value(static_cast<ValueType>(value)) {} 130 131 // Implicit conversion to BaseType. 132 // NOLINTNEXTLINE(google-explicit-constructor) 133 operator BaseType() const { return static_cast<BaseType>(value); } 134 135 // Implicit conversion to ValueType. 136 // NOLINTNEXTLINE(google-explicit-constructor) 137 operator ValueType() const { return value; } 138 139 template <typename T, typename = EnableIfMatchingEnum<T, ValueType>> 140 T cast() const { 141 return static_cast<T>(value); 142 } 143 144 // Converts to string using HWC2 stringification of BaseType. 145 std::string to_string() const { 146 return HWC2::to_string(static_cast<BaseType>(value)); 147 } 148 149 bool operator!=(const Wrapper& other) const { return value != other.value; } 150 bool operator!=(ValueType other_value) const { return value != other_value; } 151 bool operator!=(BaseType other_value) const { 152 return static_cast<BaseType>(value) != other_value; 153 } 154 bool operator==(const Wrapper& other) const { return value == other.value; } 155 bool operator==(ValueType other_value) const { return value == other_value; } 156 bool operator==(BaseType other_value) const { 157 return static_cast<BaseType>(value) == other_value; 158 } 159 160 ValueType value; 161 }; 162 163 struct Attribute final : public Wrapper<HWC2::Attribute> { 164 enum : ValueType { 165 Invalid = HWC2_ATTRIBUTE_INVALID, 166 Width = HWC2_ATTRIBUTE_WIDTH, 167 Height = HWC2_ATTRIBUTE_HEIGHT, 168 VsyncPeriod = HWC2_ATTRIBUTE_VSYNC_PERIOD, 169 DpiX = HWC2_ATTRIBUTE_DPI_X, 170 DpiY = HWC2_ATTRIBUTE_DPI_Y, 171 }; 172 173 Attribute() : Base(Invalid) {} 174 using Base::Base; 175 }; 176 177 struct BlendMode final : public Wrapper<HWC2::BlendMode> { 178 enum : ValueType { 179 Invalid = HWC2_BLEND_MODE_INVALID, 180 None = HWC2_BLEND_MODE_NONE, 181 Premultiplied = HWC2_BLEND_MODE_PREMULTIPLIED, 182 Coverage = HWC2_BLEND_MODE_COVERAGE, 183 }; 184 185 BlendMode() : Base(Invalid) {} 186 using Base::Base; 187 }; 188 189 struct Composition final : public Wrapper<HWC2::Composition> { 190 enum : ValueType { 191 Invalid = HWC2_COMPOSITION_INVALID, 192 Client = HWC2_COMPOSITION_CLIENT, 193 Device = HWC2_COMPOSITION_DEVICE, 194 SolidColor = HWC2_COMPOSITION_SOLID_COLOR, 195 Cursor = HWC2_COMPOSITION_CURSOR, 196 Sideband = HWC2_COMPOSITION_SIDEBAND, 197 }; 198 199 Composition() : Base(Invalid) {} 200 using Base::Base; 201 }; 202 203 struct DisplayType final : public Wrapper<HWC2::DisplayType> { 204 enum : ValueType { 205 Invalid = HWC2_DISPLAY_TYPE_INVALID, 206 Physical = HWC2_DISPLAY_TYPE_PHYSICAL, 207 Virtual = HWC2_DISPLAY_TYPE_VIRTUAL, 208 }; 209 210 DisplayType() : Base(Invalid) {} 211 using Base::Base; 212 }; 213 214 struct Error final : public Wrapper<HWC2::Error> { 215 enum : ValueType { 216 None = HWC2_ERROR_NONE, 217 BadConfig = HWC2_ERROR_BAD_CONFIG, 218 BadDisplay = HWC2_ERROR_BAD_DISPLAY, 219 BadLayer = HWC2_ERROR_BAD_LAYER, 220 BadParameter = HWC2_ERROR_BAD_PARAMETER, 221 HasChanges = HWC2_ERROR_HAS_CHANGES, 222 NoResources = HWC2_ERROR_NO_RESOURCES, 223 NotValidated = HWC2_ERROR_NOT_VALIDATED, 224 Unsupported = HWC2_ERROR_UNSUPPORTED, 225 }; 226 227 Error() : Base(None) {} 228 using Base::Base; 229 }; 230 231 struct LayerRequest final : public Wrapper<HWC2::LayerRequest> { 232 enum : ValueType { 233 ClearClientTarget = HWC2_LAYER_REQUEST_CLEAR_CLIENT_TARGET, 234 }; 235 236 LayerRequest() : Base(0) {} 237 using Base::Base; 238 }; 239 240 struct PowerMode final : public Wrapper<HWC2::PowerMode> { 241 enum : ValueType { 242 Off = HWC2_POWER_MODE_OFF, 243 DozeSuspend = HWC2_POWER_MODE_DOZE_SUSPEND, 244 Doze = HWC2_POWER_MODE_DOZE, 245 On = HWC2_POWER_MODE_ON, 246 }; 247 248 PowerMode() : Base(Off) {} 249 using Base::Base; 250 }; 251 252 struct Transform final : public Wrapper<HWC2::Transform> { 253 enum : ValueType { 254 None = 0, 255 FlipH = HWC_TRANSFORM_FLIP_H, 256 FlipV = HWC_TRANSFORM_FLIP_V, 257 Rotate90 = HWC_TRANSFORM_ROT_90, 258 Rotate180 = HWC_TRANSFORM_ROT_180, 259 Rotate270 = HWC_TRANSFORM_ROT_270, 260 FlipHRotate90 = HWC_TRANSFORM_FLIP_H_ROT_90, 261 FlipVRotate90 = HWC_TRANSFORM_FLIP_V_ROT_90, 262 }; 263 264 Transform() : Base(None) {} 265 using Base::Base; 266 }; 267 268 struct Vsync final : public Wrapper<HWC2::Vsync> { 269 enum : ValueType { 270 Invalid = HWC2_VSYNC_INVALID, 271 Enable = HWC2_VSYNC_ENABLE, 272 Disable = HWC2_VSYNC_DISABLE, 273 }; 274 275 Vsync() : Base(Invalid) {} 276 using Base::Base; 277 }; 278 279 // Utility color type. 280 struct Color final { 281 Color(const Color&) = default; 282 Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a) : r(r), g(g), b(b), a(a) {} 283 // NOLINTNEXTLINE(google-explicit-constructor) 284 Color(hwc_color_t color) : r(color.r), g(color.g), b(color.b), a(color.a) {} 285 286 // NOLINTNEXTLINE(google-explicit-constructor) 287 operator hwc_color_t() const { return {r, g, b, a}; } 288 289 uint8_t r __attribute__((aligned(1))); 290 uint8_t g __attribute__((aligned(1))); 291 uint8_t b __attribute__((aligned(1))); 292 uint8_t a __attribute__((aligned(1))); 293 }; 294 295 // Utility rectangle type. 296 struct Rect final { 297 // TODO(eieio): Implicit conversion to/from Android rect types. 298 299 int32_t left __attribute__((aligned(4))); 300 int32_t top __attribute__((aligned(4))); 301 int32_t right __attribute__((aligned(4))); 302 int32_t bottom __attribute__((aligned(4))); 303 }; 304 305 } // namespace HWC 306 307 #endif // ANDROID_LIBVRFLINGER_HWCTYPES_H 308