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