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