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