blob: 8ac08fb70dd2e34bd4cfd6fabf137854923c53b8 [file] [log] [blame]
Marissa Wall87c8ba72019-06-20 14:20:52 -07001/*
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
Marissa Wall22b2de12019-12-02 18:11:43 -080030using aidl::android::hardware::graphics::common::ExtendableType;
31using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
32using aidl::android::hardware::graphics::common::StandardMetadataType;
33using android::hardware::hidl_vec;
Marissa Wall87c8ba72019-06-20 14:20:52 -070034using android::hardware::graphics::allocator::V4_0::IAllocator;
35using android::hardware::graphics::common::V1_2::BufferUsage;
36using android::hardware::graphics::mapper::V4_0::BufferDescriptor;
37using android::hardware::graphics::mapper::V4_0::Error;
38using android::hardware::graphics::mapper::V4_0::IMapper;
Yichi Chenba40db52021-04-30 00:18:32 +080039using AidlDataspace = ::aidl::android::hardware::graphics::common::Dataspace;
Marissa Wall22b2de12019-12-02 18:11:43 -080040using BufferDump = android::hardware::graphics::mapper::V4_0::IMapper::BufferDump;
41using MetadataDump = android::hardware::graphics::mapper::V4_0::IMapper::MetadataDump;
42using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
43using MetadataTypeDescription =
44 android::hardware::graphics::mapper::V4_0::IMapper::MetadataTypeDescription;
Marissa Wall87c8ba72019-06-20 14:20:52 -070045
46namespace android {
47
48namespace {
49
50static constexpr Error kTransactionError = Error::NO_RESOURCES;
51
52uint64_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
64static 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}
Marissa Wall22b2de12019-12-02 18:11:43 -080072static inline void sBufferDescriptorInfo(std::string name, uint32_t width, uint32_t height,
73 PixelFormat format, uint32_t layerCount, uint64_t usage,
Marissa Wall87c8ba72019-06-20 14:20:52 -070074 IMapper::BufferDescriptorInfo* outDescriptorInfo) {
Marissa Wall22b2de12019-12-02 18:11:43 -080075 outDescriptorInfo->name = name;
Marissa Wall87c8ba72019-06-20 14:20:52 -070076 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;
Valerie Hau23392792020-03-09 14:01:06 -070081 outDescriptorInfo->reservedSize = 0;
Marissa Wall87c8ba72019-06-20 14:20:52 -070082}
83
84} // anonymous namespace
85
86void Gralloc4Mapper::preload() {
87 android::hardware::preloadPassthroughService<IMapper>();
88}
89
90Gralloc4Mapper::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
101bool Gralloc4Mapper::isLoaded() const {
102 return mMapper != nullptr;
103}
104
105status_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
117status_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
142status_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
156void 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
164status_t Gralloc4Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width,
Marissa Wall22b2de12019-12-02 18:11:43 -0800165 uint32_t height, PixelFormat format,
Marissa Wall87c8ba72019-06-20 14:20:52 -0700166 uint32_t layerCount, uint64_t usage,
167 uint32_t stride) const {
168 IMapper::BufferDescriptorInfo descriptorInfo;
Marissa Wall22b2de12019-12-02 18:11:43 -0800169 sBufferDescriptorInfo("validateBufferSize", width, height, format, layerCount, usage,
170 &descriptorInfo);
Marissa Wall87c8ba72019-06-20 14:20:52 -0700171
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
178void 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
201status_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 {
Marissa Wall22b2de12019-12-02 18:11:43 -0800204 std::vector<ui::PlaneLayout> planeLayouts;
205 status_t err = getPlaneLayouts(bufferHandle, &planeLayouts);
206
Valerie Hau3bb97912020-04-09 10:40:10 -0700207 if (err == NO_ERROR && !planeLayouts.empty()) {
Marissa Wall22b2de12019-12-02 18:11:43 -0800208 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 }
Marissa Wall20611c62019-11-05 15:06:24 -0800234 }
235
Marissa Wall87c8ba72019-06-20 14:20:52 -0700236 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,
Marissa Wall20611c62019-11-05 15:06:24 -0800251 [&](const auto& tmpError, const auto& tmpData) {
Marissa Wall87c8ba72019-06-20 14:20:52 -0700252 error = tmpError;
253 if (error != Error::NONE) {
254 return;
255 }
256 *outData = tmpData;
Marissa Wall87c8ba72019-06-20 14:20:52 -0700257 });
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
Marissa Wall22b2de12019-12-02 18:11:43 -0800271status_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;
Marissa Wall90df5852020-02-27 10:17:02 -0800369 return static_cast<status_t>(Error::NONE);
Marissa Wall87c8ba72019-06-20 14:20:52 -0700370}
371
372int 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
Marissa Wall22b2de12019-12-02 18:11:43 -0800406status_t Gralloc4Mapper::isSupported(uint32_t width, uint32_t height, PixelFormat format,
Marissa Wall87c8ba72019-06-20 14:20:52 -0700407 uint32_t layerCount, uint64_t usage,
408 bool* outSupported) const {
409 IMapper::BufferDescriptorInfo descriptorInfo;
Marissa Wall22b2de12019-12-02 18:11:43 -0800410 sBufferDescriptorInfo("isSupported", width, height, format, layerCount, usage, &descriptorInfo);
Marissa Wall87c8ba72019-06-20 14:20:52 -0700411
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
Marissa Wall22b2de12019-12-02 18:11:43 -0800436template <class T>
437status_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
464status_t Gralloc4Mapper::getBufferId(buffer_handle_t bufferHandle, uint64_t* outBufferId) const {
465 return get(bufferHandle, gralloc4::MetadataType_BufferId, gralloc4::decodeBufferId,
466 outBufferId);
467}
468
469status_t Gralloc4Mapper::getName(buffer_handle_t bufferHandle, std::string* outName) const {
470 return get(bufferHandle, gralloc4::MetadataType_Name, gralloc4::decodeName, outName);
471}
472
473status_t Gralloc4Mapper::getWidth(buffer_handle_t bufferHandle, uint64_t* outWidth) const {
474 return get(bufferHandle, gralloc4::MetadataType_Width, gralloc4::decodeWidth, outWidth);
475}
476
477status_t Gralloc4Mapper::getHeight(buffer_handle_t bufferHandle, uint64_t* outHeight) const {
478 return get(bufferHandle, gralloc4::MetadataType_Height, gralloc4::decodeHeight, outHeight);
479}
480
481status_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
487status_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
493status_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
499status_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
505status_t Gralloc4Mapper::getUsage(buffer_handle_t bufferHandle, uint64_t* outUsage) const {
506 return get(bufferHandle, gralloc4::MetadataType_Usage, gralloc4::decodeUsage, outUsage);
507}
508
509status_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
515status_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
521status_t Gralloc4Mapper::getCompression(buffer_handle_t bufferHandle,
522 ExtendableType* outCompression) const {
523 return get(bufferHandle, gralloc4::MetadataType_Compression, gralloc4::decodeCompression,
524 outCompression);
525}
526
527status_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
544status_t Gralloc4Mapper::getInterlaced(buffer_handle_t bufferHandle,
545 ExtendableType* outInterlaced) const {
546 return get(bufferHandle, gralloc4::MetadataType_Interlaced, gralloc4::decodeInterlaced,
547 outInterlaced);
548}
549
550status_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
567status_t Gralloc4Mapper::getChromaSiting(buffer_handle_t bufferHandle,
568 ExtendableType* outChromaSiting) const {
569 return get(bufferHandle, gralloc4::MetadataType_ChromaSiting, gralloc4::decodeChromaSiting,
570 outChromaSiting);
571}
572
573status_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
590status_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
596status_t Gralloc4Mapper::getDataspace(buffer_handle_t bufferHandle,
597 ui::Dataspace* outDataspace) const {
598 if (!outDataspace) {
599 return BAD_VALUE;
600 }
Yichi Chenba40db52021-04-30 00:18:32 +0800601 AidlDataspace dataspace;
Marissa Wall22b2de12019-12-02 18:11:43 -0800602 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
613status_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
Marissa Wallef785e12019-12-12 14:26:59 -0800619status_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
625status_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
631status_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
Alec Mouri332765e2021-10-06 16:38:12 -0700637status_t Gralloc4Mapper::getSmpte2094_10(
638 buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>>* outSmpte2094_10) const {
639 return get(bufferHandle, gralloc4::MetadataType_Smpte2094_10, gralloc4::decodeSmpte2094_10,
640 outSmpte2094_10);
641}
642
Marissa Wall22b2de12019-12-02 18:11:43 -0800643template <class T>
644status_t Gralloc4Mapper::getDefault(uint32_t width, uint32_t height, PixelFormat format,
645 uint32_t layerCount, uint64_t usage,
646 const MetadataType& metadataType,
647 DecodeFunction<T> decodeFunction, T* outMetadata) const {
648 if (!outMetadata) {
649 return BAD_VALUE;
650 }
651
652 IMapper::BufferDescriptorInfo descriptorInfo;
653 sBufferDescriptorInfo("getDefault", width, height, format, layerCount, usage, &descriptorInfo);
654
655 hidl_vec<uint8_t> vec;
656 Error error;
657 auto ret = mMapper->getFromBufferDescriptorInfo(descriptorInfo, metadataType,
658 [&](const auto& tmpError,
659 const hidl_vec<uint8_t>& tmpVec) {
660 error = tmpError;
661 vec = tmpVec;
662 });
663
664 if (!ret.isOk()) {
665 error = kTransactionError;
666 }
667
668 if (error != Error::NONE) {
669 ALOGE("getDefault(%s, %" PRIu64 ", ...) failed with %d", metadataType.name.c_str(),
670 metadataType.value, error);
671 return static_cast<status_t>(error);
672 }
673
674 return decodeFunction(vec, outMetadata);
675}
676
677status_t Gralloc4Mapper::getDefaultPixelFormatFourCC(uint32_t width, uint32_t height,
678 PixelFormat format, uint32_t layerCount,
679 uint64_t usage,
680 uint32_t* outPixelFormatFourCC) const {
681 return getDefault(width, height, format, layerCount, usage,
682 gralloc4::MetadataType_PixelFormatFourCC, gralloc4::decodePixelFormatFourCC,
683 outPixelFormatFourCC);
684}
685
686status_t Gralloc4Mapper::getDefaultPixelFormatModifier(uint32_t width, uint32_t height,
687 PixelFormat format, uint32_t layerCount,
688 uint64_t usage,
689 uint64_t* outPixelFormatModifier) const {
690 return getDefault(width, height, format, layerCount, usage,
691 gralloc4::MetadataType_PixelFormatModifier,
692 gralloc4::decodePixelFormatModifier, outPixelFormatModifier);
693}
694
695status_t Gralloc4Mapper::getDefaultAllocationSize(uint32_t width, uint32_t height,
696 PixelFormat format, uint32_t layerCount,
697 uint64_t usage,
698 uint64_t* outAllocationSize) const {
699 return getDefault(width, height, format, layerCount, usage,
700 gralloc4::MetadataType_AllocationSize, gralloc4::decodeAllocationSize,
701 outAllocationSize);
702}
703
704status_t Gralloc4Mapper::getDefaultProtectedContent(uint32_t width, uint32_t height,
705 PixelFormat format, uint32_t layerCount,
706 uint64_t usage,
707 uint64_t* outProtectedContent) const {
708 return getDefault(width, height, format, layerCount, usage,
709 gralloc4::MetadataType_ProtectedContent, gralloc4::decodeProtectedContent,
710 outProtectedContent);
711}
712
713status_t Gralloc4Mapper::getDefaultCompression(uint32_t width, uint32_t height, PixelFormat format,
714 uint32_t layerCount, uint64_t usage,
715 ExtendableType* outCompression) const {
716 return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_Compression,
717 gralloc4::decodeCompression, outCompression);
718}
719
720status_t Gralloc4Mapper::getDefaultCompression(uint32_t width, uint32_t height, PixelFormat format,
721 uint32_t layerCount, uint64_t usage,
722 ui::Compression* outCompression) const {
723 if (!outCompression) {
724 return BAD_VALUE;
725 }
726 ExtendableType compression;
727 status_t error = getDefaultCompression(width, height, format, layerCount, usage, &compression);
728 if (error) {
729 return error;
730 }
731 if (!gralloc4::isStandardCompression(compression)) {
732 return BAD_TYPE;
733 }
734 *outCompression = gralloc4::getStandardCompressionValue(compression);
735 return NO_ERROR;
736}
737
738status_t Gralloc4Mapper::getDefaultInterlaced(uint32_t width, uint32_t height, PixelFormat format,
739 uint32_t layerCount, uint64_t usage,
740 ExtendableType* outInterlaced) const {
741 return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_Interlaced,
742 gralloc4::decodeInterlaced, outInterlaced);
743}
744
745status_t Gralloc4Mapper::getDefaultInterlaced(uint32_t width, uint32_t height, PixelFormat format,
746 uint32_t layerCount, uint64_t usage,
747 ui::Interlaced* outInterlaced) const {
748 if (!outInterlaced) {
749 return BAD_VALUE;
750 }
751 ExtendableType interlaced;
752 status_t error = getDefaultInterlaced(width, height, format, layerCount, usage, &interlaced);
753 if (error) {
754 return error;
755 }
756 if (!gralloc4::isStandardInterlaced(interlaced)) {
757 return BAD_TYPE;
758 }
759 *outInterlaced = gralloc4::getStandardInterlacedValue(interlaced);
760 return NO_ERROR;
761}
762
763status_t Gralloc4Mapper::getDefaultChromaSiting(uint32_t width, uint32_t height, PixelFormat format,
764 uint32_t layerCount, uint64_t usage,
765 ExtendableType* outChromaSiting) const {
766 return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_ChromaSiting,
767 gralloc4::decodeChromaSiting, outChromaSiting);
768}
769
770status_t Gralloc4Mapper::getDefaultChromaSiting(uint32_t width, uint32_t height, PixelFormat format,
771 uint32_t layerCount, uint64_t usage,
772 ui::ChromaSiting* outChromaSiting) const {
773 if (!outChromaSiting) {
774 return BAD_VALUE;
775 }
776 ExtendableType chromaSiting;
777 status_t error =
778 getDefaultChromaSiting(width, height, format, layerCount, usage, &chromaSiting);
779 if (error) {
780 return error;
781 }
782 if (!gralloc4::isStandardChromaSiting(chromaSiting)) {
783 return BAD_TYPE;
784 }
785 *outChromaSiting = gralloc4::getStandardChromaSitingValue(chromaSiting);
786 return NO_ERROR;
787}
788
789status_t Gralloc4Mapper::getDefaultPlaneLayouts(
790 uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, uint64_t usage,
791 std::vector<ui::PlaneLayout>* outPlaneLayouts) const {
792 return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_PlaneLayouts,
793 gralloc4::decodePlaneLayouts, outPlaneLayouts);
794}
795
796std::vector<MetadataTypeDescription> Gralloc4Mapper::listSupportedMetadataTypes() const {
797 hidl_vec<MetadataTypeDescription> descriptions;
798 Error error;
799 auto ret = mMapper->listSupportedMetadataTypes(
800 [&](const auto& tmpError, const auto& tmpDescriptions) {
801 error = tmpError;
802 descriptions = tmpDescriptions;
803 });
804
805 if (!ret.isOk()) {
806 error = kTransactionError;
807 }
808
809 if (error != Error::NONE) {
810 ALOGE("listSupportedMetadataType() failed with %d", error);
811 return {};
812 }
813
814 return static_cast<std::vector<MetadataTypeDescription>>(descriptions);
815}
816
817template <class T>
818status_t Gralloc4Mapper::metadataDumpHelper(const BufferDump& bufferDump,
819 StandardMetadataType metadataType,
820 DecodeFunction<T> decodeFunction, T* outT) const {
821 const auto& metadataDump = bufferDump.metadataDump;
822
823 auto itr =
824 std::find_if(metadataDump.begin(), metadataDump.end(),
825 [&](const MetadataDump& tmpMetadataDump) {
826 if (!gralloc4::isStandardMetadataType(tmpMetadataDump.metadataType)) {
827 return false;
828 }
829 return metadataType ==
830 gralloc4::getStandardMetadataTypeValue(
831 tmpMetadataDump.metadataType);
832 });
833 if (itr == metadataDump.end()) {
834 return BAD_VALUE;
835 }
836
837 return decodeFunction(itr->metadata, outT);
838}
839
840status_t Gralloc4Mapper::bufferDumpHelper(const BufferDump& bufferDump, std::ostringstream* outDump,
841 uint64_t* outAllocationSize, bool less) const {
842 uint64_t bufferId;
843 std::string name;
844 uint64_t width;
845 uint64_t height;
846 uint64_t layerCount;
847 ui::PixelFormat pixelFormatRequested;
848 uint32_t pixelFormatFourCC;
849 uint64_t pixelFormatModifier;
850 uint64_t usage;
Yichi Chenba40db52021-04-30 00:18:32 +0800851 AidlDataspace dataspace;
Marissa Wall22b2de12019-12-02 18:11:43 -0800852 uint64_t allocationSize;
853 uint64_t protectedContent;
854 ExtendableType compression;
855 ExtendableType interlaced;
856 ExtendableType chromaSiting;
857 std::vector<ui::PlaneLayout> planeLayouts;
858
859 status_t error = metadataDumpHelper(bufferDump, StandardMetadataType::BUFFER_ID,
860 gralloc4::decodeBufferId, &bufferId);
861 if (error != NO_ERROR) {
862 return error;
863 }
864 error = metadataDumpHelper(bufferDump, StandardMetadataType::NAME, gralloc4::decodeName, &name);
865 if (error != NO_ERROR) {
866 return error;
867 }
868 error = metadataDumpHelper(bufferDump, StandardMetadataType::WIDTH, gralloc4::decodeWidth,
869 &width);
870 if (error != NO_ERROR) {
871 return error;
872 }
873 error = metadataDumpHelper(bufferDump, StandardMetadataType::HEIGHT, gralloc4::decodeHeight,
874 &height);
875 if (error != NO_ERROR) {
876 return error;
877 }
878 error = metadataDumpHelper(bufferDump, StandardMetadataType::LAYER_COUNT,
879 gralloc4::decodeLayerCount, &layerCount);
880 if (error != NO_ERROR) {
881 return error;
882 }
883 error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_REQUESTED,
884 gralloc4::decodePixelFormatRequested, &pixelFormatRequested);
885 if (error != NO_ERROR) {
886 return error;
887 }
888 error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_FOURCC,
889 gralloc4::decodePixelFormatFourCC, &pixelFormatFourCC);
890 if (error != NO_ERROR) {
891 return error;
892 }
893 error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_MODIFIER,
894 gralloc4::decodePixelFormatModifier, &pixelFormatModifier);
895 if (error != NO_ERROR) {
896 return error;
897 }
898 error = metadataDumpHelper(bufferDump, StandardMetadataType::USAGE, gralloc4::decodeUsage,
899 &usage);
900 if (error != NO_ERROR) {
901 return error;
902 }
Yichi Chenba40db52021-04-30 00:18:32 +0800903 error = metadataDumpHelper(bufferDump, StandardMetadataType::DATASPACE,
904 gralloc4::decodeDataspace, &dataspace);
905 if (error != NO_ERROR) {
906 return error;
907 }
Marissa Wall22b2de12019-12-02 18:11:43 -0800908 error = metadataDumpHelper(bufferDump, StandardMetadataType::ALLOCATION_SIZE,
909 gralloc4::decodeAllocationSize, &allocationSize);
910 if (error != NO_ERROR) {
911 return error;
912 }
913 error = metadataDumpHelper(bufferDump, StandardMetadataType::PROTECTED_CONTENT,
914 gralloc4::decodeProtectedContent, &protectedContent);
915 if (error != NO_ERROR) {
916 return error;
917 }
918 error = metadataDumpHelper(bufferDump, StandardMetadataType::COMPRESSION,
919 gralloc4::decodeCompression, &compression);
920 if (error != NO_ERROR) {
921 return error;
922 }
923 error = metadataDumpHelper(bufferDump, StandardMetadataType::INTERLACED,
924 gralloc4::decodeInterlaced, &interlaced);
925 if (error != NO_ERROR) {
926 return error;
927 }
928 error = metadataDumpHelper(bufferDump, StandardMetadataType::CHROMA_SITING,
929 gralloc4::decodeChromaSiting, &chromaSiting);
930 if (error != NO_ERROR) {
931 return error;
932 }
933 error = metadataDumpHelper(bufferDump, StandardMetadataType::PLANE_LAYOUTS,
934 gralloc4::decodePlaneLayouts, &planeLayouts);
935 if (error != NO_ERROR) {
936 return error;
937 }
938
939 if (outAllocationSize) {
940 *outAllocationSize = allocationSize;
941 }
942 double allocationSizeKiB = static_cast<double>(allocationSize) / 1024;
943
944 *outDump << "+ name:" << name << ", id:" << bufferId << ", size:" << allocationSizeKiB
945 << "KiB, w/h:" << width << "x" << height << ", usage: 0x" << std::hex << usage
946 << std::dec << ", req fmt:" << static_cast<int32_t>(pixelFormatRequested)
947 << ", fourcc/mod:" << pixelFormatFourCC << "/" << pixelFormatModifier
Yichi Chen6de5b582021-09-13 20:00:52 +0800948 << ", dataspace: 0x" << std::hex << static_cast<uint32_t>(dataspace) << std::dec
Marissa Wall22b2de12019-12-02 18:11:43 -0800949 << ", compressed: ";
950
951 if (less) {
952 bool isCompressed = !gralloc4::isStandardCompression(compression) ||
953 (gralloc4::getStandardCompressionValue(compression) != ui::Compression::NONE);
954 *outDump << std::boolalpha << isCompressed << "\n";
955 } else {
956 *outDump << gralloc4::getCompressionName(compression) << "\n";
957 }
958
959 bool firstPlane = true;
960 for (const auto& planeLayout : planeLayouts) {
961 if (firstPlane) {
962 firstPlane = false;
963 *outDump << "\tplanes: ";
964 } else {
965 *outDump << "\t ";
966 }
967
968 for (size_t i = 0; i < planeLayout.components.size(); i++) {
969 const auto& planeLayoutComponent = planeLayout.components[i];
970 *outDump << gralloc4::getPlaneLayoutComponentTypeName(planeLayoutComponent.type);
971 if (i < planeLayout.components.size() - 1) {
972 *outDump << "/";
973 } else {
974 *outDump << ":\t";
975 }
976 }
977 *outDump << " w/h:" << planeLayout.widthInSamples << "x" << planeLayout.heightInSamples
978 << ", stride:" << planeLayout.strideInBytes
979 << " bytes, size:" << planeLayout.totalSizeInBytes;
980 if (!less) {
981 *outDump << ", inc:" << planeLayout.sampleIncrementInBits
982 << " bits, subsampling w/h:" << planeLayout.horizontalSubsampling << "x"
983 << planeLayout.verticalSubsampling;
984 }
985 *outDump << "\n";
986 }
987
988 if (!less) {
989 *outDump << "\tlayer cnt: " << layerCount << ", protected content: " << protectedContent
990 << ", interlaced: " << gralloc4::getInterlacedName(interlaced)
991 << ", chroma siting:" << gralloc4::getChromaSitingName(chromaSiting) << "\n";
992 }
993
994 return NO_ERROR;
995}
996
997std::string Gralloc4Mapper::dumpBuffer(buffer_handle_t bufferHandle, bool less) const {
998 auto buffer = const_cast<native_handle_t*>(bufferHandle);
999
1000 BufferDump bufferDump;
1001 Error error;
1002 auto ret = mMapper->dumpBuffer(buffer, [&](const auto& tmpError, const auto& tmpBufferDump) {
1003 error = tmpError;
1004 bufferDump = tmpBufferDump;
1005 });
1006
1007 if (!ret.isOk()) {
1008 error = kTransactionError;
1009 }
1010
1011 if (error != Error::NONE) {
1012 ALOGE("dumpBuffer() failed with %d", error);
1013 return "";
1014 }
1015
1016 std::ostringstream stream;
1017 stream.precision(2);
1018
1019 status_t err = bufferDumpHelper(bufferDump, &stream, nullptr, less);
1020 if (err != NO_ERROR) {
1021 ALOGE("bufferDumpHelper() failed with %d", err);
1022 return "";
1023 }
1024
1025 return stream.str();
1026}
1027
1028std::string Gralloc4Mapper::dumpBuffers(bool less) const {
1029 hidl_vec<BufferDump> bufferDumps;
1030 Error error;
1031 auto ret = mMapper->dumpBuffers([&](const auto& tmpError, const auto& tmpBufferDump) {
1032 error = tmpError;
1033 bufferDumps = tmpBufferDump;
1034 });
1035
1036 if (!ret.isOk()) {
1037 error = kTransactionError;
1038 }
1039
1040 if (error != Error::NONE) {
1041 ALOGE("dumpBuffer() failed with %d", error);
1042 return "";
1043 }
1044
1045 uint64_t totalAllocationSize = 0;
1046 std::ostringstream stream;
1047 stream.precision(2);
1048
1049 stream << "Imported gralloc buffers:\n";
1050
1051 for (const auto& bufferDump : bufferDumps) {
1052 uint64_t allocationSize = 0;
1053 status_t err = bufferDumpHelper(bufferDump, &stream, &allocationSize, less);
1054 if (err != NO_ERROR) {
1055 ALOGE("bufferDumpHelper() failed with %d", err);
1056 return "";
1057 }
1058 totalAllocationSize += allocationSize;
1059 }
1060
1061 double totalAllocationSizeKiB = static_cast<double>(totalAllocationSize) / 1024;
1062 stream << "Total imported by gralloc: " << totalAllocationSizeKiB << "KiB\n";
1063 return stream.str();
1064}
1065
Marissa Wall87c8ba72019-06-20 14:20:52 -07001066Gralloc4Allocator::Gralloc4Allocator(const Gralloc4Mapper& mapper) : mMapper(mapper) {
1067 mAllocator = IAllocator::getService();
1068 if (mAllocator == nullptr) {
Yiwei Zhange6124d92020-11-16 02:52:51 +00001069 ALOGW("allocator 4.x is not supported");
Marissa Wall87c8ba72019-06-20 14:20:52 -07001070 return;
1071 }
1072}
1073
1074bool Gralloc4Allocator::isLoaded() const {
1075 return mAllocator != nullptr;
1076}
1077
Marissa Wall22b2de12019-12-02 18:11:43 -08001078std::string Gralloc4Allocator::dumpDebugInfo(bool less) const {
1079 return mMapper.dumpBuffers(less);
Marissa Wall87c8ba72019-06-20 14:20:52 -07001080}
1081
Marissa Wall22b2de12019-12-02 18:11:43 -08001082status_t Gralloc4Allocator::allocate(std::string requestorName, uint32_t width, uint32_t height,
1083 android::PixelFormat format, uint32_t layerCount,
1084 uint64_t usage, uint32_t bufferCount, uint32_t* outStride,
1085 buffer_handle_t* outBufferHandles, bool importBuffers) const {
Marissa Wall87c8ba72019-06-20 14:20:52 -07001086 IMapper::BufferDescriptorInfo descriptorInfo;
Marissa Wall22b2de12019-12-02 18:11:43 -08001087 sBufferDescriptorInfo(requestorName, width, height, format, layerCount, usage, &descriptorInfo);
Marissa Wall87c8ba72019-06-20 14:20:52 -07001088
1089 BufferDescriptor descriptor;
1090 status_t error = mMapper.createDescriptor(static_cast<void*>(&descriptorInfo),
1091 static_cast<void*>(&descriptor));
1092 if (error != NO_ERROR) {
1093 return error;
1094 }
1095
1096 auto ret = mAllocator->allocate(descriptor, bufferCount,
1097 [&](const auto& tmpError, const auto& tmpStride,
1098 const auto& tmpBuffers) {
1099 error = static_cast<status_t>(tmpError);
1100 if (tmpError != Error::NONE) {
1101 return;
1102 }
1103
Marissa Wallbfcf81f2019-11-27 10:36:29 -08001104 if (importBuffers) {
1105 for (uint32_t i = 0; i < bufferCount; i++) {
1106 error = mMapper.importBuffer(tmpBuffers[i],
1107 &outBufferHandles[i]);
1108 if (error != NO_ERROR) {
1109 for (uint32_t j = 0; j < i; j++) {
1110 mMapper.freeBuffer(outBufferHandles[j]);
1111 outBufferHandles[j] = nullptr;
1112 }
1113 return;
Marissa Wall87c8ba72019-06-20 14:20:52 -07001114 }
Marissa Wallbfcf81f2019-11-27 10:36:29 -08001115 }
1116 } else {
1117 for (uint32_t i = 0; i < bufferCount; i++) {
1118 outBufferHandles[i] = native_handle_clone(
1119 tmpBuffers[i].getNativeHandle());
1120 if (!outBufferHandles[i]) {
1121 for (uint32_t j = 0; j < i; j++) {
1122 auto buffer = const_cast<native_handle_t*>(
1123 outBufferHandles[j]);
1124 native_handle_close(buffer);
1125 native_handle_delete(buffer);
1126 outBufferHandles[j] = nullptr;
1127 }
1128 }
Marissa Wall87c8ba72019-06-20 14:20:52 -07001129 }
1130 }
1131 *outStride = tmpStride;
1132 });
1133
1134 // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
1135 hardware::IPCThreadState::self()->flushCommands();
1136
1137 return (ret.isOk()) ? error : static_cast<status_t>(kTransactionError);
1138}
1139
1140} // namespace android