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