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