1 /*
2 * Copyright (C) 2020 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 <android/hardware/graphics/mapper/3.0/IMapper.h>
18 #include <cutils/native_handle.h>
19 #include <sync/sync.h>
20
21 #include "cb_handle_30.h"
22 #include "host_connection_session.h"
23 #include "FormatConversions.h"
24 #include "debug.h"
25
26 #include "android/base/Tracing.h"
27
28 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
29
30 const int kOMX_COLOR_FormatYUV420Planar = 19;
31
32 using ::android::hardware::hidl_handle;
33 using ::android::hardware::hidl_vec;
34 using ::android::hardware::Return;
35 using ::android::hardware::Void;
36
37 using ::android::hardware::graphics::common::V1_2::PixelFormat;
38 using ::android::hardware::graphics::common::V1_0::BufferUsage;
39
40 namespace MapperV3 = ::android::hardware::graphics::mapper::V3_0;
41
42 using IMapper3 = MapperV3::IMapper;
43 using Error3 = MapperV3::Error;
44 using YCbCrLayout3 = MapperV3::YCbCrLayout;
45
46 namespace {
align(const size_t v,const size_t a)47 size_t align(const size_t v, const size_t a) { return (v + a - 1) & ~(a - 1); }
48
waitFenceFd(const int fd,const char * logname)49 static int waitFenceFd(const int fd, const char* logname) {
50 const int warningTimeout = 5000;
51 if (sync_wait(fd, warningTimeout) < 0) {
52 if (errno == ETIME) {
53 ALOGW("%s: fence %d didn't signal in %d ms", logname, fd, warningTimeout);
54 if (sync_wait(fd, -1) < 0) {
55 RETURN_ERROR(errno);
56 } else {
57 RETURN(0);
58 }
59 } else {
60 RETURN_ERROR(errno);
61 }
62 } else {
63 RETURN(0);
64 }
65 }
66
waitHidlFence(const hidl_handle & hidlHandle,const char * logname)67 int waitHidlFence(const hidl_handle& hidlHandle, const char* logname) {
68 const native_handle_t* nativeHandle = hidlHandle.getNativeHandle();
69
70 if (!nativeHandle) {
71 RETURN(0);
72 }
73 if (nativeHandle->numFds > 1) {
74 RETURN_ERROR(-EINVAL);
75 }
76 if (nativeHandle->numInts != 0) {
77 RETURN_ERROR(-EINVAL);
78 }
79
80 return waitFenceFd(nativeHandle->data[0], logname);
81 }
82
83 constexpr uint64_t one64 = 1;
84
ones(int from,int to)85 constexpr uint64_t ones(int from, int to) {
86 return ((one64 << (to - from + 1)) - 1) << from;
87 }
88
89 class GoldfishMapper : public IMapper3 {
90 public:
GoldfishMapper()91 GoldfishMapper() : m_hostConn(HostConnection::createUnique()) {
92 GoldfishAddressSpaceHostMemoryAllocator host_memory_allocator(false);
93 CRASH_IF(!host_memory_allocator.is_opened(),
94 "GoldfishAddressSpaceHostMemoryAllocator failed to open");
95
96 GoldfishAddressSpaceBlock bufferBits;
97 CRASH_IF(host_memory_allocator.hostMalloc(&bufferBits, 256),
98 "hostMalloc failed");
99
100 m_physAddrToOffset = bufferBits.physAddr() - bufferBits.offset();
101
102 host_memory_allocator.hostFree(&bufferBits);
103 }
104
importBuffer(const hidl_handle & hh,importBuffer_cb hidl_cb)105 Return<void> importBuffer(const hidl_handle& hh,
106 importBuffer_cb hidl_cb) {
107 native_handle_t* imported = nullptr;
108 const Error3 e = importBufferImpl(hh.getNativeHandle(), &imported);
109 if (e == Error3::NONE) {
110 hidl_cb(Error3::NONE, imported);
111 } else {
112 hidl_cb(e, nullptr);
113 }
114 return {};
115 }
116
freeBuffer(void * raw)117 Return<Error3> freeBuffer(void* raw) {
118 if (!raw) {
119 RETURN_ERROR(Error3::BAD_BUFFER);
120 }
121 cb_handle_30_t* cb = cb_handle_30_t::from(raw);
122 if (!cb) {
123 RETURN_ERROR(Error3::BAD_BUFFER);
124 }
125
126 if (cb->hostHandle) {
127 const HostConnectionSession conn = getHostConnectionSession();
128 ExtendedRCEncoderContext *const rcEnc = conn.getRcEncoder();
129 rcEnc->rcCloseColorBuffer(rcEnc, cb->hostHandle);
130 }
131
132 if (cb->mmapedSize > 0) {
133 GoldfishAddressSpaceBlock::memoryUnmap(cb->getBufferPtr(), cb->mmapedSize);
134 }
135
136 native_handle_close(cb);
137 native_handle_delete(cb);
138
139 RETURN(Error3::NONE);
140 }
141
lock(void * raw,uint64_t cpuUsage,const Rect & accessRegion,const hidl_handle & acquireFence,lock_cb hidl_cb)142 Return<void> lock(void* raw,
143 uint64_t cpuUsage,
144 const Rect& accessRegion,
145 const hidl_handle& acquireFence,
146 lock_cb hidl_cb) {
147 void* ptr = nullptr;
148 int32_t bytesPerPixel = 0;
149 int32_t bytesPerStride = 0;
150
151 const Error3 e = lockImpl(raw, cpuUsage, accessRegion, acquireFence,
152 &ptr, &bytesPerPixel, &bytesPerStride);
153 if (e == Error3::NONE) {
154 hidl_cb(Error3::NONE, ptr, bytesPerPixel, bytesPerStride);
155 } else {
156 hidl_cb(e, nullptr, 0, 0);
157 }
158 return {};
159 }
160
lockYCbCr(void * raw,uint64_t cpuUsage,const Rect & accessRegion,const hidl_handle & acquireFence,lockYCbCr_cb hidl_cb)161 Return<void> lockYCbCr(void* raw,
162 uint64_t cpuUsage,
163 const Rect& accessRegion,
164 const hidl_handle& acquireFence,
165 lockYCbCr_cb hidl_cb) {
166 YCbCrLayout3 ycbcr = {};
167 const Error3 e = lockYCbCrImpl(raw, cpuUsage, accessRegion, acquireFence,
168 &ycbcr);
169 if (e == Error3::NONE) {
170 hidl_cb(Error3::NONE, ycbcr);
171 } else {
172 hidl_cb(e, {});
173 }
174 return {};
175 }
176
unlock(void * raw,unlock_cb hidl_cb)177 Return<void> unlock(void* raw, unlock_cb hidl_cb) {
178 hidl_cb(unlockImpl(raw), {});
179 return {};
180
181 }
182
createDescriptor(const BufferDescriptorInfo & description,createDescriptor_cb hidl_cb)183 Return<void> createDescriptor(const BufferDescriptorInfo& description,
184 createDescriptor_cb hidl_cb) {
185 hidl_vec<uint32_t> raw;
186 encodeBufferDescriptorInfo(description, &raw);
187 hidl_cb(Error3::NONE, raw);
188 return {};
189 }
190
isSupported(const IMapper::BufferDescriptorInfo & description,isSupported_cb hidl_cb)191 Return<void> isSupported(const IMapper::BufferDescriptorInfo& description,
192 isSupported_cb hidl_cb) {
193 hidl_cb(Error3::NONE, isSupportedImpl(description));
194 return {};
195 }
196
validateBufferSize(void * buffer,const BufferDescriptorInfo & descriptor,uint32_t stride)197 Return<Error3> validateBufferSize(void* buffer,
198 const BufferDescriptorInfo& descriptor,
199 uint32_t stride) {
200 const cb_handle_30_t* cb = cb_handle_30_t::from(buffer);
201 if (cb) {
202 return validateBufferSizeImpl(*cb, descriptor, stride);
203 } else {
204 RETURN_ERROR(Error3::BAD_BUFFER);
205 }
206 }
207
getTransportSize(void * buffer,getTransportSize_cb hidl_cb)208 Return<void> getTransportSize(void* buffer,
209 getTransportSize_cb hidl_cb) {
210 const cb_handle_30_t* cb = cb_handle_30_t::from(buffer);
211 if (cb) {
212 hidl_cb(Error3::NONE, cb->numFds, cb->numInts);
213 } else {
214 hidl_cb(Error3::BAD_BUFFER, 0, 0);
215 }
216
217 return {};
218 }
219
220 private: // **** impl ****
importBufferImpl(const native_handle_t * nh,native_handle_t ** phandle)221 Error3 importBufferImpl(const native_handle_t* nh, native_handle_t** phandle) {
222 if (!nh) {
223 RETURN_ERROR(Error3::BAD_BUFFER);
224 }
225 native_handle_t* imported = native_handle_clone(nh);
226 if (!imported) {
227 RETURN_ERROR(Error3::BAD_BUFFER);
228 }
229 cb_handle_30_t* cb = cb_handle_30_t::from(imported);
230 if (!cb) {
231 native_handle_close(imported);
232 native_handle_delete(imported);
233 RETURN_ERROR(Error3::BAD_BUFFER);
234 }
235
236 if (cb->mmapedSize > 0) {
237 void* ptr;
238 const int res = GoldfishAddressSpaceBlock::memoryMap(
239 cb->getBufferPtr(),
240 cb->mmapedSize,
241 cb->bufferFd,
242 cb->getMmapedOffset(),
243 &ptr);
244 if (res) {
245 native_handle_close(imported);
246 native_handle_delete(imported);
247 RETURN_ERROR(Error3::NO_RESOURCES);
248 }
249 cb->setBufferPtr(ptr);
250 }
251
252 if (cb->hostHandle) {
253 const HostConnectionSession conn = getHostConnectionSession();
254 ExtendedRCEncoderContext *const rcEnc = conn.getRcEncoder();
255 rcEnc->rcOpenColorBuffer2(rcEnc, cb->hostHandle);
256 }
257
258 *phandle = imported;
259 RETURN(Error3::NONE);
260 }
261
lockImpl(void * raw,uint64_t cpuUsage,const Rect & accessRegion,const hidl_handle & acquireFence,void ** pptr,int32_t * pBytesPerPixel,int32_t * pBytesPerStride)262 Error3 lockImpl(void* raw,
263 uint64_t cpuUsage,
264 const Rect& accessRegion,
265 const hidl_handle& acquireFence,
266 void** pptr,
267 int32_t* pBytesPerPixel,
268 int32_t* pBytesPerStride) {
269 if (!raw) {
270 RETURN_ERROR(Error3::BAD_BUFFER);
271 }
272 cb_handle_30_t* cb = cb_handle_30_t::from(raw);
273 if (!cb) {
274 RETURN_ERROR(Error3::BAD_BUFFER);
275 }
276 if (!cb->bufferSize) {
277 RETURN_ERROR(Error3::BAD_BUFFER);
278 }
279 char* const bufferBits = static_cast<char*>(cb->getBufferPtr());
280 if (!bufferBits) {
281 RETURN_ERROR(Error3::BAD_BUFFER);
282 }
283 if (waitHidlFence(acquireFence, __func__)) {
284 RETURN_ERROR(Error3::BAD_VALUE);
285 }
286
287 if (cb->hostHandle) {
288 const Error3 e = lockHostImpl(*cb, cpuUsage, accessRegion, bufferBits);
289 if (e != Error3::NONE) {
290 return e;
291 }
292 }
293
294 *pptr = bufferBits;
295 *pBytesPerPixel = cb->bytesPerPixel;
296 *pBytesPerStride = cb->bytesPerPixel * cb->stride;
297 RETURN(Error3::NONE);
298 }
299
lockYCbCrImpl(void * raw,uint64_t cpuUsage,const Rect & accessRegion,const hidl_handle & acquireFence,YCbCrLayout3 * pYcbcr)300 Error3 lockYCbCrImpl(void* raw,
301 uint64_t cpuUsage,
302 const Rect& accessRegion,
303 const hidl_handle& acquireFence,
304 YCbCrLayout3* pYcbcr) {
305 if (!raw) {
306 RETURN_ERROR(Error3::BAD_BUFFER);
307 }
308 cb_handle_30_t* cb = cb_handle_30_t::from(raw);
309 if (!cb) {
310 RETURN_ERROR(Error3::BAD_BUFFER);
311 }
312 if (!cb->bufferSize) {
313 RETURN_ERROR(Error3::BAD_BUFFER);
314 }
315 char* const bufferBits = static_cast<char*>(cb->getBufferPtr());
316 if (!bufferBits) {
317 RETURN_ERROR(Error3::BAD_BUFFER);
318 }
319 if (waitHidlFence(acquireFence, __func__)) {
320 RETURN_ERROR(Error3::BAD_VALUE);
321 }
322
323 size_t uOffset;
324 size_t vOffset;
325 size_t yStride;
326 size_t cStride;
327 size_t cStep;
328 switch (static_cast<PixelFormat>(cb->format)) {
329 case PixelFormat::YCRCB_420_SP:
330 yStride = cb->width;
331 cStride = yStride;
332 vOffset = yStride * cb->height;
333 uOffset = vOffset + 1;
334 cStep = 2;
335 break;
336
337 case PixelFormat::YV12:
338 // https://developer.android.com/reference/android/graphics/ImageFormat.html#YV12
339 yStride = align(cb->width, 16);
340 cStride = align(yStride / 2, 16);
341 vOffset = yStride * cb->height;
342 uOffset = vOffset + (cStride * cb->height / 2);
343 cStep = 1;
344 break;
345
346 case PixelFormat::YCBCR_420_888:
347 yStride = cb->width;
348 cStride = yStride / 2;
349 uOffset = cb->height * yStride;
350 vOffset = uOffset + cStride * cb->height / 2;
351 cStep = 1;
352 break;
353
354 default:
355 if (static_cast<android::hardware::graphics::common::V1_1::PixelFormat>(cb->format) ==
356 android::hardware::graphics::common::V1_1::PixelFormat::YCBCR_P010) {
357 yStride = cb->width * 2;
358 cStride = yStride;
359 uOffset = cb->height * yStride;
360 vOffset = uOffset + 2;
361 cStep = 4;
362 break;
363 }
364
365 ALOGE("%s:%d unexpected format (%d)", __func__, __LINE__, cb->format);
366 RETURN_ERROR(Error3::BAD_BUFFER);
367 }
368
369 if (cb->hostHandle) {
370 const Error3 e = lockHostImpl(*cb, cpuUsage, accessRegion, bufferBits);
371 if (e != Error3::NONE) {
372 return e;
373 }
374 }
375
376 pYcbcr->y = bufferBits;
377 pYcbcr->cb = bufferBits + uOffset;
378 pYcbcr->cr = bufferBits + vOffset;
379 pYcbcr->yStride = yStride;
380 pYcbcr->cStride = cStride;
381 pYcbcr->chromaStep = cStep;
382
383 RETURN(Error3::NONE);
384 }
385
lockHostImpl(cb_handle_30_t & cb,const uint32_t usage,const Rect & accessRegion,char * const bufferBits)386 Error3 lockHostImpl(cb_handle_30_t& cb,
387 const uint32_t usage,
388 const Rect& accessRegion,
389 char* const bufferBits) {
390 const bool usageSwRead = usage & BufferUsage::CPU_READ_MASK;
391 const bool usageSwWrite = usage & BufferUsage::CPU_WRITE_MASK;
392 const bool usageHwCamera = usage & (BufferUsage::CAMERA_INPUT | BufferUsage::CAMERA_OUTPUT);
393 const bool usageHwCameraWrite = usage & BufferUsage::CAMERA_OUTPUT;
394
395 const HostConnectionSession conn = getHostConnectionSession();
396 ExtendedRCEncoderContext *const rcEnc = conn.getRcEncoder();
397
398 const int res = rcEnc->rcColorBufferCacheFlush(
399 rcEnc, cb.hostHandle, 0, usageSwRead);
400 if (res < 0) {
401 RETURN_ERROR(Error3::NO_RESOURCES);
402 }
403
404 // camera delivers bits to the buffer directly and does not require
405 // an explicit read.
406 const bool cbReadable = cb.usage & BufferUsage::CPU_READ_MASK;
407 if (usageSwRead && !usageHwCamera && cbReadable) {
408 if (gralloc_is_yuv_format(cb.format)) {
409 if (rcEnc->hasYUVCache()) {
410 uint32_t bufferSize;
411 switch (static_cast<PixelFormat>(cb.format)) {
412 case PixelFormat::YV12:
413 get_yv12_offsets(cb.width, cb.height,
414 nullptr, nullptr, &bufferSize);
415 break;
416 case PixelFormat::YCBCR_420_888:
417 get_yuv420p_offsets(cb.width, cb.height,
418 nullptr, nullptr, &bufferSize);
419 break;
420 default:
421 CRASH("Unexpected format, switch is out of sync with gralloc_is_yuv_format");
422 break;
423 }
424
425 rcEnc->rcReadColorBufferYUV(rcEnc, cb.hostHandle,
426 0, 0, cb.width, cb.height,
427 bufferBits, bufferSize);
428 } else {
429 // We are using RGB888
430 std::vector<char> tmpBuf(cb.width * cb.height * 3);
431 rcEnc->rcReadColorBuffer(rcEnc, cb.hostHandle,
432 0, 0, cb.width, cb.height,
433 cb.glFormat, cb.glType,
434 tmpBuf.data());
435 switch (static_cast<PixelFormat>(cb.format)) {
436 case PixelFormat::YV12:
437 rgb888_to_yv12(bufferBits, tmpBuf.data(),
438 cb.width, cb.height,
439 accessRegion.left,
440 accessRegion.top,
441 accessRegion.left + accessRegion.width - 1,
442 accessRegion.top + accessRegion.height - 1);
443 break;
444 case PixelFormat::YCBCR_420_888:
445 rgb888_to_yuv420p(bufferBits, tmpBuf.data(),
446 cb.width, cb.height,
447 accessRegion.left,
448 accessRegion.top,
449 accessRegion.left + accessRegion.width - 1,
450 accessRegion.top + accessRegion.height - 1);
451 break;
452 default:
453 CRASH("Unexpected format, switch is out of sync with gralloc_is_yuv_format");
454 break;
455 }
456 }
457 } else {
458 if (rcEnc->featureInfo()->hasReadColorBufferDma) {
459 {
460 AEMU_SCOPED_TRACE("bindDmaDirectly");
461 rcEnc->bindDmaDirectly(bufferBits,
462 getMmapedPhysAddr(cb.getMmapedOffset()));
463 }
464 rcEnc->rcReadColorBufferDMA(rcEnc,
465 cb.hostHandle,
466 0, 0, cb.width, cb.height,
467 cb.glFormat, cb.glType,
468 bufferBits, cb.width * cb.height * cb.bytesPerPixel);
469 } else {
470 rcEnc->rcReadColorBuffer(rcEnc,
471 cb.hostHandle,
472 0, 0, cb.width, cb.height,
473 cb.glFormat, cb.glType,
474 bufferBits);
475 }
476 }
477 }
478
479 if (usageSwWrite || usageHwCameraWrite) {
480 cb.lockedLeft = accessRegion.left;
481 cb.lockedTop = accessRegion.top;
482 cb.lockedWidth = accessRegion.width;
483 cb.lockedHeight = accessRegion.height;
484 } else {
485 cb.lockedLeft = 0;
486 cb.lockedTop = 0;
487 cb.lockedWidth = cb.width;
488 cb.lockedHeight = cb.height;
489 }
490
491 cb.locked = 1;
492 cb.lockedUsage = usage;
493
494 RETURN(Error3::NONE);
495 }
496
unlockImpl(void * raw)497 Error3 unlockImpl(void* raw) {
498 AEMU_SCOPED_TRACE("unlockImpl body");
499 if (!raw) {
500 RETURN_ERROR(Error3::BAD_BUFFER);
501 }
502 cb_handle_30_t* cb = cb_handle_30_t::from(raw);
503 if (!cb) {
504 RETURN_ERROR(Error3::BAD_BUFFER);
505 }
506 if (!cb->bufferSize) {
507 RETURN_ERROR(Error3::BAD_BUFFER);
508 }
509 char* const bufferBits = static_cast<char*>(cb->getBufferPtr());
510 if (!bufferBits) {
511 RETURN_ERROR(Error3::BAD_BUFFER);
512 }
513
514 if (cb->hostHandle) {
515 unlockHostImpl(*cb, bufferBits);
516 }
517
518 RETURN(Error3::NONE);
519 }
520
unlockHostImpl(cb_handle_30_t & cb,char * const bufferBits)521 void unlockHostImpl(cb_handle_30_t& cb, char* const bufferBits) {
522 AEMU_SCOPED_TRACE("unlockHostImpl body");
523 const int bpp = glUtilsPixelBitSize(cb.glFormat, cb.glType) >> 3;
524 const uint32_t lockedUsage = cb.lockedUsage;
525 const uint32_t rgbSize = cb.width * cb.height * bpp;
526 const char* bitsToSend;
527 uint32_t sizeToSend;
528
529 const uint32_t usageSwWrite = (uint32_t)BufferUsage::CPU_WRITE_MASK;
530 uint32_t readOnly = (!(lockedUsage & usageSwWrite));
531
532 if (!readOnly) {
533 if (gralloc_is_yuv_format(cb.format)) {
534 bitsToSend = bufferBits;
535 switch (static_cast<PixelFormat>(cb.format)) {
536 case PixelFormat::YV12:
537 get_yv12_offsets(cb.width, cb.height, nullptr, nullptr, &sizeToSend);
538 break;
539 case PixelFormat::YCBCR_420_888:
540 get_yuv420p_offsets(cb.width, cb.height, nullptr, nullptr, &sizeToSend);
541 break;
542 default:
543 CRASH("Unexpected format, switch is out of sync with gralloc_is_yuv_format");
544 break;
545 }
546 } else {
547 bitsToSend = bufferBits;
548 sizeToSend = rgbSize;
549 }
550
551 {
552 const HostConnectionSession conn = getHostConnectionSession();
553 ExtendedRCEncoderContext *const rcEnc = conn.getRcEncoder();
554 {
555 AEMU_SCOPED_TRACE("bindDmaDirectly");
556 rcEnc->bindDmaDirectly(bufferBits,
557 getMmapedPhysAddr(cb.getMmapedOffset()));
558 }
559 {
560 AEMU_SCOPED_TRACE("updateColorBuffer");
561 rcEnc->rcUpdateColorBufferDMA(rcEnc, cb.hostHandle,
562 0, 0, cb.width, cb.height,
563 cb.glFormat, cb.glType,
564 const_cast<char*>(bitsToSend),
565 sizeToSend);
566 }
567 }
568 }
569
570 cb.lockedLeft = 0;
571 cb.lockedTop = 0;
572 cb.lockedWidth = 0;
573 cb.lockedHeight = 0;
574 cb.locked = 0;
575 cb.lockedUsage = 0;
576 }
577
578 /* BufferUsage bits that must be zero */
579 static constexpr uint64_t kReservedUsage =
580 (one64 << 10)
581 | (one64 << 13)
582 | (one64 << 19)
583 | (one64 << 21)
584 | ones(25, 27) /* bits 25-27 must be zero and are reserved for future versions */
585 | ones(32, 47); /* bits 32-47 must be zero and are reserved for future versions */
586
isSupportedImpl(const IMapper::BufferDescriptorInfo & descriptor) const587 bool isSupportedImpl(const IMapper::BufferDescriptorInfo& descriptor) const {
588 if (!descriptor.width) { RETURN(false); }
589 if (!descriptor.height) { RETURN(false); }
590 if (descriptor.layerCount != 1) { RETURN(false); }
591
592 const uint64_t usage64 = descriptor.usage;
593 if (usage64 & kReservedUsage) {
594 RETURN(false);
595 }
596
597 const uint32_t usage = usage64;
598 const bool usageSwWrite = usage & BufferUsage::CPU_WRITE_MASK;
599 const bool usageSwRead = usage & BufferUsage::CPU_READ_MASK;
600 const bool usageHwCamWrite = usage & BufferUsage::CAMERA_OUTPUT;
601 const bool usageHwCamRead = usage & BufferUsage::CAMERA_INPUT;
602
603 switch (descriptor.format) {
604 case PixelFormat::RGBA_8888:
605 case PixelFormat::RGBX_8888:
606 case PixelFormat::BGRA_8888:
607 case PixelFormat::RGB_565:
608 case PixelFormat::RGBA_FP16:
609 case PixelFormat::RGBA_1010102:
610 case PixelFormat::YCRCB_420_SP:
611 case PixelFormat::YV12:
612 case PixelFormat::YCBCR_420_888:
613 RETURN(true);
614
615 case PixelFormat::IMPLEMENTATION_DEFINED:
616 if (usage & BufferUsage::CAMERA_OUTPUT) {
617 RETURN(true);
618 }
619 RETURN(false);
620
621 case PixelFormat::RGB_888:
622 RETURN(0 == (usage & (BufferUsage::GPU_TEXTURE |
623 BufferUsage::GPU_RENDER_TARGET |
624 BufferUsage::COMPOSER_OVERLAY |
625 BufferUsage::COMPOSER_CLIENT_TARGET)));
626
627 case PixelFormat::RAW16:
628 case PixelFormat::Y16:
629 RETURN((usageSwRead || usageHwCamRead) &&
630 (usageSwWrite || usageHwCamWrite));
631
632 case PixelFormat::BLOB:
633 RETURN(usageSwRead);
634
635 default:
636 if (static_cast<int>(descriptor.format) == kOMX_COLOR_FormatYUV420Planar) {
637 return (usage & BufferUsage::VIDEO_DECODER) != 0;
638 }
639
640 RETURN(false);
641 }
642 }
643
validateBufferSizeImpl(const cb_handle_t &,const BufferDescriptorInfo &,uint32_t)644 Error3 validateBufferSizeImpl(const cb_handle_t& /*cb*/,
645 const BufferDescriptorInfo& /*descriptor*/,
646 uint32_t /*stride*/) {
647 RETURN(Error3::NONE);
648 }
649
getHostConnectionSession() const650 HostConnectionSession getHostConnectionSession() const {
651 return HostConnectionSession(m_hostConn.get());
652 }
653
encodeBufferDescriptorInfo(const BufferDescriptorInfo & d,hidl_vec<uint32_t> * raw)654 static void encodeBufferDescriptorInfo(const BufferDescriptorInfo& d,
655 hidl_vec<uint32_t>* raw) {
656 raw->resize(5);
657
658 (*raw)[0] = d.width;
659 (*raw)[1] = d.height;
660 (*raw)[2] = d.layerCount;
661 (*raw)[3] = static_cast<uint32_t>(d.format);
662 (*raw)[4] = d.usage & UINT32_MAX;
663 }
664
getMmapedPhysAddr(uint64_t offset) const665 uint64_t getMmapedPhysAddr(uint64_t offset) const {
666 return m_physAddrToOffset + offset;
667 }
668
669 std::unique_ptr<HostConnection> m_hostConn;
670 uint64_t m_physAddrToOffset;
671 };
672 } // namespace
673
HIDL_FETCH_IMapper(const char *)674 extern "C" IMapper3* HIDL_FETCH_IMapper(const char* /*name*/) {
675 return new GoldfishMapper;
676 }
677