| 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"
14 #include "impeller/toolkit/android/proc_table.h"
15
16 namespace impeller::android {
17
18 enum class HardwareBufferFormat {
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 ///
28 kR8G8B8A8UNormInt,
29 };
30
31 enum class HardwareBufferUsageFlags {
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
42 using HardwareBufferUsage = Mask<HardwareBufferUsageFlags>;
43
44 //------------------------------------------------------------------------------
45 /// @brief A descriptor use to specify hardware buffer allocations.
46 ///
47 struct HardwareBufferDescriptor {
48 HardwareBufferFormat format = HardwareBufferFormat::kR8G8B8A8UNormInt;
49 ISize size;
50 HardwareBufferUsage usage = HardwareBufferUsageFlags::kNone;
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 ///
65 static HardwareBufferDescriptor MakeForSwapchainImage(const ISize& size);
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 ///
95 class HardwareBuffer {
96 public:
97 static bool IsAvailableOnPlatform();
98
99 explicit HardwareBuffer(HardwareBufferDescriptor descriptor);
100
101 ~HardwareBuffer();
102
103 HardwareBuffer(const HardwareBuffer&) = delete;
104
105 HardwareBuffer& operator=(const HardwareBuffer&) = delete;
106
107 bool IsValid() const;
108
109 AHardwareBuffer* GetHandle() const;
110
111 const HardwareBufferDescriptor& GetDescriptor() const;
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
181 IMPELLER_ENUM_IS_MASK(android::HardwareBufferUsageFlags);
182
183 } // namespace impeller
184
185 #endif // FLUTTER_IMPELLER_TOOLKIT_ANDROID_HARDWARE_BUFFER_H_
proc_table.h
type
GLenum type
Definition: blit_command_gles.cc:151
impeller::android::HardwareBuffer
A wrapper for AHardwareBuffer https://developer.android.com/ndk/reference/group/a-hardware-buffer.
Definition: hardware_buffer.h:95
impeller::android::HardwareBuffer::HardwareBuffer
HardwareBuffer(HardwareBufferDescriptor descriptor)
Definition: hardware_buffer.cc:57
impeller::android::HardwareBuffer::IsAvailableOnPlatform
static bool IsAvailableOnPlatform()
Definition: hardware_buffer.cc:107
impeller::android::HardwareBuffer::GetDescriptor
const HardwareBufferDescriptor & GetDescriptor() const
Definition: hardware_buffer.cc:99
impeller::android::HardwareBuffer::GetHandle
AHardwareBuffer * GetHandle() const
Definition: hardware_buffer.cc:83
impeller::android::HardwareBuffer::GetAndroidDescriptor
const AHardwareBuffer_Desc & GetAndroidDescriptor() const
Definition: hardware_buffer.cc:103
impeller::android::HardwareBuffer::operator=
HardwareBuffer & operator=(const HardwareBuffer &)=delete
impeller::android::HardwareBuffer::IsValid
bool IsValid() const
Definition: hardware_buffer.cc:79
impeller::android::HardwareBuffer::Unlock
bool Unlock() const
Unlock a mapping previously locked for CPU access.
Definition: hardware_buffer.cc:161
impeller::android::HardwareBuffer::~HardwareBuffer
~HardwareBuffer()
impeller::android::HardwareBuffer::Describe
static std::optional< AHardwareBuffer_Desc > Describe(AHardwareBuffer *buffer)
Definition: hardware_buffer.cc:127
impeller::android::HardwareBuffer::CPUAccessType
CPUAccessType
Definition: hardware_buffer.h:135
impeller::android::HardwareBuffer::CPUAccessType::kRead
@ kRead
impeller::android::HardwareBuffer::CPUAccessType::kWrite
@ kWrite
impeller::android::HardwareBuffer::HardwareBuffer
HardwareBuffer(const HardwareBuffer &)=delete
impeller::android::HardwareBuffer::Lock
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 ...
Definition: hardware_buffer.cc:137
impeller::android::HardwareBuffer::GetSystemUniqueID
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...
Definition: hardware_buffer.cc:111
value
int32_t value
Definition: dl_golden_unittests.cc:444
mask.h
impeller::android
Definition: choreographer.cc:9
impeller::android::GetProcTable
const ProcTable & GetProcTable()
Definition: proc_table.cc:12
impeller::android::HardwareBufferFormat
HardwareBufferFormat
Definition: hardware_buffer.h:18
impeller::android::HardwareBufferFormat::kR8G8B8A8UNormInt
@ kR8G8B8A8UNormInt
impeller::android::HardwareBufferUsageFlags
HardwareBufferUsageFlags
Definition: hardware_buffer.h:31
impeller::android::HardwareBufferUsageFlags::kCompositorOverlay
@ kCompositorOverlay
impeller::android::HardwareBufferUsageFlags::kNone
@ kNone
impeller::android::HardwareBufferUsageFlags::kFrameBufferAttachment
@ kFrameBufferAttachment
impeller::android::HardwareBufferUsageFlags::kCPUReadRarely
@ kCPUReadRarely
impeller::android::HardwareBufferUsageFlags::kCPUWriteOften
@ kCPUWriteOften
impeller::android::HardwareBufferUsageFlags::kCPUReadOften
@ kCPUReadOften
impeller::android::HardwareBufferUsageFlags::kSampledImage
@ kSampledImage
impeller::android::HardwareBufferUsageFlags::kCPUWriteRarely
@ kCPUWriteRarely
impeller
Definition: allocation.cc:12
impeller::IMPELLER_ENUM_IS_MASK
IMPELLER_ENUM_IS_MASK(MyMaskBits)
size.h
impeller::Mask< HardwareBufferUsageFlags >
impeller::TSize
Definition: size.h:25
impeller::android::HardwareBufferDescriptor
A descriptor use to specify hardware buffer allocations.
Definition: hardware_buffer.h:47
impeller::android::HardwareBufferDescriptor::MakeForSwapchainImage
static HardwareBufferDescriptor MakeForSwapchainImage(const ISize &size)
Create a descriptor of the given size that is suitable for use as a swapchain image.
Definition: hardware_buffer.cc:87
impeller::android::HardwareBufferDescriptor::operator==
constexpr bool operator==(const HardwareBufferDescriptor &o) const
Definition: hardware_buffer.h:76
impeller::android::HardwareBufferDescriptor::operator!=
constexpr bool operator!=(const HardwareBufferDescriptor &o) const
Definition: hardware_buffer.h:80
impeller::android::HardwareBufferDescriptor::size
ISize size
Definition: hardware_buffer.h:49
impeller::android::HardwareBufferDescriptor::usage
HardwareBufferUsage usage
Definition: hardware_buffer.h:50
impeller::android::HardwareBufferDescriptor::IsAllocatable
bool IsAllocatable() const
If hardware buffers can be created using this descriptor. Allocatable descriptors may still cause fai...
Definition: hardware_buffer.cc:52
impeller::android::HardwareBufferDescriptor::format
HardwareBufferFormat format
Definition: hardware_buffer.h:48