xref: /aosp_15_r20/frameworks/native/libs/ui/Gralloc4.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright 2019 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "Gralloc4"
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include <aidl/android/hardware/graphics/allocator/AllocationError.h>
20*38e8c45fSAndroid Build Coastguard Worker #include <aidl/android/hardware/graphics/allocator/AllocationResult.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <aidl/android/hardware/graphics/common/BufferUsage.h>
22*38e8c45fSAndroid Build Coastguard Worker #include <aidlcommonsupport/NativeHandle.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <android/binder_enums.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <android/binder_manager.h>
25*38e8c45fSAndroid Build Coastguard Worker #include <cutils/android_filesystem_config.h>
26*38e8c45fSAndroid Build Coastguard Worker #include <cutils/multiuser.h>
27*38e8c45fSAndroid Build Coastguard Worker #include <gralloctypes/Gralloc4.h>
28*38e8c45fSAndroid Build Coastguard Worker #include <hidl/ServiceManagement.h>
29*38e8c45fSAndroid Build Coastguard Worker #include <hwbinder/IPCThreadState.h>
30*38e8c45fSAndroid Build Coastguard Worker #include <ui/Gralloc4.h>
31*38e8c45fSAndroid Build Coastguard Worker 
32*38e8c45fSAndroid Build Coastguard Worker #include <inttypes.h>
33*38e8c45fSAndroid Build Coastguard Worker #include <log/log.h>
34*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic push
35*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wzero-length-array"
36*38e8c45fSAndroid Build Coastguard Worker #include <sync/sync.h>
37*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic pop
38*38e8c45fSAndroid Build Coastguard Worker 
39*38e8c45fSAndroid Build Coastguard Worker using aidl::android::hardware::graphics::allocator::AllocationError;
40*38e8c45fSAndroid Build Coastguard Worker using aidl::android::hardware::graphics::allocator::AllocationResult;
41*38e8c45fSAndroid Build Coastguard Worker using aidl::android::hardware::graphics::common::ExtendableType;
42*38e8c45fSAndroid Build Coastguard Worker using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
43*38e8c45fSAndroid Build Coastguard Worker using aidl::android::hardware::graphics::common::StandardMetadataType;
44*38e8c45fSAndroid Build Coastguard Worker using android::hardware::hidl_vec;
45*38e8c45fSAndroid Build Coastguard Worker using android::hardware::graphics::allocator::V4_0::IAllocator;
46*38e8c45fSAndroid Build Coastguard Worker using android::hardware::graphics::common::V1_2::BufferUsage;
47*38e8c45fSAndroid Build Coastguard Worker using android::hardware::graphics::common::V1_2::PixelFormat;
48*38e8c45fSAndroid Build Coastguard Worker using android::hardware::graphics::mapper::V4_0::BufferDescriptor;
49*38e8c45fSAndroid Build Coastguard Worker using android::hardware::graphics::mapper::V4_0::Error;
50*38e8c45fSAndroid Build Coastguard Worker using android::hardware::graphics::mapper::V4_0::IMapper;
51*38e8c45fSAndroid Build Coastguard Worker using AidlIAllocator = ::aidl::android::hardware::graphics::allocator::IAllocator;
52*38e8c45fSAndroid Build Coastguard Worker using AidlBufferUsage = ::aidl::android::hardware::graphics::common::BufferUsage;
53*38e8c45fSAndroid Build Coastguard Worker using AidlDataspace = ::aidl::android::hardware::graphics::common::Dataspace;
54*38e8c45fSAndroid Build Coastguard Worker using AidlNativeHandle = ::aidl::android::hardware::common::NativeHandle;
55*38e8c45fSAndroid Build Coastguard Worker using BufferDump = android::hardware::graphics::mapper::V4_0::IMapper::BufferDump;
56*38e8c45fSAndroid Build Coastguard Worker using MetadataDump = android::hardware::graphics::mapper::V4_0::IMapper::MetadataDump;
57*38e8c45fSAndroid Build Coastguard Worker using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
58*38e8c45fSAndroid Build Coastguard Worker using MetadataTypeDescription =
59*38e8c45fSAndroid Build Coastguard Worker         android::hardware::graphics::mapper::V4_0::IMapper::MetadataTypeDescription;
60*38e8c45fSAndroid Build Coastguard Worker 
61*38e8c45fSAndroid Build Coastguard Worker namespace android {
62*38e8c45fSAndroid Build Coastguard Worker 
63*38e8c45fSAndroid Build Coastguard Worker namespace {
64*38e8c45fSAndroid Build Coastguard Worker 
65*38e8c45fSAndroid Build Coastguard Worker static constexpr Error kTransactionError = Error::NO_RESOURCES;
66*38e8c45fSAndroid Build Coastguard Worker static const auto kAidlAllocatorServiceName = AidlIAllocator::descriptor + std::string("/default");
67*38e8c45fSAndroid Build Coastguard Worker 
68*38e8c45fSAndroid Build Coastguard Worker // TODO(b/72323293, b/72703005): Remove these invalid bits from callers
69*38e8c45fSAndroid Build Coastguard Worker static constexpr uint64_t kRemovedUsageBits = static_cast<uint64_t>((1 << 10) | (1 << 13));
70*38e8c45fSAndroid Build Coastguard Worker 
getValidUsageBits()71*38e8c45fSAndroid Build Coastguard Worker uint64_t getValidUsageBits() {
72*38e8c45fSAndroid Build Coastguard Worker     static const uint64_t validUsageBits = []() -> uint64_t {
73*38e8c45fSAndroid Build Coastguard Worker         uint64_t bits = 0;
74*38e8c45fSAndroid Build Coastguard Worker         for (const auto bit :
75*38e8c45fSAndroid Build Coastguard Worker              hardware::hidl_enum_range<hardware::graphics::common::V1_2::BufferUsage>()) {
76*38e8c45fSAndroid Build Coastguard Worker             bits = bits | bit;
77*38e8c45fSAndroid Build Coastguard Worker         }
78*38e8c45fSAndroid Build Coastguard Worker         return bits;
79*38e8c45fSAndroid Build Coastguard Worker     }();
80*38e8c45fSAndroid Build Coastguard Worker     return validUsageBits | kRemovedUsageBits;
81*38e8c45fSAndroid Build Coastguard Worker }
82*38e8c45fSAndroid Build Coastguard Worker 
getValidUsageBits41()83*38e8c45fSAndroid Build Coastguard Worker uint64_t getValidUsageBits41() {
84*38e8c45fSAndroid Build Coastguard Worker     static const uint64_t validUsageBits = []() -> uint64_t {
85*38e8c45fSAndroid Build Coastguard Worker         uint64_t bits = 0;
86*38e8c45fSAndroid Build Coastguard Worker         for (const auto bit : ndk::enum_range<AidlBufferUsage>{}) {
87*38e8c45fSAndroid Build Coastguard Worker             bits |= static_cast<int64_t>(bit);
88*38e8c45fSAndroid Build Coastguard Worker         }
89*38e8c45fSAndroid Build Coastguard Worker         return bits;
90*38e8c45fSAndroid Build Coastguard Worker     }();
91*38e8c45fSAndroid Build Coastguard Worker     return validUsageBits;
92*38e8c45fSAndroid Build Coastguard Worker }
93*38e8c45fSAndroid Build Coastguard Worker 
sGralloc4Rect(const Rect & rect)94*38e8c45fSAndroid Build Coastguard Worker static inline IMapper::Rect sGralloc4Rect(const Rect& rect) {
95*38e8c45fSAndroid Build Coastguard Worker     IMapper::Rect outRect{};
96*38e8c45fSAndroid Build Coastguard Worker     outRect.left = rect.left;
97*38e8c45fSAndroid Build Coastguard Worker     outRect.top = rect.top;
98*38e8c45fSAndroid Build Coastguard Worker     outRect.width = rect.width();
99*38e8c45fSAndroid Build Coastguard Worker     outRect.height = rect.height();
100*38e8c45fSAndroid Build Coastguard Worker     return outRect;
101*38e8c45fSAndroid Build Coastguard Worker }
102*38e8c45fSAndroid Build Coastguard Worker 
103*38e8c45fSAndroid Build Coastguard Worker // See if gralloc "4.1" is available.
hasIAllocatorAidl()104*38e8c45fSAndroid Build Coastguard Worker static bool hasIAllocatorAidl() {
105*38e8c45fSAndroid Build Coastguard Worker     // Avoid re-querying repeatedly for this information;
106*38e8c45fSAndroid Build Coastguard Worker     static bool sHasIAllocatorAidl = []() -> bool {
107*38e8c45fSAndroid Build Coastguard Worker         if (__builtin_available(android 31, *)) {
108*38e8c45fSAndroid Build Coastguard Worker             return AServiceManager_isDeclared(kAidlAllocatorServiceName.c_str());
109*38e8c45fSAndroid Build Coastguard Worker         }
110*38e8c45fSAndroid Build Coastguard Worker         return false;
111*38e8c45fSAndroid Build Coastguard Worker     }();
112*38e8c45fSAndroid Build Coastguard Worker     return sHasIAllocatorAidl;
113*38e8c45fSAndroid Build Coastguard Worker }
114*38e8c45fSAndroid Build Coastguard Worker 
115*38e8c45fSAndroid Build Coastguard Worker // Determines whether the passed info is compatible with the mapper.
validateBufferDescriptorInfo(IMapper::BufferDescriptorInfo * descriptorInfo)116*38e8c45fSAndroid Build Coastguard Worker static status_t validateBufferDescriptorInfo(IMapper::BufferDescriptorInfo* descriptorInfo) {
117*38e8c45fSAndroid Build Coastguard Worker     uint64_t validUsageBits = getValidUsageBits();
118*38e8c45fSAndroid Build Coastguard Worker     if (hasIAllocatorAidl()) {
119*38e8c45fSAndroid Build Coastguard Worker         validUsageBits |= getValidUsageBits41();
120*38e8c45fSAndroid Build Coastguard Worker     }
121*38e8c45fSAndroid Build Coastguard Worker 
122*38e8c45fSAndroid Build Coastguard Worker     if (descriptorInfo->usage & ~validUsageBits) {
123*38e8c45fSAndroid Build Coastguard Worker         ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64,
124*38e8c45fSAndroid Build Coastguard Worker               descriptorInfo->usage & ~validUsageBits);
125*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
126*38e8c45fSAndroid Build Coastguard Worker     }
127*38e8c45fSAndroid Build Coastguard Worker 
128*38e8c45fSAndroid Build Coastguard Worker     // Combinations that are only allowed with gralloc 4.1.
129*38e8c45fSAndroid Build Coastguard Worker     // Previous grallocs must be protected from this.
130*38e8c45fSAndroid Build Coastguard Worker     if (!hasIAllocatorAidl() &&
131*38e8c45fSAndroid Build Coastguard Worker             descriptorInfo->format != hardware::graphics::common::V1_2::PixelFormat::BLOB &&
132*38e8c45fSAndroid Build Coastguard Worker             descriptorInfo->usage & BufferUsage::GPU_DATA_BUFFER) {
133*38e8c45fSAndroid Build Coastguard Worker         ALOGE("non-BLOB pixel format with GPU_DATA_BUFFER usage is not supported prior to gralloc 4.1");
134*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
135*38e8c45fSAndroid Build Coastguard Worker     }
136*38e8c45fSAndroid Build Coastguard Worker 
137*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
138*38e8c45fSAndroid Build Coastguard Worker }
139*38e8c45fSAndroid Build Coastguard Worker 
sBufferDescriptorInfo(std::string name,uint32_t width,uint32_t height,PixelFormat format,uint32_t layerCount,uint64_t usage,IMapper::BufferDescriptorInfo * outDescriptorInfo)140*38e8c45fSAndroid Build Coastguard Worker static inline status_t sBufferDescriptorInfo(std::string name, uint32_t width, uint32_t height,
141*38e8c45fSAndroid Build Coastguard Worker                                              PixelFormat format, uint32_t layerCount,
142*38e8c45fSAndroid Build Coastguard Worker                                              uint64_t usage,
143*38e8c45fSAndroid Build Coastguard Worker                                              IMapper::BufferDescriptorInfo* outDescriptorInfo) {
144*38e8c45fSAndroid Build Coastguard Worker     outDescriptorInfo->name = name;
145*38e8c45fSAndroid Build Coastguard Worker     outDescriptorInfo->width = width;
146*38e8c45fSAndroid Build Coastguard Worker     outDescriptorInfo->height = height;
147*38e8c45fSAndroid Build Coastguard Worker     outDescriptorInfo->layerCount = layerCount;
148*38e8c45fSAndroid Build Coastguard Worker     outDescriptorInfo->format = static_cast<hardware::graphics::common::V1_2::PixelFormat>(format);
149*38e8c45fSAndroid Build Coastguard Worker     outDescriptorInfo->usage = usage;
150*38e8c45fSAndroid Build Coastguard Worker     outDescriptorInfo->reservedSize = 0;
151*38e8c45fSAndroid Build Coastguard Worker 
152*38e8c45fSAndroid Build Coastguard Worker     return validateBufferDescriptorInfo(outDescriptorInfo);
153*38e8c45fSAndroid Build Coastguard Worker }
154*38e8c45fSAndroid Build Coastguard Worker 
155*38e8c45fSAndroid Build Coastguard Worker } // anonymous namespace
156*38e8c45fSAndroid Build Coastguard Worker 
preload()157*38e8c45fSAndroid Build Coastguard Worker void Gralloc4Mapper::preload() {
158*38e8c45fSAndroid Build Coastguard Worker     android::hardware::preloadPassthroughService<IMapper>();
159*38e8c45fSAndroid Build Coastguard Worker }
160*38e8c45fSAndroid Build Coastguard Worker 
Gralloc4Mapper()161*38e8c45fSAndroid Build Coastguard Worker Gralloc4Mapper::Gralloc4Mapper() {
162*38e8c45fSAndroid Build Coastguard Worker     mMapper = IMapper::getService();
163*38e8c45fSAndroid Build Coastguard Worker     if (mMapper == nullptr) {
164*38e8c45fSAndroid Build Coastguard Worker         ALOGI("mapper 4.x is not supported");
165*38e8c45fSAndroid Build Coastguard Worker         return;
166*38e8c45fSAndroid Build Coastguard Worker     }
167*38e8c45fSAndroid Build Coastguard Worker     if (mMapper->isRemote()) {
168*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
169*38e8c45fSAndroid Build Coastguard Worker     }
170*38e8c45fSAndroid Build Coastguard Worker }
171*38e8c45fSAndroid Build Coastguard Worker 
isLoaded() const172*38e8c45fSAndroid Build Coastguard Worker bool Gralloc4Mapper::isLoaded() const {
173*38e8c45fSAndroid Build Coastguard Worker     return mMapper != nullptr;
174*38e8c45fSAndroid Build Coastguard Worker }
175*38e8c45fSAndroid Build Coastguard Worker 
createDescriptor(void * bufferDescriptorInfo,void * outBufferDescriptor) const176*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::createDescriptor(void* bufferDescriptorInfo,
177*38e8c45fSAndroid Build Coastguard Worker                                           void* outBufferDescriptor) const {
178*38e8c45fSAndroid Build Coastguard Worker     IMapper::BufferDescriptorInfo* descriptorInfo =
179*38e8c45fSAndroid Build Coastguard Worker             static_cast<IMapper::BufferDescriptorInfo*>(bufferDescriptorInfo);
180*38e8c45fSAndroid Build Coastguard Worker     BufferDescriptor* outDescriptor = static_cast<BufferDescriptor*>(outBufferDescriptor);
181*38e8c45fSAndroid Build Coastguard Worker 
182*38e8c45fSAndroid Build Coastguard Worker     status_t status = validateBufferDescriptorInfo(descriptorInfo);
183*38e8c45fSAndroid Build Coastguard Worker     if (status != NO_ERROR) {
184*38e8c45fSAndroid Build Coastguard Worker         return status;
185*38e8c45fSAndroid Build Coastguard Worker     }
186*38e8c45fSAndroid Build Coastguard Worker 
187*38e8c45fSAndroid Build Coastguard Worker     Error error;
188*38e8c45fSAndroid Build Coastguard Worker     auto hidl_cb = [&](const auto& tmpError, const auto& tmpDescriptor) {
189*38e8c45fSAndroid Build Coastguard Worker         error = tmpError;
190*38e8c45fSAndroid Build Coastguard Worker         if (error != Error::NONE) {
191*38e8c45fSAndroid Build Coastguard Worker             return;
192*38e8c45fSAndroid Build Coastguard Worker         }
193*38e8c45fSAndroid Build Coastguard Worker         *outDescriptor = tmpDescriptor;
194*38e8c45fSAndroid Build Coastguard Worker     };
195*38e8c45fSAndroid Build Coastguard Worker 
196*38e8c45fSAndroid Build Coastguard Worker     hardware::Return<void> ret = mMapper->createDescriptor(*descriptorInfo, hidl_cb);
197*38e8c45fSAndroid Build Coastguard Worker 
198*38e8c45fSAndroid Build Coastguard Worker     return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
199*38e8c45fSAndroid Build Coastguard Worker }
200*38e8c45fSAndroid Build Coastguard Worker 
importBuffer(const native_handle_t * rawHandle,buffer_handle_t * outBufferHandle) const201*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::importBuffer(const native_handle_t* rawHandle,
202*38e8c45fSAndroid Build Coastguard Worker                                       buffer_handle_t* outBufferHandle) const {
203*38e8c45fSAndroid Build Coastguard Worker     Error error;
204*38e8c45fSAndroid Build Coastguard Worker     auto ret = mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
205*38e8c45fSAndroid Build Coastguard Worker         error = tmpError;
206*38e8c45fSAndroid Build Coastguard Worker         if (error != Error::NONE) {
207*38e8c45fSAndroid Build Coastguard Worker             return;
208*38e8c45fSAndroid Build Coastguard Worker         }
209*38e8c45fSAndroid Build Coastguard Worker         *outBufferHandle = static_cast<buffer_handle_t>(tmpBuffer);
210*38e8c45fSAndroid Build Coastguard Worker     });
211*38e8c45fSAndroid Build Coastguard Worker 
212*38e8c45fSAndroid Build Coastguard Worker     return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
213*38e8c45fSAndroid Build Coastguard Worker }
214*38e8c45fSAndroid Build Coastguard Worker 
freeBuffer(buffer_handle_t bufferHandle) const215*38e8c45fSAndroid Build Coastguard Worker void Gralloc4Mapper::freeBuffer(buffer_handle_t bufferHandle) const {
216*38e8c45fSAndroid Build Coastguard Worker     auto buffer = const_cast<native_handle_t*>(bufferHandle);
217*38e8c45fSAndroid Build Coastguard Worker     auto ret = mMapper->freeBuffer(buffer);
218*38e8c45fSAndroid Build Coastguard Worker 
219*38e8c45fSAndroid Build Coastguard Worker     auto error = (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
220*38e8c45fSAndroid Build Coastguard Worker     ALOGE_IF(error != Error::NONE, "freeBuffer(%p) failed with %d", buffer, error);
221*38e8c45fSAndroid Build Coastguard Worker }
222*38e8c45fSAndroid Build Coastguard Worker 
validateBufferSize(buffer_handle_t bufferHandle,uint32_t width,uint32_t height,PixelFormat format,uint32_t layerCount,uint64_t usage,uint32_t stride) const223*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width,
224*38e8c45fSAndroid Build Coastguard Worker                                             uint32_t height, PixelFormat format,
225*38e8c45fSAndroid Build Coastguard Worker                                             uint32_t layerCount, uint64_t usage,
226*38e8c45fSAndroid Build Coastguard Worker                                             uint32_t stride) const {
227*38e8c45fSAndroid Build Coastguard Worker     IMapper::BufferDescriptorInfo descriptorInfo;
228*38e8c45fSAndroid Build Coastguard Worker     if (auto error = sBufferDescriptorInfo("validateBufferSize", width, height, format, layerCount,
229*38e8c45fSAndroid Build Coastguard Worker                                            usage, &descriptorInfo) != OK) {
230*38e8c45fSAndroid Build Coastguard Worker         return error;
231*38e8c45fSAndroid Build Coastguard Worker     }
232*38e8c45fSAndroid Build Coastguard Worker 
233*38e8c45fSAndroid Build Coastguard Worker     auto buffer = const_cast<native_handle_t*>(bufferHandle);
234*38e8c45fSAndroid Build Coastguard Worker     auto ret = mMapper->validateBufferSize(buffer, descriptorInfo, stride);
235*38e8c45fSAndroid Build Coastguard Worker 
236*38e8c45fSAndroid Build Coastguard Worker     return static_cast<status_t>((ret.isOk()) ? static_cast<Error>(ret) : kTransactionError);
237*38e8c45fSAndroid Build Coastguard Worker }
238*38e8c45fSAndroid Build Coastguard Worker 
getTransportSize(buffer_handle_t bufferHandle,uint32_t * outNumFds,uint32_t * outNumInts) const239*38e8c45fSAndroid Build Coastguard Worker void Gralloc4Mapper::getTransportSize(buffer_handle_t bufferHandle, uint32_t* outNumFds,
240*38e8c45fSAndroid Build Coastguard Worker                                       uint32_t* outNumInts) const {
241*38e8c45fSAndroid Build Coastguard Worker     *outNumFds = uint32_t(bufferHandle->numFds);
242*38e8c45fSAndroid Build Coastguard Worker     *outNumInts = uint32_t(bufferHandle->numInts);
243*38e8c45fSAndroid Build Coastguard Worker 
244*38e8c45fSAndroid Build Coastguard Worker     Error error;
245*38e8c45fSAndroid Build Coastguard Worker     auto buffer = const_cast<native_handle_t*>(bufferHandle);
246*38e8c45fSAndroid Build Coastguard Worker     auto ret = mMapper->getTransportSize(buffer,
247*38e8c45fSAndroid Build Coastguard Worker                                          [&](const auto& tmpError, const auto& tmpNumFds,
248*38e8c45fSAndroid Build Coastguard Worker                                              const auto& tmpNumInts) {
249*38e8c45fSAndroid Build Coastguard Worker                                              error = tmpError;
250*38e8c45fSAndroid Build Coastguard Worker                                              if (error != Error::NONE) {
251*38e8c45fSAndroid Build Coastguard Worker                                                  return;
252*38e8c45fSAndroid Build Coastguard Worker                                              }
253*38e8c45fSAndroid Build Coastguard Worker                                              *outNumFds = tmpNumFds;
254*38e8c45fSAndroid Build Coastguard Worker                                              *outNumInts = tmpNumInts;
255*38e8c45fSAndroid Build Coastguard Worker                                          });
256*38e8c45fSAndroid Build Coastguard Worker 
257*38e8c45fSAndroid Build Coastguard Worker     error = (ret.isOk()) ? error : kTransactionError;
258*38e8c45fSAndroid Build Coastguard Worker 
259*38e8c45fSAndroid Build Coastguard Worker     ALOGE_IF(error != Error::NONE, "getTransportSize(%p) failed with %d", buffer, error);
260*38e8c45fSAndroid Build Coastguard Worker }
261*38e8c45fSAndroid Build Coastguard Worker 
lock(buffer_handle_t bufferHandle,uint64_t usage,const Rect & bounds,int acquireFence,void ** outData,int32_t * outBytesPerPixel,int32_t * outBytesPerStride) const262*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
263*38e8c45fSAndroid Build Coastguard Worker                               int acquireFence, void** outData, int32_t* outBytesPerPixel,
264*38e8c45fSAndroid Build Coastguard Worker                               int32_t* outBytesPerStride) const {
265*38e8c45fSAndroid Build Coastguard Worker     if (outBytesPerPixel) *outBytesPerPixel = -1;
266*38e8c45fSAndroid Build Coastguard Worker     if (outBytesPerStride) *outBytesPerStride = -1;
267*38e8c45fSAndroid Build Coastguard Worker 
268*38e8c45fSAndroid Build Coastguard Worker     auto buffer = const_cast<native_handle_t*>(bufferHandle);
269*38e8c45fSAndroid Build Coastguard Worker 
270*38e8c45fSAndroid Build Coastguard Worker     IMapper::Rect accessRegion = sGralloc4Rect(bounds);
271*38e8c45fSAndroid Build Coastguard Worker 
272*38e8c45fSAndroid Build Coastguard Worker     // put acquireFence in a hidl_handle
273*38e8c45fSAndroid Build Coastguard Worker     hardware::hidl_handle acquireFenceHandle;
274*38e8c45fSAndroid Build Coastguard Worker     NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
275*38e8c45fSAndroid Build Coastguard Worker     if (acquireFence >= 0) {
276*38e8c45fSAndroid Build Coastguard Worker         auto h = native_handle_init(acquireFenceStorage, 1, 0);
277*38e8c45fSAndroid Build Coastguard Worker         h->data[0] = acquireFence;
278*38e8c45fSAndroid Build Coastguard Worker         acquireFenceHandle = h;
279*38e8c45fSAndroid Build Coastguard Worker     }
280*38e8c45fSAndroid Build Coastguard Worker 
281*38e8c45fSAndroid Build Coastguard Worker     Error error;
282*38e8c45fSAndroid Build Coastguard Worker     auto ret = mMapper->lock(buffer, usage, accessRegion, acquireFenceHandle,
283*38e8c45fSAndroid Build Coastguard Worker                              [&](const auto& tmpError, const auto& tmpData) {
284*38e8c45fSAndroid Build Coastguard Worker                                  error = tmpError;
285*38e8c45fSAndroid Build Coastguard Worker                                  if (error != Error::NONE) {
286*38e8c45fSAndroid Build Coastguard Worker                                      return;
287*38e8c45fSAndroid Build Coastguard Worker                                  }
288*38e8c45fSAndroid Build Coastguard Worker                                  *outData = tmpData;
289*38e8c45fSAndroid Build Coastguard Worker                              });
290*38e8c45fSAndroid Build Coastguard Worker 
291*38e8c45fSAndroid Build Coastguard Worker     // we own acquireFence even on errors
292*38e8c45fSAndroid Build Coastguard Worker     if (acquireFence >= 0) {
293*38e8c45fSAndroid Build Coastguard Worker         close(acquireFence);
294*38e8c45fSAndroid Build Coastguard Worker     }
295*38e8c45fSAndroid Build Coastguard Worker 
296*38e8c45fSAndroid Build Coastguard Worker     error = (ret.isOk()) ? error : kTransactionError;
297*38e8c45fSAndroid Build Coastguard Worker 
298*38e8c45fSAndroid Build Coastguard Worker     ALOGW_IF(error != Error::NONE, "lock(%p, ...) failed: %d", bufferHandle, error);
299*38e8c45fSAndroid Build Coastguard Worker 
300*38e8c45fSAndroid Build Coastguard Worker     return static_cast<status_t>(error);
301*38e8c45fSAndroid Build Coastguard Worker }
302*38e8c45fSAndroid Build Coastguard Worker 
lock(buffer_handle_t bufferHandle,uint64_t usage,const Rect & bounds,int acquireFence,android_ycbcr * outYcbcr) const303*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
304*38e8c45fSAndroid Build Coastguard Worker                               int acquireFence, android_ycbcr* outYcbcr) const {
305*38e8c45fSAndroid Build Coastguard Worker     if (!outYcbcr) {
306*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
307*38e8c45fSAndroid Build Coastguard Worker     }
308*38e8c45fSAndroid Build Coastguard Worker 
309*38e8c45fSAndroid Build Coastguard Worker     std::vector<ui::PlaneLayout> planeLayouts;
310*38e8c45fSAndroid Build Coastguard Worker     status_t error = getPlaneLayouts(bufferHandle, &planeLayouts);
311*38e8c45fSAndroid Build Coastguard Worker     if (error != NO_ERROR) {
312*38e8c45fSAndroid Build Coastguard Worker         return error;
313*38e8c45fSAndroid Build Coastguard Worker     }
314*38e8c45fSAndroid Build Coastguard Worker 
315*38e8c45fSAndroid Build Coastguard Worker     void* data = nullptr;
316*38e8c45fSAndroid Build Coastguard Worker     error = lock(bufferHandle, usage, bounds, acquireFence, &data, nullptr, nullptr);
317*38e8c45fSAndroid Build Coastguard Worker     if (error != NO_ERROR) {
318*38e8c45fSAndroid Build Coastguard Worker         return error;
319*38e8c45fSAndroid Build Coastguard Worker     }
320*38e8c45fSAndroid Build Coastguard Worker 
321*38e8c45fSAndroid Build Coastguard Worker     android_ycbcr ycbcr;
322*38e8c45fSAndroid Build Coastguard Worker 
323*38e8c45fSAndroid Build Coastguard Worker     ycbcr.y = nullptr;
324*38e8c45fSAndroid Build Coastguard Worker     ycbcr.cb = nullptr;
325*38e8c45fSAndroid Build Coastguard Worker     ycbcr.cr = nullptr;
326*38e8c45fSAndroid Build Coastguard Worker     ycbcr.ystride = 0;
327*38e8c45fSAndroid Build Coastguard Worker     ycbcr.cstride = 0;
328*38e8c45fSAndroid Build Coastguard Worker     ycbcr.chroma_step = 0;
329*38e8c45fSAndroid Build Coastguard Worker 
330*38e8c45fSAndroid Build Coastguard Worker     for (const auto& planeLayout : planeLayouts) {
331*38e8c45fSAndroid Build Coastguard Worker         for (const auto& planeLayoutComponent : planeLayout.components) {
332*38e8c45fSAndroid Build Coastguard Worker             if (!gralloc4::isStandardPlaneLayoutComponentType(planeLayoutComponent.type)) {
333*38e8c45fSAndroid Build Coastguard Worker                 continue;
334*38e8c45fSAndroid Build Coastguard Worker             }
335*38e8c45fSAndroid Build Coastguard Worker 
336*38e8c45fSAndroid Build Coastguard Worker             uint8_t* tmpData = static_cast<uint8_t*>(data) + planeLayout.offsetInBytes;
337*38e8c45fSAndroid Build Coastguard Worker 
338*38e8c45fSAndroid Build Coastguard Worker             // Note that `offsetInBits` may not be a multiple of 8 for packed formats (e.g. P010)
339*38e8c45fSAndroid Build Coastguard Worker             // but we still want to point to the start of the first byte.
340*38e8c45fSAndroid Build Coastguard Worker             tmpData += (planeLayoutComponent.offsetInBits / 8);
341*38e8c45fSAndroid Build Coastguard Worker 
342*38e8c45fSAndroid Build Coastguard Worker             uint64_t sampleIncrementInBytes;
343*38e8c45fSAndroid Build Coastguard Worker 
344*38e8c45fSAndroid Build Coastguard Worker             auto type = static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value);
345*38e8c45fSAndroid Build Coastguard Worker             switch (type) {
346*38e8c45fSAndroid Build Coastguard Worker                 case PlaneLayoutComponentType::Y:
347*38e8c45fSAndroid Build Coastguard Worker                     if ((ycbcr.y != nullptr) || (planeLayout.sampleIncrementInBits % 8 != 0)) {
348*38e8c45fSAndroid Build Coastguard Worker                         unlock(bufferHandle);
349*38e8c45fSAndroid Build Coastguard Worker                         return BAD_VALUE;
350*38e8c45fSAndroid Build Coastguard Worker                     }
351*38e8c45fSAndroid Build Coastguard Worker                     ycbcr.y = tmpData;
352*38e8c45fSAndroid Build Coastguard Worker                     ycbcr.ystride = planeLayout.strideInBytes;
353*38e8c45fSAndroid Build Coastguard Worker                     break;
354*38e8c45fSAndroid Build Coastguard Worker 
355*38e8c45fSAndroid Build Coastguard Worker                 case PlaneLayoutComponentType::CB:
356*38e8c45fSAndroid Build Coastguard Worker                 case PlaneLayoutComponentType::CR:
357*38e8c45fSAndroid Build Coastguard Worker                     if (planeLayout.sampleIncrementInBits % 8 != 0) {
358*38e8c45fSAndroid Build Coastguard Worker                         unlock(bufferHandle);
359*38e8c45fSAndroid Build Coastguard Worker                         return BAD_VALUE;
360*38e8c45fSAndroid Build Coastguard Worker                     }
361*38e8c45fSAndroid Build Coastguard Worker 
362*38e8c45fSAndroid Build Coastguard Worker                     sampleIncrementInBytes = planeLayout.sampleIncrementInBits / 8;
363*38e8c45fSAndroid Build Coastguard Worker                     if ((sampleIncrementInBytes != 1) && (sampleIncrementInBytes != 2) &&
364*38e8c45fSAndroid Build Coastguard Worker                         (sampleIncrementInBytes != 4)) {
365*38e8c45fSAndroid Build Coastguard Worker                         unlock(bufferHandle);
366*38e8c45fSAndroid Build Coastguard Worker                         return BAD_VALUE;
367*38e8c45fSAndroid Build Coastguard Worker                     }
368*38e8c45fSAndroid Build Coastguard Worker 
369*38e8c45fSAndroid Build Coastguard Worker                     if (ycbcr.cstride == 0 && ycbcr.chroma_step == 0) {
370*38e8c45fSAndroid Build Coastguard Worker                         ycbcr.cstride = planeLayout.strideInBytes;
371*38e8c45fSAndroid Build Coastguard Worker                         ycbcr.chroma_step = sampleIncrementInBytes;
372*38e8c45fSAndroid Build Coastguard Worker                     } else {
373*38e8c45fSAndroid Build Coastguard Worker                         if ((static_cast<int64_t>(ycbcr.cstride) != planeLayout.strideInBytes) ||
374*38e8c45fSAndroid Build Coastguard Worker                             (ycbcr.chroma_step != sampleIncrementInBytes)) {
375*38e8c45fSAndroid Build Coastguard Worker                             unlock(bufferHandle);
376*38e8c45fSAndroid Build Coastguard Worker                             return BAD_VALUE;
377*38e8c45fSAndroid Build Coastguard Worker                         }
378*38e8c45fSAndroid Build Coastguard Worker                     }
379*38e8c45fSAndroid Build Coastguard Worker 
380*38e8c45fSAndroid Build Coastguard Worker                     if (type == PlaneLayoutComponentType::CB) {
381*38e8c45fSAndroid Build Coastguard Worker                         if (ycbcr.cb != nullptr) {
382*38e8c45fSAndroid Build Coastguard Worker                             unlock(bufferHandle);
383*38e8c45fSAndroid Build Coastguard Worker                             return BAD_VALUE;
384*38e8c45fSAndroid Build Coastguard Worker                         }
385*38e8c45fSAndroid Build Coastguard Worker                         ycbcr.cb = tmpData;
386*38e8c45fSAndroid Build Coastguard Worker                     } else {
387*38e8c45fSAndroid Build Coastguard Worker                         if (ycbcr.cr != nullptr) {
388*38e8c45fSAndroid Build Coastguard Worker                             unlock(bufferHandle);
389*38e8c45fSAndroid Build Coastguard Worker                             return BAD_VALUE;
390*38e8c45fSAndroid Build Coastguard Worker                         }
391*38e8c45fSAndroid Build Coastguard Worker                         ycbcr.cr = tmpData;
392*38e8c45fSAndroid Build Coastguard Worker                     }
393*38e8c45fSAndroid Build Coastguard Worker                     break;
394*38e8c45fSAndroid Build Coastguard Worker                 default:
395*38e8c45fSAndroid Build Coastguard Worker                     break;
396*38e8c45fSAndroid Build Coastguard Worker             };
397*38e8c45fSAndroid Build Coastguard Worker         }
398*38e8c45fSAndroid Build Coastguard Worker     }
399*38e8c45fSAndroid Build Coastguard Worker 
400*38e8c45fSAndroid Build Coastguard Worker     *outYcbcr = ycbcr;
401*38e8c45fSAndroid Build Coastguard Worker     return static_cast<status_t>(Error::NONE);
402*38e8c45fSAndroid Build Coastguard Worker }
403*38e8c45fSAndroid Build Coastguard Worker 
unlock(buffer_handle_t bufferHandle) const404*38e8c45fSAndroid Build Coastguard Worker int Gralloc4Mapper::unlock(buffer_handle_t bufferHandle) const {
405*38e8c45fSAndroid Build Coastguard Worker     auto buffer = const_cast<native_handle_t*>(bufferHandle);
406*38e8c45fSAndroid Build Coastguard Worker 
407*38e8c45fSAndroid Build Coastguard Worker     int releaseFence = -1;
408*38e8c45fSAndroid Build Coastguard Worker     Error error;
409*38e8c45fSAndroid Build Coastguard Worker     auto ret = mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
410*38e8c45fSAndroid Build Coastguard Worker         error = tmpError;
411*38e8c45fSAndroid Build Coastguard Worker         if (error != Error::NONE) {
412*38e8c45fSAndroid Build Coastguard Worker             return;
413*38e8c45fSAndroid Build Coastguard Worker         }
414*38e8c45fSAndroid Build Coastguard Worker 
415*38e8c45fSAndroid Build Coastguard Worker         auto fenceHandle = tmpReleaseFence.getNativeHandle();
416*38e8c45fSAndroid Build Coastguard Worker         if (fenceHandle && fenceHandle->numFds == 1) {
417*38e8c45fSAndroid Build Coastguard Worker             int fd = dup(fenceHandle->data[0]);
418*38e8c45fSAndroid Build Coastguard Worker             if (fd >= 0) {
419*38e8c45fSAndroid Build Coastguard Worker                 releaseFence = fd;
420*38e8c45fSAndroid Build Coastguard Worker             } else {
421*38e8c45fSAndroid Build Coastguard Worker                 ALOGW("failed to dup unlock release fence");
422*38e8c45fSAndroid Build Coastguard Worker                 sync_wait(fenceHandle->data[0], -1);
423*38e8c45fSAndroid Build Coastguard Worker             }
424*38e8c45fSAndroid Build Coastguard Worker         }
425*38e8c45fSAndroid Build Coastguard Worker     });
426*38e8c45fSAndroid Build Coastguard Worker 
427*38e8c45fSAndroid Build Coastguard Worker     if (!ret.isOk()) {
428*38e8c45fSAndroid Build Coastguard Worker         error = kTransactionError;
429*38e8c45fSAndroid Build Coastguard Worker     }
430*38e8c45fSAndroid Build Coastguard Worker 
431*38e8c45fSAndroid Build Coastguard Worker     if (error != Error::NONE) {
432*38e8c45fSAndroid Build Coastguard Worker         ALOGE("unlock(%p) failed with %d", buffer, error);
433*38e8c45fSAndroid Build Coastguard Worker     }
434*38e8c45fSAndroid Build Coastguard Worker 
435*38e8c45fSAndroid Build Coastguard Worker     return releaseFence;
436*38e8c45fSAndroid Build Coastguard Worker }
437*38e8c45fSAndroid Build Coastguard Worker 
isSupported(uint32_t width,uint32_t height,PixelFormat format,uint32_t layerCount,uint64_t usage,bool * outSupported) const438*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::isSupported(uint32_t width, uint32_t height, PixelFormat format,
439*38e8c45fSAndroid Build Coastguard Worker                                      uint32_t layerCount, uint64_t usage,
440*38e8c45fSAndroid Build Coastguard Worker                                      bool* outSupported) const {
441*38e8c45fSAndroid Build Coastguard Worker     IMapper::BufferDescriptorInfo descriptorInfo;
442*38e8c45fSAndroid Build Coastguard Worker     if (sBufferDescriptorInfo("isSupported", width, height, format, layerCount, usage,
443*38e8c45fSAndroid Build Coastguard Worker                               &descriptorInfo) != OK) {
444*38e8c45fSAndroid Build Coastguard Worker         // Usage isn't known to the HAL or otherwise failed validation.
445*38e8c45fSAndroid Build Coastguard Worker         *outSupported = false;
446*38e8c45fSAndroid Build Coastguard Worker         return OK;
447*38e8c45fSAndroid Build Coastguard Worker     }
448*38e8c45fSAndroid Build Coastguard Worker 
449*38e8c45fSAndroid Build Coastguard Worker     Error error;
450*38e8c45fSAndroid Build Coastguard Worker     auto ret = mMapper->isSupported(descriptorInfo,
451*38e8c45fSAndroid Build Coastguard Worker                                     [&](const auto& tmpError, const auto& tmpSupported) {
452*38e8c45fSAndroid Build Coastguard Worker                                         error = tmpError;
453*38e8c45fSAndroid Build Coastguard Worker                                         if (error != Error::NONE) {
454*38e8c45fSAndroid Build Coastguard Worker                                             return;
455*38e8c45fSAndroid Build Coastguard Worker                                         }
456*38e8c45fSAndroid Build Coastguard Worker                                         if (outSupported) {
457*38e8c45fSAndroid Build Coastguard Worker                                             *outSupported = tmpSupported;
458*38e8c45fSAndroid Build Coastguard Worker                                         }
459*38e8c45fSAndroid Build Coastguard Worker                                     });
460*38e8c45fSAndroid Build Coastguard Worker 
461*38e8c45fSAndroid Build Coastguard Worker     if (!ret.isOk()) {
462*38e8c45fSAndroid Build Coastguard Worker         error = kTransactionError;
463*38e8c45fSAndroid Build Coastguard Worker     }
464*38e8c45fSAndroid Build Coastguard Worker 
465*38e8c45fSAndroid Build Coastguard Worker     if (error != Error::NONE) {
466*38e8c45fSAndroid Build Coastguard Worker         ALOGE("isSupported(%u, %u, %d, %u, ...) failed with %d", width, height, format, layerCount,
467*38e8c45fSAndroid Build Coastguard Worker               error);
468*38e8c45fSAndroid Build Coastguard Worker     }
469*38e8c45fSAndroid Build Coastguard Worker 
470*38e8c45fSAndroid Build Coastguard Worker     return static_cast<status_t>(error);
471*38e8c45fSAndroid Build Coastguard Worker }
472*38e8c45fSAndroid Build Coastguard Worker 
473*38e8c45fSAndroid Build Coastguard Worker template <class T>
get(buffer_handle_t bufferHandle,const MetadataType & metadataType,DecodeFunction<T> decodeFunction,T * outMetadata) const474*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::get(buffer_handle_t bufferHandle, const MetadataType& metadataType,
475*38e8c45fSAndroid Build Coastguard Worker                              DecodeFunction<T> decodeFunction, T* outMetadata) const {
476*38e8c45fSAndroid Build Coastguard Worker     if (!outMetadata) {
477*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
478*38e8c45fSAndroid Build Coastguard Worker     }
479*38e8c45fSAndroid Build Coastguard Worker 
480*38e8c45fSAndroid Build Coastguard Worker     hidl_vec<uint8_t> vec;
481*38e8c45fSAndroid Build Coastguard Worker     Error error;
482*38e8c45fSAndroid Build Coastguard Worker     auto ret = mMapper->get(const_cast<native_handle_t*>(bufferHandle), metadataType,
483*38e8c45fSAndroid Build Coastguard Worker                             [&](const auto& tmpError, const hidl_vec<uint8_t>& tmpVec) {
484*38e8c45fSAndroid Build Coastguard Worker                                 error = tmpError;
485*38e8c45fSAndroid Build Coastguard Worker                                 vec = tmpVec;
486*38e8c45fSAndroid Build Coastguard Worker                             });
487*38e8c45fSAndroid Build Coastguard Worker 
488*38e8c45fSAndroid Build Coastguard Worker     if (!ret.isOk()) {
489*38e8c45fSAndroid Build Coastguard Worker         error = kTransactionError;
490*38e8c45fSAndroid Build Coastguard Worker     }
491*38e8c45fSAndroid Build Coastguard Worker 
492*38e8c45fSAndroid Build Coastguard Worker     if (error != Error::NONE) {
493*38e8c45fSAndroid Build Coastguard Worker         ALOGE("get(%s, %" PRIu64 ", ...) failed with %d", metadataType.name.c_str(),
494*38e8c45fSAndroid Build Coastguard Worker               metadataType.value, error);
495*38e8c45fSAndroid Build Coastguard Worker         return static_cast<status_t>(error);
496*38e8c45fSAndroid Build Coastguard Worker     }
497*38e8c45fSAndroid Build Coastguard Worker 
498*38e8c45fSAndroid Build Coastguard Worker     return decodeFunction(vec, outMetadata);
499*38e8c45fSAndroid Build Coastguard Worker }
500*38e8c45fSAndroid Build Coastguard Worker 
501*38e8c45fSAndroid Build Coastguard Worker template <class T>
set(buffer_handle_t bufferHandle,const MetadataType & metadataType,const T & metadata,EncodeFunction<T> encodeFunction) const502*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::set(buffer_handle_t bufferHandle, const MetadataType& metadataType,
503*38e8c45fSAndroid Build Coastguard Worker                              const T& metadata, EncodeFunction<T> encodeFunction) const {
504*38e8c45fSAndroid Build Coastguard Worker     hidl_vec<uint8_t> encodedMetadata;
505*38e8c45fSAndroid Build Coastguard Worker     if (const status_t status = encodeFunction(metadata, &encodedMetadata); status != OK) {
506*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Encoding metadata(%s) failed with %d", metadataType.name.c_str(), status);
507*38e8c45fSAndroid Build Coastguard Worker         return status;
508*38e8c45fSAndroid Build Coastguard Worker     }
509*38e8c45fSAndroid Build Coastguard Worker     hidl_vec<uint8_t> vec;
510*38e8c45fSAndroid Build Coastguard Worker     auto ret =
511*38e8c45fSAndroid Build Coastguard Worker             mMapper->set(const_cast<native_handle_t*>(bufferHandle), metadataType, encodedMetadata);
512*38e8c45fSAndroid Build Coastguard Worker 
513*38e8c45fSAndroid Build Coastguard Worker     const Error error = ret.withDefault(kTransactionError);
514*38e8c45fSAndroid Build Coastguard Worker     switch (error) {
515*38e8c45fSAndroid Build Coastguard Worker         case Error::BAD_DESCRIPTOR:
516*38e8c45fSAndroid Build Coastguard Worker         case Error::BAD_BUFFER:
517*38e8c45fSAndroid Build Coastguard Worker         case Error::BAD_VALUE:
518*38e8c45fSAndroid Build Coastguard Worker         case Error::NO_RESOURCES:
519*38e8c45fSAndroid Build Coastguard Worker             ALOGE("set(%s, %" PRIu64 ", ...) failed with %d", metadataType.name.c_str(),
520*38e8c45fSAndroid Build Coastguard Worker                   metadataType.value, error);
521*38e8c45fSAndroid Build Coastguard Worker             break;
522*38e8c45fSAndroid Build Coastguard Worker         // It is not an error to attempt to set metadata that a particular gralloc implementation
523*38e8c45fSAndroid Build Coastguard Worker         // happens to not support.
524*38e8c45fSAndroid Build Coastguard Worker         case Error::UNSUPPORTED:
525*38e8c45fSAndroid Build Coastguard Worker         case Error::NONE:
526*38e8c45fSAndroid Build Coastguard Worker             break;
527*38e8c45fSAndroid Build Coastguard Worker     }
528*38e8c45fSAndroid Build Coastguard Worker 
529*38e8c45fSAndroid Build Coastguard Worker     return static_cast<status_t>(error);
530*38e8c45fSAndroid Build Coastguard Worker }
531*38e8c45fSAndroid Build Coastguard Worker 
getBufferId(buffer_handle_t bufferHandle,uint64_t * outBufferId) const532*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::getBufferId(buffer_handle_t bufferHandle, uint64_t* outBufferId) const {
533*38e8c45fSAndroid Build Coastguard Worker     return get(bufferHandle, gralloc4::MetadataType_BufferId, gralloc4::decodeBufferId,
534*38e8c45fSAndroid Build Coastguard Worker                outBufferId);
535*38e8c45fSAndroid Build Coastguard Worker }
536*38e8c45fSAndroid Build Coastguard Worker 
getName(buffer_handle_t bufferHandle,std::string * outName) const537*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::getName(buffer_handle_t bufferHandle, std::string* outName) const {
538*38e8c45fSAndroid Build Coastguard Worker     return get(bufferHandle, gralloc4::MetadataType_Name, gralloc4::decodeName, outName);
539*38e8c45fSAndroid Build Coastguard Worker }
540*38e8c45fSAndroid Build Coastguard Worker 
getWidth(buffer_handle_t bufferHandle,uint64_t * outWidth) const541*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::getWidth(buffer_handle_t bufferHandle, uint64_t* outWidth) const {
542*38e8c45fSAndroid Build Coastguard Worker     return get(bufferHandle, gralloc4::MetadataType_Width, gralloc4::decodeWidth, outWidth);
543*38e8c45fSAndroid Build Coastguard Worker }
544*38e8c45fSAndroid Build Coastguard Worker 
getHeight(buffer_handle_t bufferHandle,uint64_t * outHeight) const545*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::getHeight(buffer_handle_t bufferHandle, uint64_t* outHeight) const {
546*38e8c45fSAndroid Build Coastguard Worker     return get(bufferHandle, gralloc4::MetadataType_Height, gralloc4::decodeHeight, outHeight);
547*38e8c45fSAndroid Build Coastguard Worker }
548*38e8c45fSAndroid Build Coastguard Worker 
getLayerCount(buffer_handle_t bufferHandle,uint64_t * outLayerCount) const549*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::getLayerCount(buffer_handle_t bufferHandle,
550*38e8c45fSAndroid Build Coastguard Worker                                        uint64_t* outLayerCount) const {
551*38e8c45fSAndroid Build Coastguard Worker     return get(bufferHandle, gralloc4::MetadataType_LayerCount, gralloc4::decodeLayerCount,
552*38e8c45fSAndroid Build Coastguard Worker                outLayerCount);
553*38e8c45fSAndroid Build Coastguard Worker }
554*38e8c45fSAndroid Build Coastguard Worker 
getPixelFormatRequested(buffer_handle_t bufferHandle,ui::PixelFormat * outPixelFormatRequested) const555*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::getPixelFormatRequested(buffer_handle_t bufferHandle,
556*38e8c45fSAndroid Build Coastguard Worker                                                  ui::PixelFormat* outPixelFormatRequested) const {
557*38e8c45fSAndroid Build Coastguard Worker     return get(bufferHandle, gralloc4::MetadataType_PixelFormatRequested,
558*38e8c45fSAndroid Build Coastguard Worker                gralloc4::decodePixelFormatRequested, outPixelFormatRequested);
559*38e8c45fSAndroid Build Coastguard Worker }
560*38e8c45fSAndroid Build Coastguard Worker 
getPixelFormatFourCC(buffer_handle_t bufferHandle,uint32_t * outPixelFormatFourCC) const561*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::getPixelFormatFourCC(buffer_handle_t bufferHandle,
562*38e8c45fSAndroid Build Coastguard Worker                                               uint32_t* outPixelFormatFourCC) const {
563*38e8c45fSAndroid Build Coastguard Worker     return get(bufferHandle, gralloc4::MetadataType_PixelFormatFourCC,
564*38e8c45fSAndroid Build Coastguard Worker                gralloc4::decodePixelFormatFourCC, outPixelFormatFourCC);
565*38e8c45fSAndroid Build Coastguard Worker }
566*38e8c45fSAndroid Build Coastguard Worker 
getPixelFormatModifier(buffer_handle_t bufferHandle,uint64_t * outPixelFormatModifier) const567*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::getPixelFormatModifier(buffer_handle_t bufferHandle,
568*38e8c45fSAndroid Build Coastguard Worker                                                 uint64_t* outPixelFormatModifier) const {
569*38e8c45fSAndroid Build Coastguard Worker     return get(bufferHandle, gralloc4::MetadataType_PixelFormatModifier,
570*38e8c45fSAndroid Build Coastguard Worker                gralloc4::decodePixelFormatModifier, outPixelFormatModifier);
571*38e8c45fSAndroid Build Coastguard Worker }
572*38e8c45fSAndroid Build Coastguard Worker 
getUsage(buffer_handle_t bufferHandle,uint64_t * outUsage) const573*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::getUsage(buffer_handle_t bufferHandle, uint64_t* outUsage) const {
574*38e8c45fSAndroid Build Coastguard Worker     return get(bufferHandle, gralloc4::MetadataType_Usage, gralloc4::decodeUsage, outUsage);
575*38e8c45fSAndroid Build Coastguard Worker }
576*38e8c45fSAndroid Build Coastguard Worker 
getAllocationSize(buffer_handle_t bufferHandle,uint64_t * outAllocationSize) const577*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::getAllocationSize(buffer_handle_t bufferHandle,
578*38e8c45fSAndroid Build Coastguard Worker                                            uint64_t* outAllocationSize) const {
579*38e8c45fSAndroid Build Coastguard Worker     return get(bufferHandle, gralloc4::MetadataType_AllocationSize, gralloc4::decodeAllocationSize,
580*38e8c45fSAndroid Build Coastguard Worker                outAllocationSize);
581*38e8c45fSAndroid Build Coastguard Worker }
582*38e8c45fSAndroid Build Coastguard Worker 
getProtectedContent(buffer_handle_t bufferHandle,uint64_t * outProtectedContent) const583*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::getProtectedContent(buffer_handle_t bufferHandle,
584*38e8c45fSAndroid Build Coastguard Worker                                              uint64_t* outProtectedContent) const {
585*38e8c45fSAndroid Build Coastguard Worker     return get(bufferHandle, gralloc4::MetadataType_ProtectedContent,
586*38e8c45fSAndroid Build Coastguard Worker                gralloc4::decodeProtectedContent, outProtectedContent);
587*38e8c45fSAndroid Build Coastguard Worker }
588*38e8c45fSAndroid Build Coastguard Worker 
getCompression(buffer_handle_t bufferHandle,ExtendableType * outCompression) const589*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::getCompression(buffer_handle_t bufferHandle,
590*38e8c45fSAndroid Build Coastguard Worker                                         ExtendableType* outCompression) const {
591*38e8c45fSAndroid Build Coastguard Worker     return get(bufferHandle, gralloc4::MetadataType_Compression, gralloc4::decodeCompression,
592*38e8c45fSAndroid Build Coastguard Worker                outCompression);
593*38e8c45fSAndroid Build Coastguard Worker }
594*38e8c45fSAndroid Build Coastguard Worker 
getCompression(buffer_handle_t bufferHandle,ui::Compression * outCompression) const595*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::getCompression(buffer_handle_t bufferHandle,
596*38e8c45fSAndroid Build Coastguard Worker                                         ui::Compression* outCompression) const {
597*38e8c45fSAndroid Build Coastguard Worker     if (!outCompression) {
598*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
599*38e8c45fSAndroid Build Coastguard Worker     }
600*38e8c45fSAndroid Build Coastguard Worker     ExtendableType compression;
601*38e8c45fSAndroid Build Coastguard Worker     status_t error = getCompression(bufferHandle, &compression);
602*38e8c45fSAndroid Build Coastguard Worker     if (error) {
603*38e8c45fSAndroid Build Coastguard Worker         return error;
604*38e8c45fSAndroid Build Coastguard Worker     }
605*38e8c45fSAndroid Build Coastguard Worker     if (!gralloc4::isStandardCompression(compression)) {
606*38e8c45fSAndroid Build Coastguard Worker         return BAD_TYPE;
607*38e8c45fSAndroid Build Coastguard Worker     }
608*38e8c45fSAndroid Build Coastguard Worker     *outCompression = gralloc4::getStandardCompressionValue(compression);
609*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
610*38e8c45fSAndroid Build Coastguard Worker }
611*38e8c45fSAndroid Build Coastguard Worker 
getInterlaced(buffer_handle_t bufferHandle,ExtendableType * outInterlaced) const612*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::getInterlaced(buffer_handle_t bufferHandle,
613*38e8c45fSAndroid Build Coastguard Worker                                        ExtendableType* outInterlaced) const {
614*38e8c45fSAndroid Build Coastguard Worker     return get(bufferHandle, gralloc4::MetadataType_Interlaced, gralloc4::decodeInterlaced,
615*38e8c45fSAndroid Build Coastguard Worker                outInterlaced);
616*38e8c45fSAndroid Build Coastguard Worker }
617*38e8c45fSAndroid Build Coastguard Worker 
getInterlaced(buffer_handle_t bufferHandle,ui::Interlaced * outInterlaced) const618*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::getInterlaced(buffer_handle_t bufferHandle,
619*38e8c45fSAndroid Build Coastguard Worker                                        ui::Interlaced* outInterlaced) const {
620*38e8c45fSAndroid Build Coastguard Worker     if (!outInterlaced) {
621*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
622*38e8c45fSAndroid Build Coastguard Worker     }
623*38e8c45fSAndroid Build Coastguard Worker     ExtendableType interlaced;
624*38e8c45fSAndroid Build Coastguard Worker     status_t error = getInterlaced(bufferHandle, &interlaced);
625*38e8c45fSAndroid Build Coastguard Worker     if (error) {
626*38e8c45fSAndroid Build Coastguard Worker         return error;
627*38e8c45fSAndroid Build Coastguard Worker     }
628*38e8c45fSAndroid Build Coastguard Worker     if (!gralloc4::isStandardInterlaced(interlaced)) {
629*38e8c45fSAndroid Build Coastguard Worker         return BAD_TYPE;
630*38e8c45fSAndroid Build Coastguard Worker     }
631*38e8c45fSAndroid Build Coastguard Worker     *outInterlaced = gralloc4::getStandardInterlacedValue(interlaced);
632*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
633*38e8c45fSAndroid Build Coastguard Worker }
634*38e8c45fSAndroid Build Coastguard Worker 
getChromaSiting(buffer_handle_t bufferHandle,ExtendableType * outChromaSiting) const635*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::getChromaSiting(buffer_handle_t bufferHandle,
636*38e8c45fSAndroid Build Coastguard Worker                                          ExtendableType* outChromaSiting) const {
637*38e8c45fSAndroid Build Coastguard Worker     return get(bufferHandle, gralloc4::MetadataType_ChromaSiting, gralloc4::decodeChromaSiting,
638*38e8c45fSAndroid Build Coastguard Worker                outChromaSiting);
639*38e8c45fSAndroid Build Coastguard Worker }
640*38e8c45fSAndroid Build Coastguard Worker 
getChromaSiting(buffer_handle_t bufferHandle,ui::ChromaSiting * outChromaSiting) const641*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::getChromaSiting(buffer_handle_t bufferHandle,
642*38e8c45fSAndroid Build Coastguard Worker                                          ui::ChromaSiting* outChromaSiting) const {
643*38e8c45fSAndroid Build Coastguard Worker     if (!outChromaSiting) {
644*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
645*38e8c45fSAndroid Build Coastguard Worker     }
646*38e8c45fSAndroid Build Coastguard Worker     ExtendableType chromaSiting;
647*38e8c45fSAndroid Build Coastguard Worker     status_t error = getChromaSiting(bufferHandle, &chromaSiting);
648*38e8c45fSAndroid Build Coastguard Worker     if (error) {
649*38e8c45fSAndroid Build Coastguard Worker         return error;
650*38e8c45fSAndroid Build Coastguard Worker     }
651*38e8c45fSAndroid Build Coastguard Worker     if (!gralloc4::isStandardChromaSiting(chromaSiting)) {
652*38e8c45fSAndroid Build Coastguard Worker         return BAD_TYPE;
653*38e8c45fSAndroid Build Coastguard Worker     }
654*38e8c45fSAndroid Build Coastguard Worker     *outChromaSiting = gralloc4::getStandardChromaSitingValue(chromaSiting);
655*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
656*38e8c45fSAndroid Build Coastguard Worker }
657*38e8c45fSAndroid Build Coastguard Worker 
getPlaneLayouts(buffer_handle_t bufferHandle,std::vector<ui::PlaneLayout> * outPlaneLayouts) const658*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::getPlaneLayouts(buffer_handle_t bufferHandle,
659*38e8c45fSAndroid Build Coastguard Worker                                          std::vector<ui::PlaneLayout>* outPlaneLayouts) const {
660*38e8c45fSAndroid Build Coastguard Worker     return get(bufferHandle, gralloc4::MetadataType_PlaneLayouts, gralloc4::decodePlaneLayouts,
661*38e8c45fSAndroid Build Coastguard Worker                outPlaneLayouts);
662*38e8c45fSAndroid Build Coastguard Worker }
663*38e8c45fSAndroid Build Coastguard Worker 
getDataspace(buffer_handle_t bufferHandle,ui::Dataspace * outDataspace) const664*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::getDataspace(buffer_handle_t bufferHandle,
665*38e8c45fSAndroid Build Coastguard Worker                                       ui::Dataspace* outDataspace) const {
666*38e8c45fSAndroid Build Coastguard Worker     if (!outDataspace) {
667*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
668*38e8c45fSAndroid Build Coastguard Worker     }
669*38e8c45fSAndroid Build Coastguard Worker     AidlDataspace dataspace;
670*38e8c45fSAndroid Build Coastguard Worker     status_t error = get(bufferHandle, gralloc4::MetadataType_Dataspace, gralloc4::decodeDataspace,
671*38e8c45fSAndroid Build Coastguard Worker                          &dataspace);
672*38e8c45fSAndroid Build Coastguard Worker     if (error) {
673*38e8c45fSAndroid Build Coastguard Worker         return error;
674*38e8c45fSAndroid Build Coastguard Worker     }
675*38e8c45fSAndroid Build Coastguard Worker 
676*38e8c45fSAndroid Build Coastguard Worker     // Gralloc4 uses stable AIDL dataspace but the rest of the system still uses HIDL dataspace
677*38e8c45fSAndroid Build Coastguard Worker     *outDataspace = static_cast<ui::Dataspace>(dataspace);
678*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
679*38e8c45fSAndroid Build Coastguard Worker }
680*38e8c45fSAndroid Build Coastguard Worker 
setDataspace(buffer_handle_t bufferHandle,ui::Dataspace dataspace) const681*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::setDataspace(buffer_handle_t bufferHandle, ui::Dataspace dataspace) const {
682*38e8c45fSAndroid Build Coastguard Worker     return set(bufferHandle, gralloc4::MetadataType_Dataspace,
683*38e8c45fSAndroid Build Coastguard Worker                static_cast<aidl::android::hardware::graphics::common::Dataspace>(dataspace),
684*38e8c45fSAndroid Build Coastguard Worker                gralloc4::encodeDataspace);
685*38e8c45fSAndroid Build Coastguard Worker }
686*38e8c45fSAndroid Build Coastguard Worker 
getBlendMode(buffer_handle_t bufferHandle,ui::BlendMode * outBlendMode) const687*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::getBlendMode(buffer_handle_t bufferHandle,
688*38e8c45fSAndroid Build Coastguard Worker                                       ui::BlendMode* outBlendMode) const {
689*38e8c45fSAndroid Build Coastguard Worker     return get(bufferHandle, gralloc4::MetadataType_BlendMode, gralloc4::decodeBlendMode,
690*38e8c45fSAndroid Build Coastguard Worker                outBlendMode);
691*38e8c45fSAndroid Build Coastguard Worker }
692*38e8c45fSAndroid Build Coastguard Worker 
getSmpte2086(buffer_handle_t bufferHandle,std::optional<ui::Smpte2086> * outSmpte2086) const693*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::getSmpte2086(buffer_handle_t bufferHandle,
694*38e8c45fSAndroid Build Coastguard Worker                                       std::optional<ui::Smpte2086>* outSmpte2086) const {
695*38e8c45fSAndroid Build Coastguard Worker     return get(bufferHandle, gralloc4::MetadataType_Smpte2086, gralloc4::decodeSmpte2086,
696*38e8c45fSAndroid Build Coastguard Worker                outSmpte2086);
697*38e8c45fSAndroid Build Coastguard Worker }
698*38e8c45fSAndroid Build Coastguard Worker 
setSmpte2086(buffer_handle_t bufferHandle,std::optional<ui::Smpte2086> smpte2086) const699*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::setSmpte2086(buffer_handle_t bufferHandle,
700*38e8c45fSAndroid Build Coastguard Worker                                       std::optional<ui::Smpte2086> smpte2086) const {
701*38e8c45fSAndroid Build Coastguard Worker     return set(bufferHandle, gralloc4::MetadataType_Smpte2086, smpte2086,
702*38e8c45fSAndroid Build Coastguard Worker                gralloc4::encodeSmpte2086);
703*38e8c45fSAndroid Build Coastguard Worker }
704*38e8c45fSAndroid Build Coastguard Worker 
getCta861_3(buffer_handle_t bufferHandle,std::optional<ui::Cta861_3> * outCta861_3) const705*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::getCta861_3(buffer_handle_t bufferHandle,
706*38e8c45fSAndroid Build Coastguard Worker                                      std::optional<ui::Cta861_3>* outCta861_3) const {
707*38e8c45fSAndroid Build Coastguard Worker     return get(bufferHandle, gralloc4::MetadataType_Cta861_3, gralloc4::decodeCta861_3,
708*38e8c45fSAndroid Build Coastguard Worker                outCta861_3);
709*38e8c45fSAndroid Build Coastguard Worker }
710*38e8c45fSAndroid Build Coastguard Worker 
setCta861_3(buffer_handle_t bufferHandle,std::optional<ui::Cta861_3> cta861_3) const711*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::setCta861_3(buffer_handle_t bufferHandle,
712*38e8c45fSAndroid Build Coastguard Worker                                      std::optional<ui::Cta861_3> cta861_3) const {
713*38e8c45fSAndroid Build Coastguard Worker     return set(bufferHandle, gralloc4::MetadataType_Cta861_3, cta861_3, gralloc4::encodeCta861_3);
714*38e8c45fSAndroid Build Coastguard Worker }
715*38e8c45fSAndroid Build Coastguard Worker 
getSmpte2094_40(buffer_handle_t bufferHandle,std::optional<std::vector<uint8_t>> * outSmpte2094_40) const716*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::getSmpte2094_40(
717*38e8c45fSAndroid Build Coastguard Worker         buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>>* outSmpte2094_40) const {
718*38e8c45fSAndroid Build Coastguard Worker     return get(bufferHandle, gralloc4::MetadataType_Smpte2094_40, gralloc4::decodeSmpte2094_40,
719*38e8c45fSAndroid Build Coastguard Worker                outSmpte2094_40);
720*38e8c45fSAndroid Build Coastguard Worker }
721*38e8c45fSAndroid Build Coastguard Worker 
setSmpte2094_40(buffer_handle_t bufferHandle,std::optional<std::vector<uint8_t>> smpte2094_40) const722*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::setSmpte2094_40(buffer_handle_t bufferHandle,
723*38e8c45fSAndroid Build Coastguard Worker                                          std::optional<std::vector<uint8_t>> smpte2094_40) const {
724*38e8c45fSAndroid Build Coastguard Worker     return set(bufferHandle, gralloc4::MetadataType_Smpte2094_40, smpte2094_40,
725*38e8c45fSAndroid Build Coastguard Worker                gralloc4::encodeSmpte2094_40);
726*38e8c45fSAndroid Build Coastguard Worker }
727*38e8c45fSAndroid Build Coastguard Worker 
getSmpte2094_10(buffer_handle_t bufferHandle,std::optional<std::vector<uint8_t>> * outSmpte2094_10) const728*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::getSmpte2094_10(
729*38e8c45fSAndroid Build Coastguard Worker         buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>>* outSmpte2094_10) const {
730*38e8c45fSAndroid Build Coastguard Worker     return get(bufferHandle, gralloc4::MetadataType_Smpte2094_10, gralloc4::decodeSmpte2094_10,
731*38e8c45fSAndroid Build Coastguard Worker                outSmpte2094_10);
732*38e8c45fSAndroid Build Coastguard Worker }
733*38e8c45fSAndroid Build Coastguard Worker 
setSmpte2094_10(buffer_handle_t bufferHandle,std::optional<std::vector<uint8_t>> smpte2094_10) const734*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::setSmpte2094_10(buffer_handle_t bufferHandle,
735*38e8c45fSAndroid Build Coastguard Worker                                          std::optional<std::vector<uint8_t>> smpte2094_10) const {
736*38e8c45fSAndroid Build Coastguard Worker     return set(bufferHandle, gralloc4::MetadataType_Smpte2094_10, smpte2094_10,
737*38e8c45fSAndroid Build Coastguard Worker                gralloc4::encodeSmpte2094_10);
738*38e8c45fSAndroid Build Coastguard Worker }
739*38e8c45fSAndroid Build Coastguard Worker 
listSupportedMetadataTypes() const740*38e8c45fSAndroid Build Coastguard Worker std::vector<MetadataTypeDescription> Gralloc4Mapper::listSupportedMetadataTypes() const {
741*38e8c45fSAndroid Build Coastguard Worker     hidl_vec<MetadataTypeDescription> descriptions;
742*38e8c45fSAndroid Build Coastguard Worker     Error error;
743*38e8c45fSAndroid Build Coastguard Worker     auto ret = mMapper->listSupportedMetadataTypes(
744*38e8c45fSAndroid Build Coastguard Worker             [&](const auto& tmpError, const auto& tmpDescriptions) {
745*38e8c45fSAndroid Build Coastguard Worker                 error = tmpError;
746*38e8c45fSAndroid Build Coastguard Worker                 descriptions = tmpDescriptions;
747*38e8c45fSAndroid Build Coastguard Worker             });
748*38e8c45fSAndroid Build Coastguard Worker 
749*38e8c45fSAndroid Build Coastguard Worker     if (!ret.isOk()) {
750*38e8c45fSAndroid Build Coastguard Worker         error = kTransactionError;
751*38e8c45fSAndroid Build Coastguard Worker     }
752*38e8c45fSAndroid Build Coastguard Worker 
753*38e8c45fSAndroid Build Coastguard Worker     if (error != Error::NONE) {
754*38e8c45fSAndroid Build Coastguard Worker         ALOGE("listSupportedMetadataType() failed with %d", error);
755*38e8c45fSAndroid Build Coastguard Worker         return {};
756*38e8c45fSAndroid Build Coastguard Worker     }
757*38e8c45fSAndroid Build Coastguard Worker 
758*38e8c45fSAndroid Build Coastguard Worker     return static_cast<std::vector<MetadataTypeDescription>>(descriptions);
759*38e8c45fSAndroid Build Coastguard Worker }
760*38e8c45fSAndroid Build Coastguard Worker 
761*38e8c45fSAndroid Build Coastguard Worker template <class T>
metadataDumpHelper(const BufferDump & bufferDump,StandardMetadataType metadataType,DecodeFunction<T> decodeFunction,T * outT) const762*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::metadataDumpHelper(const BufferDump& bufferDump,
763*38e8c45fSAndroid Build Coastguard Worker                                             StandardMetadataType metadataType,
764*38e8c45fSAndroid Build Coastguard Worker                                             DecodeFunction<T> decodeFunction, T* outT) const {
765*38e8c45fSAndroid Build Coastguard Worker     const auto& metadataDump = bufferDump.metadataDump;
766*38e8c45fSAndroid Build Coastguard Worker 
767*38e8c45fSAndroid Build Coastguard Worker     auto itr =
768*38e8c45fSAndroid Build Coastguard Worker             std::find_if(metadataDump.begin(), metadataDump.end(),
769*38e8c45fSAndroid Build Coastguard Worker                          [&](const MetadataDump& tmpMetadataDump) {
770*38e8c45fSAndroid Build Coastguard Worker                              if (!gralloc4::isStandardMetadataType(tmpMetadataDump.metadataType)) {
771*38e8c45fSAndroid Build Coastguard Worker                                  return false;
772*38e8c45fSAndroid Build Coastguard Worker                              }
773*38e8c45fSAndroid Build Coastguard Worker                              return metadataType ==
774*38e8c45fSAndroid Build Coastguard Worker                                      gralloc4::getStandardMetadataTypeValue(
775*38e8c45fSAndroid Build Coastguard Worker                                              tmpMetadataDump.metadataType);
776*38e8c45fSAndroid Build Coastguard Worker                          });
777*38e8c45fSAndroid Build Coastguard Worker     if (itr == metadataDump.end()) {
778*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
779*38e8c45fSAndroid Build Coastguard Worker     }
780*38e8c45fSAndroid Build Coastguard Worker 
781*38e8c45fSAndroid Build Coastguard Worker     return decodeFunction(itr->metadata, outT);
782*38e8c45fSAndroid Build Coastguard Worker }
783*38e8c45fSAndroid Build Coastguard Worker 
bufferDumpHelper(const BufferDump & bufferDump,std::ostringstream * outDump,uint64_t * outAllocationSize,bool less) const784*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Mapper::bufferDumpHelper(const BufferDump& bufferDump, std::ostringstream* outDump,
785*38e8c45fSAndroid Build Coastguard Worker                                           uint64_t* outAllocationSize, bool less) const {
786*38e8c45fSAndroid Build Coastguard Worker     uint64_t bufferId;
787*38e8c45fSAndroid Build Coastguard Worker     std::string name;
788*38e8c45fSAndroid Build Coastguard Worker     uint64_t width;
789*38e8c45fSAndroid Build Coastguard Worker     uint64_t height;
790*38e8c45fSAndroid Build Coastguard Worker     uint64_t layerCount;
791*38e8c45fSAndroid Build Coastguard Worker     ui::PixelFormat pixelFormatRequested;
792*38e8c45fSAndroid Build Coastguard Worker     uint32_t pixelFormatFourCC;
793*38e8c45fSAndroid Build Coastguard Worker     uint64_t pixelFormatModifier;
794*38e8c45fSAndroid Build Coastguard Worker     uint64_t usage;
795*38e8c45fSAndroid Build Coastguard Worker     AidlDataspace dataspace;
796*38e8c45fSAndroid Build Coastguard Worker     uint64_t allocationSize;
797*38e8c45fSAndroid Build Coastguard Worker     uint64_t protectedContent;
798*38e8c45fSAndroid Build Coastguard Worker     ExtendableType compression;
799*38e8c45fSAndroid Build Coastguard Worker     ExtendableType interlaced;
800*38e8c45fSAndroid Build Coastguard Worker     ExtendableType chromaSiting;
801*38e8c45fSAndroid Build Coastguard Worker     std::vector<ui::PlaneLayout> planeLayouts;
802*38e8c45fSAndroid Build Coastguard Worker 
803*38e8c45fSAndroid Build Coastguard Worker     status_t error = metadataDumpHelper(bufferDump, StandardMetadataType::BUFFER_ID,
804*38e8c45fSAndroid Build Coastguard Worker                                         gralloc4::decodeBufferId, &bufferId);
805*38e8c45fSAndroid Build Coastguard Worker     if (error != NO_ERROR) {
806*38e8c45fSAndroid Build Coastguard Worker         return error;
807*38e8c45fSAndroid Build Coastguard Worker     }
808*38e8c45fSAndroid Build Coastguard Worker     error = metadataDumpHelper(bufferDump, StandardMetadataType::NAME, gralloc4::decodeName, &name);
809*38e8c45fSAndroid Build Coastguard Worker     if (error != NO_ERROR) {
810*38e8c45fSAndroid Build Coastguard Worker         return error;
811*38e8c45fSAndroid Build Coastguard Worker     }
812*38e8c45fSAndroid Build Coastguard Worker     error = metadataDumpHelper(bufferDump, StandardMetadataType::WIDTH, gralloc4::decodeWidth,
813*38e8c45fSAndroid Build Coastguard Worker                                &width);
814*38e8c45fSAndroid Build Coastguard Worker     if (error != NO_ERROR) {
815*38e8c45fSAndroid Build Coastguard Worker         return error;
816*38e8c45fSAndroid Build Coastguard Worker     }
817*38e8c45fSAndroid Build Coastguard Worker     error = metadataDumpHelper(bufferDump, StandardMetadataType::HEIGHT, gralloc4::decodeHeight,
818*38e8c45fSAndroid Build Coastguard Worker                                &height);
819*38e8c45fSAndroid Build Coastguard Worker     if (error != NO_ERROR) {
820*38e8c45fSAndroid Build Coastguard Worker         return error;
821*38e8c45fSAndroid Build Coastguard Worker     }
822*38e8c45fSAndroid Build Coastguard Worker     error = metadataDumpHelper(bufferDump, StandardMetadataType::LAYER_COUNT,
823*38e8c45fSAndroid Build Coastguard Worker                                gralloc4::decodeLayerCount, &layerCount);
824*38e8c45fSAndroid Build Coastguard Worker     if (error != NO_ERROR) {
825*38e8c45fSAndroid Build Coastguard Worker         return error;
826*38e8c45fSAndroid Build Coastguard Worker     }
827*38e8c45fSAndroid Build Coastguard Worker     error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_REQUESTED,
828*38e8c45fSAndroid Build Coastguard Worker                                gralloc4::decodePixelFormatRequested, &pixelFormatRequested);
829*38e8c45fSAndroid Build Coastguard Worker     if (error != NO_ERROR) {
830*38e8c45fSAndroid Build Coastguard Worker         return error;
831*38e8c45fSAndroid Build Coastguard Worker     }
832*38e8c45fSAndroid Build Coastguard Worker     error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_FOURCC,
833*38e8c45fSAndroid Build Coastguard Worker                                gralloc4::decodePixelFormatFourCC, &pixelFormatFourCC);
834*38e8c45fSAndroid Build Coastguard Worker     if (error != NO_ERROR) {
835*38e8c45fSAndroid Build Coastguard Worker         return error;
836*38e8c45fSAndroid Build Coastguard Worker     }
837*38e8c45fSAndroid Build Coastguard Worker     error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_MODIFIER,
838*38e8c45fSAndroid Build Coastguard Worker                                gralloc4::decodePixelFormatModifier, &pixelFormatModifier);
839*38e8c45fSAndroid Build Coastguard Worker     if (error != NO_ERROR) {
840*38e8c45fSAndroid Build Coastguard Worker         return error;
841*38e8c45fSAndroid Build Coastguard Worker     }
842*38e8c45fSAndroid Build Coastguard Worker     error = metadataDumpHelper(bufferDump, StandardMetadataType::USAGE, gralloc4::decodeUsage,
843*38e8c45fSAndroid Build Coastguard Worker                                &usage);
844*38e8c45fSAndroid Build Coastguard Worker     if (error != NO_ERROR) {
845*38e8c45fSAndroid Build Coastguard Worker         return error;
846*38e8c45fSAndroid Build Coastguard Worker     }
847*38e8c45fSAndroid Build Coastguard Worker     error = metadataDumpHelper(bufferDump, StandardMetadataType::DATASPACE,
848*38e8c45fSAndroid Build Coastguard Worker                                gralloc4::decodeDataspace, &dataspace);
849*38e8c45fSAndroid Build Coastguard Worker     if (error != NO_ERROR) {
850*38e8c45fSAndroid Build Coastguard Worker         return error;
851*38e8c45fSAndroid Build Coastguard Worker     }
852*38e8c45fSAndroid Build Coastguard Worker     error = metadataDumpHelper(bufferDump, StandardMetadataType::ALLOCATION_SIZE,
853*38e8c45fSAndroid Build Coastguard Worker                                gralloc4::decodeAllocationSize, &allocationSize);
854*38e8c45fSAndroid Build Coastguard Worker     if (error != NO_ERROR) {
855*38e8c45fSAndroid Build Coastguard Worker         return error;
856*38e8c45fSAndroid Build Coastguard Worker     }
857*38e8c45fSAndroid Build Coastguard Worker     error = metadataDumpHelper(bufferDump, StandardMetadataType::PROTECTED_CONTENT,
858*38e8c45fSAndroid Build Coastguard Worker                                gralloc4::decodeProtectedContent, &protectedContent);
859*38e8c45fSAndroid Build Coastguard Worker     if (error != NO_ERROR) {
860*38e8c45fSAndroid Build Coastguard Worker         return error;
861*38e8c45fSAndroid Build Coastguard Worker     }
862*38e8c45fSAndroid Build Coastguard Worker     error = metadataDumpHelper(bufferDump, StandardMetadataType::COMPRESSION,
863*38e8c45fSAndroid Build Coastguard Worker                                gralloc4::decodeCompression, &compression);
864*38e8c45fSAndroid Build Coastguard Worker     if (error != NO_ERROR) {
865*38e8c45fSAndroid Build Coastguard Worker         return error;
866*38e8c45fSAndroid Build Coastguard Worker     }
867*38e8c45fSAndroid Build Coastguard Worker     error = metadataDumpHelper(bufferDump, StandardMetadataType::INTERLACED,
868*38e8c45fSAndroid Build Coastguard Worker                                gralloc4::decodeInterlaced, &interlaced);
869*38e8c45fSAndroid Build Coastguard Worker     if (error != NO_ERROR) {
870*38e8c45fSAndroid Build Coastguard Worker         return error;
871*38e8c45fSAndroid Build Coastguard Worker     }
872*38e8c45fSAndroid Build Coastguard Worker     error = metadataDumpHelper(bufferDump, StandardMetadataType::CHROMA_SITING,
873*38e8c45fSAndroid Build Coastguard Worker                                gralloc4::decodeChromaSiting, &chromaSiting);
874*38e8c45fSAndroid Build Coastguard Worker     if (error != NO_ERROR) {
875*38e8c45fSAndroid Build Coastguard Worker         return error;
876*38e8c45fSAndroid Build Coastguard Worker     }
877*38e8c45fSAndroid Build Coastguard Worker     error = metadataDumpHelper(bufferDump, StandardMetadataType::PLANE_LAYOUTS,
878*38e8c45fSAndroid Build Coastguard Worker                                gralloc4::decodePlaneLayouts, &planeLayouts);
879*38e8c45fSAndroid Build Coastguard Worker     if (error != NO_ERROR) {
880*38e8c45fSAndroid Build Coastguard Worker         return error;
881*38e8c45fSAndroid Build Coastguard Worker     }
882*38e8c45fSAndroid Build Coastguard Worker 
883*38e8c45fSAndroid Build Coastguard Worker     if (outAllocationSize) {
884*38e8c45fSAndroid Build Coastguard Worker         *outAllocationSize = allocationSize;
885*38e8c45fSAndroid Build Coastguard Worker     }
886*38e8c45fSAndroid Build Coastguard Worker     double allocationSizeKiB = static_cast<double>(allocationSize) / 1024;
887*38e8c45fSAndroid Build Coastguard Worker 
888*38e8c45fSAndroid Build Coastguard Worker     *outDump << "+ name:" << name << ", id:" << bufferId << ", size:" << std::fixed
889*38e8c45fSAndroid Build Coastguard Worker              << allocationSizeKiB << "KiB, w/h:" << width << "x" << height << ", usage: 0x"
890*38e8c45fSAndroid Build Coastguard Worker              << std::hex << usage << std::dec
891*38e8c45fSAndroid Build Coastguard Worker              << ", req fmt:" << static_cast<int32_t>(pixelFormatRequested)
892*38e8c45fSAndroid Build Coastguard Worker              << ", fourcc/mod:" << pixelFormatFourCC << "/" << pixelFormatModifier
893*38e8c45fSAndroid Build Coastguard Worker              << ", dataspace: 0x" << std::hex << static_cast<uint32_t>(dataspace) << std::dec
894*38e8c45fSAndroid Build Coastguard Worker              << ", compressed: ";
895*38e8c45fSAndroid Build Coastguard Worker 
896*38e8c45fSAndroid Build Coastguard Worker     if (less) {
897*38e8c45fSAndroid Build Coastguard Worker         bool isCompressed = !gralloc4::isStandardCompression(compression) ||
898*38e8c45fSAndroid Build Coastguard Worker                 (gralloc4::getStandardCompressionValue(compression) != ui::Compression::NONE);
899*38e8c45fSAndroid Build Coastguard Worker         *outDump << std::boolalpha << isCompressed << "\n";
900*38e8c45fSAndroid Build Coastguard Worker     } else {
901*38e8c45fSAndroid Build Coastguard Worker         *outDump << gralloc4::getCompressionName(compression) << "\n";
902*38e8c45fSAndroid Build Coastguard Worker     }
903*38e8c45fSAndroid Build Coastguard Worker 
904*38e8c45fSAndroid Build Coastguard Worker     bool firstPlane = true;
905*38e8c45fSAndroid Build Coastguard Worker     for (const auto& planeLayout : planeLayouts) {
906*38e8c45fSAndroid Build Coastguard Worker         if (firstPlane) {
907*38e8c45fSAndroid Build Coastguard Worker             firstPlane = false;
908*38e8c45fSAndroid Build Coastguard Worker             *outDump << "\tplanes: ";
909*38e8c45fSAndroid Build Coastguard Worker         } else {
910*38e8c45fSAndroid Build Coastguard Worker             *outDump << "\t        ";
911*38e8c45fSAndroid Build Coastguard Worker         }
912*38e8c45fSAndroid Build Coastguard Worker 
913*38e8c45fSAndroid Build Coastguard Worker         for (size_t i = 0; i < planeLayout.components.size(); i++) {
914*38e8c45fSAndroid Build Coastguard Worker             const auto& planeLayoutComponent = planeLayout.components[i];
915*38e8c45fSAndroid Build Coastguard Worker             *outDump << gralloc4::getPlaneLayoutComponentTypeName(planeLayoutComponent.type);
916*38e8c45fSAndroid Build Coastguard Worker             if (i < planeLayout.components.size() - 1) {
917*38e8c45fSAndroid Build Coastguard Worker                 *outDump << "/";
918*38e8c45fSAndroid Build Coastguard Worker             } else {
919*38e8c45fSAndroid Build Coastguard Worker                 *outDump << ":\t";
920*38e8c45fSAndroid Build Coastguard Worker             }
921*38e8c45fSAndroid Build Coastguard Worker         }
922*38e8c45fSAndroid Build Coastguard Worker         *outDump << " w/h:" << planeLayout.widthInSamples << "x" << planeLayout.heightInSamples
923*38e8c45fSAndroid Build Coastguard Worker                  << ", stride:" << planeLayout.strideInBytes
924*38e8c45fSAndroid Build Coastguard Worker                  << " bytes, size:" << planeLayout.totalSizeInBytes;
925*38e8c45fSAndroid Build Coastguard Worker         if (!less) {
926*38e8c45fSAndroid Build Coastguard Worker             *outDump << ", inc:" << planeLayout.sampleIncrementInBits
927*38e8c45fSAndroid Build Coastguard Worker                      << " bits, subsampling w/h:" << planeLayout.horizontalSubsampling << "x"
928*38e8c45fSAndroid Build Coastguard Worker                      << planeLayout.verticalSubsampling;
929*38e8c45fSAndroid Build Coastguard Worker         }
930*38e8c45fSAndroid Build Coastguard Worker         *outDump << "\n";
931*38e8c45fSAndroid Build Coastguard Worker     }
932*38e8c45fSAndroid Build Coastguard Worker 
933*38e8c45fSAndroid Build Coastguard Worker     if (!less) {
934*38e8c45fSAndroid Build Coastguard Worker         *outDump << "\tlayer cnt: " << layerCount << ", protected content: " << protectedContent
935*38e8c45fSAndroid Build Coastguard Worker                  << ", interlaced: " << gralloc4::getInterlacedName(interlaced)
936*38e8c45fSAndroid Build Coastguard Worker                  << ", chroma siting:" << gralloc4::getChromaSitingName(chromaSiting) << "\n";
937*38e8c45fSAndroid Build Coastguard Worker     }
938*38e8c45fSAndroid Build Coastguard Worker 
939*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
940*38e8c45fSAndroid Build Coastguard Worker }
941*38e8c45fSAndroid Build Coastguard Worker 
dumpBuffer(buffer_handle_t bufferHandle,bool less) const942*38e8c45fSAndroid Build Coastguard Worker std::string Gralloc4Mapper::dumpBuffer(buffer_handle_t bufferHandle, bool less) const {
943*38e8c45fSAndroid Build Coastguard Worker     auto buffer = const_cast<native_handle_t*>(bufferHandle);
944*38e8c45fSAndroid Build Coastguard Worker 
945*38e8c45fSAndroid Build Coastguard Worker     BufferDump bufferDump;
946*38e8c45fSAndroid Build Coastguard Worker     Error error;
947*38e8c45fSAndroid Build Coastguard Worker     auto ret = mMapper->dumpBuffer(buffer, [&](const auto& tmpError, const auto& tmpBufferDump) {
948*38e8c45fSAndroid Build Coastguard Worker         error = tmpError;
949*38e8c45fSAndroid Build Coastguard Worker         bufferDump = tmpBufferDump;
950*38e8c45fSAndroid Build Coastguard Worker     });
951*38e8c45fSAndroid Build Coastguard Worker 
952*38e8c45fSAndroid Build Coastguard Worker     if (!ret.isOk()) {
953*38e8c45fSAndroid Build Coastguard Worker         error = kTransactionError;
954*38e8c45fSAndroid Build Coastguard Worker     }
955*38e8c45fSAndroid Build Coastguard Worker 
956*38e8c45fSAndroid Build Coastguard Worker     if (error != Error::NONE) {
957*38e8c45fSAndroid Build Coastguard Worker         ALOGE("dumpBuffer() failed with %d", error);
958*38e8c45fSAndroid Build Coastguard Worker         return "";
959*38e8c45fSAndroid Build Coastguard Worker     }
960*38e8c45fSAndroid Build Coastguard Worker 
961*38e8c45fSAndroid Build Coastguard Worker     std::ostringstream stream;
962*38e8c45fSAndroid Build Coastguard Worker     stream.precision(2);
963*38e8c45fSAndroid Build Coastguard Worker 
964*38e8c45fSAndroid Build Coastguard Worker     status_t err = bufferDumpHelper(bufferDump, &stream, nullptr, less);
965*38e8c45fSAndroid Build Coastguard Worker     if (err != NO_ERROR) {
966*38e8c45fSAndroid Build Coastguard Worker         ALOGE("bufferDumpHelper() failed with %d", err);
967*38e8c45fSAndroid Build Coastguard Worker         return "";
968*38e8c45fSAndroid Build Coastguard Worker     }
969*38e8c45fSAndroid Build Coastguard Worker 
970*38e8c45fSAndroid Build Coastguard Worker     return stream.str();
971*38e8c45fSAndroid Build Coastguard Worker }
972*38e8c45fSAndroid Build Coastguard Worker 
dumpBuffers(bool less) const973*38e8c45fSAndroid Build Coastguard Worker std::string Gralloc4Mapper::dumpBuffers(bool less) const {
974*38e8c45fSAndroid Build Coastguard Worker     hidl_vec<BufferDump> bufferDumps;
975*38e8c45fSAndroid Build Coastguard Worker     Error error;
976*38e8c45fSAndroid Build Coastguard Worker     auto ret = mMapper->dumpBuffers([&](const auto& tmpError, const auto& tmpBufferDump) {
977*38e8c45fSAndroid Build Coastguard Worker         error = tmpError;
978*38e8c45fSAndroid Build Coastguard Worker         bufferDumps = tmpBufferDump;
979*38e8c45fSAndroid Build Coastguard Worker     });
980*38e8c45fSAndroid Build Coastguard Worker 
981*38e8c45fSAndroid Build Coastguard Worker     if (!ret.isOk()) {
982*38e8c45fSAndroid Build Coastguard Worker         error = kTransactionError;
983*38e8c45fSAndroid Build Coastguard Worker     }
984*38e8c45fSAndroid Build Coastguard Worker 
985*38e8c45fSAndroid Build Coastguard Worker     if (error != Error::NONE) {
986*38e8c45fSAndroid Build Coastguard Worker         ALOGE("dumpBuffer() failed with %d", error);
987*38e8c45fSAndroid Build Coastguard Worker         return "";
988*38e8c45fSAndroid Build Coastguard Worker     }
989*38e8c45fSAndroid Build Coastguard Worker 
990*38e8c45fSAndroid Build Coastguard Worker     uint64_t totalAllocationSize = 0;
991*38e8c45fSAndroid Build Coastguard Worker     std::ostringstream stream;
992*38e8c45fSAndroid Build Coastguard Worker     stream.precision(2);
993*38e8c45fSAndroid Build Coastguard Worker 
994*38e8c45fSAndroid Build Coastguard Worker     stream << "Imported gralloc buffers:\n";
995*38e8c45fSAndroid Build Coastguard Worker 
996*38e8c45fSAndroid Build Coastguard Worker     for (const auto& bufferDump : bufferDumps) {
997*38e8c45fSAndroid Build Coastguard Worker         uint64_t allocationSize = 0;
998*38e8c45fSAndroid Build Coastguard Worker         status_t err = bufferDumpHelper(bufferDump, &stream, &allocationSize, less);
999*38e8c45fSAndroid Build Coastguard Worker         if (err != NO_ERROR) {
1000*38e8c45fSAndroid Build Coastguard Worker             ALOGE("bufferDumpHelper() failed with %d", err);
1001*38e8c45fSAndroid Build Coastguard Worker             return "";
1002*38e8c45fSAndroid Build Coastguard Worker         }
1003*38e8c45fSAndroid Build Coastguard Worker         totalAllocationSize += allocationSize;
1004*38e8c45fSAndroid Build Coastguard Worker     }
1005*38e8c45fSAndroid Build Coastguard Worker 
1006*38e8c45fSAndroid Build Coastguard Worker     double totalAllocationSizeKiB = static_cast<double>(totalAllocationSize) / 1024;
1007*38e8c45fSAndroid Build Coastguard Worker     stream << "Total imported by gralloc: " << totalAllocationSizeKiB << "KiB\n";
1008*38e8c45fSAndroid Build Coastguard Worker     return stream.str();
1009*38e8c45fSAndroid Build Coastguard Worker }
1010*38e8c45fSAndroid Build Coastguard Worker 
Gralloc4Allocator(const Gralloc4Mapper & mapper)1011*38e8c45fSAndroid Build Coastguard Worker Gralloc4Allocator::Gralloc4Allocator(const Gralloc4Mapper& mapper) : mMapper(mapper) {
1012*38e8c45fSAndroid Build Coastguard Worker     mAllocator = IAllocator::getService();
1013*38e8c45fSAndroid Build Coastguard Worker     if (__builtin_available(android 31, *)) {
1014*38e8c45fSAndroid Build Coastguard Worker         if (hasIAllocatorAidl()) {
1015*38e8c45fSAndroid Build Coastguard Worker             // TODO(b/269517338): Perform the isolated checking for this in service manager instead.
1016*38e8c45fSAndroid Build Coastguard Worker             uid_t aid = multiuser_get_app_id(getuid());
1017*38e8c45fSAndroid Build Coastguard Worker             if (aid >= AID_ISOLATED_START && aid <= AID_ISOLATED_END) {
1018*38e8c45fSAndroid Build Coastguard Worker                 mAidlAllocator = AidlIAllocator::fromBinder(ndk::SpAIBinder(
1019*38e8c45fSAndroid Build Coastguard Worker                         AServiceManager_getService(kAidlAllocatorServiceName.c_str())));
1020*38e8c45fSAndroid Build Coastguard Worker             } else {
1021*38e8c45fSAndroid Build Coastguard Worker                 mAidlAllocator = AidlIAllocator::fromBinder(ndk::SpAIBinder(
1022*38e8c45fSAndroid Build Coastguard Worker                         AServiceManager_waitForService(kAidlAllocatorServiceName.c_str())));
1023*38e8c45fSAndroid Build Coastguard Worker             }
1024*38e8c45fSAndroid Build Coastguard Worker             ALOGE_IF(!mAidlAllocator, "AIDL IAllocator declared but failed to get service");
1025*38e8c45fSAndroid Build Coastguard Worker         }
1026*38e8c45fSAndroid Build Coastguard Worker     }
1027*38e8c45fSAndroid Build Coastguard Worker     if (mAllocator == nullptr && mAidlAllocator == nullptr) {
1028*38e8c45fSAndroid Build Coastguard Worker         ALOGW("allocator 4.x is not supported");
1029*38e8c45fSAndroid Build Coastguard Worker         return;
1030*38e8c45fSAndroid Build Coastguard Worker     }
1031*38e8c45fSAndroid Build Coastguard Worker }
1032*38e8c45fSAndroid Build Coastguard Worker 
isLoaded() const1033*38e8c45fSAndroid Build Coastguard Worker bool Gralloc4Allocator::isLoaded() const {
1034*38e8c45fSAndroid Build Coastguard Worker     return mAllocator != nullptr || mAidlAllocator != nullptr;
1035*38e8c45fSAndroid Build Coastguard Worker }
1036*38e8c45fSAndroid Build Coastguard Worker 
dumpDebugInfo(bool less) const1037*38e8c45fSAndroid Build Coastguard Worker std::string Gralloc4Allocator::dumpDebugInfo(bool less) const {
1038*38e8c45fSAndroid Build Coastguard Worker     return mMapper.dumpBuffers(less);
1039*38e8c45fSAndroid Build Coastguard Worker }
1040*38e8c45fSAndroid Build Coastguard Worker 
allocate(std::string requestorName,uint32_t width,uint32_t height,android::PixelFormat format,uint32_t layerCount,uint64_t usage,uint32_t * outStride,buffer_handle_t * outBufferHandles,bool importBuffers) const1041*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc4Allocator::allocate(std::string requestorName, uint32_t width, uint32_t height,
1042*38e8c45fSAndroid Build Coastguard Worker                                      android::PixelFormat format, uint32_t layerCount,
1043*38e8c45fSAndroid Build Coastguard Worker                                      uint64_t usage, uint32_t* outStride,
1044*38e8c45fSAndroid Build Coastguard Worker                                      buffer_handle_t* outBufferHandles, bool importBuffers) const {
1045*38e8c45fSAndroid Build Coastguard Worker     IMapper::BufferDescriptorInfo descriptorInfo;
1046*38e8c45fSAndroid Build Coastguard Worker     if (auto error = sBufferDescriptorInfo(requestorName, width, height, format, layerCount, usage,
1047*38e8c45fSAndroid Build Coastguard Worker                                            &descriptorInfo) != OK) {
1048*38e8c45fSAndroid Build Coastguard Worker         return error;
1049*38e8c45fSAndroid Build Coastguard Worker     }
1050*38e8c45fSAndroid Build Coastguard Worker 
1051*38e8c45fSAndroid Build Coastguard Worker     BufferDescriptor descriptor;
1052*38e8c45fSAndroid Build Coastguard Worker     status_t error = mMapper.createDescriptor(static_cast<void*>(&descriptorInfo),
1053*38e8c45fSAndroid Build Coastguard Worker                                               static_cast<void*>(&descriptor));
1054*38e8c45fSAndroid Build Coastguard Worker     if (error != NO_ERROR) {
1055*38e8c45fSAndroid Build Coastguard Worker         return error;
1056*38e8c45fSAndroid Build Coastguard Worker     }
1057*38e8c45fSAndroid Build Coastguard Worker 
1058*38e8c45fSAndroid Build Coastguard Worker     constexpr auto bufferCount = 1;
1059*38e8c45fSAndroid Build Coastguard Worker 
1060*38e8c45fSAndroid Build Coastguard Worker     if (mAidlAllocator) {
1061*38e8c45fSAndroid Build Coastguard Worker         AllocationResult result;
1062*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic push
1063*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wdeprecated-declarations"
1064*38e8c45fSAndroid Build Coastguard Worker         auto status = mAidlAllocator->allocate(descriptor, bufferCount, &result);
1065*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic pop // deprecation
1066*38e8c45fSAndroid Build Coastguard Worker         if (!status.isOk()) {
1067*38e8c45fSAndroid Build Coastguard Worker             error = status.getExceptionCode();
1068*38e8c45fSAndroid Build Coastguard Worker             if (error == EX_SERVICE_SPECIFIC) {
1069*38e8c45fSAndroid Build Coastguard Worker                 error = status.getServiceSpecificError();
1070*38e8c45fSAndroid Build Coastguard Worker             }
1071*38e8c45fSAndroid Build Coastguard Worker             if (error == OK) {
1072*38e8c45fSAndroid Build Coastguard Worker                 error = UNKNOWN_ERROR;
1073*38e8c45fSAndroid Build Coastguard Worker             }
1074*38e8c45fSAndroid Build Coastguard Worker         } else {
1075*38e8c45fSAndroid Build Coastguard Worker             if (importBuffers) {
1076*38e8c45fSAndroid Build Coastguard Worker                 for (uint32_t i = 0; i < bufferCount; i++) {
1077*38e8c45fSAndroid Build Coastguard Worker                     auto handle = makeFromAidl(result.buffers[i]);
1078*38e8c45fSAndroid Build Coastguard Worker                     error = mMapper.importBuffer(handle, &outBufferHandles[i]);
1079*38e8c45fSAndroid Build Coastguard Worker                     native_handle_delete(handle);
1080*38e8c45fSAndroid Build Coastguard Worker                     if (error != NO_ERROR) {
1081*38e8c45fSAndroid Build Coastguard Worker                         for (uint32_t j = 0; j < i; j++) {
1082*38e8c45fSAndroid Build Coastguard Worker                             mMapper.freeBuffer(outBufferHandles[j]);
1083*38e8c45fSAndroid Build Coastguard Worker                             outBufferHandles[j] = nullptr;
1084*38e8c45fSAndroid Build Coastguard Worker                         }
1085*38e8c45fSAndroid Build Coastguard Worker                         break;
1086*38e8c45fSAndroid Build Coastguard Worker                     }
1087*38e8c45fSAndroid Build Coastguard Worker                 }
1088*38e8c45fSAndroid Build Coastguard Worker             } else {
1089*38e8c45fSAndroid Build Coastguard Worker                 for (uint32_t i = 0; i < bufferCount; i++) {
1090*38e8c45fSAndroid Build Coastguard Worker                     outBufferHandles[i] = dupFromAidl(result.buffers[i]);
1091*38e8c45fSAndroid Build Coastguard Worker                     if (!outBufferHandles[i]) {
1092*38e8c45fSAndroid Build Coastguard Worker                         for (uint32_t j = 0; j < i; j++) {
1093*38e8c45fSAndroid Build Coastguard Worker                             auto buffer = const_cast<native_handle_t*>(outBufferHandles[j]);
1094*38e8c45fSAndroid Build Coastguard Worker                             native_handle_close(buffer);
1095*38e8c45fSAndroid Build Coastguard Worker                             native_handle_delete(buffer);
1096*38e8c45fSAndroid Build Coastguard Worker                             outBufferHandles[j] = nullptr;
1097*38e8c45fSAndroid Build Coastguard Worker                         }
1098*38e8c45fSAndroid Build Coastguard Worker                     }
1099*38e8c45fSAndroid Build Coastguard Worker                 }
1100*38e8c45fSAndroid Build Coastguard Worker             }
1101*38e8c45fSAndroid Build Coastguard Worker         }
1102*38e8c45fSAndroid Build Coastguard Worker         *outStride = result.stride;
1103*38e8c45fSAndroid Build Coastguard Worker         // Release all the resources held by AllocationResult (specifically any remaining FDs)
1104*38e8c45fSAndroid Build Coastguard Worker         result = {};
1105*38e8c45fSAndroid Build Coastguard Worker         // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
1106*38e8c45fSAndroid Build Coastguard Worker         hardware::IPCThreadState::self()->flushCommands();
1107*38e8c45fSAndroid Build Coastguard Worker         return error;
1108*38e8c45fSAndroid Build Coastguard Worker     }
1109*38e8c45fSAndroid Build Coastguard Worker 
1110*38e8c45fSAndroid Build Coastguard Worker     auto ret = mAllocator->allocate(descriptor, bufferCount,
1111*38e8c45fSAndroid Build Coastguard Worker                                     [&](const auto& tmpError, const auto& tmpStride,
1112*38e8c45fSAndroid Build Coastguard Worker                                         const auto& tmpBuffers) {
1113*38e8c45fSAndroid Build Coastguard Worker                                         error = static_cast<status_t>(tmpError);
1114*38e8c45fSAndroid Build Coastguard Worker                                         if (tmpError != Error::NONE) {
1115*38e8c45fSAndroid Build Coastguard Worker                                             return;
1116*38e8c45fSAndroid Build Coastguard Worker                                         }
1117*38e8c45fSAndroid Build Coastguard Worker 
1118*38e8c45fSAndroid Build Coastguard Worker                                         if (importBuffers) {
1119*38e8c45fSAndroid Build Coastguard Worker                                             for (uint32_t i = 0; i < bufferCount; i++) {
1120*38e8c45fSAndroid Build Coastguard Worker                                                 error = mMapper.importBuffer(tmpBuffers[i],
1121*38e8c45fSAndroid Build Coastguard Worker                                                                              &outBufferHandles[i]);
1122*38e8c45fSAndroid Build Coastguard Worker                                                 if (error != NO_ERROR) {
1123*38e8c45fSAndroid Build Coastguard Worker                                                     for (uint32_t j = 0; j < i; j++) {
1124*38e8c45fSAndroid Build Coastguard Worker                                                         mMapper.freeBuffer(outBufferHandles[j]);
1125*38e8c45fSAndroid Build Coastguard Worker                                                         outBufferHandles[j] = nullptr;
1126*38e8c45fSAndroid Build Coastguard Worker                                                     }
1127*38e8c45fSAndroid Build Coastguard Worker                                                     return;
1128*38e8c45fSAndroid Build Coastguard Worker                                                 }
1129*38e8c45fSAndroid Build Coastguard Worker                                             }
1130*38e8c45fSAndroid Build Coastguard Worker                                         } else {
1131*38e8c45fSAndroid Build Coastguard Worker                                             for (uint32_t i = 0; i < bufferCount; i++) {
1132*38e8c45fSAndroid Build Coastguard Worker                                                 outBufferHandles[i] = native_handle_clone(
1133*38e8c45fSAndroid Build Coastguard Worker                                                         tmpBuffers[i].getNativeHandle());
1134*38e8c45fSAndroid Build Coastguard Worker                                                 if (!outBufferHandles[i]) {
1135*38e8c45fSAndroid Build Coastguard Worker                                                     for (uint32_t j = 0; j < i; j++) {
1136*38e8c45fSAndroid Build Coastguard Worker                                                         auto buffer = const_cast<native_handle_t*>(
1137*38e8c45fSAndroid Build Coastguard Worker                                                                 outBufferHandles[j]);
1138*38e8c45fSAndroid Build Coastguard Worker                                                         native_handle_close(buffer);
1139*38e8c45fSAndroid Build Coastguard Worker                                                         native_handle_delete(buffer);
1140*38e8c45fSAndroid Build Coastguard Worker                                                         outBufferHandles[j] = nullptr;
1141*38e8c45fSAndroid Build Coastguard Worker                                                     }
1142*38e8c45fSAndroid Build Coastguard Worker                                                 }
1143*38e8c45fSAndroid Build Coastguard Worker                                             }
1144*38e8c45fSAndroid Build Coastguard Worker                                         }
1145*38e8c45fSAndroid Build Coastguard Worker                                         *outStride = tmpStride;
1146*38e8c45fSAndroid Build Coastguard Worker                                     });
1147*38e8c45fSAndroid Build Coastguard Worker 
1148*38e8c45fSAndroid Build Coastguard Worker     // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
1149*38e8c45fSAndroid Build Coastguard Worker     hardware::IPCThreadState::self()->flushCommands();
1150*38e8c45fSAndroid Build Coastguard Worker 
1151*38e8c45fSAndroid Build Coastguard Worker     return (ret.isOk()) ? error : static_cast<status_t>(kTransactionError);
1152*38e8c45fSAndroid Build Coastguard Worker }
1153*38e8c45fSAndroid Build Coastguard Worker 
1154*38e8c45fSAndroid Build Coastguard Worker } // namespace android
1155