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