1 /*
2 * Copyright (C) 2024 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 #include <array>
18 #include <mutex>
19 #include <string_view>
20 #include <unordered_set>
21 #include <vector>
22
23 #include <cutils/native_handle.h>
24 #include <log/log.h>
25 #include <sync/sync.h>
26
27 #include <aidl/android/hardware/graphics/common/BufferUsage.h>
28 #include <aidl/android/hardware/graphics/common/ChromaSiting.h>
29 #include <aidl/android/hardware/graphics/common/Compression.h>
30 #include <aidl/android/hardware/graphics/common/Interlaced.h>
31 #include <aidl/android/hardware/graphics/common/PixelFormat.h>
32 #include <aidl/android/hardware/graphics/common/StandardMetadataType.h>
33
34 #include <android/hardware/graphics/mapper/IMapper.h>
35 #include <android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h>
36
37 #include <debug.h>
38 #include <FormatConversions.h>
39 #include <goldfish_address_space.h>
40 #include <gralloc_cb_bp.h>
41
42 #include "CbExternalMetadata.h"
43 #include "DebugLevel.h"
44 #include "HostConnectionSession.h"
45
46 #ifndef DRM_FORMAT_MOD_LINEAR
47 #define DRM_FORMAT_MOD_LINEAR 0
48 #endif
49
50 namespace aahgc = ::aidl::android::hardware::graphics::common;
51 using aahgc::BufferUsage;
52 using aahgc::ChromaSiting;
53 using aahgc::Interlaced;
54 using aahgc::PixelFormat;
55 using aahgc::StandardMetadataType;
56
57 using ::android::hardware::graphics::mapper::MetadataReader;
58 using ::android::hardware::graphics::mapper::MetadataWriter;
59
60 namespace {
61 constexpr size_t kMetadataBufferInitialSize = 1024;
62 constexpr uint32_t kCPU_READ_MASK = static_cast<uint32_t>(BufferUsage::CPU_READ_MASK);
63 constexpr uint32_t kCPU_WRITE_MASK = static_cast<uint32_t>(BufferUsage::CPU_WRITE_MASK);
64
65 using namespace std::literals;
66
67 const char kStandardMetadataTypeStr[] = "android.hardware.graphics.common.StandardMetadataType";
68 const std::string_view kStandardMetadataTypeTag(kStandardMetadataTypeStr, sizeof(kStandardMetadataTypeStr) - 1);
69 const std::string_view kChromaSitingTag = "android.hardware.graphics.common.ChromaSiting"sv;
70 const std::string_view kCompressionTag = "android.hardware.graphics.common.Compression"sv;
71 const std::string_view kInterlacedTag = "android.hardware.graphics.common.Interlaced"sv;
72 const std::string_view kPlaneLayoutComponentTypeTag = "android.hardware.graphics.common.PlaneLayoutComponentType"sv;
73
arraySize(T (&)[SIZE])74 template<class T, size_t SIZE> constexpr size_t arraySize(T (&)[SIZE]) { return SIZE; }
75
getPixelFormat(const cb_handle_t & cb)76 PixelFormat getPixelFormat(const cb_handle_t& cb) {
77 return static_cast<PixelFormat>(cb.format);
78 }
79
isYuvFormat(const PixelFormat format)80 bool isYuvFormat(const PixelFormat format) {
81 switch (format) {
82 case PixelFormat::YCRCB_420_SP:
83 case PixelFormat::YV12:
84 case PixelFormat::YCBCR_420_888:
85 case PixelFormat::YCBCR_P010:
86 return true;
87
88 default:
89 return false;
90 }
91 }
92
getFormatChromaSiting(const PixelFormat format)93 ChromaSiting getFormatChromaSiting(const PixelFormat format) {
94 return isYuvFormat(format) ? ChromaSiting::SITED_INTERSTITIAL : ChromaSiting::NONE;
95 }
96
getExternalMetadata(const cb_handle_t & cb)97 CbExternalMetadata& getExternalMetadata(const cb_handle_t& cb) {
98 CbExternalMetadata& m = *reinterpret_cast<CbExternalMetadata*>(
99 cb.getBufferPtr() + cb.externalMetadataOffset);
100 LOG_ALWAYS_FATAL_IF(m.magic != CbExternalMetadata::kMagicValue);
101 return m;
102 }
103
getID(const cb_handle_t & cb)104 uint64_t getID(const cb_handle_t& cb) {
105 return getExternalMetadata(cb).bufferID;
106 }
107
waitFenceFd(const int fd,const char * logname)108 int waitFenceFd(const int fd, const char* logname) {
109 const int warningTimeout = 5000;
110 if (sync_wait(fd, warningTimeout) < 0) {
111 if (errno == ETIME) {
112 ALOGW("%s: fence %d didn't signal in %d ms", logname, fd, warningTimeout);
113 if (sync_wait(fd, -1) < 0) {
114 return errno;
115 } else {
116 return 0;
117 }
118 } else {
119 return errno;
120 }
121 } else {
122 return 0;
123 }
124 }
125
126 const AIMapper_MetadataTypeDescription kMetadataTypeDescriptionList[] = {
127 {
128 .metadataType = {
129 .name = kStandardMetadataTypeStr,
130 .value = static_cast<int64_t>(StandardMetadataType::BUFFER_ID),
131 },
132 .isGettable = true,
133 .isSettable = false,
134 },
135 {
136 .metadataType = {
137 .name = kStandardMetadataTypeStr,
138 .value = static_cast<int64_t>(StandardMetadataType::NAME),
139 },
140 .isGettable = true,
141 .isSettable = false,
142 },
143 {
144 .metadataType = {
145 .name = kStandardMetadataTypeStr,
146 .value = static_cast<int64_t>(StandardMetadataType::WIDTH),
147 },
148 .isGettable = true,
149 .isSettable = false,
150 },
151 {
152 .metadataType = {
153 .name = kStandardMetadataTypeStr,
154 .value = static_cast<int64_t>(StandardMetadataType::HEIGHT),
155 },
156 .isGettable = true,
157 .isSettable = false,
158 },
159 {
160 .metadataType = {
161 .name = kStandardMetadataTypeStr,
162 .value = static_cast<int64_t>(StandardMetadataType::LAYER_COUNT),
163 },
164 .isGettable = true,
165 .isSettable = false,
166 },
167 {
168 .metadataType = {
169 .name = kStandardMetadataTypeStr,
170 .value = static_cast<int64_t>(StandardMetadataType::PIXEL_FORMAT_REQUESTED),
171 },
172 .isGettable = true,
173 .isSettable = false,
174 },
175 {
176 .metadataType = {
177 .name = kStandardMetadataTypeStr,
178 .value = static_cast<int64_t>(StandardMetadataType::PIXEL_FORMAT_FOURCC),
179 },
180 .isGettable = true,
181 .isSettable = false,
182 },
183 {
184 .metadataType = {
185 .name = kStandardMetadataTypeStr,
186 .value = static_cast<int64_t>(StandardMetadataType::PIXEL_FORMAT_MODIFIER),
187 },
188 .isGettable = true,
189 .isSettable = false,
190 },
191 {
192 .metadataType = {
193 .name = kStandardMetadataTypeStr,
194 .value = static_cast<int64_t>(StandardMetadataType::USAGE),
195 },
196 .isGettable = true,
197 .isSettable = false,
198 },
199 {
200 .metadataType = {
201 .name = kStandardMetadataTypeStr,
202 .value = static_cast<int64_t>(StandardMetadataType::ALLOCATION_SIZE),
203 },
204 .isGettable = true,
205 .isSettable = false,
206 },
207 {
208 .metadataType = {
209 .name = kStandardMetadataTypeStr,
210 .value = static_cast<int64_t>(StandardMetadataType::PROTECTED_CONTENT),
211 },
212 .isGettable = true,
213 .isSettable = false,
214 },
215 {
216 .metadataType = {
217 .name = kStandardMetadataTypeStr,
218 .value = static_cast<int64_t>(StandardMetadataType::COMPRESSION),
219 },
220 .isGettable = true,
221 .isSettable = false,
222 },
223 {
224 .metadataType = {
225 .name = kStandardMetadataTypeStr,
226 .value = static_cast<int64_t>(StandardMetadataType::INTERLACED),
227 },
228 .isGettable = true,
229 .isSettable = false,
230 },
231 {
232 .metadataType = {
233 .name = kStandardMetadataTypeStr,
234 .value = static_cast<int64_t>(StandardMetadataType::CHROMA_SITING),
235 },
236 .isGettable = true,
237 .isSettable = false,
238 },
239 {
240 .metadataType = {
241 .name = kStandardMetadataTypeStr,
242 .value = static_cast<int64_t>(StandardMetadataType::PLANE_LAYOUTS),
243 },
244 .isGettable = true,
245 .isSettable = false,
246 },
247 {
248 .metadataType = {
249 .name = kStandardMetadataTypeStr,
250 .value = static_cast<int64_t>(StandardMetadataType::CROP),
251 },
252 .isGettable = true,
253 .isSettable = false,
254 },
255 {
256 .metadataType = {
257 .name = kStandardMetadataTypeStr,
258 .value = static_cast<int64_t>(StandardMetadataType::DATASPACE),
259 },
260 .isGettable = true,
261 .isSettable = true,
262 },
263 {
264 .metadataType = {
265 .name = kStandardMetadataTypeStr,
266 .value = static_cast<int64_t>(StandardMetadataType::BLEND_MODE),
267 },
268 .isGettable = true,
269 .isSettable = true,
270 },
271 {
272 .metadataType = {
273 .name = kStandardMetadataTypeStr,
274 .value = static_cast<int64_t>(StandardMetadataType::SMPTE2086),
275 },
276 .isGettable = true,
277 .isSettable = true,
278 },
279 {
280 .metadataType = {
281 .name = kStandardMetadataTypeStr,
282 .value = static_cast<int64_t>(StandardMetadataType::CTA861_3),
283 },
284 .isGettable = true,
285 .isSettable = true,
286 },
287 {
288 .metadataType = {
289 .name = kStandardMetadataTypeStr,
290 .value = static_cast<int64_t>(StandardMetadataType::STRIDE),
291 },
292 .isGettable = true,
293 .isSettable = false,
294 },
295 };
296
297 struct GoldfishMapper {
GoldfishMapper__anon555456480111::GoldfishMapper298 GoldfishMapper()
299 : mHostConn(HostConnection::createUnique(kCapsetNone))
300 , mDebugLevel(getDebugLevel()) {
301 GoldfishAddressSpaceHostMemoryAllocator hostMemoryAllocator(false);
302 LOG_ALWAYS_FATAL_IF(!hostMemoryAllocator.is_opened(),
303 "GoldfishAddressSpaceHostMemoryAllocator failed to open");
304
305 GoldfishAddressSpaceBlock bufferBits;
306 LOG_ALWAYS_FATAL_IF(hostMemoryAllocator.hostMalloc(&bufferBits, 256),
307 "hostMalloc failed");
308
309 mPhysAddrToOffset = bufferBits.physAddr() - bufferBits.offset();
310 hostMemoryAllocator.hostFree(&bufferBits);
311
312 static GoldfishMapper* s_instance;
313
314 mMapper.version = AIMAPPER_VERSION_5;
315 mMapper.v5.importBuffer = [](const native_handle_t* handle,
316 buffer_handle_t* outBufferHandle) {
317 return s_instance->importBuffer(handle, outBufferHandle);
318 };
319 mMapper.v5.freeBuffer = [](buffer_handle_t buffer) {
320 return s_instance->freeBuffer(buffer);
321 };
322 mMapper.v5.getTransportSize = &getTransportSize;
323 mMapper.v5.lock = [](buffer_handle_t buffer, uint64_t cpuUsage,
324 ARect accessRegion, int acquireFence,
325 void** outData){
326 return s_instance->lock(buffer, cpuUsage, accessRegion,
327 acquireFence, outData);
328 };
329 mMapper.v5.unlock = [](buffer_handle_t buffer, int* releaseFence) {
330 return s_instance->unlock(buffer, releaseFence);
331 };
332 mMapper.v5.flushLockedBuffer = [](buffer_handle_t buffer) {
333 return s_instance->flushLockedBuffer(buffer);
334 };
335 mMapper.v5.rereadLockedBuffer = [](buffer_handle_t buffer) {
336 return s_instance->rereadLockedBuffer(buffer);
337 };
338 mMapper.v5.getMetadata = [](const buffer_handle_t buffer,
339 const AIMapper_MetadataType metadataType,
340 void* const destBuffer, const size_t destBufferSize) {
341 return s_instance->getMetadata(buffer, metadataType,
342 destBuffer, destBufferSize);
343 };
344 mMapper.v5.getStandardMetadata = [](const buffer_handle_t buffer,
345 const int64_t standardMetadataType,
346 void* const destBuffer,
347 const size_t destBufferSize) {
348 return s_instance->getStandardMetadata(buffer, standardMetadataType,
349 destBuffer, destBufferSize);
350 };
351 mMapper.v5.setMetadata = [](const buffer_handle_t buffer,
352 const AIMapper_MetadataType metadataType,
353 const void* const metadata, const size_t metadataSize) {
354 return s_instance->setMetadata(buffer, metadataType,
355 metadata, metadataSize);
356 };
357 mMapper.v5.setStandardMetadata = [](const buffer_handle_t buffer,
358 const int64_t standardMetadataType,
359 const void* const metadata,
360 const size_t metadataSize) {
361 return s_instance->setStandardMetadata(buffer, standardMetadataType,
362 metadata, metadataSize);
363 };
364 mMapper.v5.listSupportedMetadataTypes = &listSupportedMetadataTypes;
365 mMapper.v5.dumpBuffer = [](const buffer_handle_t buffer,
366 const AIMapper_DumpBufferCallback dumpBufferCallback,
367 void* const context) {
368 return s_instance->dumpBuffer(buffer, dumpBufferCallback, context);
369 };
370 mMapper.v5.dumpAllBuffers = [](AIMapper_BeginDumpBufferCallback beginDumpCallback,
371 AIMapper_DumpBufferCallback dumpBufferCallback,
372 void* context){
373 return s_instance->dumpAllBuffers(beginDumpCallback, dumpBufferCallback,
374 context);
375 };
376 mMapper.v5.getReservedRegion = [](const buffer_handle_t buffer,
377 void** const outReservedRegion,
378 uint64_t* const outReservedSize) {
379 return s_instance->getReservedRegion(buffer, outReservedRegion,
380 outReservedSize);
381 };
382
383 s_instance = this;
384 }
385
getAIMapper__anon555456480111::GoldfishMapper386 AIMapper& getAIMapper() {
387 return mMapper;
388 }
389
390 private:
importBuffer__anon555456480111::GoldfishMapper391 AIMapper_Error importBuffer(const native_handle_t* const handle,
392 buffer_handle_t* const outBufferHandle) {
393 if (!handle) {
394 return FAILURE(AIMAPPER_ERROR_BAD_BUFFER);
395 }
396 native_handle_t* const imported = native_handle_clone(handle);
397 if (!imported) {
398 return FAILURE(AIMAPPER_ERROR_BAD_BUFFER);
399 }
400 cb_handle_t* const cb = cb_handle_t::from(imported);
401 if (!cb) {
402 native_handle_close(imported);
403 native_handle_delete(imported);
404 return FAILURE(AIMAPPER_ERROR_BAD_BUFFER);
405 }
406
407 if (cb->mmapedSize) {
408 const int bufferFd = cb->bufferFd;
409 LOG_ALWAYS_FATAL_IF(bufferFd < 0);
410
411 void* newPtr;
412 const int err = GoldfishAddressSpaceBlock::memoryMap(
413 cb->getBufferPtr(), cb->mmapedSize,
414 bufferFd, cb->getMmapedOffset(), &newPtr);
415 if (err) {
416 native_handle_close(imported);
417 native_handle_delete(imported);
418 return FAILURE_V(AIMAPPER_ERROR_NO_RESOURCES, "%s: %s",
419 "NO_RESOURCES", strerror(err));
420 }
421 cb->setBufferPtr(newPtr);
422 }
423
424 if (mDebugLevel >= DebugLevel::IMPORT) {
425 ALOGD("%s:%d: id=%" PRIu64, __func__, __LINE__, getID(*cb));
426 }
427
428 std::lock_guard<std::mutex> lock(mImportedBuffersMtx);
429 LOG_ALWAYS_FATAL_IF(!mImportedBuffers.insert(cb).second);
430 *outBufferHandle = cb;
431 return AIMAPPER_ERROR_NONE;
432 }
433
freeBuffer__anon555456480111::GoldfishMapper434 AIMapper_Error freeBuffer(buffer_handle_t buffer) {
435 cb_handle_t* const cb = const_cast<cb_handle_t*>(static_cast<const cb_handle_t*>(buffer));
436
437 {
438 std::lock_guard<std::mutex> lock(mImportedBuffersMtx);
439 if (mImportedBuffers.erase(cb) == 0) {
440 return FAILURE(AIMAPPER_ERROR_BAD_BUFFER);
441 }
442 }
443
444 if (mDebugLevel >= DebugLevel::IMPORT) {
445 ALOGD("%s:%d: id=%" PRIu64, __func__, __LINE__, getID(*cb));
446 }
447
448 if (cb->hostHandle && (cb->lockedUsage & kCPU_WRITE_MASK)) {
449 flushToHost(*cb);
450 }
451 GoldfishAddressSpaceBlock::memoryUnmap(cb->getBufferPtr(),
452 cb->mmapedSize);
453 native_handle_close(cb);
454 native_handle_delete(cb);
455 return AIMAPPER_ERROR_NONE;
456 }
457
getTransportSize__anon555456480111::GoldfishMapper458 static AIMapper_Error getTransportSize(const buffer_handle_t buffer,
459 uint32_t* const outNumFds,
460 uint32_t* const outNumInts) {
461 const cb_handle_t* const cb = cb_handle_t::from(buffer);
462 if (!cb) {
463 return FAILURE(AIMAPPER_ERROR_BAD_BUFFER);
464 }
465
466 *outNumFds = cb->numFds;
467 *outNumInts = cb->numInts;
468 return AIMAPPER_ERROR_NONE;
469 }
470
lock__anon555456480111::GoldfishMapper471 AIMapper_Error lock(const buffer_handle_t buffer, const uint64_t uncheckedUsage,
472 const ARect& accessRegion, const int acquireFence,
473 void** const outData) const {
474 cb_handle_t* const cb = validateCb(buffer);
475 if (!cb) {
476 return FAILURE(AIMAPPER_ERROR_BAD_BUFFER);
477 }
478
479 const CbExternalMetadata& metadata = getExternalMetadata(*cb);
480 if (cb->lockedUsage) {
481 return FAILURE_V(AIMAPPER_ERROR_BAD_BUFFER, "%s: id=%" PRIu64,
482 "BAD_BUFFER(lockedUsage)", metadata.bufferID);
483 }
484
485 if ((accessRegion.left < 0) ||
486 (accessRegion.top < 0) ||
487 (accessRegion.bottom < accessRegion.top) ||
488 (accessRegion.right < accessRegion.left) ||
489 (accessRegion.right > metadata.width) ||
490 (accessRegion.bottom > metadata.height)) {
491 return FAILURE_V(AIMAPPER_ERROR_BAD_VALUE, "%s: id=%" PRIu64,
492 "BAD_VALUE(accessRegion)", metadata.bufferID);
493 }
494 if (accessRegion.right && (accessRegion.left == accessRegion.right)) {
495 return FAILURE_V(AIMAPPER_ERROR_BAD_VALUE, "%s: id=%" PRIu64,
496 "BAD_VALUE(accessRegion)", metadata.bufferID);
497 }
498 if (accessRegion.bottom && (accessRegion.top == accessRegion.bottom)) {
499 return FAILURE_V(AIMAPPER_ERROR_BAD_VALUE, "%s: id=%" PRIu64,
500 "BAD_VALUE(accessRegion)", metadata.bufferID);
501 }
502
503 const uint8_t cpuUsage = uncheckedUsage & cb->usage & (kCPU_READ_MASK | kCPU_WRITE_MASK);
504 if (cpuUsage == 0) {
505 return FAILURE_V(AIMAPPER_ERROR_BAD_VALUE, "%s: id=%" PRIu64,
506 "BAD_VALUE(uncheckedUsage)", metadata.bufferID);
507 }
508 if ((acquireFence >= 0) && waitFenceFd(acquireFence, __func__)) {
509 return FAILURE_V(AIMAPPER_ERROR_NO_RESOURCES, "%s: id=%" PRIu64,
510 "NO_RESOURCES(acquireFence)", metadata.bufferID);
511 }
512
513 if (mDebugLevel >= DebugLevel::LOCK) {
514 ALOGD("%s:%d: id=%" PRIu64 " usage=0x%X accessRegion="
515 "{ .left=%d, .top=%d, .right=%d, .bottom=%d }",
516 __func__, __LINE__, metadata.bufferID, cpuUsage, accessRegion.left,
517 accessRegion.top, accessRegion.right, accessRegion.bottom);
518 }
519
520 if (cb->hostHandle) {
521 const AIMapper_Error e = readFromHost(*cb);
522 if (e != AIMAPPER_ERROR_NONE) {
523 return e;
524 }
525 }
526
527 cb->lockedUsage = cpuUsage;
528 *outData = cb->getBufferPtr();
529 return AIMAPPER_ERROR_NONE;
530 }
531
unlock__anon555456480111::GoldfishMapper532 AIMapper_Error unlock(const buffer_handle_t buffer, int* const releaseFence) const {
533 cb_handle_t* const cb = validateCb(buffer);
534 if (!cb) {
535 return FAILURE(AIMAPPER_ERROR_BAD_BUFFER);
536 }
537 if (cb->lockedUsage == 0) {
538 return FAILURE_V(AIMAPPER_ERROR_BAD_BUFFER, "%s: id=%" PRIu64,
539 "BAD_BUFFER(lockedUsage)", getID(*cb));
540 }
541
542 if (mDebugLevel >= DebugLevel::LOCK) {
543 ALOGD("%s:%d: id=%" PRIu64, __func__, __LINE__, getID(*cb));
544 }
545
546 if (cb->hostHandle && (cb->lockedUsage & kCPU_WRITE_MASK)) {
547 flushToHost(*cb);
548 }
549
550 cb->lockedUsage = 0;
551 *releaseFence = -1;
552 return AIMAPPER_ERROR_NONE;
553 }
554
flushLockedBuffer__anon555456480111::GoldfishMapper555 AIMapper_Error flushLockedBuffer(const buffer_handle_t buffer) const {
556 const cb_handle_t* const cb = validateCb(buffer);
557 if (!cb) {
558 return FAILURE(AIMAPPER_ERROR_BAD_BUFFER);
559 }
560 if (mDebugLevel >= DebugLevel::FLUSH) {
561 ALOGD("%s:%d: id=%" PRIu64, __func__, __LINE__, getID(*cb));
562 }
563 if ((cb->lockedUsage & kCPU_WRITE_MASK) == 0) {
564 return FAILURE_V(AIMAPPER_ERROR_BAD_BUFFER, "%s: id=%" PRIu64 ,
565 "BAD_BUFFER(lockedUsage)", getID(*cb));
566 }
567 if (cb->hostHandle) {
568 flushToHost(*cb);
569 }
570 return AIMAPPER_ERROR_NONE;
571 }
572
rereadLockedBuffer__anon555456480111::GoldfishMapper573 AIMapper_Error rereadLockedBuffer(const buffer_handle_t buffer) const {
574 const cb_handle_t* const cb = validateCb(buffer);
575 if (!cb) {
576 return FAILURE(AIMAPPER_ERROR_BAD_BUFFER);
577 }
578 if (mDebugLevel >= DebugLevel::FLUSH) {
579 ALOGD("%s:%d: id=%" PRIu64, __func__, __LINE__, getID(*cb));
580 }
581 if ((cb->lockedUsage & kCPU_READ_MASK) == 0) {
582 return FAILURE_V(AIMAPPER_ERROR_BAD_BUFFER, "%s: id=%" PRIu64 ,
583 "BAD_BUFFER(lockedUsage)", getID(*cb));
584 }
585
586 if (cb->hostHandle) {
587 return readFromHost(*cb);
588 } else {
589 return AIMAPPER_ERROR_NONE;
590 }
591 }
592
readFromHost__anon555456480111::GoldfishMapper593 AIMapper_Error readFromHost(const cb_handle_t& cb) const {
594 const CbExternalMetadata& metadata = getExternalMetadata(cb);
595 const HostConnectionSession conn = getHostConnectionSession();
596 ExtendedRCEncoderContext *const rcEnc = conn.getRcEncoder();
597
598 const int res = rcEnc->rcColorBufferCacheFlush(
599 rcEnc, cb.hostHandle, 0, true);
600 if (res < 0) {
601 return FAILURE_V(AIMAPPER_ERROR_NO_RESOURCES, "%s: id=%" PRIu64 " res=%d",
602 "NO_RESOURCES", metadata.bufferID, res);
603 }
604
605 if (isYuvFormat(getPixelFormat(cb))) {
606 LOG_ALWAYS_FATAL_IF(!rcEnc->hasYUVCache());
607 rcEnc->rcReadColorBufferYUV(rcEnc, cb.hostHandle,
608 0, 0, metadata.width, metadata.height,
609 cb.getBufferPtr(), cb.bufferSize);
610 } else {
611 LOG_ALWAYS_FATAL_IF(!rcEnc->featureInfo()->hasReadColorBufferDma);
612 rcEnc->bindDmaDirectly(cb.getBufferPtr(),
613 getMmapedPhysAddr(cb.getMmapedOffset()));
614 rcEnc->rcReadColorBufferDMA(rcEnc, cb.hostHandle,
615 0, 0, metadata.width, metadata.height,
616 metadata.glFormat, metadata.glType,
617 cb.getBufferPtr(), cb.bufferSize);
618 }
619
620 return AIMAPPER_ERROR_NONE;
621 }
622
flushToHost__anon555456480111::GoldfishMapper623 void flushToHost(const cb_handle_t& cb) const {
624 const CbExternalMetadata& metadata = getExternalMetadata(cb);
625 const HostConnectionSession conn = getHostConnectionSession();
626 ExtendedRCEncoderContext *const rcEnc = conn.getRcEncoder();
627
628 rcEnc->bindDmaDirectly(cb.getBufferPtr(),
629 getMmapedPhysAddr(cb.getMmapedOffset()));
630 rcEnc->rcUpdateColorBufferDMA(rcEnc, cb.hostHandle,
631 0, 0, metadata.width, metadata.height,
632 metadata.glFormat, metadata.glType,
633 cb.getBufferPtr(), cb.bufferSize);
634 }
635
getMetadata__anon555456480111::GoldfishMapper636 int32_t getMetadata(const buffer_handle_t buffer,
637 const AIMapper_MetadataType metadataType,
638 void* const destBuffer, const size_t destBufferSize) const {
639 if (strcmp(metadataType.name, kStandardMetadataTypeStr)) {
640 return -FAILURE_V(AIMAPPER_ERROR_UNSUPPORTED, "%s: name=%s",
641 "UNSUPPORTED", metadataType.name);
642 } else {
643 return getStandardMetadata(buffer, metadataType.value,
644 destBuffer, destBufferSize);
645 }
646 }
647
getStandardMetadata__anon555456480111::GoldfishMapper648 int32_t getStandardMetadata(const buffer_handle_t buffer,
649 const int64_t standardMetadataType,
650 void* const destBuffer,
651 const size_t destBufferSize) const {
652 const cb_handle_t* const cb = validateCb(buffer);
653 if (!cb) {
654 return -FAILURE(AIMAPPER_ERROR_BAD_BUFFER);
655 }
656
657 // don't log dry runs
658 if (destBufferSize && (mDebugLevel >= DebugLevel::METADATA)) {
659 ALOGD("%s:%d: id=%" PRIu64 " standardMetadataType=%" PRId64,
660 __func__, __LINE__, getID(*cb), standardMetadataType);
661 }
662
663 return getStandardMetadataImpl(*cb, MetadataWriter(destBuffer, destBufferSize),
664 static_cast<StandardMetadataType>(standardMetadataType));
665 }
666
setMetadata__anon555456480111::GoldfishMapper667 AIMapper_Error setMetadata(const buffer_handle_t buffer,
668 const AIMapper_MetadataType metadataType,
669 const void* const metadata, const size_t metadataSize) const {
670 if (strcmp(metadataType.name, kStandardMetadataTypeStr)) {
671 return FAILURE_V(AIMAPPER_ERROR_UNSUPPORTED, "%s: name=%s",
672 "UNSUPPORTED", metadataType.name);
673 } else {
674 return setStandardMetadata(buffer, metadataType.value,
675 metadata, metadataSize);
676 }
677 }
678
setStandardMetadata__anon555456480111::GoldfishMapper679 AIMapper_Error setStandardMetadata(const buffer_handle_t buffer,
680 const int64_t standardMetadataType,
681 const void* const metadata,
682 const size_t metadataSize) const {
683 const cb_handle_t* const cb = validateCb(buffer);
684 if (!cb) {
685 return FAILURE(AIMAPPER_ERROR_BAD_BUFFER);
686 }
687
688 if (mDebugLevel >= DebugLevel::METADATA) {
689 ALOGD("%s:%d: id=%" PRIu64 " standardMetadataType=%" PRId64,
690 __func__, __LINE__, getID(*cb), standardMetadataType);
691 }
692
693 return setStandardMetadataImpl(*cb, MetadataReader(metadata, metadataSize),
694 static_cast<StandardMetadataType>(standardMetadataType));
695 }
696
getStandardMetadataImpl__anon555456480111::GoldfishMapper697 int32_t getStandardMetadataImpl(const cb_handle_t& cb, MetadataWriter writer,
698 const StandardMetadataType standardMetadataType) const {
699 const auto putMetadataHeader = [](MetadataWriter& writer,
700 const StandardMetadataType standardMetadataType) -> MetadataWriter& {
701 return writer.write(kStandardMetadataTypeTag)
702 .write(static_cast<int64_t>(standardMetadataType));
703 };
704
705 const CbExternalMetadata& metadata = getExternalMetadata(cb);
706 switch (standardMetadataType) {
707 case StandardMetadataType::BUFFER_ID:
708 putMetadataHeader(writer, standardMetadataType)
709 .write<uint64_t>(metadata.bufferID);
710 break;
711
712 case StandardMetadataType::NAME:
713 putMetadataHeader(writer, standardMetadataType)
714 .write(std::string_view(metadata.name, metadata.nameSize));
715 break;
716
717 case StandardMetadataType::WIDTH:
718 putMetadataHeader(writer, standardMetadataType)
719 .write<uint64_t>(metadata.width);
720 break;
721
722 case StandardMetadataType::HEIGHT:
723 putMetadataHeader(writer, standardMetadataType)
724 .write<uint64_t>(metadata.height);
725 break;
726
727 case StandardMetadataType::LAYER_COUNT:
728 putMetadataHeader(writer, standardMetadataType)
729 .write<uint64_t>(1);
730 break;
731
732 case StandardMetadataType::PIXEL_FORMAT_REQUESTED:
733 putMetadataHeader(writer, standardMetadataType)
734 .write<uint32_t>(cb.format);
735 break;
736
737 case StandardMetadataType::PIXEL_FORMAT_FOURCC:
738 putMetadataHeader(writer, standardMetadataType)
739 .write<uint32_t>(cb.drmformat);
740 break;
741
742 case StandardMetadataType::PIXEL_FORMAT_MODIFIER:
743 putMetadataHeader(writer, standardMetadataType)
744 .write<uint64_t>(DRM_FORMAT_MOD_LINEAR);
745 break;
746
747 case StandardMetadataType::USAGE:
748 putMetadataHeader(writer, standardMetadataType)
749 .write<uint64_t>(cb.usage);
750 break;
751
752 case StandardMetadataType::ALLOCATION_SIZE:
753 putMetadataHeader(writer, standardMetadataType)
754 .write<uint64_t>(cb.mmapedSize);
755 break;
756
757 case StandardMetadataType::PROTECTED_CONTENT:
758 putMetadataHeader(writer, standardMetadataType)
759 .write<uint64_t>((cb.usage & static_cast<uint64_t>(BufferUsage::PROTECTED))
760 ? 1 : 0);
761 break;
762
763 case StandardMetadataType::COMPRESSION:
764 putMetadataHeader(writer, standardMetadataType)
765 .write(kCompressionTag)
766 .write(static_cast<int64_t>(aahgc::Compression::NONE));
767 break;
768
769 case StandardMetadataType::INTERLACED:
770 putMetadataHeader(writer, standardMetadataType)
771 .write(kInterlacedTag)
772 .write(static_cast<int64_t>(aahgc::Interlaced::NONE));
773 break;
774
775 case StandardMetadataType::CHROMA_SITING:
776 putMetadataHeader(writer, standardMetadataType)
777 .write(kChromaSitingTag)
778 .write(static_cast<int64_t>(getFormatChromaSiting(getPixelFormat(cb))));
779 break;
780
781 case StandardMetadataType::PLANE_LAYOUTS: {
782 const unsigned planeLayoutSize = metadata.planeLayoutSize;
783 if (!planeLayoutSize) {
784 return -AIMAPPER_ERROR_UNSUPPORTED;
785 }
786 const PlaneLayoutComponent* const layoutComponents =
787 metadata.planeLayoutComponent;
788
789 putMetadataHeader(writer, standardMetadataType)
790 .write<int64_t>(planeLayoutSize);
791 for (unsigned plane = 0; plane < planeLayoutSize; ++plane) {
792 const auto& planeLayout = metadata.planeLayout[plane];
793 unsigned n = planeLayout.componentsSize;
794 const PlaneLayoutComponent* component =
795 layoutComponents + planeLayout.componentsBase;
796
797 writer.write<int64_t>(n);
798 for (; n > 0; --n, ++component) {
799 writer.write(kPlaneLayoutComponentTypeTag)
800 .write<int64_t>(component->type)
801 .write<int64_t>(component->offsetInBits)
802 .write<int64_t>(component->sizeInBits);
803 }
804
805 const unsigned horizontalSubsampling =
806 (1U << planeLayout.horizontalSubsamplingShift);
807 const unsigned verticalSubsampling =
808 (1U << planeLayout.verticalSubsamplingShift);
809
810 writer.write<int64_t>(planeLayout.offsetInBytes)
811 .write<int64_t>(planeLayout.sampleIncrementInBytes * CHAR_BIT)
812 .write<int64_t>(planeLayout.strideInBytes)
813 .write<int64_t>(metadata.width / horizontalSubsampling)
814 .write<int64_t>(metadata.height / verticalSubsampling)
815 .write<int64_t>(planeLayout.totalSizeInBytes)
816 .write<int64_t>(horizontalSubsampling)
817 .write<int64_t>(verticalSubsampling);
818 }
819 }
820 break;
821
822 case StandardMetadataType::CROP: {
823 unsigned planeLayoutSize = metadata.planeLayoutSize;
824 if (!planeLayoutSize) {
825 return -AIMAPPER_ERROR_UNSUPPORTED;
826 }
827
828 putMetadataHeader(writer, standardMetadataType)
829 .write<uint64_t>(planeLayoutSize);
830 for (; planeLayoutSize > 0; --planeLayoutSize) {
831 /*
832 * b/359690632: `width`,`height` and `CROP` are uint64_t
833 * in the spec. But the metadata parser in Android uses
834 * int32_t for `CROP`.
835 */
836 writer.write<int32_t>(0).write<int32_t>(0)
837 .write<int32_t>(metadata.width)
838 .write<int32_t>(metadata.height);
839 }
840 }
841 break;
842
843 case StandardMetadataType::DATASPACE:
844 putMetadataHeader(writer, standardMetadataType)
845 .write<int32_t>(metadata.dataspace);
846 break;
847
848 case StandardMetadataType::BLEND_MODE:
849 putMetadataHeader(writer, standardMetadataType)
850 .write<int32_t>(metadata.blendMode);
851 break;
852
853 case StandardMetadataType::SMPTE2086:
854 if (metadata.has_smpte2086) {
855 const auto& smpte2086 = metadata.smpte2086;
856 putMetadataHeader(writer, standardMetadataType)
857 .write(smpte2086.primaryRed.x).write(smpte2086.primaryRed.y)
858 .write(smpte2086.primaryGreen.x).write(smpte2086.primaryGreen.y)
859 .write(smpte2086.primaryBlue.x).write(smpte2086.primaryBlue.y)
860 .write(smpte2086.whitePoint.x).write(smpte2086.whitePoint.y)
861 .write(smpte2086.maxLuminance).write(smpte2086.minLuminance);
862 }
863 break;
864
865 case StandardMetadataType::CTA861_3:
866 if (metadata.has_cta861_3) {
867 const auto& cta861_3 = metadata.cta861_3;
868 putMetadataHeader(writer, standardMetadataType)
869 .write(cta861_3.maxContentLightLevel)
870 .write(cta861_3.maxFrameAverageLightLevel);
871 }
872 break;
873
874 case StandardMetadataType::STRIDE: {
875 const uint32_t value = (metadata.planeLayoutSize == 1) ?
876 (metadata.planeLayout[0].strideInBytes /
877 metadata.planeLayout[0].sampleIncrementInBytes) : 0;
878
879 putMetadataHeader(writer, standardMetadataType).write(value);
880 }
881 break;
882
883 default:
884 return -FAILURE_V(AIMAPPER_ERROR_UNSUPPORTED,
885 "%s: id=%" PRIu64 ": unexpected standardMetadataType=%" PRId64,
886 "UNSUPPORTED", metadata.bufferID, static_cast<int64_t>(standardMetadataType));
887 }
888
889 return writer.desiredSize();
890 }
891
setStandardMetadataImpl__anon555456480111::GoldfishMapper892 AIMapper_Error setStandardMetadataImpl(const cb_handle_t& cb, MetadataReader reader,
893 const StandardMetadataType standardMetadataType) const {
894 const auto checkMetadataHeader = [](MetadataReader& reader,
895 const StandardMetadataType standardMetadataType) {
896 if (reader.readString().compare(kStandardMetadataTypeTag)) {
897 return false;
898 }
899
900 const std::optional<int64_t> type = reader.readInt<int64_t>();
901 return type.has_value() &&
902 (type == static_cast<int64_t>(standardMetadataType)) &&
903 reader.ok();
904 };
905
906 CbExternalMetadata& metadata = getExternalMetadata(cb);
907 switch (standardMetadataType) {
908 case StandardMetadataType::DATASPACE:
909 if (!checkMetadataHeader(reader, standardMetadataType)) {
910 return FAILURE_V(AIMAPPER_ERROR_BAD_VALUE, "%s: id=%" PRIu64 ": %s",
911 "BAD_VALUE", metadata.bufferID, "DATASPACE");
912 }
913
914 reader.read(metadata.dataspace);
915 if (!reader.ok()) {
916 return FAILURE_V(AIMAPPER_ERROR_BAD_VALUE, "%s: id=%" PRIu64 ": %s",
917 "BAD_VALUE", metadata.bufferID, "DATASPACE");
918 }
919 break;
920
921 case StandardMetadataType::BLEND_MODE:
922 if (!checkMetadataHeader(reader, standardMetadataType)) {
923 return FAILURE_V(AIMAPPER_ERROR_BAD_VALUE, "%s: id=%" PRIu64 ": %s",
924 "BAD_VALUE", metadata.bufferID, "BLEND_MODE");
925 }
926 reader.read(metadata.blendMode);
927 if (!reader.ok()) {
928 return FAILURE_V(AIMAPPER_ERROR_BAD_VALUE, "%s: id=%" PRIu64 ": %s",
929 "BAD_VALUE", metadata.bufferID, "BLEND_MODE");
930 }
931 break;
932
933 case StandardMetadataType::SMPTE2086:
934 if (reader.remaining() > 0) {
935 if (!checkMetadataHeader(reader, standardMetadataType)) {
936 return FAILURE_V(AIMAPPER_ERROR_BAD_VALUE, "%s: id=%" PRIu64 ": %s",
937 "BAD_VALUE", metadata.bufferID, "SMPTE2086");
938 }
939
940 CbExternalMetadata::Smpte2086 smpte2086;
941 reader.read(smpte2086.primaryRed.x).read(smpte2086.primaryRed.y)
942 .read(smpte2086.primaryGreen.x).read(smpte2086.primaryGreen.y)
943 .read(smpte2086.primaryBlue.x).read(smpte2086.primaryBlue.y)
944 .read(smpte2086.whitePoint.x).read(smpte2086.whitePoint.y)
945 .read(smpte2086.maxLuminance).read(smpte2086.minLuminance);
946 if (reader.ok()) {
947 metadata.smpte2086 = smpte2086;
948 metadata.has_smpte2086 = true;
949 } else {
950 return FAILURE_V(AIMAPPER_ERROR_BAD_VALUE, "%s: id=%" PRIu64 ": %s",
951 "BAD_VALUE", metadata.bufferID, "SMPTE2086");
952 }
953 } else {
954 metadata.has_smpte2086 = false;
955 }
956 break;
957
958 case StandardMetadataType::CTA861_3:
959 if (reader.remaining() > 0) {
960 if (!checkMetadataHeader(reader, standardMetadataType)) {
961 return FAILURE_V(AIMAPPER_ERROR_BAD_VALUE, "%s: id=%" PRIu64 ": %s",
962 "BAD_VALUE", metadata.bufferID, "CTA861_3");
963 }
964
965 CbExternalMetadata::Cta861_3 cta861_3;
966 reader.read(cta861_3.maxContentLightLevel)
967 .read(cta861_3.maxFrameAverageLightLevel);
968 if (reader.ok()) {
969 metadata.cta861_3 = cta861_3;
970 metadata.has_cta861_3 = true;
971 } else {
972 return FAILURE_V(AIMAPPER_ERROR_BAD_VALUE, "%s: id=%" PRIu64 ": %s",
973 "BAD_VALUE", metadata.bufferID, "CTA861_3");
974 }
975 } else {
976 metadata.has_cta861_3 = false;
977 }
978 break;
979
980 default:
981 return FAILURE_V(AIMAPPER_ERROR_UNSUPPORTED,
982 "%s: id=%" PRIu64 ": standardMetadataType=%" PRId64,
983 "UNSUPPORTED", metadata.bufferID, static_cast<int64_t>(standardMetadataType));
984 }
985
986 return AIMAPPER_ERROR_NONE;
987 }
988
listSupportedMetadataTypes__anon555456480111::GoldfishMapper989 static AIMapper_Error listSupportedMetadataTypes(
990 const AIMapper_MetadataTypeDescription** outDescriptionList,
991 size_t* outNumberOfDescriptions) {
992 *outDescriptionList = kMetadataTypeDescriptionList;
993 *outNumberOfDescriptions = arraySize(kMetadataTypeDescriptionList);
994 return AIMAPPER_ERROR_NONE;
995 }
996
dumpBuffer__anon555456480111::GoldfishMapper997 AIMapper_Error dumpBuffer(const buffer_handle_t buffer,
998 const AIMapper_DumpBufferCallback dumpBufferCallback,
999 void* const context) const {
1000 const cb_handle_t* const cb = validateCb(buffer);
1001 if (!cb) {
1002 return FAILURE(AIMAPPER_ERROR_BAD_BUFFER);
1003 }
1004
1005 if (mDebugLevel >= DebugLevel::METADATA) {
1006 ALOGD("%s:%d: id=%" PRIu64, __func__, __LINE__, getID(*cb));
1007 }
1008
1009 std::vector<uint8_t> metadataBuffer(kMetadataBufferInitialSize);
1010 dumpBufferImpl(*cb, dumpBufferCallback, context, metadataBuffer);
1011 return AIMAPPER_ERROR_NONE;
1012 }
1013
dumpBufferImpl__anon555456480111::GoldfishMapper1014 void dumpBufferImpl(const cb_handle_t& cb,
1015 const AIMapper_DumpBufferCallback dumpBufferCallback,
1016 void* const context,
1017 std::vector<uint8_t>& metadataBuffer) const {
1018 for (const auto& m : kMetadataTypeDescriptionList) {
1019 if (m.isGettable) {
1020 bool firstTry = true;
1021 retryWithLargerBuffer:
1022 MetadataWriter writer(metadataBuffer.data(), metadataBuffer.size());
1023 const int32_t desiredSize = getStandardMetadataImpl(cb, writer,
1024 static_cast<StandardMetadataType>(m.metadataType.value));
1025 if (desiredSize < 0) {
1026 // should not happen, update `getStandardMetadata`
1027 continue;
1028 } else if (desiredSize <= metadataBuffer.size()) {
1029 (*dumpBufferCallback)(context, m.metadataType,
1030 metadataBuffer.data(), desiredSize);
1031 } else {
1032 LOG_ALWAYS_FATAL_IF(!firstTry);
1033 metadataBuffer.resize(desiredSize);
1034 firstTry = false;
1035 goto retryWithLargerBuffer;
1036 }
1037 }
1038 }
1039 }
1040
dumpAllBuffers__anon555456480111::GoldfishMapper1041 AIMapper_Error dumpAllBuffers(const AIMapper_BeginDumpBufferCallback beginDumpCallback,
1042 const AIMapper_DumpBufferCallback dumpBufferCallback,
1043 void* const context) const {
1044 std::vector<uint8_t> metadataBuffer(kMetadataBufferInitialSize);
1045
1046 std::lock_guard<std::mutex> lock(mImportedBuffersMtx);
1047 for (const cb_handle_t* const cb : mImportedBuffers) {
1048 (*beginDumpCallback)(context);
1049 dumpBufferImpl(*cb, dumpBufferCallback, context, metadataBuffer);
1050 }
1051
1052 return AIMAPPER_ERROR_NONE;
1053 }
1054
getReservedRegion__anon555456480111::GoldfishMapper1055 AIMapper_Error getReservedRegion(const buffer_handle_t buffer,
1056 void** const outReservedRegion,
1057 uint64_t* const outReservedSize) const {
1058 const cb_handle_t* const cb = validateCb(buffer);
1059 if (!cb) {
1060 return FAILURE(AIMAPPER_ERROR_BAD_BUFFER);
1061 }
1062
1063 CbExternalMetadata& metadata = getExternalMetadata(*cb);
1064 const size_t reservedRegionSize = metadata.reservedRegionSize;
1065 if (reservedRegionSize) {
1066 *outReservedRegion = &metadata + 1; // right after `CbExternalMetadata`
1067 } else {
1068 *outReservedRegion = nullptr;
1069 }
1070 *outReservedSize = reservedRegionSize;
1071 return AIMAPPER_ERROR_NONE;
1072 }
1073
validateCb__anon555456480111::GoldfishMapper1074 cb_handle_t* validateCb(const buffer_handle_t buffer) const {
1075 cb_handle_t* cb = const_cast<cb_handle_t*>(static_cast<const cb_handle_t*>(buffer));
1076 std::lock_guard<std::mutex> lock(mImportedBuffersMtx);
1077 return mImportedBuffers.count(cb) ? cb : nullptr;
1078 }
1079
getHostConnectionSession__anon555456480111::GoldfishMapper1080 HostConnectionSession getHostConnectionSession() const {
1081 return HostConnectionSession(mHostConn.get());
1082 }
1083
getMmapedPhysAddr__anon555456480111::GoldfishMapper1084 uint64_t getMmapedPhysAddr(const uint64_t offset) const {
1085 return mPhysAddrToOffset + offset;
1086 }
1087
1088 AIMapper mMapper;
1089 const std::unique_ptr<HostConnection> mHostConn;
1090 std::unordered_set<const cb_handle_t*> mImportedBuffers;
1091 uint64_t mPhysAddrToOffset;
1092 mutable std::mutex mImportedBuffersMtx;
1093 const DebugLevel mDebugLevel;
1094 };
1095 } // namespace
1096
1097 extern "C" uint32_t ANDROID_HAL_MAPPER_VERSION = AIMAPPER_VERSION_5;
1098
AIMapper_loadIMapper(AIMapper * _Nullable * _Nonnull outImplementation)1099 extern "C" AIMapper_Error AIMapper_loadIMapper(AIMapper* _Nullable* _Nonnull outImplementation) {
1100 static GoldfishMapper instance;
1101 *outImplementation = &instance.getAIMapper();
1102 return AIMAPPER_ERROR_NONE;
1103 }
1104