| 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 = default;
77 };
78
79 //------------------------------------------------------------------------------
80 /// @brief A wrapper for AHardwareBuffer
81 /// https://developer.android.com/ndk/reference/group/a-hardware-buffer
82 ///
83 /// This wrapper creates and owns a handle to a managed hardware
84 /// buffer. That is, there is no ability to take a reference to an
85 /// externally created hardware buffer.
86 ///
87 /// This wrapper is only available on Android API 29 and above.
88 ///
89 class HardwareBuffer {
90 public:
91 static bool IsAvailableOnPlatform();
92
93 explicit HardwareBuffer(HardwareBufferDescriptor descriptor);
94
95 ~HardwareBuffer();
96
97 HardwareBuffer(const HardwareBuffer&) = delete;
98
99 HardwareBuffer& operator=(const HardwareBuffer&) = delete;
100
101 bool IsValid() const;
102
103 AHardwareBuffer* GetHandle() const;
104
105 const HardwareBufferDescriptor& GetDescriptor() const;
106
107 const AHardwareBuffer_Desc& GetAndroidDescriptor() const;
108
109 static std::optional<AHardwareBuffer_Desc> Describe(AHardwareBuffer* buffer);
110
111 //----------------------------------------------------------------------------
112 /// @brief Get the system wide unique ID of the hardware buffer if
113 /// possible. This is only available on Android API 31 and above.
114 /// Within the process, the handle are unique.
115 ///
116 /// @return The system unique id if one can be obtained.
117 ///
118 std::optional<uint64_t> GetSystemUniqueID() const;
119
120 //----------------------------------------------------------------------------
121 /// @brief Get the system wide unique ID of the hardware buffer if
122 /// possible. This is only available on Android API 31 and above.
123 /// Within the process, the handle are unique.
124 ///
125 /// @return The system unique id if one can be obtained.
126 ///
127 static std::optional<uint64_t> GetSystemUniqueID(AHardwareBuffer* buffer);
128
129 enum class CPUAccessType {
130 kRead,
131 kWrite,
132 };
133 //----------------------------------------------------------------------------
134 /// @brief Lock the buffer for CPU access. This call may fail if the
135 /// buffer was not created with one the usages that allow for CPU
136 /// access.
137 ///
138 /// @param[in] type The type
139 ///
140 /// @return A host-accessible buffer if there was no error related to
141 /// usage or buffer validity.
142 ///
143 void* Lock(CPUAccessType type) const;
144
145 //----------------------------------------------------------------------------
146 /// @brief Unlock a mapping previously locked for CPU access.
147 ///
148 /// @return If the unlock was successful.
149 ///
150 bool Unlock() const;
151
152 private:
153 struct UniqueAHardwareBufferTraits {
154 static AHardwareBuffer* InvalidValue() { return nullptr; }
155
156 static bool IsValid(AHardwareBuffer* value) {
157 return value != InvalidValue();
158 }
159
160 static void Free(AHardwareBuffer* value) {
161 GetProcTable().AHardwareBuffer_release(value);
162 }
163 };
164
165 const HardwareBufferDescriptor descriptor_;
166 const AHardwareBuffer_Desc android_descriptor_;
167 fml::UniqueObject<AHardwareBuffer*, UniqueAHardwareBufferTraits> buffer_;
168 bool is_valid_ = false;
169 };
170
171 } // namespace impeller::android
172
173 namespace impeller {
174
175 IMPELLER_ENUM_IS_MASK(android::HardwareBufferUsageFlags);
176
177 } // namespace impeller
178
179 #endif // FLUTTER_IMPELLER_TOOLKIT_ANDROID_HARDWARE_BUFFER_H_
proc_table.h
type
GLenum type
Definition: blit_command_gles.cc:153
impeller::android::HardwareBuffer
A wrapper for AHardwareBuffer https://developer.android.com/ndk/reference/group/a-hardware-buffer.
Definition: hardware_buffer.h:89
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:129
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:459
mask.h
impeller::android
Definition: ahb_texture_source_vk_unittests.cc:16
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::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
impeller::android::HardwareBufferDescriptor::operator==
constexpr bool operator==(const HardwareBufferDescriptor &o) const =default