hwc_types.h revision 2251d822dac2a96aad4184a6fdc2690f0a58af7c
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
21namespace 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.
25using ColorMode = int32_t;  // android_color_mode_t;
26using Config = hwc2_config_t;
27using ColorTransform =
28    std::underlying_type<android_color_transform_t>::type;          // int32_t;
29using Dataspace = std::underlying_type<android_dataspace_t>::type;  // int32_t;
30using DisplayId = hwc2_display_t;
31using DisplayRequest = std::underlying_type<HWC2::DisplayRequest>::type;
32using Hdr = std::underlying_type<android_hdr_t>::type;  // int32_t;
33using Layer = hwc2_layer_t;
34using 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.
40template <typename...>
41using TestTypeExpression = void;
42
43// Traits type to determine the underlying type of an enum, integer,
44// or wrapper class.
45template <typename T, typename = typename std::is_enum<T>::type,
46          typename = typename std::is_integral<T>::type, typename = void>
47struct 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.
52template <typename T>
53struct 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.
58template <typename T>
59struct 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.
64template <typename T>
65struct 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.
71template <typename T, typename U, typename ReturnType = void>
72using 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.
79template <typename T, typename U, typename Return = void>
80using 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.
90template <typename T, typename U>
91EnableIfSafeCast<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.
100template <typename EnumType>
101struct 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  Wrapper(ValueType value) : value(value) {}
120
121  // Implicit conversion from BaseType.
122  Wrapper(BaseType value) : value(static_cast<ValueType>(value)) {}
123
124  // Implicit conversion from an enum type of the same underlying type.
125  template <typename T, typename = EnableIfMatchingEnum<T, ValueType>>
126  Wrapper(const T& value) : value(static_cast<ValueType>(value)) {}
127
128  // Implicit conversion to BaseType.
129  operator BaseType() const { return static_cast<BaseType>(value); }
130
131  // Implicit conversion to ValueType.
132  operator ValueType() const { return value; }
133
134  template <typename T, typename = EnableIfMatchingEnum<T, ValueType>>
135  T cast() const {
136    return static_cast<T>(value);
137  }
138
139  // Converts to string using HWC2 stringification of BaseType.
140  std::string to_string() const {
141    return HWC2::to_string(static_cast<BaseType>(value));
142  }
143
144  bool operator!=(const Wrapper& other) const { return value != other.value; }
145  bool operator!=(ValueType other_value) const { return value != other_value; }
146  bool operator!=(BaseType other_value) const {
147    return static_cast<BaseType>(value) != other_value;
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
155  ValueType value;
156};
157
158struct Attribute final : public Wrapper<HWC2::Attribute> {
159  enum : ValueType {
160    Invalid = HWC2_ATTRIBUTE_INVALID,
161    Width = HWC2_ATTRIBUTE_WIDTH,
162    Height = HWC2_ATTRIBUTE_HEIGHT,
163    VsyncPeriod = HWC2_ATTRIBUTE_VSYNC_PERIOD,
164    DpiX = HWC2_ATTRIBUTE_DPI_X,
165    DpiY = HWC2_ATTRIBUTE_DPI_Y,
166  };
167
168  Attribute() : Base(Invalid) {}
169  using Base::Base;
170};
171
172struct BlendMode final : public Wrapper<HWC2::BlendMode> {
173  enum : ValueType {
174    Invalid = HWC2_BLEND_MODE_INVALID,
175    None = HWC2_BLEND_MODE_NONE,
176    Premultiplied = HWC2_BLEND_MODE_PREMULTIPLIED,
177    Coverage = HWC2_BLEND_MODE_COVERAGE,
178  };
179
180  BlendMode() : Base(Invalid) {}
181  using Base::Base;
182};
183
184struct Composition final : public Wrapper<HWC2::Composition> {
185  enum : ValueType {
186    Invalid = HWC2_COMPOSITION_INVALID,
187    Client = HWC2_COMPOSITION_CLIENT,
188    Device = HWC2_COMPOSITION_DEVICE,
189    SolidColor = HWC2_COMPOSITION_SOLID_COLOR,
190    Cursor = HWC2_COMPOSITION_CURSOR,
191    Sideband = HWC2_COMPOSITION_SIDEBAND,
192  };
193
194  Composition() : Base(Invalid) {}
195  using Base::Base;
196};
197
198struct DisplayType final : public Wrapper<HWC2::DisplayType> {
199  enum : ValueType {
200    Invalid = HWC2_DISPLAY_TYPE_INVALID,
201    Physical = HWC2_DISPLAY_TYPE_PHYSICAL,
202    Virtual = HWC2_DISPLAY_TYPE_VIRTUAL,
203  };
204
205  DisplayType() : Base(Invalid) {}
206  using Base::Base;
207};
208
209struct Error final : public Wrapper<HWC2::Error> {
210  enum : ValueType {
211    None = HWC2_ERROR_NONE,
212    BadConfig = HWC2_ERROR_BAD_CONFIG,
213    BadDisplay = HWC2_ERROR_BAD_DISPLAY,
214    BadLayer = HWC2_ERROR_BAD_LAYER,
215    BadParameter = HWC2_ERROR_BAD_PARAMETER,
216    HasChanges = HWC2_ERROR_HAS_CHANGES,
217    NoResources = HWC2_ERROR_NO_RESOURCES,
218    NotValidated = HWC2_ERROR_NOT_VALIDATED,
219    Unsupported = HWC2_ERROR_UNSUPPORTED,
220  };
221
222  Error() : Base(None) {}
223  using Base::Base;
224};
225
226struct LayerRequest final : public Wrapper<HWC2::LayerRequest> {
227  enum : ValueType {
228    ClearClientTarget = HWC2_LAYER_REQUEST_CLEAR_CLIENT_TARGET,
229  };
230
231  LayerRequest() : Base(0) {}
232  using Base::Base;
233};
234
235struct PowerMode final : public Wrapper<HWC2::PowerMode> {
236  enum : ValueType {
237    Off = HWC2_POWER_MODE_OFF,
238    DozeSuspend = HWC2_POWER_MODE_DOZE_SUSPEND,
239    Doze = HWC2_POWER_MODE_DOZE,
240    On = HWC2_POWER_MODE_ON,
241  };
242
243  PowerMode() : Base(Off) {}
244  using Base::Base;
245};
246
247struct Transform final : public Wrapper<HWC2::Transform> {
248  enum : ValueType {
249    None = 0,
250    FlipH = HWC_TRANSFORM_FLIP_H,
251    FlipV = HWC_TRANSFORM_FLIP_V,
252    Rotate90 = HWC_TRANSFORM_ROT_90,
253    Rotate180 = HWC_TRANSFORM_ROT_180,
254    Rotate270 = HWC_TRANSFORM_ROT_270,
255    FlipHRotate90 = HWC_TRANSFORM_FLIP_H_ROT_90,
256    FlipVRotate90 = HWC_TRANSFORM_FLIP_V_ROT_90,
257  };
258
259  Transform() : Base(None) {}
260  using Base::Base;
261};
262
263struct Vsync final : public Wrapper<HWC2::Vsync> {
264  enum : ValueType {
265    Invalid = HWC2_VSYNC_INVALID,
266    Enable = HWC2_VSYNC_ENABLE,
267    Disable = HWC2_VSYNC_DISABLE,
268  };
269
270  Vsync() : Base(Invalid) {}
271  using Base::Base;
272};
273
274// Utility color type.
275struct Color final {
276  Color(const Color&) = default;
277  Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a) : r(r), g(g), b(b), a(a) {}
278  Color(hwc_color_t color) : r(color.r), g(color.g), b(color.b), a(color.a) {}
279
280  operator hwc_color_t() const { return {r, g, b, a}; }
281
282  uint8_t r __attribute__((aligned(1)));
283  uint8_t g __attribute__((aligned(1)));
284  uint8_t b __attribute__((aligned(1)));
285  uint8_t a __attribute__((aligned(1)));
286};
287
288// Utility rectangle type.
289struct Rect final {
290  // TODO(eieio): Implicit conversion to/from Android rect types.
291
292  int32_t left __attribute__((aligned(4)));
293  int32_t top __attribute__((aligned(4)));
294  int32_t right __attribute__((aligned(4)));
295  int32_t bottom __attribute__((aligned(4)));
296};
297
298}  // namespace HWC
299
300#endif  // ANDROID_LIBVRFLINGER_HWCTYPES_H
301