Flutter Impeller
hardware_buffer.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef FLUTTER_IMPELLER_TOOLKIT_ANDROID_HARDWARE_BUFFER_H_
6 #define FLUTTER_IMPELLER_TOOLKIT_ANDROID_HARDWARE_BUFFER_H_
7 
8 #include <optional>
9 
10 #include "flutter/fml/unique_fd.h"
11 #include "flutter/fml/unique_object.h"
12 #include "impeller/base/mask.h"
13 #include "impeller/geometry/size.h"
15 
16 namespace impeller::android {
17 
19  //----------------------------------------------------------------------------
20  /// This format is guaranteed to be supported on all versions of Android. This
21  /// format can also be converted to an Impeller and Vulkan format.
22  ///
23  /// @see Vulkan Format: VK_FORMAT_R8G8B8A8_UNORM
24  /// @see OpenGL ES Format: GL_RGBA8
25  ///
26  /// Why have many format when one format do trick?
27  ///
29 };
30 
32  kNone = 0u,
33  kFrameBufferAttachment = 1u << 0u,
34  kCompositorOverlay = 1u << 1u,
35  kSampledImage = 1u << 2u,
36  kCPUReadRarely = 1u << 3u,
37  kCPUReadOften = 1u << 4u,
38  kCPUWriteRarely = 1u << 5u,
39  kCPUWriteOften = 1u << 6u,
40 };
41 
43 
44 //------------------------------------------------------------------------------
45 /// @brief A descriptor use to specify hardware buffer allocations.
46 ///
51 
52  //----------------------------------------------------------------------------
53  /// @brief Create a descriptor of the given size that is suitable for use
54  /// as a swapchain image.
55  ///
56  /// @warning Descriptors of zero size are not allocatable. The next best
57  /// valid size is picked. So make sure to check the actual size of
58  /// the descriptor after this call is made to determine the size
59  /// of the allocated hardware buffer.
60  ///
61  /// @param[in] size The size. See the restrictions about valid sizes above.
62  ///
63  /// @return The hardware buffer descriptor.
64  ///
66 
67  //----------------------------------------------------------------------------
68  /// @brief If hardware buffers can be created using this descriptor.
69  /// Allocatable descriptors may still cause failing allocations in
70  /// case of resource exhaustion.
71  ///
72  /// @return `true` if allocatable (unless resource exhaustion).
73  ///
74  bool IsAllocatable() const;
75 
76  constexpr bool operator==(const HardwareBufferDescriptor& o) const {
77  return format == o.format && size == o.size && usage == o.usage;
78  }
79 
80  constexpr bool operator!=(const HardwareBufferDescriptor& o) const {
81  return !(*this == o);
82  }
83 };
84 
85 //------------------------------------------------------------------------------
86 /// @brief A wrapper for AHardwareBuffer
87 /// https://developer.android.com/ndk/reference/group/a-hardware-buffer
88 ///
89 /// This wrapper creates and owns a handle to a managed hardware
90 /// buffer. That is, there is no ability to take a reference to an
91 /// externally created hardware buffer.
92 ///
93 /// This wrapper is only available on Android API 29 and above.
94 ///
96  public:
97  static bool IsAvailableOnPlatform();
98 
99  explicit HardwareBuffer(HardwareBufferDescriptor descriptor);
100 
102 
103  HardwareBuffer(const HardwareBuffer&) = delete;
104 
106 
107  bool IsValid() const;
108 
109  AHardwareBuffer* GetHandle() const;
110 
112 
113  const AHardwareBuffer_Desc& GetAndroidDescriptor() const;
114 
115  static std::optional<AHardwareBuffer_Desc> Describe(AHardwareBuffer* buffer);
116 
117  //----------------------------------------------------------------------------
118  /// @brief Get the system wide unique ID of the hardware buffer if
119  /// possible. This is only available on Android API 31 and above.
120  /// Within the process, the handle are unique.
121  ///
122  /// @return The system unique id if one can be obtained.
123  ///
124  std::optional<uint64_t> GetSystemUniqueID() const;
125 
126  //----------------------------------------------------------------------------
127  /// @brief Get the system wide unique ID of the hardware buffer if
128  /// possible. This is only available on Android API 31 and above.
129  /// Within the process, the handle are unique.
130  ///
131  /// @return The system unique id if one can be obtained.
132  ///
133  static std::optional<uint64_t> GetSystemUniqueID(AHardwareBuffer* buffer);
134 
135  enum class CPUAccessType {
136  kRead,
137  kWrite,
138  };
139  //----------------------------------------------------------------------------
140  /// @brief Lock the buffer for CPU access. This call may fail if the
141  /// buffer was not created with one the usages that allow for CPU
142  /// access.
143  ///
144  /// @param[in] type The type
145  ///
146  /// @return A host-accessible buffer if there was no error related to
147  /// usage or buffer validity.
148  ///
149  void* Lock(CPUAccessType type) const;
150 
151  //----------------------------------------------------------------------------
152  /// @brief Unlock a mapping previously locked for CPU access.
153  ///
154  /// @return If the unlock was successful.
155  ///
156  bool Unlock() const;
157 
158  private:
159  struct UniqueAHardwareBufferTraits {
160  static AHardwareBuffer* InvalidValue() { return nullptr; }
161 
162  static bool IsValid(AHardwareBuffer* value) {
163  return value != InvalidValue();
164  }
165 
166  static void Free(AHardwareBuffer* value) {
167  GetProcTable().AHardwareBuffer_release(value);
168  }
169  };
170 
171  const HardwareBufferDescriptor descriptor_;
172  const AHardwareBuffer_Desc android_descriptor_;
173  fml::UniqueObject<AHardwareBuffer*, UniqueAHardwareBufferTraits> buffer_;
174  bool is_valid_ = false;
175 };
176 
177 } // namespace impeller::android
178 
179 namespace impeller {
180 
182 
183 } // namespace impeller
184 
185 #endif // FLUTTER_IMPELLER_TOOLKIT_ANDROID_HARDWARE_BUFFER_H_
GLenum type
A wrapper for AHardwareBuffer https://developer.android.com/ndk/reference/group/a-hardware-buffer.
HardwareBuffer(HardwareBufferDescriptor descriptor)
const HardwareBufferDescriptor & GetDescriptor() const
AHardwareBuffer * GetHandle() const
const AHardwareBuffer_Desc & GetAndroidDescriptor() const
HardwareBuffer & operator=(const HardwareBuffer &)=delete
bool Unlock() const
Unlock a mapping previously locked for CPU access.
static std::optional< AHardwareBuffer_Desc > Describe(AHardwareBuffer *buffer)
HardwareBuffer(const HardwareBuffer &)=delete
void * Lock(CPUAccessType type) const
Lock the buffer for CPU access. This call may fail if the buffer was not created with one the usages ...
std::optional< uint64_t > GetSystemUniqueID() const
Get the system wide unique ID of the hardware buffer if possible. This is only available on Android A...
int32_t value
const ProcTable & GetProcTable()
Definition: proc_table.cc:12
IMPELLER_ENUM_IS_MASK(MyMaskBits)
A descriptor use to specify hardware buffer allocations.
static HardwareBufferDescriptor MakeForSwapchainImage(const ISize &size)
Create a descriptor of the given size that is suitable for use as a swapchain image.
constexpr bool operator==(const HardwareBufferDescriptor &o) const
constexpr bool operator!=(const HardwareBufferDescriptor &o) const
bool IsAllocatable() const
If hardware buffers can be created using this descriptor. Allocatable descriptors may still cause fai...