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