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