• 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 <hidl/ServiceManagement.h>
20 #include <hwbinder/IPCThreadState.h>
21 #include <ui/Gralloc4.h>
22 
23 #include <inttypes.h>
24 #include <log/log.h>
25 #pragma clang diagnostic push
26 #pragma clang diagnostic ignored "-Wzero-length-array"
27 #include <sync/sync.h>
28 #pragma clang diagnostic pop
29 
30 using aidl::android::hardware::graphics::common::ExtendableType;
31 using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
32 using aidl::android::hardware::graphics::common::StandardMetadataType;
33 using android::hardware::hidl_vec;
34 using android::hardware::graphics::allocator::V4_0::IAllocator;
35 using android::hardware::graphics::common::V1_2::BufferUsage;
36 using android::hardware::graphics::mapper::V4_0::BufferDescriptor;
37 using android::hardware::graphics::mapper::V4_0::Error;
38 using android::hardware::graphics::mapper::V4_0::IMapper;
39 using AidlDataspace = ::aidl::android::hardware::graphics::common::Dataspace;
40 using BufferDump = android::hardware::graphics::mapper::V4_0::IMapper::BufferDump;
41 using MetadataDump = android::hardware::graphics::mapper::V4_0::IMapper::MetadataDump;
42 using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
43 using MetadataTypeDescription =
44         android::hardware::graphics::mapper::V4_0::IMapper::MetadataTypeDescription;
45 
46 namespace android {
47 
48 namespace {
49 
50 static constexpr Error kTransactionError = Error::NO_RESOURCES;
51 
getValidUsageBits()52 uint64_t getValidUsageBits() {
53     static const uint64_t validUsageBits = []() -> uint64_t {
54         uint64_t bits = 0;
55         for (const auto bit :
56              hardware::hidl_enum_range<hardware::graphics::common::V1_2::BufferUsage>()) {
57             bits = bits | bit;
58         }
59         return bits;
60     }();
61     return validUsageBits;
62 }
63 
sGralloc4Rect(const Rect & rect)64 static inline IMapper::Rect sGralloc4Rect(const Rect& rect) {
65     IMapper::Rect outRect{};
66     outRect.left = rect.left;
67     outRect.top = rect.top;
68     outRect.width = rect.width();
69     outRect.height = rect.height();
70     return outRect;
71 }
sBufferDescriptorInfo(std::string name,uint32_t width,uint32_t height,PixelFormat format,uint32_t layerCount,uint64_t usage,IMapper::BufferDescriptorInfo * outDescriptorInfo)72 static inline void sBufferDescriptorInfo(std::string name, uint32_t width, uint32_t height,
73                                          PixelFormat format, uint32_t layerCount, uint64_t usage,
74                                          IMapper::BufferDescriptorInfo* outDescriptorInfo) {
75     outDescriptorInfo->name = name;
76     outDescriptorInfo->width = width;
77     outDescriptorInfo->height = height;
78     outDescriptorInfo->layerCount = layerCount;
79     outDescriptorInfo->format = static_cast<hardware::graphics::common::V1_2::PixelFormat>(format);
80     outDescriptorInfo->usage = usage;
81     outDescriptorInfo->reservedSize = 0;
82 }
83 
84 } // anonymous namespace
85 
preload()86 void Gralloc4Mapper::preload() {
87     android::hardware::preloadPassthroughService<IMapper>();
88 }
89 
Gralloc4Mapper()90 Gralloc4Mapper::Gralloc4Mapper() {
91     mMapper = IMapper::getService();
92     if (mMapper == nullptr) {
93         ALOGI("mapper 4.x is not supported");
94         return;
95     }
96     if (mMapper->isRemote()) {
97         LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
98     }
99 }
100 
isLoaded() const101 bool Gralloc4Mapper::isLoaded() const {
102     return mMapper != nullptr;
103 }
104 
validateBufferDescriptorInfo(IMapper::BufferDescriptorInfo * descriptorInfo) const105 status_t Gralloc4Mapper::validateBufferDescriptorInfo(
106         IMapper::BufferDescriptorInfo* descriptorInfo) const {
107     uint64_t validUsageBits = getValidUsageBits();
108 
109     if (descriptorInfo->usage & ~validUsageBits) {
110         ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64,
111               descriptorInfo->usage & ~validUsageBits);
112         return BAD_VALUE;
113     }
114     return NO_ERROR;
115 }
116 
createDescriptor(void * bufferDescriptorInfo,void * outBufferDescriptor) const117 status_t Gralloc4Mapper::createDescriptor(void* bufferDescriptorInfo,
118                                           void* outBufferDescriptor) const {
119     IMapper::BufferDescriptorInfo* descriptorInfo =
120             static_cast<IMapper::BufferDescriptorInfo*>(bufferDescriptorInfo);
121     BufferDescriptor* outDescriptor = static_cast<BufferDescriptor*>(outBufferDescriptor);
122 
123     status_t status = validateBufferDescriptorInfo(descriptorInfo);
124     if (status != NO_ERROR) {
125         return status;
126     }
127 
128     Error error;
129     auto hidl_cb = [&](const auto& tmpError, const auto& tmpDescriptor) {
130         error = tmpError;
131         if (error != Error::NONE) {
132             return;
133         }
134         *outDescriptor = tmpDescriptor;
135     };
136 
137     hardware::Return<void> ret = mMapper->createDescriptor(*descriptorInfo, hidl_cb);
138 
139     return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
140 }
141 
importBuffer(const hardware::hidl_handle & rawHandle,buffer_handle_t * outBufferHandle) const142 status_t Gralloc4Mapper::importBuffer(const hardware::hidl_handle& rawHandle,
143                                       buffer_handle_t* outBufferHandle) const {
144     Error error;
145     auto ret = mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
146         error = tmpError;
147         if (error != Error::NONE) {
148             return;
149         }
150         *outBufferHandle = static_cast<buffer_handle_t>(tmpBuffer);
151     });
152 
153     return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
154 }
155 
freeBuffer(buffer_handle_t bufferHandle) const156 void Gralloc4Mapper::freeBuffer(buffer_handle_t bufferHandle) const {
157     auto buffer = const_cast<native_handle_t*>(bufferHandle);
158     auto ret = mMapper->freeBuffer(buffer);
159 
160     auto error = (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
161     ALOGE_IF(error != Error::NONE, "freeBuffer(%p) failed with %d", buffer, error);
162 }
163 
validateBufferSize(buffer_handle_t bufferHandle,uint32_t width,uint32_t height,PixelFormat format,uint32_t layerCount,uint64_t usage,uint32_t stride) const164 status_t Gralloc4Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width,
165                                             uint32_t height, PixelFormat format,
166                                             uint32_t layerCount, uint64_t usage,
167                                             uint32_t stride) const {
168     IMapper::BufferDescriptorInfo descriptorInfo;
169     sBufferDescriptorInfo("validateBufferSize", width, height, format, layerCount, usage,
170                           &descriptorInfo);
171 
172     auto buffer = const_cast<native_handle_t*>(bufferHandle);
173     auto ret = mMapper->validateBufferSize(buffer, descriptorInfo, stride);
174 
175     return static_cast<status_t>((ret.isOk()) ? static_cast<Error>(ret) : kTransactionError);
176 }
177 
getTransportSize(buffer_handle_t bufferHandle,uint32_t * outNumFds,uint32_t * outNumInts) const178 void Gralloc4Mapper::getTransportSize(buffer_handle_t bufferHandle, uint32_t* outNumFds,
179                                       uint32_t* outNumInts) const {
180     *outNumFds = uint32_t(bufferHandle->numFds);
181     *outNumInts = uint32_t(bufferHandle->numInts);
182 
183     Error error;
184     auto buffer = const_cast<native_handle_t*>(bufferHandle);
185     auto ret = mMapper->getTransportSize(buffer,
186                                          [&](const auto& tmpError, const auto& tmpNumFds,
187                                              const auto& tmpNumInts) {
188                                              error = tmpError;
189                                              if (error != Error::NONE) {
190                                                  return;
191                                              }
192                                              *outNumFds = tmpNumFds;
193                                              *outNumInts = tmpNumInts;
194                                          });
195 
196     error = (ret.isOk()) ? error : kTransactionError;
197 
198     ALOGE_IF(error != Error::NONE, "getTransportSize(%p) failed with %d", buffer, error);
199 }
200 
lock(buffer_handle_t bufferHandle,uint64_t usage,const Rect & bounds,int acquireFence,void ** outData,int32_t * outBytesPerPixel,int32_t * outBytesPerStride) const201 status_t Gralloc4Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
202                               int acquireFence, void** outData, int32_t* outBytesPerPixel,
203                               int32_t* outBytesPerStride) const {
204     std::vector<ui::PlaneLayout> planeLayouts;
205     status_t err = getPlaneLayouts(bufferHandle, &planeLayouts);
206 
207     if (err == NO_ERROR && !planeLayouts.empty()) {
208         if (outBytesPerPixel) {
209             int32_t bitsPerPixel = planeLayouts.front().sampleIncrementInBits;
210             for (const auto& planeLayout : planeLayouts) {
211                 if (bitsPerPixel != planeLayout.sampleIncrementInBits) {
212                     bitsPerPixel = -1;
213                 }
214             }
215             if (bitsPerPixel >= 0 && bitsPerPixel % 8 == 0) {
216                 *outBytesPerPixel = bitsPerPixel / 8;
217             } else {
218                 *outBytesPerPixel = -1;
219             }
220         }
221         if (outBytesPerStride) {
222             int32_t bytesPerStride = planeLayouts.front().strideInBytes;
223             for (const auto& planeLayout : planeLayouts) {
224                 if (bytesPerStride != planeLayout.strideInBytes) {
225                     bytesPerStride = -1;
226                 }
227             }
228             if (bytesPerStride >= 0) {
229                 *outBytesPerStride = bytesPerStride;
230             } else {
231                 *outBytesPerStride = -1;
232             }
233         }
234     }
235 
236     auto buffer = const_cast<native_handle_t*>(bufferHandle);
237 
238     IMapper::Rect accessRegion = sGralloc4Rect(bounds);
239 
240     // put acquireFence in a hidl_handle
241     hardware::hidl_handle acquireFenceHandle;
242     NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
243     if (acquireFence >= 0) {
244         auto h = native_handle_init(acquireFenceStorage, 1, 0);
245         h->data[0] = acquireFence;
246         acquireFenceHandle = h;
247     }
248 
249     Error error;
250     auto ret = mMapper->lock(buffer, usage, accessRegion, acquireFenceHandle,
251                              [&](const auto& tmpError, const auto& tmpData) {
252                                  error = tmpError;
253                                  if (error != Error::NONE) {
254                                      return;
255                                  }
256                                  *outData = tmpData;
257                              });
258 
259     // we own acquireFence even on errors
260     if (acquireFence >= 0) {
261         close(acquireFence);
262     }
263 
264     error = (ret.isOk()) ? error : kTransactionError;
265 
266     ALOGW_IF(error != Error::NONE, "lock(%p, ...) failed: %d", bufferHandle, error);
267 
268     return static_cast<status_t>(error);
269 }
270 
lock(buffer_handle_t bufferHandle,uint64_t usage,const Rect & bounds,int acquireFence,android_ycbcr * outYcbcr) const271 status_t Gralloc4Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
272                               int acquireFence, android_ycbcr* outYcbcr) const {
273     if (!outYcbcr) {
274         return BAD_VALUE;
275     }
276 
277     std::vector<ui::PlaneLayout> planeLayouts;
278     status_t error = getPlaneLayouts(bufferHandle, &planeLayouts);
279     if (error != NO_ERROR) {
280         return error;
281     }
282 
283     void* data = nullptr;
284     error = lock(bufferHandle, usage, bounds, acquireFence, &data, nullptr, nullptr);
285     if (error != NO_ERROR) {
286         return error;
287     }
288 
289     android_ycbcr ycbcr;
290 
291     ycbcr.y = nullptr;
292     ycbcr.cb = nullptr;
293     ycbcr.cr = nullptr;
294     ycbcr.ystride = 0;
295     ycbcr.cstride = 0;
296     ycbcr.chroma_step = 0;
297 
298     for (const auto& planeLayout : planeLayouts) {
299         for (const auto& planeLayoutComponent : planeLayout.components) {
300             if (!gralloc4::isStandardPlaneLayoutComponentType(planeLayoutComponent.type)) {
301                 continue;
302             }
303             if (0 != planeLayoutComponent.offsetInBits % 8) {
304                 unlock(bufferHandle);
305                 return BAD_VALUE;
306             }
307 
308             uint8_t* tmpData = static_cast<uint8_t*>(data) + planeLayout.offsetInBytes +
309                     (planeLayoutComponent.offsetInBits / 8);
310             uint64_t sampleIncrementInBytes;
311 
312             auto type = static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value);
313             switch (type) {
314                 case PlaneLayoutComponentType::Y:
315                     if ((ycbcr.y != nullptr) || (planeLayoutComponent.sizeInBits != 8) ||
316                         (planeLayout.sampleIncrementInBits != 8)) {
317                         unlock(bufferHandle);
318                         return BAD_VALUE;
319                     }
320                     ycbcr.y = tmpData;
321                     ycbcr.ystride = planeLayout.strideInBytes;
322                     break;
323 
324                 case PlaneLayoutComponentType::CB:
325                 case PlaneLayoutComponentType::CR:
326                     if (planeLayout.sampleIncrementInBits % 8 != 0) {
327                         unlock(bufferHandle);
328                         return BAD_VALUE;
329                     }
330 
331                     sampleIncrementInBytes = planeLayout.sampleIncrementInBits / 8;
332                     if ((sampleIncrementInBytes != 1) && (sampleIncrementInBytes != 2)) {
333                         unlock(bufferHandle);
334                         return BAD_VALUE;
335                     }
336 
337                     if (ycbcr.cstride == 0 && ycbcr.chroma_step == 0) {
338                         ycbcr.cstride = planeLayout.strideInBytes;
339                         ycbcr.chroma_step = sampleIncrementInBytes;
340                     } else {
341                         if ((static_cast<int64_t>(ycbcr.cstride) != planeLayout.strideInBytes) ||
342                             (ycbcr.chroma_step != sampleIncrementInBytes)) {
343                             unlock(bufferHandle);
344                             return BAD_VALUE;
345                         }
346                     }
347 
348                     if (type == PlaneLayoutComponentType::CB) {
349                         if (ycbcr.cb != nullptr) {
350                             unlock(bufferHandle);
351                             return BAD_VALUE;
352                         }
353                         ycbcr.cb = tmpData;
354                     } else {
355                         if (ycbcr.cr != nullptr) {
356                             unlock(bufferHandle);
357                             return BAD_VALUE;
358                         }
359                         ycbcr.cr = tmpData;
360                     }
361                     break;
362                 default:
363                     break;
364             };
365         }
366     }
367 
368     *outYcbcr = ycbcr;
369     return static_cast<status_t>(Error::NONE);
370 }
371 
unlock(buffer_handle_t bufferHandle) const372 int Gralloc4Mapper::unlock(buffer_handle_t bufferHandle) const {
373     auto buffer = const_cast<native_handle_t*>(bufferHandle);
374 
375     int releaseFence = -1;
376     Error error;
377     auto ret = mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
378         error = tmpError;
379         if (error != Error::NONE) {
380             return;
381         }
382 
383         auto fenceHandle = tmpReleaseFence.getNativeHandle();
384         if (fenceHandle && fenceHandle->numFds == 1) {
385             int fd = dup(fenceHandle->data[0]);
386             if (fd >= 0) {
387                 releaseFence = fd;
388             } else {
389                 ALOGD("failed to dup unlock release fence");
390                 sync_wait(fenceHandle->data[0], -1);
391             }
392         }
393     });
394 
395     if (!ret.isOk()) {
396         error = kTransactionError;
397     }
398 
399     if (error != Error::NONE) {
400         ALOGE("unlock(%p) failed with %d", buffer, error);
401     }
402 
403     return releaseFence;
404 }
405 
isSupported(uint32_t width,uint32_t height,PixelFormat format,uint32_t layerCount,uint64_t usage,bool * outSupported) const406 status_t Gralloc4Mapper::isSupported(uint32_t width, uint32_t height, PixelFormat format,
407                                      uint32_t layerCount, uint64_t usage,
408                                      bool* outSupported) const {
409     IMapper::BufferDescriptorInfo descriptorInfo;
410     sBufferDescriptorInfo("isSupported", width, height, format, layerCount, usage, &descriptorInfo);
411 
412     Error error;
413     auto ret = mMapper->isSupported(descriptorInfo,
414                                     [&](const auto& tmpError, const auto& tmpSupported) {
415                                         error = tmpError;
416                                         if (error != Error::NONE) {
417                                             return;
418                                         }
419                                         if (outSupported) {
420                                             *outSupported = tmpSupported;
421                                         }
422                                     });
423 
424     if (!ret.isOk()) {
425         error = kTransactionError;
426     }
427 
428     if (error != Error::NONE) {
429         ALOGE("isSupported(%u, %u, %d, %u, ...) failed with %d", width, height, format, layerCount,
430               error);
431     }
432 
433     return static_cast<status_t>(error);
434 }
435 
436 template <class T>
get(buffer_handle_t bufferHandle,const MetadataType & metadataType,DecodeFunction<T> decodeFunction,T * outMetadata) const437 status_t Gralloc4Mapper::get(buffer_handle_t bufferHandle, const MetadataType& metadataType,
438                              DecodeFunction<T> decodeFunction, T* outMetadata) const {
439     if (!outMetadata) {
440         return BAD_VALUE;
441     }
442 
443     hidl_vec<uint8_t> vec;
444     Error error;
445     auto ret = mMapper->get(const_cast<native_handle_t*>(bufferHandle), metadataType,
446                             [&](const auto& tmpError, const hidl_vec<uint8_t>& tmpVec) {
447                                 error = tmpError;
448                                 vec = tmpVec;
449                             });
450 
451     if (!ret.isOk()) {
452         error = kTransactionError;
453     }
454 
455     if (error != Error::NONE) {
456         ALOGE("get(%s, %" PRIu64 ", ...) failed with %d", metadataType.name.c_str(),
457               metadataType.value, error);
458         return static_cast<status_t>(error);
459     }
460 
461     return decodeFunction(vec, outMetadata);
462 }
463 
getBufferId(buffer_handle_t bufferHandle,uint64_t * outBufferId) const464 status_t Gralloc4Mapper::getBufferId(buffer_handle_t bufferHandle, uint64_t* outBufferId) const {
465     return get(bufferHandle, gralloc4::MetadataType_BufferId, gralloc4::decodeBufferId,
466                outBufferId);
467 }
468 
getName(buffer_handle_t bufferHandle,std::string * outName) const469 status_t Gralloc4Mapper::getName(buffer_handle_t bufferHandle, std::string* outName) const {
470     return get(bufferHandle, gralloc4::MetadataType_Name, gralloc4::decodeName, outName);
471 }
472 
getWidth(buffer_handle_t bufferHandle,uint64_t * outWidth) const473 status_t Gralloc4Mapper::getWidth(buffer_handle_t bufferHandle, uint64_t* outWidth) const {
474     return get(bufferHandle, gralloc4::MetadataType_Width, gralloc4::decodeWidth, outWidth);
475 }
476 
getHeight(buffer_handle_t bufferHandle,uint64_t * outHeight) const477 status_t Gralloc4Mapper::getHeight(buffer_handle_t bufferHandle, uint64_t* outHeight) const {
478     return get(bufferHandle, gralloc4::MetadataType_Height, gralloc4::decodeHeight, outHeight);
479 }
480 
getLayerCount(buffer_handle_t bufferHandle,uint64_t * outLayerCount) const481 status_t Gralloc4Mapper::getLayerCount(buffer_handle_t bufferHandle,
482                                        uint64_t* outLayerCount) const {
483     return get(bufferHandle, gralloc4::MetadataType_LayerCount, gralloc4::decodeLayerCount,
484                outLayerCount);
485 }
486 
getPixelFormatRequested(buffer_handle_t bufferHandle,ui::PixelFormat * outPixelFormatRequested) const487 status_t Gralloc4Mapper::getPixelFormatRequested(buffer_handle_t bufferHandle,
488                                                  ui::PixelFormat* outPixelFormatRequested) const {
489     return get(bufferHandle, gralloc4::MetadataType_PixelFormatRequested,
490                gralloc4::decodePixelFormatRequested, outPixelFormatRequested);
491 }
492 
getPixelFormatFourCC(buffer_handle_t bufferHandle,uint32_t * outPixelFormatFourCC) const493 status_t Gralloc4Mapper::getPixelFormatFourCC(buffer_handle_t bufferHandle,
494                                               uint32_t* outPixelFormatFourCC) const {
495     return get(bufferHandle, gralloc4::MetadataType_PixelFormatFourCC,
496                gralloc4::decodePixelFormatFourCC, outPixelFormatFourCC);
497 }
498 
getPixelFormatModifier(buffer_handle_t bufferHandle,uint64_t * outPixelFormatModifier) const499 status_t Gralloc4Mapper::getPixelFormatModifier(buffer_handle_t bufferHandle,
500                                                 uint64_t* outPixelFormatModifier) const {
501     return get(bufferHandle, gralloc4::MetadataType_PixelFormatModifier,
502                gralloc4::decodePixelFormatModifier, outPixelFormatModifier);
503 }
504 
getUsage(buffer_handle_t bufferHandle,uint64_t * outUsage) const505 status_t Gralloc4Mapper::getUsage(buffer_handle_t bufferHandle, uint64_t* outUsage) const {
506     return get(bufferHandle, gralloc4::MetadataType_Usage, gralloc4::decodeUsage, outUsage);
507 }
508 
getAllocationSize(buffer_handle_t bufferHandle,uint64_t * outAllocationSize) const509 status_t Gralloc4Mapper::getAllocationSize(buffer_handle_t bufferHandle,
510                                            uint64_t* outAllocationSize) const {
511     return get(bufferHandle, gralloc4::MetadataType_AllocationSize, gralloc4::decodeAllocationSize,
512                outAllocationSize);
513 }
514 
getProtectedContent(buffer_handle_t bufferHandle,uint64_t * outProtectedContent) const515 status_t Gralloc4Mapper::getProtectedContent(buffer_handle_t bufferHandle,
516                                              uint64_t* outProtectedContent) const {
517     return get(bufferHandle, gralloc4::MetadataType_ProtectedContent,
518                gralloc4::decodeProtectedContent, outProtectedContent);
519 }
520 
getCompression(buffer_handle_t bufferHandle,ExtendableType * outCompression) const521 status_t Gralloc4Mapper::getCompression(buffer_handle_t bufferHandle,
522                                         ExtendableType* outCompression) const {
523     return get(bufferHandle, gralloc4::MetadataType_Compression, gralloc4::decodeCompression,
524                outCompression);
525 }
526 
getCompression(buffer_handle_t bufferHandle,ui::Compression * outCompression) const527 status_t Gralloc4Mapper::getCompression(buffer_handle_t bufferHandle,
528                                         ui::Compression* outCompression) const {
529     if (!outCompression) {
530         return BAD_VALUE;
531     }
532     ExtendableType compression;
533     status_t error = getCompression(bufferHandle, &compression);
534     if (error) {
535         return error;
536     }
537     if (!gralloc4::isStandardCompression(compression)) {
538         return BAD_TYPE;
539     }
540     *outCompression = gralloc4::getStandardCompressionValue(compression);
541     return NO_ERROR;
542 }
543 
getInterlaced(buffer_handle_t bufferHandle,ExtendableType * outInterlaced) const544 status_t Gralloc4Mapper::getInterlaced(buffer_handle_t bufferHandle,
545                                        ExtendableType* outInterlaced) const {
546     return get(bufferHandle, gralloc4::MetadataType_Interlaced, gralloc4::decodeInterlaced,
547                outInterlaced);
548 }
549 
getInterlaced(buffer_handle_t bufferHandle,ui::Interlaced * outInterlaced) const550 status_t Gralloc4Mapper::getInterlaced(buffer_handle_t bufferHandle,
551                                        ui::Interlaced* outInterlaced) const {
552     if (!outInterlaced) {
553         return BAD_VALUE;
554     }
555     ExtendableType interlaced;
556     status_t error = getInterlaced(bufferHandle, &interlaced);
557     if (error) {
558         return error;
559     }
560     if (!gralloc4::isStandardInterlaced(interlaced)) {
561         return BAD_TYPE;
562     }
563     *outInterlaced = gralloc4::getStandardInterlacedValue(interlaced);
564     return NO_ERROR;
565 }
566 
getChromaSiting(buffer_handle_t bufferHandle,ExtendableType * outChromaSiting) const567 status_t Gralloc4Mapper::getChromaSiting(buffer_handle_t bufferHandle,
568                                          ExtendableType* outChromaSiting) const {
569     return get(bufferHandle, gralloc4::MetadataType_ChromaSiting, gralloc4::decodeChromaSiting,
570                outChromaSiting);
571 }
572 
getChromaSiting(buffer_handle_t bufferHandle,ui::ChromaSiting * outChromaSiting) const573 status_t Gralloc4Mapper::getChromaSiting(buffer_handle_t bufferHandle,
574                                          ui::ChromaSiting* outChromaSiting) const {
575     if (!outChromaSiting) {
576         return BAD_VALUE;
577     }
578     ExtendableType chromaSiting;
579     status_t error = getChromaSiting(bufferHandle, &chromaSiting);
580     if (error) {
581         return error;
582     }
583     if (!gralloc4::isStandardChromaSiting(chromaSiting)) {
584         return BAD_TYPE;
585     }
586     *outChromaSiting = gralloc4::getStandardChromaSitingValue(chromaSiting);
587     return NO_ERROR;
588 }
589 
getPlaneLayouts(buffer_handle_t bufferHandle,std::vector<ui::PlaneLayout> * outPlaneLayouts) const590 status_t Gralloc4Mapper::getPlaneLayouts(buffer_handle_t bufferHandle,
591                                          std::vector<ui::PlaneLayout>* outPlaneLayouts) const {
592     return get(bufferHandle, gralloc4::MetadataType_PlaneLayouts, gralloc4::decodePlaneLayouts,
593                outPlaneLayouts);
594 }
595 
getDataspace(buffer_handle_t bufferHandle,ui::Dataspace * outDataspace) const596 status_t Gralloc4Mapper::getDataspace(buffer_handle_t bufferHandle,
597                                       ui::Dataspace* outDataspace) const {
598     if (!outDataspace) {
599         return BAD_VALUE;
600     }
601     AidlDataspace dataspace;
602     status_t error = get(bufferHandle, gralloc4::MetadataType_Dataspace, gralloc4::decodeDataspace,
603                          &dataspace);
604     if (error) {
605         return error;
606     }
607 
608     // Gralloc4 uses stable AIDL dataspace but the rest of the system still uses HIDL dataspace
609     *outDataspace = static_cast<ui::Dataspace>(dataspace);
610     return NO_ERROR;
611 }
612 
getBlendMode(buffer_handle_t bufferHandle,ui::BlendMode * outBlendMode) const613 status_t Gralloc4Mapper::getBlendMode(buffer_handle_t bufferHandle,
614                                       ui::BlendMode* outBlendMode) const {
615     return get(bufferHandle, gralloc4::MetadataType_BlendMode, gralloc4::decodeBlendMode,
616                outBlendMode);
617 }
618 
getSmpte2086(buffer_handle_t bufferHandle,std::optional<ui::Smpte2086> * outSmpte2086) const619 status_t Gralloc4Mapper::getSmpte2086(buffer_handle_t bufferHandle,
620                                       std::optional<ui::Smpte2086>* outSmpte2086) const {
621     return get(bufferHandle, gralloc4::MetadataType_Smpte2086, gralloc4::decodeSmpte2086,
622                outSmpte2086);
623 }
624 
getCta861_3(buffer_handle_t bufferHandle,std::optional<ui::Cta861_3> * outCta861_3) const625 status_t Gralloc4Mapper::getCta861_3(buffer_handle_t bufferHandle,
626                                      std::optional<ui::Cta861_3>* outCta861_3) const {
627     return get(bufferHandle, gralloc4::MetadataType_Cta861_3, gralloc4::decodeCta861_3,
628                outCta861_3);
629 }
630 
getSmpte2094_40(buffer_handle_t bufferHandle,std::optional<std::vector<uint8_t>> * outSmpte2094_40) const631 status_t Gralloc4Mapper::getSmpte2094_40(
632         buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>>* outSmpte2094_40) const {
633     return get(bufferHandle, gralloc4::MetadataType_Smpte2094_40, gralloc4::decodeSmpte2094_40,
634                outSmpte2094_40);
635 }
636 
637 template <class T>
getDefault(uint32_t width,uint32_t height,PixelFormat format,uint32_t layerCount,uint64_t usage,const MetadataType & metadataType,DecodeFunction<T> decodeFunction,T * outMetadata) const638 status_t Gralloc4Mapper::getDefault(uint32_t width, uint32_t height, PixelFormat format,
639                                     uint32_t layerCount, uint64_t usage,
640                                     const MetadataType& metadataType,
641                                     DecodeFunction<T> decodeFunction, T* outMetadata) const {
642     if (!outMetadata) {
643         return BAD_VALUE;
644     }
645 
646     IMapper::BufferDescriptorInfo descriptorInfo;
647     sBufferDescriptorInfo("getDefault", width, height, format, layerCount, usage, &descriptorInfo);
648 
649     hidl_vec<uint8_t> vec;
650     Error error;
651     auto ret = mMapper->getFromBufferDescriptorInfo(descriptorInfo, metadataType,
652                                                     [&](const auto& tmpError,
653                                                         const hidl_vec<uint8_t>& tmpVec) {
654                                                         error = tmpError;
655                                                         vec = tmpVec;
656                                                     });
657 
658     if (!ret.isOk()) {
659         error = kTransactionError;
660     }
661 
662     if (error != Error::NONE) {
663         ALOGE("getDefault(%s, %" PRIu64 ", ...) failed with %d", metadataType.name.c_str(),
664               metadataType.value, error);
665         return static_cast<status_t>(error);
666     }
667 
668     return decodeFunction(vec, outMetadata);
669 }
670 
getDefaultPixelFormatFourCC(uint32_t width,uint32_t height,PixelFormat format,uint32_t layerCount,uint64_t usage,uint32_t * outPixelFormatFourCC) const671 status_t Gralloc4Mapper::getDefaultPixelFormatFourCC(uint32_t width, uint32_t height,
672                                                      PixelFormat format, uint32_t layerCount,
673                                                      uint64_t usage,
674                                                      uint32_t* outPixelFormatFourCC) const {
675     return getDefault(width, height, format, layerCount, usage,
676                       gralloc4::MetadataType_PixelFormatFourCC, gralloc4::decodePixelFormatFourCC,
677                       outPixelFormatFourCC);
678 }
679 
getDefaultPixelFormatModifier(uint32_t width,uint32_t height,PixelFormat format,uint32_t layerCount,uint64_t usage,uint64_t * outPixelFormatModifier) const680 status_t Gralloc4Mapper::getDefaultPixelFormatModifier(uint32_t width, uint32_t height,
681                                                        PixelFormat format, uint32_t layerCount,
682                                                        uint64_t usage,
683                                                        uint64_t* outPixelFormatModifier) const {
684     return getDefault(width, height, format, layerCount, usage,
685                       gralloc4::MetadataType_PixelFormatModifier,
686                       gralloc4::decodePixelFormatModifier, outPixelFormatModifier);
687 }
688 
getDefaultAllocationSize(uint32_t width,uint32_t height,PixelFormat format,uint32_t layerCount,uint64_t usage,uint64_t * outAllocationSize) const689 status_t Gralloc4Mapper::getDefaultAllocationSize(uint32_t width, uint32_t height,
690                                                   PixelFormat format, uint32_t layerCount,
691                                                   uint64_t usage,
692                                                   uint64_t* outAllocationSize) const {
693     return getDefault(width, height, format, layerCount, usage,
694                       gralloc4::MetadataType_AllocationSize, gralloc4::decodeAllocationSize,
695                       outAllocationSize);
696 }
697 
getDefaultProtectedContent(uint32_t width,uint32_t height,PixelFormat format,uint32_t layerCount,uint64_t usage,uint64_t * outProtectedContent) const698 status_t Gralloc4Mapper::getDefaultProtectedContent(uint32_t width, uint32_t height,
699                                                     PixelFormat format, uint32_t layerCount,
700                                                     uint64_t usage,
701                                                     uint64_t* outProtectedContent) const {
702     return getDefault(width, height, format, layerCount, usage,
703                       gralloc4::MetadataType_ProtectedContent, gralloc4::decodeProtectedContent,
704                       outProtectedContent);
705 }
706 
getDefaultCompression(uint32_t width,uint32_t height,PixelFormat format,uint32_t layerCount,uint64_t usage,ExtendableType * outCompression) const707 status_t Gralloc4Mapper::getDefaultCompression(uint32_t width, uint32_t height, PixelFormat format,
708                                                uint32_t layerCount, uint64_t usage,
709                                                ExtendableType* outCompression) const {
710     return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_Compression,
711                       gralloc4::decodeCompression, outCompression);
712 }
713 
getDefaultCompression(uint32_t width,uint32_t height,PixelFormat format,uint32_t layerCount,uint64_t usage,ui::Compression * outCompression) const714 status_t Gralloc4Mapper::getDefaultCompression(uint32_t width, uint32_t height, PixelFormat format,
715                                                uint32_t layerCount, uint64_t usage,
716                                                ui::Compression* outCompression) const {
717     if (!outCompression) {
718         return BAD_VALUE;
719     }
720     ExtendableType compression;
721     status_t error = getDefaultCompression(width, height, format, layerCount, usage, &compression);
722     if (error) {
723         return error;
724     }
725     if (!gralloc4::isStandardCompression(compression)) {
726         return BAD_TYPE;
727     }
728     *outCompression = gralloc4::getStandardCompressionValue(compression);
729     return NO_ERROR;
730 }
731 
getDefaultInterlaced(uint32_t width,uint32_t height,PixelFormat format,uint32_t layerCount,uint64_t usage,ExtendableType * outInterlaced) const732 status_t Gralloc4Mapper::getDefaultInterlaced(uint32_t width, uint32_t height, PixelFormat format,
733                                               uint32_t layerCount, uint64_t usage,
734                                               ExtendableType* outInterlaced) const {
735     return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_Interlaced,
736                       gralloc4::decodeInterlaced, outInterlaced);
737 }
738 
getDefaultInterlaced(uint32_t width,uint32_t height,PixelFormat format,uint32_t layerCount,uint64_t usage,ui::Interlaced * outInterlaced) const739 status_t Gralloc4Mapper::getDefaultInterlaced(uint32_t width, uint32_t height, PixelFormat format,
740                                               uint32_t layerCount, uint64_t usage,
741                                               ui::Interlaced* outInterlaced) const {
742     if (!outInterlaced) {
743         return BAD_VALUE;
744     }
745     ExtendableType interlaced;
746     status_t error = getDefaultInterlaced(width, height, format, layerCount, usage, &interlaced);
747     if (error) {
748         return error;
749     }
750     if (!gralloc4::isStandardInterlaced(interlaced)) {
751         return BAD_TYPE;
752     }
753     *outInterlaced = gralloc4::getStandardInterlacedValue(interlaced);
754     return NO_ERROR;
755 }
756 
getDefaultChromaSiting(uint32_t width,uint32_t height,PixelFormat format,uint32_t layerCount,uint64_t usage,ExtendableType * outChromaSiting) const757 status_t Gralloc4Mapper::getDefaultChromaSiting(uint32_t width, uint32_t height, PixelFormat format,
758                                                 uint32_t layerCount, uint64_t usage,
759                                                 ExtendableType* outChromaSiting) const {
760     return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_ChromaSiting,
761                       gralloc4::decodeChromaSiting, outChromaSiting);
762 }
763 
getDefaultChromaSiting(uint32_t width,uint32_t height,PixelFormat format,uint32_t layerCount,uint64_t usage,ui::ChromaSiting * outChromaSiting) const764 status_t Gralloc4Mapper::getDefaultChromaSiting(uint32_t width, uint32_t height, PixelFormat format,
765                                                 uint32_t layerCount, uint64_t usage,
766                                                 ui::ChromaSiting* outChromaSiting) const {
767     if (!outChromaSiting) {
768         return BAD_VALUE;
769     }
770     ExtendableType chromaSiting;
771     status_t error =
772             getDefaultChromaSiting(width, height, format, layerCount, usage, &chromaSiting);
773     if (error) {
774         return error;
775     }
776     if (!gralloc4::isStandardChromaSiting(chromaSiting)) {
777         return BAD_TYPE;
778     }
779     *outChromaSiting = gralloc4::getStandardChromaSitingValue(chromaSiting);
780     return NO_ERROR;
781 }
782 
getDefaultPlaneLayouts(uint32_t width,uint32_t height,PixelFormat format,uint32_t layerCount,uint64_t usage,std::vector<ui::PlaneLayout> * outPlaneLayouts) const783 status_t Gralloc4Mapper::getDefaultPlaneLayouts(
784         uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, uint64_t usage,
785         std::vector<ui::PlaneLayout>* outPlaneLayouts) const {
786     return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_PlaneLayouts,
787                       gralloc4::decodePlaneLayouts, outPlaneLayouts);
788 }
789 
listSupportedMetadataTypes() const790 std::vector<MetadataTypeDescription> Gralloc4Mapper::listSupportedMetadataTypes() const {
791     hidl_vec<MetadataTypeDescription> descriptions;
792     Error error;
793     auto ret = mMapper->listSupportedMetadataTypes(
794             [&](const auto& tmpError, const auto& tmpDescriptions) {
795                 error = tmpError;
796                 descriptions = tmpDescriptions;
797             });
798 
799     if (!ret.isOk()) {
800         error = kTransactionError;
801     }
802 
803     if (error != Error::NONE) {
804         ALOGE("listSupportedMetadataType() failed with %d", error);
805         return {};
806     }
807 
808     return static_cast<std::vector<MetadataTypeDescription>>(descriptions);
809 }
810 
811 template <class T>
metadataDumpHelper(const BufferDump & bufferDump,StandardMetadataType metadataType,DecodeFunction<T> decodeFunction,T * outT) const812 status_t Gralloc4Mapper::metadataDumpHelper(const BufferDump& bufferDump,
813                                             StandardMetadataType metadataType,
814                                             DecodeFunction<T> decodeFunction, T* outT) const {
815     const auto& metadataDump = bufferDump.metadataDump;
816 
817     auto itr =
818             std::find_if(metadataDump.begin(), metadataDump.end(),
819                          [&](const MetadataDump& tmpMetadataDump) {
820                              if (!gralloc4::isStandardMetadataType(tmpMetadataDump.metadataType)) {
821                                  return false;
822                              }
823                              return metadataType ==
824                                      gralloc4::getStandardMetadataTypeValue(
825                                              tmpMetadataDump.metadataType);
826                          });
827     if (itr == metadataDump.end()) {
828         return BAD_VALUE;
829     }
830 
831     return decodeFunction(itr->metadata, outT);
832 }
833 
bufferDumpHelper(const BufferDump & bufferDump,std::ostringstream * outDump,uint64_t * outAllocationSize,bool less) const834 status_t Gralloc4Mapper::bufferDumpHelper(const BufferDump& bufferDump, std::ostringstream* outDump,
835                                           uint64_t* outAllocationSize, bool less) const {
836     uint64_t bufferId;
837     std::string name;
838     uint64_t width;
839     uint64_t height;
840     uint64_t layerCount;
841     ui::PixelFormat pixelFormatRequested;
842     uint32_t pixelFormatFourCC;
843     uint64_t pixelFormatModifier;
844     uint64_t usage;
845     AidlDataspace dataspace;
846     uint64_t allocationSize;
847     uint64_t protectedContent;
848     ExtendableType compression;
849     ExtendableType interlaced;
850     ExtendableType chromaSiting;
851     std::vector<ui::PlaneLayout> planeLayouts;
852 
853     status_t error = metadataDumpHelper(bufferDump, StandardMetadataType::BUFFER_ID,
854                                         gralloc4::decodeBufferId, &bufferId);
855     if (error != NO_ERROR) {
856         return error;
857     }
858     error = metadataDumpHelper(bufferDump, StandardMetadataType::NAME, gralloc4::decodeName, &name);
859     if (error != NO_ERROR) {
860         return error;
861     }
862     error = metadataDumpHelper(bufferDump, StandardMetadataType::WIDTH, gralloc4::decodeWidth,
863                                &width);
864     if (error != NO_ERROR) {
865         return error;
866     }
867     error = metadataDumpHelper(bufferDump, StandardMetadataType::HEIGHT, gralloc4::decodeHeight,
868                                &height);
869     if (error != NO_ERROR) {
870         return error;
871     }
872     error = metadataDumpHelper(bufferDump, StandardMetadataType::LAYER_COUNT,
873                                gralloc4::decodeLayerCount, &layerCount);
874     if (error != NO_ERROR) {
875         return error;
876     }
877     error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_REQUESTED,
878                                gralloc4::decodePixelFormatRequested, &pixelFormatRequested);
879     if (error != NO_ERROR) {
880         return error;
881     }
882     error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_FOURCC,
883                                gralloc4::decodePixelFormatFourCC, &pixelFormatFourCC);
884     if (error != NO_ERROR) {
885         return error;
886     }
887     error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_MODIFIER,
888                                gralloc4::decodePixelFormatModifier, &pixelFormatModifier);
889     if (error != NO_ERROR) {
890         return error;
891     }
892     error = metadataDumpHelper(bufferDump, StandardMetadataType::USAGE, gralloc4::decodeUsage,
893                                &usage);
894     if (error != NO_ERROR) {
895         return error;
896     }
897     error = metadataDumpHelper(bufferDump, StandardMetadataType::DATASPACE,
898                                gralloc4::decodeDataspace, &dataspace);
899     if (error != NO_ERROR) {
900         return error;
901     }
902     error = metadataDumpHelper(bufferDump, StandardMetadataType::ALLOCATION_SIZE,
903                                gralloc4::decodeAllocationSize, &allocationSize);
904     if (error != NO_ERROR) {
905         return error;
906     }
907     error = metadataDumpHelper(bufferDump, StandardMetadataType::PROTECTED_CONTENT,
908                                gralloc4::decodeProtectedContent, &protectedContent);
909     if (error != NO_ERROR) {
910         return error;
911     }
912     error = metadataDumpHelper(bufferDump, StandardMetadataType::COMPRESSION,
913                                gralloc4::decodeCompression, &compression);
914     if (error != NO_ERROR) {
915         return error;
916     }
917     error = metadataDumpHelper(bufferDump, StandardMetadataType::INTERLACED,
918                                gralloc4::decodeInterlaced, &interlaced);
919     if (error != NO_ERROR) {
920         return error;
921     }
922     error = metadataDumpHelper(bufferDump, StandardMetadataType::CHROMA_SITING,
923                                gralloc4::decodeChromaSiting, &chromaSiting);
924     if (error != NO_ERROR) {
925         return error;
926     }
927     error = metadataDumpHelper(bufferDump, StandardMetadataType::PLANE_LAYOUTS,
928                                gralloc4::decodePlaneLayouts, &planeLayouts);
929     if (error != NO_ERROR) {
930         return error;
931     }
932 
933     if (outAllocationSize) {
934         *outAllocationSize = allocationSize;
935     }
936     double allocationSizeKiB = static_cast<double>(allocationSize) / 1024;
937 
938     *outDump << "+ name:" << name << ", id:" << bufferId << ", size:" << allocationSizeKiB
939              << "KiB, w/h:" << width << "x" << height << ", usage: 0x" << std::hex << usage
940              << std::dec << ", req fmt:" << static_cast<int32_t>(pixelFormatRequested)
941              << ", fourcc/mod:" << pixelFormatFourCC << "/" << pixelFormatModifier
942              << ", dataspace: 0x" << std::hex << static_cast<uint32_t>(dataspace)
943              << ", compressed: ";
944 
945     if (less) {
946         bool isCompressed = !gralloc4::isStandardCompression(compression) ||
947                 (gralloc4::getStandardCompressionValue(compression) != ui::Compression::NONE);
948         *outDump << std::boolalpha << isCompressed << "\n";
949     } else {
950         *outDump << gralloc4::getCompressionName(compression) << "\n";
951     }
952 
953     bool firstPlane = true;
954     for (const auto& planeLayout : planeLayouts) {
955         if (firstPlane) {
956             firstPlane = false;
957             *outDump << "\tplanes: ";
958         } else {
959             *outDump << "\t        ";
960         }
961 
962         for (size_t i = 0; i < planeLayout.components.size(); i++) {
963             const auto& planeLayoutComponent = planeLayout.components[i];
964             *outDump << gralloc4::getPlaneLayoutComponentTypeName(planeLayoutComponent.type);
965             if (i < planeLayout.components.size() - 1) {
966                 *outDump << "/";
967             } else {
968                 *outDump << ":\t";
969             }
970         }
971         *outDump << " w/h:" << planeLayout.widthInSamples << "x" << planeLayout.heightInSamples
972                  << ", stride:" << planeLayout.strideInBytes
973                  << " bytes, size:" << planeLayout.totalSizeInBytes;
974         if (!less) {
975             *outDump << ", inc:" << planeLayout.sampleIncrementInBits
976                      << " bits, subsampling w/h:" << planeLayout.horizontalSubsampling << "x"
977                      << planeLayout.verticalSubsampling;
978         }
979         *outDump << "\n";
980     }
981 
982     if (!less) {
983         *outDump << "\tlayer cnt: " << layerCount << ", protected content: " << protectedContent
984                  << ", interlaced: " << gralloc4::getInterlacedName(interlaced)
985                  << ", chroma siting:" << gralloc4::getChromaSitingName(chromaSiting) << "\n";
986     }
987 
988     return NO_ERROR;
989 }
990 
dumpBuffer(buffer_handle_t bufferHandle,bool less) const991 std::string Gralloc4Mapper::dumpBuffer(buffer_handle_t bufferHandle, bool less) const {
992     auto buffer = const_cast<native_handle_t*>(bufferHandle);
993 
994     BufferDump bufferDump;
995     Error error;
996     auto ret = mMapper->dumpBuffer(buffer, [&](const auto& tmpError, const auto& tmpBufferDump) {
997         error = tmpError;
998         bufferDump = tmpBufferDump;
999     });
1000 
1001     if (!ret.isOk()) {
1002         error = kTransactionError;
1003     }
1004 
1005     if (error != Error::NONE) {
1006         ALOGE("dumpBuffer() failed with %d", error);
1007         return "";
1008     }
1009 
1010     std::ostringstream stream;
1011     stream.precision(2);
1012 
1013     status_t err = bufferDumpHelper(bufferDump, &stream, nullptr, less);
1014     if (err != NO_ERROR) {
1015         ALOGE("bufferDumpHelper() failed with %d", err);
1016         return "";
1017     }
1018 
1019     return stream.str();
1020 }
1021 
dumpBuffers(bool less) const1022 std::string Gralloc4Mapper::dumpBuffers(bool less) const {
1023     hidl_vec<BufferDump> bufferDumps;
1024     Error error;
1025     auto ret = mMapper->dumpBuffers([&](const auto& tmpError, const auto& tmpBufferDump) {
1026         error = tmpError;
1027         bufferDumps = tmpBufferDump;
1028     });
1029 
1030     if (!ret.isOk()) {
1031         error = kTransactionError;
1032     }
1033 
1034     if (error != Error::NONE) {
1035         ALOGE("dumpBuffer() failed with %d", error);
1036         return "";
1037     }
1038 
1039     uint64_t totalAllocationSize = 0;
1040     std::ostringstream stream;
1041     stream.precision(2);
1042 
1043     stream << "Imported gralloc buffers:\n";
1044 
1045     for (const auto& bufferDump : bufferDumps) {
1046         uint64_t allocationSize = 0;
1047         status_t err = bufferDumpHelper(bufferDump, &stream, &allocationSize, less);
1048         if (err != NO_ERROR) {
1049             ALOGE("bufferDumpHelper() failed with %d", err);
1050             return "";
1051         }
1052         totalAllocationSize += allocationSize;
1053     }
1054 
1055     double totalAllocationSizeKiB = static_cast<double>(totalAllocationSize) / 1024;
1056     stream << "Total imported by gralloc: " << totalAllocationSizeKiB << "KiB\n";
1057     return stream.str();
1058 }
1059 
Gralloc4Allocator(const Gralloc4Mapper & mapper)1060 Gralloc4Allocator::Gralloc4Allocator(const Gralloc4Mapper& mapper) : mMapper(mapper) {
1061     mAllocator = IAllocator::getService();
1062     if (mAllocator == nullptr) {
1063         ALOGW("allocator 4.x is not supported");
1064         return;
1065     }
1066 }
1067 
isLoaded() const1068 bool Gralloc4Allocator::isLoaded() const {
1069     return mAllocator != nullptr;
1070 }
1071 
dumpDebugInfo(bool less) const1072 std::string Gralloc4Allocator::dumpDebugInfo(bool less) const {
1073     return mMapper.dumpBuffers(less);
1074 }
1075 
allocate(std::string requestorName,uint32_t width,uint32_t height,android::PixelFormat format,uint32_t layerCount,uint64_t usage,uint32_t bufferCount,uint32_t * outStride,buffer_handle_t * outBufferHandles,bool importBuffers) const1076 status_t Gralloc4Allocator::allocate(std::string requestorName, uint32_t width, uint32_t height,
1077                                      android::PixelFormat format, uint32_t layerCount,
1078                                      uint64_t usage, uint32_t bufferCount, uint32_t* outStride,
1079                                      buffer_handle_t* outBufferHandles, bool importBuffers) const {
1080     IMapper::BufferDescriptorInfo descriptorInfo;
1081     sBufferDescriptorInfo(requestorName, width, height, format, layerCount, usage, &descriptorInfo);
1082 
1083     BufferDescriptor descriptor;
1084     status_t error = mMapper.createDescriptor(static_cast<void*>(&descriptorInfo),
1085                                               static_cast<void*>(&descriptor));
1086     if (error != NO_ERROR) {
1087         return error;
1088     }
1089 
1090     auto ret = mAllocator->allocate(descriptor, bufferCount,
1091                                     [&](const auto& tmpError, const auto& tmpStride,
1092                                         const auto& tmpBuffers) {
1093                                         error = static_cast<status_t>(tmpError);
1094                                         if (tmpError != Error::NONE) {
1095                                             return;
1096                                         }
1097 
1098                                         if (importBuffers) {
1099                                             for (uint32_t i = 0; i < bufferCount; i++) {
1100                                                 error = mMapper.importBuffer(tmpBuffers[i],
1101                                                                              &outBufferHandles[i]);
1102                                                 if (error != NO_ERROR) {
1103                                                     for (uint32_t j = 0; j < i; j++) {
1104                                                         mMapper.freeBuffer(outBufferHandles[j]);
1105                                                         outBufferHandles[j] = nullptr;
1106                                                     }
1107                                                     return;
1108                                                 }
1109                                             }
1110                                         } else {
1111                                             for (uint32_t i = 0; i < bufferCount; i++) {
1112                                                 outBufferHandles[i] = native_handle_clone(
1113                                                         tmpBuffers[i].getNativeHandle());
1114                                                 if (!outBufferHandles[i]) {
1115                                                     for (uint32_t j = 0; j < i; j++) {
1116                                                         auto buffer = const_cast<native_handle_t*>(
1117                                                                 outBufferHandles[j]);
1118                                                         native_handle_close(buffer);
1119                                                         native_handle_delete(buffer);
1120                                                         outBufferHandles[j] = nullptr;
1121                                                     }
1122                                                 }
1123                                             }
1124                                         }
1125                                         *outStride = tmpStride;
1126                                     });
1127 
1128     // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
1129     hardware::IPCThreadState::self()->flushCommands();
1130 
1131     return (ret.isOk()) ? error : static_cast<status_t>(kTransactionError);
1132 }
1133 
1134 } // namespace android
1135