blob: f799ce4cb05ffef33a4006949695e481b5979325 [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;
Marissa Wall22b2de12019-12-02 18:11:43 -080039using BufferDump = android::hardware::graphics::mapper::V4_0::IMapper::BufferDump;
40using MetadataDump = android::hardware::graphics::mapper::V4_0::IMapper::MetadataDump;
41using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
42using MetadataTypeDescription =
43 android::hardware::graphics::mapper::V4_0::IMapper::MetadataTypeDescription;
Marissa Wall87c8ba72019-06-20 14:20:52 -070044
45namespace android {
46
47namespace {
48
49static constexpr Error kTransactionError = Error::NO_RESOURCES;
50
51uint64_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
63static 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}
Marissa Wall22b2de12019-12-02 18:11:43 -080071static inline void sBufferDescriptorInfo(std::string name, uint32_t width, uint32_t height,
72 PixelFormat format, uint32_t layerCount, uint64_t usage,
Marissa Wall87c8ba72019-06-20 14:20:52 -070073 IMapper::BufferDescriptorInfo* outDescriptorInfo) {
Marissa Wall22b2de12019-12-02 18:11:43 -080074 outDescriptorInfo->name = name;
Marissa Wall87c8ba72019-06-20 14:20:52 -070075 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;
Valerie Hau23392792020-03-09 14:01:06 -070080 outDescriptorInfo->reservedSize = 0;
Marissa Wall87c8ba72019-06-20 14:20:52 -070081}
82
83} // anonymous namespace
84
85void Gralloc4Mapper::preload() {
86 android::hardware::preloadPassthroughService<IMapper>();
87}
88
89Gralloc4Mapper::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
100bool Gralloc4Mapper::isLoaded() const {
101 return mMapper != nullptr;
102}
103
104status_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
116status_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
141status_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
155void 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
163status_t Gralloc4Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width,
Marissa Wall22b2de12019-12-02 18:11:43 -0800164 uint32_t height, PixelFormat format,
Marissa Wall87c8ba72019-06-20 14:20:52 -0700165 uint32_t layerCount, uint64_t usage,
166 uint32_t stride) const {
167 IMapper::BufferDescriptorInfo descriptorInfo;
Marissa Wall22b2de12019-12-02 18:11:43 -0800168 sBufferDescriptorInfo("validateBufferSize", width, height, format, layerCount, usage,
169 &descriptorInfo);
Marissa Wall87c8ba72019-06-20 14:20:52 -0700170
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
177void 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
200status_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 {
Marissa Wall22b2de12019-12-02 18:11:43 -0800203 std::vector<ui::PlaneLayout> planeLayouts;
204 status_t err = getPlaneLayouts(bufferHandle, &planeLayouts);
205
Valerie Hau3bb97912020-04-09 10:40:10 -0700206 if (err == NO_ERROR && !planeLayouts.empty()) {
Marissa Wall22b2de12019-12-02 18:11:43 -0800207 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 }
Marissa Wall20611c62019-11-05 15:06:24 -0800233 }
234
Marissa Wall87c8ba72019-06-20 14:20:52 -0700235 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,
Marissa Wall20611c62019-11-05 15:06:24 -0800250 [&](const auto& tmpError, const auto& tmpData) {
Marissa Wall87c8ba72019-06-20 14:20:52 -0700251 error = tmpError;
252 if (error != Error::NONE) {
253 return;
254 }
255 *outData = tmpData;
Marissa Wall87c8ba72019-06-20 14:20:52 -0700256 });
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
Marissa Wall22b2de12019-12-02 18:11:43 -0800270status_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;
Marissa Wall90df5852020-02-27 10:17:02 -0800368 return static_cast<status_t>(Error::NONE);
Marissa Wall87c8ba72019-06-20 14:20:52 -0700369}
370
371int 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
Marissa Wall22b2de12019-12-02 18:11:43 -0800405status_t Gralloc4Mapper::isSupported(uint32_t width, uint32_t height, PixelFormat format,
Marissa Wall87c8ba72019-06-20 14:20:52 -0700406 uint32_t layerCount, uint64_t usage,
407 bool* outSupported) const {
408 IMapper::BufferDescriptorInfo descriptorInfo;
Marissa Wall22b2de12019-12-02 18:11:43 -0800409 sBufferDescriptorInfo("isSupported", width, height, format, layerCount, usage, &descriptorInfo);
Marissa Wall87c8ba72019-06-20 14:20:52 -0700410
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
Marissa Wall22b2de12019-12-02 18:11:43 -0800435template <class T>
436status_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
463status_t Gralloc4Mapper::getBufferId(buffer_handle_t bufferHandle, uint64_t* outBufferId) const {
464 return get(bufferHandle, gralloc4::MetadataType_BufferId, gralloc4::decodeBufferId,
465 outBufferId);
466}
467
468status_t Gralloc4Mapper::getName(buffer_handle_t bufferHandle, std::string* outName) const {
469 return get(bufferHandle, gralloc4::MetadataType_Name, gralloc4::decodeName, outName);
470}
471
472status_t Gralloc4Mapper::getWidth(buffer_handle_t bufferHandle, uint64_t* outWidth) const {
473 return get(bufferHandle, gralloc4::MetadataType_Width, gralloc4::decodeWidth, outWidth);
474}
475
476status_t Gralloc4Mapper::getHeight(buffer_handle_t bufferHandle, uint64_t* outHeight) const {
477 return get(bufferHandle, gralloc4::MetadataType_Height, gralloc4::decodeHeight, outHeight);
478}
479
480status_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
486status_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
492status_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
498status_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
504status_t Gralloc4Mapper::getUsage(buffer_handle_t bufferHandle, uint64_t* outUsage) const {
505 return get(bufferHandle, gralloc4::MetadataType_Usage, gralloc4::decodeUsage, outUsage);
506}
507
508status_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
514status_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
520status_t Gralloc4Mapper::getCompression(buffer_handle_t bufferHandle,
521 ExtendableType* outCompression) const {
522 return get(bufferHandle, gralloc4::MetadataType_Compression, gralloc4::decodeCompression,
523 outCompression);
524}
525
526status_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
543status_t Gralloc4Mapper::getInterlaced(buffer_handle_t bufferHandle,
544 ExtendableType* outInterlaced) const {
545 return get(bufferHandle, gralloc4::MetadataType_Interlaced, gralloc4::decodeInterlaced,
546 outInterlaced);
547}
548
549status_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
566status_t Gralloc4Mapper::getChromaSiting(buffer_handle_t bufferHandle,
567 ExtendableType* outChromaSiting) const {
568 return get(bufferHandle, gralloc4::MetadataType_ChromaSiting, gralloc4::decodeChromaSiting,
569 outChromaSiting);
570}
571
572status_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
589status_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
595status_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
612status_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
Marissa Wallef785e12019-12-12 14:26:59 -0800618status_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
624status_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
630status_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
Marissa Wall22b2de12019-12-02 18:11:43 -0800636template <class T>
637status_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
670status_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
679status_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
688status_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
697status_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
706status_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
713status_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
731status_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
738status_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
756status_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
763status_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
782status_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
789std::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
810template <class T>
811status_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
833status_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
983std::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
1014std::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
Marissa Wall87c8ba72019-06-20 14:20:52 -07001052Gralloc4Allocator::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
1060bool Gralloc4Allocator::isLoaded() const {
1061 return mAllocator != nullptr;
1062}
1063
Marissa Wall22b2de12019-12-02 18:11:43 -08001064std::string Gralloc4Allocator::dumpDebugInfo(bool less) const {
1065 return mMapper.dumpBuffers(less);
Marissa Wall87c8ba72019-06-20 14:20:52 -07001066}
1067
Marissa Wall22b2de12019-12-02 18:11:43 -08001068status_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 {
Marissa Wall87c8ba72019-06-20 14:20:52 -07001072 IMapper::BufferDescriptorInfo descriptorInfo;
Marissa Wall22b2de12019-12-02 18:11:43 -08001073 sBufferDescriptorInfo(requestorName, width, height, format, layerCount, usage, &descriptorInfo);
Marissa Wall87c8ba72019-06-20 14:20:52 -07001074
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
Marissa Wallbfcf81f2019-11-27 10:36:29 -08001090 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;
Marissa Wall87c8ba72019-06-20 14:20:52 -07001100 }
Marissa Wallbfcf81f2019-11-27 10:36:29 -08001101 }
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 }
Marissa Wall87c8ba72019-06-20 14:20:52 -07001115 }
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