1 /*
2 * Copyright (C) 2019 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 <string.h>
18 #include <pthread.h>
19 #include <limits.h>
20 #include <unistd.h>
21 #include <errno.h>
22
23 #include <set>
24 #include <map>
25 #include <vector>
26 #include <string>
27 #include <algorithm>
28
29 #include <log/log.h>
30 #include <sys/mman.h>
31
32 #include <hardware/hardware.h>
33 #include <hardware/gralloc.h>
34
35 #include <gralloc_cb_bp.h>
36 #include "gralloc_common.h"
37 #include "goldfish_address_space.h"
38 #include "HostConnection.h"
39 #include "FormatConversions.h"
40 #include <qemu_pipe_bp.h>
41
42 #define CRASH(MSG) \
43 do { \
44 ALOGE("%s:%d crashed with '%s'", __func__, __LINE__, MSG); \
45 ::abort(); \
46 } while (false)
47
48 #define CRASH_IF(COND, MSG) \
49 do { \
50 if ((COND)) { \
51 ALOGE("%s:%d crashed on '%s' with '%s'", __func__, __LINE__, #COND, MSG); \
52 ::abort(); \
53 } \
54 } while (false)
55
56 #define RETURN_ERROR_CODE(X) \
57 do { \
58 ALOGE("%s:%d failed with '%s' (%d)", \
59 __func__, __LINE__, strerror(-(X)), -(X)); \
60 return (X); \
61 } while (false)
62
63 #define RETURN_ERROR(X) \
64 do { \
65 ALOGE("%s:%d failed with '%s'", __func__, __LINE__, #X); \
66 return (X); \
67 } while (false)
68
69 #define OMX_COLOR_FormatYUV420Planar 19
70
71 namespace {
72
73 const char GOLDFISH_GRALLOC_MODULE_NAME[] = "Graphics Memory Allocator Module";
74
make_hw_device(hw_module_t * module,int (* close)(hw_device_t *))75 hw_device_t make_hw_device(hw_module_t* module, int (*close)(hw_device_t*)) {
76 hw_device_t result = {};
77
78 result.tag = HARDWARE_DEVICE_TAG;
79 result.version = 0;
80 result.module = module;
81 result.close = close;
82
83 return result;
84 }
85
align(const size_t v,const size_t a)86 size_t align(const size_t v, const size_t a) { return (v + a - 1) & ~(a - 1); }
87
88 class HostConnectionSession {
89 public:
HostConnectionSession(HostConnection * hc)90 explicit HostConnectionSession(HostConnection* hc) : conn(hc) {
91 hc->lock();
92 }
93
~HostConnectionSession()94 ~HostConnectionSession() {
95 if (conn) {
96 conn->unlock();
97 }
98 }
99
HostConnectionSession(HostConnectionSession && rhs)100 HostConnectionSession(HostConnectionSession&& rhs) : conn(rhs.conn) {
101 rhs.conn = nullptr;
102 }
103
operator =(HostConnectionSession && rhs)104 HostConnectionSession& operator=(HostConnectionSession&& rhs) {
105 if (this != &rhs) {
106 std::swap(conn, rhs.conn);
107 }
108 return *this;
109 }
110
111 HostConnectionSession(const HostConnectionSession&) = delete;
112 HostConnectionSession& operator=(const HostConnectionSession&) = delete;
113
getRcEncoder() const114 ExtendedRCEncoderContext* getRcEncoder() const {
115 return conn->rcEncoder();
116 }
117
118 private:
119 HostConnection* conn;
120 };
121
122 class goldfish_gralloc30_module_t;
123 class goldfish_gralloc30_device_t;
124 class goldfish_fb30_device_t;
125
126 class buffer_manager_t {
127 public:
128 buffer_manager_t() = default;
129 buffer_manager_t(const buffer_manager_t&) = delete;
130 buffer_manager_t& operator=(const buffer_manager_t&) = delete;
131 buffer_manager_t(buffer_manager_t&&) = delete;
132 buffer_manager_t& operator=(buffer_manager_t&&) = delete;
~buffer_manager_t()133 virtual ~buffer_manager_t() {}
134
135 virtual uint64_t getMmapedPhysAddr(uint64_t offset) const = 0;
136
137 virtual int alloc_buffer(int usage,
138 int width, int height, int format,
139 EmulatorFrameworkFormat emulatorFrameworkFormat,
140 int glFormat, int glType,
141 size_t bufferSize,
142 buffer_handle_t* pHandle) = 0;
143 virtual int free_buffer(buffer_handle_t h) = 0;
144 virtual int register_buffer(buffer_handle_t h) = 0;
145 virtual int unregister_buffer(buffer_handle_t h) = 0;
146 };
147
148 std::unique_ptr<buffer_manager_t> create_buffer_manager(goldfish_gralloc30_module_t*);
149
150 class goldfish_gralloc30_module_t {
151 public:
152 // TODO(b/142677230): Use unique pointers instead.
goldfish_gralloc30_module_t()153 goldfish_gralloc30_module_t()
154 : m_hostConn(HostConnection::createUnique().release()) {
155 CRASH_IF(!m_hostConn, "m_hostConn cannot be nullptr");
156 m_bufferManager = create_buffer_manager(this);
157 CRASH_IF(!m_bufferManager, "m_bufferManager cannot be nullptr");
158 }
159
getHostConnectionSession() const160 HostConnectionSession getHostConnectionSession() const {
161 return HostConnectionSession(m_hostConn /*.get()*/);
162 }
163
alloc_buffer(int usage,int width,int height,int format,EmulatorFrameworkFormat emulatorFrameworkFormat,int glFormat,int glType,size_t bufferSize,buffer_handle_t * pHandle)164 int alloc_buffer(int usage,
165 int width, int height, int format,
166 EmulatorFrameworkFormat emulatorFrameworkFormat,
167 int glFormat, int glType,
168 size_t bufferSize,
169 buffer_handle_t* pHandle) {
170 return m_bufferManager->alloc_buffer(usage,
171 width, height, format,
172 emulatorFrameworkFormat,
173 glFormat, glType,
174 bufferSize,
175 pHandle);
176 }
177
free_buffer(buffer_handle_t h)178 int free_buffer(buffer_handle_t h) {
179 return m_bufferManager->free_buffer(h);
180 }
181
register_buffer(buffer_handle_t h)182 int register_buffer(buffer_handle_t h) {
183 return m_bufferManager->register_buffer(h);
184 }
185
unregister_buffer(buffer_handle_t h)186 int unregister_buffer(buffer_handle_t h) {
187 return m_bufferManager->unregister_buffer(h);
188 }
189
lock(cb_handle_t & handle,const int usage,const int left,const int top,const int width,const int height,void ** vaddr)190 int lock(cb_handle_t& handle,
191 const int usage,
192 const int left, const int top, const int width, const int height,
193 void** vaddr) {
194 if (!handle.bufferSize) { RETURN_ERROR_CODE(-EINVAL); }
195 char* const bufferBits = static_cast<char*>(handle.getBufferPtr());
196 if (!bufferBits) { RETURN_ERROR_CODE(-EINVAL); }
197
198 if (handle.hostHandle) {
199 const int res = lock_impl(handle,
200 usage,
201 left, top, width, height,
202 bufferBits);
203 if (res) { return res; }
204 }
205
206 *vaddr = bufferBits;
207 return 0;
208 }
209
unlock(cb_handle_t & handle)210 int unlock(cb_handle_t& handle) {
211 if (!handle.bufferSize) { RETURN_ERROR_CODE(-EINVAL); }
212
213 char* const bufferBits = static_cast<char*>(handle.getBufferPtr());
214 if (!bufferBits) { RETURN_ERROR_CODE(-EINVAL); }
215
216 if (handle.hostHandle) {
217 unlock_impl(handle, bufferBits);
218 }
219
220 return 0;
221 }
222
lock_ycbcr(cb_handle_t & handle,const int usage,const int left,const int top,const int width,const int height,android_ycbcr * ycbcr)223 int lock_ycbcr(cb_handle_t& handle,
224 const int usage,
225 const int left, const int top, const int width, const int height,
226 android_ycbcr* ycbcr) {
227 if (!ycbcr) { RETURN_ERROR_CODE(-EINVAL); }
228 if (!handle.bufferSize) { RETURN_ERROR_CODE(-EINVAL); }
229 char* const bufferBits = static_cast<char*>(handle.getBufferPtr());
230 if (!bufferBits) { RETURN_ERROR_CODE(-EINVAL); }
231
232 size_t uOffset;
233 size_t vOffset;
234 size_t yStride;
235 size_t cStride;
236 size_t cStep;
237
238 switch (handle.format) {
239 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
240 yStride = handle.width;
241 cStride = yStride;
242 vOffset = yStride * handle.height;
243 uOffset = vOffset + 1;
244 cStep = 2;
245 break;
246
247 case HAL_PIXEL_FORMAT_YV12:
248 // https://developer.android.com/reference/android/graphics/ImageFormat.html#YV12
249 yStride = align(handle.width, 16);
250 cStride = align(yStride / 2, 16);
251 vOffset = yStride * handle.height;
252 uOffset = vOffset + (cStride * handle.height / 2);
253 cStep = 1;
254 break;
255
256 case HAL_PIXEL_FORMAT_YCbCr_420_888:
257 yStride = handle.width;
258 cStride = yStride / 2;
259 uOffset = handle.height * yStride;
260 vOffset = uOffset + cStride * handle.height / 2;
261 cStep = 1;
262 break;
263
264 default:
265 ALOGE("%s:%d unexpected format (%d)", __func__, __LINE__, handle.format);
266 RETURN_ERROR_CODE(-EINVAL);
267 }
268
269 if (handle.hostHandle) {
270 const int res = lock_impl(handle,
271 usage,
272 left, top, width, height,
273 bufferBits);
274 if (res) { return res; }
275 }
276
277 memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
278 char* const vaddr1 = static_cast<char*>(bufferBits);
279 ycbcr->y = vaddr1;
280 ycbcr->cb = vaddr1 + uOffset;
281 ycbcr->cr = vaddr1 + vOffset;
282 ycbcr->ystride = yStride;
283 ycbcr->cstride = cStride;
284 ycbcr->chroma_step = cStep;
285 return 0;
286 }
287
288 private:
lock_impl(cb_handle_t & handle,const int usage,const int left,const int top,const int width,const int height,char * const bufferBits)289 int lock_impl(cb_handle_t& handle,
290 const int usage,
291 const int left, const int top, const int width, const int height,
292 char* const bufferBits) {
293 const bool usageSwRead = usage & GRALLOC_USAGE_SW_READ_MASK;
294 const bool usageSwWrite = usage & GRALLOC_USAGE_SW_WRITE_MASK;
295 const bool usageHwCamera = usage & GRALLOC_USAGE_HW_CAMERA_MASK;
296 const bool usageHwCameraWrite = usage & GRALLOC_USAGE_HW_CAMERA_WRITE;
297
298 const HostConnectionSession conn = getHostConnectionSession();
299 ExtendedRCEncoderContext *const rcEnc = conn.getRcEncoder();
300
301 const int res = rcEnc->rcColorBufferCacheFlush(
302 rcEnc, handle.hostHandle, 0, usageSwRead);
303 if (res < 0) {
304 RETURN_ERROR_CODE(-EBUSY);
305 }
306
307 // camera delivers bits to the buffer directly and does not require
308 // an explicit read.
309 if (usageSwRead && !usageHwCamera) {
310 if (gralloc_is_yuv_format(handle.format)) {
311 if (rcEnc->hasYUVCache()) {
312 uint32_t bufferSize;
313
314 switch (handle.format) {
315 case HAL_PIXEL_FORMAT_YV12:
316 get_yv12_offsets(handle.width, handle.height,
317 nullptr, nullptr, &bufferSize);
318 break;
319 case HAL_PIXEL_FORMAT_YCbCr_420_888:
320 get_yuv420p_offsets(handle.width, handle.height,
321 nullptr, nullptr, &bufferSize);
322 break;
323 default:
324 CRASH("Unexpected format, switch is out of sync with gralloc_is_yuv_format");
325 break;
326 }
327
328 rcEnc->rcReadColorBufferYUV(rcEnc, handle.hostHandle,
329 0, 0, handle.width, handle.height,
330 bufferBits, bufferSize);
331 } else {
332 // We are using RGB888
333 std::vector<char> tmpBuf(handle.width * handle.height * 3);
334 rcEnc->rcReadColorBuffer(rcEnc, handle.hostHandle,
335 0, 0, handle.width, handle.height,
336 handle.glFormat, handle.glType,
337 tmpBuf.data());
338
339 switch (handle.format) {
340 case HAL_PIXEL_FORMAT_YV12:
341 rgb888_to_yv12(bufferBits, tmpBuf.data(),
342 handle.width, handle.height,
343 left, top,
344 left + width - 1, top + height - 1);
345 break;
346 case HAL_PIXEL_FORMAT_YCbCr_420_888:
347 rgb888_to_yuv420p(bufferBits, tmpBuf.data(),
348 handle.width, handle.height,
349 left, top,
350 left + width - 1, top + height - 1);
351 break;
352 default:
353 CRASH("Unexpected format, switch is out of sync with gralloc_is_yuv_format");
354 break;
355 }
356 }
357 } else {
358 rcEnc->rcReadColorBuffer(rcEnc,
359 handle.hostHandle,
360 0, 0, handle.width, handle.height,
361 handle.glFormat, handle.glType,
362 bufferBits);
363 }
364 }
365
366 if (usageSwWrite || usageHwCameraWrite) {
367 handle.lockedLeft = left;
368 handle.lockedTop = top;
369 handle.lockedWidth = width;
370 handle.lockedHeight = height;
371 } else {
372 handle.lockedLeft = 0;
373 handle.lockedTop = 0;
374 handle.lockedWidth = handle.width;
375 handle.lockedHeight = handle.height;
376 }
377
378 return 0;
379 }
380
unlock_impl(cb_handle_t & handle,char * const bufferBits)381 void unlock_impl(cb_handle_t& handle, char* const bufferBits) {
382 const int bpp = glUtilsPixelBitSize(handle.glFormat, handle.glType) >> 3;
383 const int left = handle.lockedLeft;
384 const int top = handle.lockedTop;
385 const int width = handle.lockedWidth;
386 const int height = handle.lockedHeight;
387 const uint32_t rgbSize = width * height * bpp;
388
389 std::vector<char> convertedBuf;
390 const char* bitsToSend;
391 uint32_t sizeToSend;
392 if (gralloc_is_yuv_format(handle.format)) {
393 bitsToSend = bufferBits;
394 switch (handle.format) {
395 case HAL_PIXEL_FORMAT_YV12:
396 get_yv12_offsets(width, height, nullptr, nullptr, &sizeToSend);
397 break;
398
399 case HAL_PIXEL_FORMAT_YCbCr_420_888:
400 get_yuv420p_offsets(width, height, nullptr, nullptr, &sizeToSend);
401 break;
402
403 default:
404 CRASH("Unexpected format, switch is out of sync with gralloc_is_yuv_format");
405 break;
406 }
407 } else {
408 convertedBuf.resize(rgbSize);
409 copy_rgb_buffer_from_unlocked(
410 convertedBuf.data(), bufferBits,
411 handle.width,
412 width, height, top, left, bpp);
413 bitsToSend = convertedBuf.data();
414 sizeToSend = rgbSize;
415 }
416
417 {
418 const HostConnectionSession conn = getHostConnectionSession();
419 ExtendedRCEncoderContext *const rcEnc = conn.getRcEncoder();
420
421 rcEnc->bindDmaDirectly(bufferBits,
422 m_bufferManager->getMmapedPhysAddr(handle.getMmapedOffset()));
423 rcEnc->rcUpdateColorBufferDMA(rcEnc, handle.hostHandle,
424 left, top, width, height,
425 handle.glFormat, handle.glType,
426 const_cast<char*>(bitsToSend), sizeToSend);
427 }
428
429 handle.lockedLeft = 0;
430 handle.lockedTop = 0;
431 handle.lockedWidth = 0;
432 handle.lockedHeight = 0;
433 }
434
435 //std::unique_ptr<HostConnection> m_hostConn; // b/142677230
436 HostConnection* m_hostConn;
437 std::unique_ptr<buffer_manager_t> m_bufferManager;
438 };
439
440 // no ctor/dctor here
441 struct private_module_t {
impl__anon1242cbb90111::private_module_t442 goldfish_gralloc30_module_t* impl() {
443 return &gralloc30;
444 }
445
to_hw_module__anon1242cbb90111::private_module_t446 hw_module_t* to_hw_module() { return &base.common; }
447
from_hw_module__anon1242cbb90111::private_module_t448 static private_module_t* from_hw_module(const hw_module_t* m) {
449 if (!m) {
450 RETURN_ERROR(nullptr);
451 }
452
453 if ((m->id == GRALLOC_HARDWARE_MODULE_ID) && (m->name == GOLDFISH_GRALLOC_MODULE_NAME)) {
454 return reinterpret_cast<private_module_t*>(const_cast<hw_module_t*>(m));
455 } else {
456 RETURN_ERROR(nullptr);
457 }
458 }
459
from_gralloc_module__anon1242cbb90111::private_module_t460 static private_module_t* from_gralloc_module(const gralloc_module_t* m) {
461 if (!m) {
462 RETURN_ERROR(nullptr);
463 }
464
465 return from_hw_module(&m->common);
466 }
467
468 gralloc_module_t base;
469 goldfish_gralloc30_module_t gralloc30;
470 };
471
472 class goldfish_gralloc30_device_t {
473 alloc_device_t device;
474 goldfish_gralloc30_module_t* gralloc_module;
475
476 public:
goldfish_gralloc30_device_t(private_module_t * module)477 goldfish_gralloc30_device_t(private_module_t* module)
478 : gralloc_module(module->impl()) {
479 memset(&device, 0, sizeof(device));
480 device.common = make_hw_device(module->to_hw_module(),
481 &s_goldfish_gralloc30_device_close);
482 device.alloc = &s_gralloc_alloc;
483 device.free = &s_gralloc_free;
484 }
485
get_hw_device_ptr()486 hw_device_t* get_hw_device_ptr() { return &device.common; }
487
488 private:
get_buffer_format(const int frameworkFormat,const int usage)489 static int get_buffer_format(const int frameworkFormat, const int usage) {
490 if (frameworkFormat == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
491 if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
492 if (usage & GRALLOC_USAGE_HW_TEXTURE) {
493 // Camera-to-display is RGBA
494 return HAL_PIXEL_FORMAT_RGBA_8888;
495 } else if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
496 // Camera-to-encoder is NV21
497 return HAL_PIXEL_FORMAT_YCrCb_420_SP;
498 }
499 }
500
501 RETURN_ERROR_CODE(-EINVAL);
502 } else if (frameworkFormat == OMX_COLOR_FormatYUV420Planar &&
503 (usage & GOLDFISH_GRALLOC_USAGE_GPU_DATA_BUFFER)) {
504 ALOGW("gralloc_alloc: Requested OMX_COLOR_FormatYUV420Planar, given "
505 "YCbCr_420_888, taking experimental path. "
506 "usage=%x", usage);
507 return HAL_PIXEL_FORMAT_YCbCr_420_888;
508 }
509 else {
510 return frameworkFormat;
511 }
512 }
513
gralloc_alloc(const int width,const int height,const int frameworkFormat,const int usage,buffer_handle_t * pHandle,int * pStride)514 int gralloc_alloc(const int width, const int height,
515 const int frameworkFormat,
516 const int usage,
517 buffer_handle_t* pHandle,
518 int* pStride) {
519 const bool usageSwWrite = usage & GRALLOC_USAGE_SW_WRITE_MASK;
520 const bool usageSwRead = usage & GRALLOC_USAGE_SW_READ_MASK;
521 const bool usageHwTexture = usage & GRALLOC_USAGE_HW_TEXTURE;
522 const bool usageHwRender = usage & GRALLOC_USAGE_HW_RENDER;
523 const bool usageHw2d = usage & GRALLOC_USAGE_HW_2D;
524 const bool usageHwComposer = usage & GRALLOC_USAGE_HW_COMPOSER;
525 const bool usageHwFb = usage & GRALLOC_USAGE_HW_FB;
526 const bool usageHwCamWrite = usage & GRALLOC_USAGE_HW_CAMERA_WRITE;
527 const bool usageHwCamRead = usage & GRALLOC_USAGE_HW_CAMERA_READ;
528 const bool usageRGB888Unsupported = usageHwTexture
529 || usageHwRender ||usageHw2d || usageHwComposer || usageHwFb;
530
531 int bpp = 1;
532 int glFormat = 0;
533 int glType = 0;
534 int align = 1;
535 bool yuv_format = false;
536 EmulatorFrameworkFormat emulatorFrameworkFormat = FRAMEWORK_FORMAT_GL_COMPATIBLE;
537
538 const int format = get_buffer_format(frameworkFormat, usage);
539 if (format < 0) {
540 ALOGE("%s:%d Unsupported format: frameworkFormat=%d, usage=%x",
541 __func__, __LINE__, frameworkFormat, usage);
542 return format;
543 }
544
545 switch (format) {
546 case HAL_PIXEL_FORMAT_RGBA_8888:
547 case HAL_PIXEL_FORMAT_RGBX_8888:
548 case HAL_PIXEL_FORMAT_BGRA_8888:
549 bpp = 4;
550 glFormat = GL_RGBA;
551 glType = GL_UNSIGNED_BYTE;
552 break;
553
554 case HAL_PIXEL_FORMAT_RGB_888:
555 if (usageRGB888Unsupported) {
556 RETURN_ERROR_CODE(-EINVAL); // we dont support RGB_888 for HW usage
557 } else {
558 bpp = 3;
559 glFormat = GL_RGB;
560 glType = GL_UNSIGNED_BYTE;
561 }
562 break;
563
564 case HAL_PIXEL_FORMAT_RGB_565:
565 bpp = 2;
566 glFormat = GL_RGB565;
567 glType = GL_UNSIGNED_SHORT_5_6_5;
568 break;
569
570 case HAL_PIXEL_FORMAT_RGBA_FP16:
571 bpp = 8;
572 glFormat = GL_RGBA16F;
573 glType = GL_HALF_FLOAT;
574 break;
575
576 case HAL_PIXEL_FORMAT_RGBA_1010102:
577 bpp = 4;
578 glFormat = GL_RGB10_A2;
579 glType = GL_UNSIGNED_INT_2_10_10_10_REV;
580 break;
581
582 case HAL_PIXEL_FORMAT_RAW16:
583 case HAL_PIXEL_FORMAT_Y16:
584 bpp = 2;
585 align = 16 * bpp;
586 if (!((usageSwRead || usageHwCamRead) && (usageSwWrite || usageHwCamWrite))) {
587 // Raw sensor data or Y16 only goes between camera and CPU
588 RETURN_ERROR_CODE(-EINVAL);
589 }
590 // Not expecting to actually create any GL surfaces for this
591 glFormat = GL_LUMINANCE;
592 glType = GL_UNSIGNED_SHORT;
593 break;
594
595 case HAL_PIXEL_FORMAT_BLOB:
596 if (!usageSwRead) {
597 // Blob data cannot be used by HW other than camera emulator
598 // But there is a CTS test trying to have access to it
599 // BUG: https://buganizer.corp.google.com/issues/37719518
600 RETURN_ERROR_CODE(-EINVAL);
601 }
602 // Not expecting to actually create any GL surfaces for this
603 glFormat = GL_LUMINANCE;
604 glType = GL_UNSIGNED_BYTE;
605 break;
606
607 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
608 yuv_format = true;
609 // Not expecting to actually create any GL surfaces for this
610 break;
611
612 case HAL_PIXEL_FORMAT_YV12:
613 align = 16;
614 yuv_format = true;
615 // We are going to use RGB8888 on the host for Vulkan
616 glFormat = GL_RGBA;
617 glType = GL_UNSIGNED_BYTE;
618 emulatorFrameworkFormat = FRAMEWORK_FORMAT_YV12;
619 break;
620
621 case HAL_PIXEL_FORMAT_YCbCr_420_888:
622 yuv_format = true;
623 // We are going to use RGB888 on the host
624 glFormat = GL_RGB;
625 glType = GL_UNSIGNED_BYTE;
626 emulatorFrameworkFormat = FRAMEWORK_FORMAT_YUV_420_888;
627 break;
628
629 default:
630 ALOGE("%s:%d Unsupported format: format=%d, frameworkFormat=%d, usage=%x",
631 __func__, __LINE__, format, frameworkFormat, usage);
632 RETURN_ERROR_CODE(-EINVAL);
633 }
634
635 const size_t align1 = align - 1;
636 int stride;
637 size_t bufferSize;
638
639 if (yuv_format) {
640 const size_t yStride = (width * bpp + align1) & ~align1;
641 const size_t uvStride = (yStride / 2 + align1) & ~align1;
642 const size_t uvHeight = height / 2;
643 bufferSize = yStride * height + 2 * (uvHeight * uvStride);
644 stride = yStride / bpp;
645 } else {
646 const size_t bpr = (width * bpp + align1) & ~align1;
647 bufferSize = bpr * height;
648 stride = bpr / bpp;
649 }
650
651 const int res = gralloc_module->alloc_buffer(
652 usage,
653 width, height, format,
654 emulatorFrameworkFormat,
655 glFormat, glType,
656 bufferSize,
657 pHandle);
658 if (res) {
659 return res;
660 }
661
662 *pStride = stride;
663 return 0;
664 }
665
gralloc_free(buffer_handle_t h)666 int gralloc_free(buffer_handle_t h) {
667 return gralloc_module->free_buffer(h);
668 }
669
s_goldfish_gralloc30_device_close(hw_device_t * d)670 static int s_goldfish_gralloc30_device_close(hw_device_t* d) {
671 goldfish_gralloc30_device_t* gd = from_hw_device(d);
672 if (!gd) {
673 RETURN_ERROR_CODE(-EINVAL);
674 }
675
676 std::unique_ptr<goldfish_gralloc30_device_t> deleter(gd);
677 return 0;
678 }
679
s_gralloc_alloc(alloc_device_t * ad,int w,int h,int format,int usage,buffer_handle_t * pHandle,int * pStride)680 static int s_gralloc_alloc(alloc_device_t* ad,
681 int w, int h, int format, int usage,
682 buffer_handle_t* pHandle, int* pStride) {
683 goldfish_gralloc30_device_t* gd = from_alloc_device(ad);
684 if (!gd) {
685 RETURN_ERROR_CODE(-EINVAL);
686 }
687
688 return gd->gralloc_alloc(w, h, format, usage, pHandle, pStride);
689 }
690
s_gralloc_free(alloc_device_t * ad,buffer_handle_t h)691 static int s_gralloc_free(alloc_device_t* ad, buffer_handle_t h) {
692 goldfish_gralloc30_device_t* gd = from_alloc_device(ad);
693 if (!gd) {
694 RETURN_ERROR_CODE(-EINVAL);
695 }
696
697 return gd->gralloc_free(h);
698 }
699
from_hw_device(hw_device_t * d)700 static goldfish_gralloc30_device_t* from_hw_device(hw_device_t* d) {
701 if (!d) {
702 RETURN_ERROR(nullptr);
703 }
704
705 if (d->close == &s_goldfish_gralloc30_device_close) {
706 return reinterpret_cast<goldfish_gralloc30_device_t*>(d);
707 } else {
708 RETURN_ERROR(nullptr);
709 }
710 }
711
from_alloc_device(alloc_device_t * d)712 static goldfish_gralloc30_device_t* from_alloc_device(alloc_device_t* d) {
713 if (!d) {
714 RETURN_ERROR(nullptr);
715 }
716
717 return from_hw_device(&d->common);
718 }
719 };
720
unconst(const T & x)721 template <class T> T& unconst(const T& x) { return const_cast<T&>(x); }
722
723 const uint32_t CB_HANDLE_MAGIC_30 = CB_HANDLE_MAGIC_BASE | 0x2;
724
725 struct cb_handle_30_t : public cb_handle_t {
cb_handle_30_t__anon1242cbb90111::cb_handle_30_t726 cb_handle_30_t(address_space_handle_t p_bufferFd,
727 QEMU_PIPE_HANDLE p_hostHandleRefCountFd,
728 uint32_t p_hostHandle,
729 int32_t p_usage,
730 int32_t p_width,
731 int32_t p_height,
732 int32_t p_format,
733 int32_t p_glFormat,
734 int32_t p_glType,
735 uint32_t p_bufSize,
736 void* p_bufPtr,
737 int32_t p_bufferPtrPid,
738 uint32_t p_mmapedSize,
739 uint64_t p_mmapedOffset)
740 : cb_handle_t(p_bufferFd,
741 p_hostHandleRefCountFd,
742 CB_HANDLE_MAGIC_30,
743 p_hostHandle,
744 p_usage,
745 p_width,
746 p_height,
747 p_format,
748 p_glFormat,
749 p_glType,
750 p_bufSize,
751 p_bufPtr,
752 p_mmapedOffset),
753 bufferFdAsInt(p_bufferFd),
754 bufferPtrPid(p_bufferPtrPid),
755 mmapedSize(p_mmapedSize) {
756 numInts = CB_HANDLE_NUM_INTS(numFds);
757 }
758
isValid__anon1242cbb90111::cb_handle_30_t759 bool isValid() const { return (version == sizeof(native_handle_t)) && (magic == CB_HANDLE_MAGIC_30); }
760
from__anon1242cbb90111::cb_handle_30_t761 static cb_handle_30_t* from(void* p) {
762 if (!p) { return nullptr; }
763 cb_handle_30_t* cb = static_cast<cb_handle_30_t*>(p);
764 return cb->isValid() ? cb : nullptr;
765 }
766
from__anon1242cbb90111::cb_handle_30_t767 static const cb_handle_30_t* from(const void* p) {
768 return from(const_cast<void*>(p));
769 }
770
from_unconst__anon1242cbb90111::cb_handle_30_t771 static cb_handle_30_t* from_unconst(const void* p) {
772 return from(const_cast<void*>(p));
773 }
774
775 int32_t bufferFdAsInt; // int copy of bufferFd, to check if fd was duped
776 int32_t bufferPtrPid; // pid where bufferPtr belongs to
777 uint32_t mmapedSize; // real allocation side
778 };
779
780 // goldfish_address_space_host_malloc_handle_manager_t uses
781 // GoldfishAddressSpaceHostMemoryAllocator and GoldfishAddressSpaceBlock
782 // to allocate buffers on the host.
783 // It keeps track of usage of host handles allocated by rcCreateColorBufferDMA
784 // on the guest by qemu_pipe_open("refcount").
785 class goldfish_address_space_host_malloc_buffer_manager_t : public buffer_manager_t {
786 public:
goldfish_address_space_host_malloc_buffer_manager_t(goldfish_gralloc30_module_t * gr)787 goldfish_address_space_host_malloc_buffer_manager_t(goldfish_gralloc30_module_t* gr): m_gr(gr) {
788 GoldfishAddressSpaceHostMemoryAllocator host_memory_allocator(false);
789 CRASH_IF(!host_memory_allocator.is_opened(),
790 "GoldfishAddressSpaceHostMemoryAllocator failed to open");
791
792 GoldfishAddressSpaceBlock bufferBits;
793 CRASH_IF(host_memory_allocator.hostMalloc(&bufferBits, 256),
794 "hostMalloc failed");
795
796 m_physAddrToOffset = bufferBits.physAddr() - bufferBits.offset();
797 }
798
getMmapedPhysAddr(uint64_t offset) const799 uint64_t getMmapedPhysAddr(uint64_t offset) const override {
800 return m_physAddrToOffset + offset;
801 }
802
alloc_buffer(int usage,int width,int height,int format,EmulatorFrameworkFormat emulatorFrameworkFormat,int glFormat,int glType,size_t bufferSize,buffer_handle_t * pHandle)803 int alloc_buffer(int usage,
804 int width, int height, int format,
805 EmulatorFrameworkFormat emulatorFrameworkFormat,
806 int glFormat, int glType,
807 size_t bufferSize,
808 buffer_handle_t* pHandle) override {
809 const HostConnectionSession conn = m_gr->getHostConnectionSession();
810 ExtendedRCEncoderContext *const rcEnc = conn.getRcEncoder();
811
812 GoldfishAddressSpaceHostMemoryAllocator host_memory_allocator(
813 rcEnc->featureInfo_const()->hasSharedSlotsHostMemoryAllocator);
814 if (!host_memory_allocator.is_opened()) { RETURN_ERROR_CODE(-EIO); }
815
816 GoldfishAddressSpaceBlock bufferBits;
817 if (host_memory_allocator.hostMalloc(&bufferBits, bufferSize)) { RETURN_ERROR_CODE(-EIO); }
818
819 uint32_t hostHandle = 0;
820 QEMU_PIPE_HANDLE hostHandleRefCountFd = QEMU_PIPE_INVALID_HANDLE;
821 if (need_host_cb(usage, format)) {
822 hostHandleRefCountFd = qemu_pipe_open("refcount");
823 if (!qemu_pipe_valid(hostHandleRefCountFd)) { RETURN_ERROR_CODE(-EIO); }
824
825 const GLenum allocFormat =
826 (HAL_PIXEL_FORMAT_RGBX_8888 == format) ? GL_RGB : glFormat;
827
828 hostHandle = rcEnc->rcCreateColorBufferDMA(
829 rcEnc,
830 width, height,
831 allocFormat, emulatorFrameworkFormat);
832 if (!hostHandle) {
833 qemu_pipe_close(hostHandleRefCountFd);
834 RETURN_ERROR_CODE(-EIO);
835 }
836 if (qemu_pipe_write(hostHandleRefCountFd, &hostHandle, sizeof(hostHandle)) != sizeof(hostHandle)) {
837 rcEnc->rcCloseColorBuffer(rcEnc, hostHandle);
838 qemu_pipe_close(hostHandleRefCountFd);
839 RETURN_ERROR_CODE(-EIO);
840 }
841 }
842
843 std::unique_ptr<cb_handle_30_t> handle =
844 std::make_unique<cb_handle_30_t>(
845 host_memory_allocator.release(), hostHandleRefCountFd,
846 hostHandle,
847 usage, width, height,
848 format, glFormat, glType,
849 bufferSize, bufferBits.guestPtr(), getpid(),
850 bufferBits.size(), bufferBits.offset());
851 bufferBits.release();
852
853 *pHandle = handle.release();
854 return 0;
855 }
856
free_buffer(buffer_handle_t h)857 int free_buffer(buffer_handle_t h) override {
858 std::unique_ptr<cb_handle_30_t> handle(cb_handle_30_t::from_unconst(h));
859 if (!handle) {
860 RETURN_ERROR_CODE(-EINVAL);
861 }
862
863 if (handle->bufferPtrPid != getpid()) { RETURN_ERROR_CODE(-EACCES); }
864 if (handle->bufferFd != handle->bufferFdAsInt) { RETURN_ERROR_CODE(-EACCES); }
865
866 if (qemu_pipe_valid(handle->hostHandleRefCountFd)) {
867 qemu_pipe_close(handle->hostHandleRefCountFd);
868 }
869 // We can't recycle the address block and host resources because this
870 // fd could be duped. The kernel will take care of it when the last fd
871 // will be closed.
872 if (handle->mmapedSize > 0) {
873 GoldfishAddressSpaceBlock::memoryUnmap(handle->getBufferPtr(), handle->mmapedSize);
874 }
875 GoldfishAddressSpaceHostMemoryAllocator::closeHandle(handle->bufferFd);
876
877 return 0;
878 }
879
register_buffer(buffer_handle_t h)880 int register_buffer(buffer_handle_t h) override {
881 #ifndef HOST_BUILD
882 cb_handle_30_t *handle = cb_handle_30_t::from_unconst(h);
883 if (!handle) { RETURN_ERROR_CODE(-EINVAL); }
884
885 if (handle->mmapedSize > 0) {
886 void* ptr;
887 const int res = GoldfishAddressSpaceBlock::memoryMap(
888 handle->getBufferPtr(),
889 handle->mmapedSize,
890 handle->bufferFd,
891 handle->getMmapedOffset(),
892 &ptr);
893 if (res) {
894 RETURN_ERROR_CODE(-res);
895 }
896
897 handle->setBufferPtr(ptr);
898 }
899 if (handle->hostHandle) {
900 const HostConnectionSession conn = m_gr->getHostConnectionSession();
901 ExtendedRCEncoderContext *const rcEnc = conn.getRcEncoder();
902 rcEnc->rcOpenColorBuffer2(rcEnc, handle->hostHandle);
903 }
904
905 handle->bufferFdAsInt = handle->bufferFd;
906 handle->bufferPtrPid = getpid();
907 #endif // HOST_BUILD
908
909 return 0;
910 }
911
unregister_buffer(buffer_handle_t h)912 int unregister_buffer(buffer_handle_t h) override {
913 #ifndef HOST_BUILD
914 cb_handle_30_t *handle = cb_handle_30_t::from_unconst(h);
915 if (!handle) { RETURN_ERROR_CODE(-EINVAL); }
916
917 if (handle->bufferPtrPid != getpid()) { RETURN_ERROR_CODE(-EACCES); }
918 if (handle->bufferFd != handle->bufferFdAsInt) { RETURN_ERROR_CODE(-EACCES); }
919
920 if (handle->hostHandle) {
921 const HostConnectionSession conn = m_gr->getHostConnectionSession();
922 ExtendedRCEncoderContext *const rcEnc = conn.getRcEncoder();
923 rcEnc->rcCloseColorBuffer(rcEnc, handle->hostHandle);
924 }
925 if (handle->mmapedSize > 0) {
926 GoldfishAddressSpaceBlock::memoryUnmap(handle->getBufferPtr(), handle->mmapedSize);
927 }
928
929 handle->bufferFdAsInt = -1;
930 handle->bufferPtrPid = -1;
931 #endif // HOST_BUILD
932 return 0;
933 }
934
need_host_cb(const int usage,const int format)935 static bool need_host_cb(const int usage, const int format) {
936 return ((usage & GOLDFISH_GRALLOC_USAGE_GPU_DATA_BUFFER)
937 || (format != HAL_PIXEL_FORMAT_BLOB &&
938 format != HAL_PIXEL_FORMAT_RAW16 &&
939 format != HAL_PIXEL_FORMAT_Y16))
940 && (usage & (GRALLOC_USAGE_HW_TEXTURE
941 | GRALLOC_USAGE_HW_RENDER
942 | GRALLOC_USAGE_HW_2D
943 | GRALLOC_USAGE_HW_COMPOSER
944 | GRALLOC_USAGE_HW_VIDEO_ENCODER
945 | GRALLOC_USAGE_HW_FB
946 | GRALLOC_USAGE_SW_READ_MASK));
947 }
948
949 private:
950 goldfish_gralloc30_module_t* m_gr;
951 uint64_t m_physAddrToOffset;
952 };
953
create_buffer_manager(goldfish_gralloc30_module_t * gr)954 std::unique_ptr<buffer_manager_t> create_buffer_manager(goldfish_gralloc30_module_t* gr) {
955 if (!gr) {
956 RETURN_ERROR(nullptr);
957 }
958
959 // TODO: negotiate with the host the best way to allocate memory.
960
961 return std::make_unique<goldfish_address_space_host_malloc_buffer_manager_t>(gr);
962 }
963
gralloc_register_buffer(const gralloc_module_t * gralloc_module,buffer_handle_t h)964 int gralloc_register_buffer(const gralloc_module_t* gralloc_module, buffer_handle_t h) {
965 private_module_t* module = private_module_t::from_gralloc_module(gralloc_module);
966 if (!module) {
967 RETURN_ERROR_CODE(-EINVAL);
968 }
969
970 return module->impl()->register_buffer(h);
971 }
972
gralloc_unregister_buffer(const gralloc_module_t * gralloc_module,buffer_handle_t h)973 int gralloc_unregister_buffer(const gralloc_module_t* gralloc_module, buffer_handle_t h) {
974 private_module_t* module = private_module_t::from_gralloc_module(gralloc_module);
975 if (!module) {
976 RETURN_ERROR_CODE(-EINVAL);
977 }
978
979 return module->impl()->unregister_buffer(h);
980 }
981
gralloc_lock(const gralloc_module_t * gralloc_module,buffer_handle_t bh,int usage,int l,int t,int w,int h,void ** vaddr)982 int gralloc_lock(const gralloc_module_t* gralloc_module,
983 buffer_handle_t bh, int usage,
984 int l, int t, int w, int h,
985 void** vaddr) {
986 private_module_t* module = private_module_t::from_gralloc_module(gralloc_module);
987 if (!module) {
988 RETURN_ERROR_CODE(-EINVAL);
989 }
990
991 cb_handle_t* handle = cb_handle_t::from_unconst(bh);
992 if (!handle) {
993 RETURN_ERROR_CODE(-EINVAL);
994 }
995
996 return module->impl()->lock(*handle, usage, l, t, w, h, vaddr);
997 }
998
gralloc_unlock(const gralloc_module_t * gralloc_module,buffer_handle_t bh)999 int gralloc_unlock(const gralloc_module_t* gralloc_module, buffer_handle_t bh) {
1000 private_module_t* module = private_module_t::from_gralloc_module(gralloc_module);
1001 if (!module) {
1002 RETURN_ERROR_CODE(-EINVAL);
1003 }
1004
1005 cb_handle_t* handle = cb_handle_t::from_unconst(bh);
1006 if (!handle) {
1007 RETURN_ERROR_CODE(-EINVAL);
1008 }
1009
1010 return module->impl()->unlock(*handle);
1011 }
1012
gralloc_lock_ycbcr(const gralloc_module_t * gralloc_module,buffer_handle_t bh,int usage,int l,int t,int w,int h,android_ycbcr * ycbcr)1013 int gralloc_lock_ycbcr(const gralloc_module_t* gralloc_module,
1014 buffer_handle_t bh, int usage,
1015 int l, int t, int w, int h,
1016 android_ycbcr *ycbcr) {
1017 private_module_t* module = private_module_t::from_gralloc_module(gralloc_module);
1018 if (!module) {
1019 RETURN_ERROR_CODE(-EINVAL);
1020 }
1021
1022 cb_handle_t* handle = cb_handle_t::from_unconst(bh);
1023 if (!handle) {
1024 RETURN_ERROR_CODE(-EINVAL);
1025 }
1026
1027 return module->impl()->lock_ycbcr(*handle, usage, l, t, w, h, ycbcr);
1028 }
1029
gralloc_device_open_gpu0(private_module_t * module,hw_device_t ** device)1030 int gralloc_device_open_gpu0(private_module_t* module, hw_device_t** device) {
1031 std::unique_ptr<goldfish_gralloc30_device_t> gralloc_device =
1032 std::make_unique<goldfish_gralloc30_device_t>(module);
1033 if (!gralloc_device) {
1034 RETURN_ERROR_CODE(-ENOMEM);
1035 }
1036
1037 *device = gralloc_device->get_hw_device_ptr();
1038 gralloc_device.release();
1039 return 0;
1040 }
1041
gralloc_device_open(const hw_module_t * hw_module,const char * name,hw_device_t ** device)1042 int gralloc_device_open(const hw_module_t* hw_module,
1043 const char* name,
1044 hw_device_t** device) {
1045 private_module_t* module = private_module_t::from_hw_module(hw_module);
1046 if (!module) {
1047 RETURN_ERROR_CODE(-EINVAL);
1048 }
1049 if (!name) {
1050 RETURN_ERROR_CODE(-EINVAL);
1051 }
1052 if (!device) {
1053 RETURN_ERROR_CODE(-EINVAL);
1054 }
1055
1056 if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
1057 return gralloc_device_open_gpu0(module, device);
1058 }
1059
1060 RETURN_ERROR_CODE(-EINVAL);
1061 }
1062
1063 struct hw_module_methods_t gralloc_module_methods = {
1064 .open = &gralloc_device_open
1065 };
1066 } // namespace
1067
1068 extern "C" __attribute__((visibility("default")))
1069 struct private_module_t HAL_MODULE_INFO_SYM = {
1070 .base = {
1071 .common = {
1072 .tag = HARDWARE_MODULE_TAG,
1073 .module_api_version = GRALLOC_MODULE_API_VERSION_0_2,
1074 .hal_api_version = 0,
1075 .id = GRALLOC_HARDWARE_MODULE_ID,
1076 .name = GOLDFISH_GRALLOC_MODULE_NAME,
1077 .author = "The Android Open Source Project",
1078 .methods = &gralloc_module_methods,
1079 .dso = nullptr,
1080 .reserved = {0}
1081 },
1082 .registerBuffer = &gralloc_register_buffer,
1083 .unregisterBuffer = &gralloc_unregister_buffer,
1084 .lock = &gralloc_lock,
1085 .unlock = &gralloc_unlock,
1086 .perform = nullptr, /* reserved for future use */
1087 .lock_ycbcr = &gralloc_lock_ycbcr,
1088 },
1089 };
1090