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