| Flutter Impeller |

hardware_buffer.cc
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 #include "impeller/toolkit/android/hardware_buffer.h"
6
7 #include "impeller/base/validation.h"
8
9 namespace impeller::android {
10
11 static AHardwareBuffer_Format ToAHardwareBufferFormat(
12 HardwareBufferFormat format) {
13 switch (format) {
14 case HardwareBufferFormat::kR8G8B8A8UNormInt:
15 return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
16 }
17 FML_UNREACHABLE();
18 }
19
20 static AHardwareBuffer_Desc ToAHardwareBufferDesc(
21 const HardwareBufferDescriptor& desc) {
22 AHardwareBuffer_Desc ahb_desc = {};
23 ahb_desc.width = desc.size.width;
24 ahb_desc.height = desc.size.height;
25 ahb_desc.format = ToAHardwareBufferFormat(desc.format);
26 ahb_desc.layers = 1u;
27 if (desc.usage & static_cast<HardwareBufferUsage>(
28 HardwareBufferUsageFlags::kFrameBufferAttachment)) {
29 ahb_desc.usage |= AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER;
30 }
31 if (desc.usage & static_cast<HardwareBufferUsage>(
32 HardwareBufferUsageFlags::kCompositorOverlay)) {
33 ahb_desc.usage |= AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY;
34 }
35 if (desc.usage & static_cast<HardwareBufferUsage>(
36 HardwareBufferUsageFlags::kSampledImage)) {
37 ahb_desc.usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
38 }
39 return ahb_desc;
40 }
41
42 bool HardwareBufferDescriptor::IsAllocatable() const {
43 const auto desc = ToAHardwareBufferDesc(*this);
44 return GetProcTable().AHardwareBuffer_isSupported(&desc) != 0u;
45 }
46
47 HardwareBuffer::HardwareBuffer(HardwareBufferDescriptor descriptor)
48 : descriptor_(descriptor),
49 android_descriptor_(ToAHardwareBufferDesc(descriptor_)) {
50 if (!descriptor_.IsAllocatable()) {
51 VALIDATION_LOG << "The hardware buffer descriptor is not allocatable.";
52 return;
53 }
54 const auto& proc_table = GetProcTable();
55
56 AHardwareBuffer* buffer = nullptr;
57 if (auto result =
58 proc_table.AHardwareBuffer_allocate(&android_descriptor_, &buffer);
59 result != 0 || buffer == nullptr) {
60 VALIDATION_LOG << "Could not allocate hardware buffer. Error: " << result;
61 return;
62 }
63 buffer_.reset(buffer);
64 is_valid_ = true;
65 }
66
67 HardwareBuffer::~HardwareBuffer() = default;
68
69 bool HardwareBuffer::IsValid() const {
70 return is_valid_;
71 }
72
73 AHardwareBuffer* HardwareBuffer::GetHandle() const {
74 return buffer_.get();
75 }
76
77 HardwareBufferDescriptor HardwareBufferDescriptor::MakeForSwapchainImage(
78 const ISize& size) {
79 HardwareBufferDescriptor desc;
80 desc.format = HardwareBufferFormat::kR8G8B8A8UNormInt;
81 // Zero sized hardware buffers cannot be allocated.
82 desc.size = size.Max(ISize{1u, 1u});
83 desc.usage =
84 static_cast<HardwareBufferUsage>(
85 HardwareBufferUsageFlags::kFrameBufferAttachment) |
86 static_cast<HardwareBufferUsage>(
87 HardwareBufferUsageFlags::kCompositorOverlay) |
88 static_cast<HardwareBufferUsage>(HardwareBufferUsageFlags::kSampledImage);
89 return desc;
90 }
91
92 const HardwareBufferDescriptor& HardwareBuffer::GetDescriptor() const {
93 return descriptor_;
94 }
95
96 const AHardwareBuffer_Desc& HardwareBuffer::GetAndroidDescriptor() const {
97 return android_descriptor_;
98 }
99
100 bool HardwareBuffer::IsAvailableOnPlatform() {
101 return GetProcTable().IsValid() && GetProcTable().AHardwareBuffer_isSupported;
102 }
103
104 std::optional<uint64_t> HardwareBuffer::GetSystemUniqueID() const {
105 return GetSystemUniqueID(GetHandle());
106 }
107
108 std::optional<uint64_t> HardwareBuffer::GetSystemUniqueID(
109 AHardwareBuffer* buffer) {
110 if (!GetProcTable().AHardwareBuffer_getId) {
111 return std::nullopt;
112 }
113 uint64_t out_id = 0u;
114 if (GetProcTable().AHardwareBuffer_getId(buffer, &out_id) != 0) {
115 return std::nullopt;
116 }
117 return out_id;
118 }
119
120 std::optional<AHardwareBuffer_Desc> HardwareBuffer::Describe(
121 AHardwareBuffer* buffer) {
122 if (!buffer || !GetProcTable().AHardwareBuffer_describe) {
123 return std::nullopt;
124 }
125 AHardwareBuffer_Desc desc = {};
126 GetProcTable().AHardwareBuffer_describe(buffer, &desc);
127 return desc;
128 }
129
130 } // namespace impeller::android
hardware_buffer.h
impeller::android::HardwareBuffer::IsAvailableOnPlatform
static bool IsAvailableOnPlatform()
Definition: hardware_buffer.cc:100
impeller::android::HardwareBufferUsage
uint8_t HardwareBufferUsage
Definition: hardware_buffer.h:29
impeller::android::HardwareBufferUsageFlags::kCompositorOverlay
@ kCompositorOverlay
impeller::android::ToAHardwareBufferDesc
static AHardwareBuffer_Desc ToAHardwareBufferDesc(const HardwareBufferDescriptor &desc)
Definition: hardware_buffer.cc:20
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:104
impeller::android::HardwareBuffer::GetDescriptor
const HardwareBufferDescriptor & GetDescriptor() const
Definition: hardware_buffer.cc:92
validation.h
impeller::android::HardwareBufferUsageFlags::kSampledImage
@ kSampledImage
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:77
impeller::android
Definition: choreographer.cc:9
impeller::TSize< int64_t >
impeller::android::HardwareBufferFormat
HardwareBufferFormat
Definition: hardware_buffer.h:16
impeller::TSize::Max
constexpr TSize Max(const TSize &o) const
Definition: size.h:81
impeller::android::ProcTable::IsValid
bool IsValid() const
If a valid proc table could be setup. This may fail in case of setup on non-Android platforms.
Definition: proc_table.cc:65
impeller::android::HardwareBuffer::~HardwareBuffer
~HardwareBuffer()
impeller::android::HardwareBufferFormat::kR8G8B8A8UNormInt
@ kR8G8B8A8UNormInt
impeller::android::ToAHardwareBufferFormat
static AHardwareBuffer_Format ToAHardwareBufferFormat(HardwareBufferFormat format)
Definition: hardware_buffer.cc:11
impeller::android::HardwareBufferDescriptor
A descriptor use to specify hardware buffer allocations.
Definition: hardware_buffer.h:40
impeller::android::HardwareBuffer::GetHandle
AHardwareBuffer * GetHandle() const
Definition: hardware_buffer.cc:73
impeller::TSize::width
Type width
Definition: size.h:22
impeller::android::HardwareBufferDescriptor::size
ISize size
Definition: hardware_buffer.h:42
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:73
impeller::android::HardwareBuffer::Describe
static std::optional< AHardwareBuffer_Desc > Describe(AHardwareBuffer *buffer)
Definition: hardware_buffer.cc:120
impeller::android::HardwareBufferDescriptor::usage
HardwareBufferUsage usage
Definition: hardware_buffer.h:43
impeller::android::HardwareBuffer::HardwareBuffer
HardwareBuffer(HardwareBufferDescriptor descriptor)
Definition: hardware_buffer.cc:47
impeller::android::GetProcTable
const ProcTable & GetProcTable()
Definition: proc_table.cc:12
impeller::android::HardwareBuffer::IsValid
bool IsValid() const
Definition: hardware_buffer.cc:69
impeller::android::HardwareBufferUsageFlags::kFrameBufferAttachment
@ kFrameBufferAttachment
impeller::TSize::height
Type height
Definition: size.h:23
impeller::android::HardwareBufferDescriptor::format
HardwareBufferFormat format
Definition: hardware_buffer.h:41
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:42
impeller::android::HardwareBuffer::GetAndroidDescriptor
const AHardwareBuffer_Desc & GetAndroidDescriptor() const
Definition: hardware_buffer.cc:96