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