• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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