• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (C) 2011 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 #include <string.h>
17 #include <pthread.h>
18 #include <limits.h>
19 #include <cutils/ashmem.h>
20 #include <unistd.h>
21 #include <errno.h>
22 #include <dlfcn.h>
23 #include <sys/mman.h>
24 #include "gralloc_cb.h"
25 #include "goldfish_dma.h"
26 #include "FormatConversions.h"
27 #include "HostConnection.h"
28 #include "ProcessPipe.h"
29 #include "glUtils.h"
30 #include <utils/CallStack.h>
31 #include <cutils/log.h>
32 #include <cutils/properties.h>
33 
34 #include <set>
35 #include <string>
36 #include <sstream>
37 
38 /* Set to 1 or 2 to enable debug traces */
39 #define DEBUG  0
40 
41 #if DEBUG >= 1
42 #  define D(...)   ALOGD(__VA_ARGS__)
43 #else
44 #  define D(...)   ((void)0)
45 #endif
46 
47 #if DEBUG >= 2
48 #  define DD(...)  ALOGD(__VA_ARGS__)
49 #else
50 #  define DD(...)  ((void)0)
51 #endif
52 
53 #define DBG_FUNC DBG("%s\n", __FUNCTION__)
54 
55 #ifdef GOLDFISH_HIDL_GRALLOC
56 static bool isHidlGralloc = true;
57 #else
58 static bool isHidlGralloc = false;
59 #endif
60 
getOpenCountPtr(cb_handle_t * cb)61 int32_t* getOpenCountPtr(cb_handle_t* cb) {
62     return ((int32_t*)cb->ashmemBase) + 1;
63 }
64 
getAshmemColorOffset(cb_handle_t * cb)65 uint32_t getAshmemColorOffset(cb_handle_t* cb) {
66     uint32_t res = 0;
67     if (cb->canBePosted()) res = sizeof(intptr_t);
68     if (isHidlGralloc) res = sizeof(intptr_t) * 2;
69     return res;
70 }
71 
72 //
73 // our private gralloc module structure
74 //
75 struct private_module_t {
76     gralloc_module_t base;
77 };
78 
79 /* If not NULL, this is a pointer to the fallback module.
80  * This really is gralloc.default, which we'll use if we detect
81  * that the emulator we're running in does not support GPU emulation.
82  */
83 static gralloc_module_t*  sFallback;
84 static pthread_once_t     sFallbackOnce = PTHREAD_ONCE_INIT;
85 
86 static void fallback_init(void);  // forward
87 
88 typedef struct _alloc_list_node {
89     buffer_handle_t handle;
90     _alloc_list_node *next;
91     _alloc_list_node *prev;
92 } AllocListNode;
93 
94 struct MemRegionInfo {
95     void* ashmemBase;
96     mutable uint32_t refCount;
97 };
98 
99 struct MemRegionInfoCmp {
operator ()MemRegionInfoCmp100     bool operator()(const MemRegionInfo& a, const MemRegionInfo& b) const {
101         return a.ashmemBase < b.ashmemBase;
102     }
103 };
104 
105 typedef std::set<MemRegionInfo, MemRegionInfoCmp> MemRegionSet;
106 typedef MemRegionSet::iterator mem_region_handle_t;
107 
108 //
109 // Our gralloc device structure (alloc interface)
110 //
111 struct gralloc_device_t {
112     alloc_device_t  device;
113 
114     AllocListNode *allocListHead;    // double linked list of allocated buffers
115     MemRegionSet ashmemRegions; // to track allocations of each ashmem region
116     pthread_mutex_t lock;
117 };
118 
119 struct gralloc_memregions_t {
120     MemRegionSet ashmemRegions;
121 };
122 
123 #define INITIAL_DMA_REGION_SIZE 4096
124 struct gralloc_dmaregion_t {
125     goldfish_dma_context goldfish_dma;
126     uint32_t sz;
127     uint32_t refcount;
128     pthread_mutex_t lock;
129 };
130 
131 // global device instance
132 static gralloc_memregions_t* s_grdev = NULL;
133 static gralloc_dmaregion_t* s_grdma = NULL;
134 
init_gralloc_memregions()135 void init_gralloc_memregions() {
136     if (s_grdev) return;
137     s_grdev = new gralloc_memregions_t;
138 }
139 
init_gralloc_dmaregion()140 void init_gralloc_dmaregion() {
141     D("%s: call\n", __FUNCTION__);
142     if (s_grdma) return;
143 
144     s_grdma = new gralloc_dmaregion_t;
145     s_grdma->sz = INITIAL_DMA_REGION_SIZE;
146     s_grdma->refcount = 0;
147 
148     pthread_mutex_init(&s_grdma->lock, NULL);
149     pthread_mutex_lock(&s_grdma->lock);
150     goldfish_dma_create_region(s_grdma->sz, &s_grdma->goldfish_dma);
151     pthread_mutex_unlock(&s_grdma->lock);
152 }
153 
get_gralloc_dmaregion()154 void get_gralloc_dmaregion() {
155     if (!s_grdma) return;
156     pthread_mutex_lock(&s_grdma->lock);
157     s_grdma->refcount++;
158     D("%s: call. refcount: %u\n", __FUNCTION__, s_grdma->refcount);
159     pthread_mutex_unlock(&s_grdma->lock);
160 }
161 
resize_gralloc_dmaregion_locked(uint32_t new_sz)162 static void resize_gralloc_dmaregion_locked(uint32_t new_sz) {
163     if (!s_grdma) return;
164     if (s_grdma->goldfish_dma.mapped) {
165         goldfish_dma_unmap(&s_grdma->goldfish_dma);
166     }
167     close(s_grdma->goldfish_dma.fd);
168     goldfish_dma_create_region(new_sz, &s_grdma->goldfish_dma);
169     s_grdma->sz = new_sz;
170 }
171 
put_gralloc_dmaregion()172 bool put_gralloc_dmaregion() {
173     if (!s_grdma) return false;
174     pthread_mutex_lock(&s_grdma->lock);
175     D("%s: call. refcount before: %u\n", __FUNCTION__, s_grdma->refcount);
176     s_grdma->refcount--;
177     bool shouldDelete = !s_grdma->refcount;
178     if (shouldDelete) {
179         D("%s: should delete!\n", __FUNCTION__);
180         resize_gralloc_dmaregion_locked(INITIAL_DMA_REGION_SIZE);
181         D("%s: done\n", __FUNCTION__);
182     }
183     pthread_mutex_unlock(&s_grdma->lock);
184     D("%s: exit\n", __FUNCTION__);
185     return shouldDelete;
186 }
187 
gralloc_dmaregion_register_ashmem(uint32_t sz)188 void gralloc_dmaregion_register_ashmem(uint32_t sz) {
189     if (!s_grdma) return;
190     pthread_mutex_lock(&s_grdma->lock);
191     D("%s: for sz %u, refcount %u", __FUNCTION__, sz, s_grdma->refcount);
192     uint32_t new_sz = std::max(s_grdma->sz, sz);
193     if (new_sz != s_grdma->sz) {
194         D("%s: change sz from %u to %u", __FUNCTION__, s_grdma->sz, sz);
195         resize_gralloc_dmaregion_locked(new_sz);
196     }
197     if (!s_grdma->goldfish_dma.mapped) {
198         goldfish_dma_map(&s_grdma->goldfish_dma);
199     }
200     pthread_mutex_unlock(&s_grdma->lock);
201 }
202 
get_mem_region(void * ashmemBase)203 void get_mem_region(void* ashmemBase) {
204     init_gralloc_memregions();
205     D("%s: call for %p", __FUNCTION__, ashmemBase);
206     MemRegionInfo lookup;
207     lookup.ashmemBase = ashmemBase;
208     mem_region_handle_t handle = s_grdev->ashmemRegions.find(lookup);
209     if (handle == s_grdev->ashmemRegions.end()) {
210         MemRegionInfo newRegion;
211         newRegion.ashmemBase = ashmemBase;
212         newRegion.refCount = 1;
213         s_grdev->ashmemRegions.insert(newRegion);
214     } else {
215         handle->refCount++;
216     }
217 }
218 
put_mem_region(void * ashmemBase)219 bool put_mem_region(void* ashmemBase) {
220     init_gralloc_memregions();
221     D("%s: call for %p", __FUNCTION__, ashmemBase);
222     MemRegionInfo lookup;
223     lookup.ashmemBase = ashmemBase;
224     mem_region_handle_t handle = s_grdev->ashmemRegions.find(lookup);
225     if (handle == s_grdev->ashmemRegions.end()) {
226         ALOGE("%s: error: tried to put nonexistent mem region!", __FUNCTION__);
227         return true;
228     } else {
229         handle->refCount--;
230         bool shouldRemove = !handle->refCount;
231         if (shouldRemove) {
232             s_grdev->ashmemRegions.erase(lookup);
233         }
234         return shouldRemove;
235     }
236 }
237 
dump_regions()238 void dump_regions() {
239     init_gralloc_memregions();
240     mem_region_handle_t curr = s_grdev->ashmemRegions.begin();
241     std::stringstream res;
242     for (; curr != s_grdev->ashmemRegions.end(); curr++) {
243         res << "\tashmem base " << curr->ashmemBase << " refcount " << curr->refCount << "\n";
244     }
245     ALOGD("ashmem region dump [\n%s]", res.str().c_str());
246 }
247 
248 #if DEBUG
249 
250 #define GET_ASHMEM_REGION(cb) \
251     dump_regions(); \
252     get_mem_region((void*)cb->ashmemBase); \
253     dump_regions(); \
254 
255 #define PUT_ASHMEM_REGION(cb) \
256     dump_regions(); \
257     bool SHOULD_UNMAP = put_mem_region((void*)cb->ashmemBase); \
258     dump_regions(); \
259 
260 #else
261 
262 #define GET_ASHMEM_REGION(cb) \
263     get_mem_region((void*)cb->ashmemBase); \
264 
265 #define PUT_ASHMEM_REGION(cb) \
266     bool SHOULD_UNMAP = put_mem_region((void*)cb->ashmemBase); \
267 
268 #endif
269 
270 //
271 // Our framebuffer device structure
272 //
273 struct fb_device_t {
274     framebuffer_device_t  device;
275 };
276 
map_buffer(cb_handle_t * cb,void ** vaddr)277 static int map_buffer(cb_handle_t *cb, void **vaddr)
278 {
279     if (cb->fd < 0 || cb->ashmemSize <= 0) {
280         return -EINVAL;
281     }
282 
283     int map_flags = MAP_SHARED;
284     if (isHidlGralloc) map_flags |= MAP_ANONYMOUS;
285 
286     void *addr = mmap(0, cb->ashmemSize, PROT_READ | PROT_WRITE,
287                       MAP_SHARED, cb->fd, 0);
288     if (addr == MAP_FAILED) {
289         ALOGE("%s: failed to map ashmem region!", __FUNCTION__);
290         return -errno;
291     }
292 
293     cb->ashmemBase = intptr_t(addr);
294     cb->ashmemBasePid = getpid();
295     D("%s: %p mapped ashmem base %p size %d\n", __FUNCTION__,
296       cb, cb->ashmemBase, cb->ashmemSize);
297 
298     *vaddr = addr;
299     return 0;
300 }
301 
302 #define DEFINE_HOST_CONNECTION \
303     HostConnection *hostCon = HostConnection::get(); \
304     ExtendedRCEncoderContext *rcEnc = (hostCon ? hostCon->rcEncoder() : NULL)
305 
306 #define DEFINE_AND_VALIDATE_HOST_CONNECTION \
307     HostConnection *hostCon = HostConnection::get(); \
308     if (!hostCon) { \
309         ALOGE("gralloc: Failed to get host connection\n"); \
310         return -EIO; \
311     } \
312     ExtendedRCEncoderContext *rcEnc = hostCon->rcEncoder(); \
313     if (!rcEnc) { \
314         ALOGE("gralloc: Failed to get renderControl encoder context\n"); \
315         return -EIO; \
316     }
317 
318 #if PLATFORM_SDK_VERSION < 18
319 // On older APIs, just define it as a value no one is going to use.
320 #define HAL_PIXEL_FORMAT_YCbCr_420_888 0xFFFFFFFF
321 #endif
322 
updateHostColorBuffer(cb_handle_t * cb,bool doLocked,char * pixels)323 static void updateHostColorBuffer(cb_handle_t* cb,
324                               bool doLocked,
325                               char* pixels) {
326     D("%s: call. doLocked=%d", __FUNCTION__, doLocked);
327     DEFINE_HOST_CONNECTION;
328     int bpp = glUtilsPixelBitSize(cb->glFormat, cb->glType) >> 3;
329     int left = doLocked ? cb->lockedLeft : 0;
330     int top = doLocked ? cb->lockedTop : 0;
331     int width = doLocked ? cb->lockedWidth : cb->width;
332     int height = doLocked ? cb->lockedHeight : cb->height;
333 
334     char* to_send = pixels;
335     uint32_t rgbSz = width * height * bpp;
336     uint32_t send_buffer_size = rgbSz;
337     bool is_rgb_format =
338         cb->frameworkFormat != HAL_PIXEL_FORMAT_YV12 &&
339         cb->frameworkFormat != HAL_PIXEL_FORMAT_YCbCr_420_888;
340 
341     char* convertedBuf = NULL;
342     if ((doLocked && is_rgb_format) ||
343         (!s_grdma &&
344          (doLocked || !is_rgb_format))) {
345         convertedBuf = new char[rgbSz];
346         to_send = convertedBuf;
347         send_buffer_size = rgbSz;
348     }
349 
350     if (doLocked && is_rgb_format) {
351         copy_rgb_buffer_from_unlocked(
352                 to_send, pixels,
353                 cb->width,
354                 width, height, top, left, bpp);
355     }
356 
357     if (s_grdma) {
358         if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YV12) {
359             get_yv12_offsets(width, height, NULL, NULL,
360                              &send_buffer_size);
361         }
362         if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) {
363             get_yuv420p_offsets(width, height, NULL, NULL,
364                                 &send_buffer_size);
365         }
366 
367         rcEnc->bindDmaContext(&s_grdma->goldfish_dma);
368         D("%s: call. dma update with sz=%u", __FUNCTION__, send_buffer_size);
369         pthread_mutex_lock(&s_grdma->lock);
370         rcEnc->rcUpdateColorBufferDMA(rcEnc, cb->hostHandle,
371                 left, top, width, height,
372                 cb->glFormat, cb->glType,
373                 to_send, send_buffer_size);
374         pthread_mutex_unlock(&s_grdma->lock);
375     } else {
376         if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YV12) {
377             yv12_to_rgb888(to_send, pixels,
378                            width, height, left, top,
379                            left + width - 1, top + height - 1);
380         }
381         if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) {
382             yuv420p_to_rgb888(to_send, pixels,
383                               width, height, left, top,
384                               left + width - 1, top + height - 1);
385         }
386         rcEnc->rcUpdateColorBuffer(rcEnc, cb->hostHandle,
387                 left, top, width, height,
388                 cb->glFormat, cb->glType, to_send);
389     }
390 
391     if (convertedBuf) delete [] convertedBuf;
392 }
393 
394 #ifndef GL_RGBA16F
395 #define GL_RGBA16F                        0x881A
396 #endif // GL_RGBA16F
397 #ifndef GL_UNSIGNED_INT_10_10_10_2
398 #define GL_UNSIGNED_INT_10_10_10_2        0x8DF6
399 #endif // GL_UNSIGNED_INT_10_10_10_2
400 #ifndef GL_HALF_FLOAT
401 #define GL_HALF_FLOAT                     0x140B
402 #endif // GL_HALF_FLOAT
403 //
404 // gralloc device functions (alloc interface)
405 //
gralloc_alloc(alloc_device_t * dev,int w,int h,int format,int usage,buffer_handle_t * pHandle,int * pStride)406 static int gralloc_alloc(alloc_device_t* dev,
407                          int w, int h, int format, int usage,
408                          buffer_handle_t* pHandle, int* pStride)
409 {
410     D("gralloc_alloc w=%d h=%d usage=0x%x format=0x%x\n", w, h, usage, format);
411 
412     gralloc_device_t *grdev = (gralloc_device_t *)dev;
413     if (!grdev || !pHandle || !pStride) {
414         ALOGE("gralloc_alloc: Bad inputs (grdev: %p, pHandle: %p, pStride: %p",
415                 grdev, pHandle, pStride);
416         return -EINVAL;
417     }
418 
419     //
420     // Note: in screen capture mode, both sw_write and hw_write will be on
421     // and this is a valid usage
422     //
423     bool sw_write = (0 != (usage & GRALLOC_USAGE_SW_WRITE_MASK));
424     bool hw_write = (usage & GRALLOC_USAGE_HW_RENDER);
425     bool sw_read = (0 != (usage & GRALLOC_USAGE_SW_READ_MASK));
426 #if PLATFORM_SDK_VERSION >= 17
427     bool hw_cam_write = (usage & GRALLOC_USAGE_HW_CAMERA_WRITE);
428     bool hw_cam_read = (usage & GRALLOC_USAGE_HW_CAMERA_READ);
429 #else // PLATFORM_SDK_VERSION
430     bool hw_cam_write = false;
431     bool hw_cam_read = false;
432 #endif // PLATFORM_SDK_VERSION
433 #if PLATFORM_SDK_VERSION >= 15
434     bool hw_vid_enc_read = usage & GRALLOC_USAGE_HW_VIDEO_ENCODER;
435 #else // PLATFORM_SDK_VERSION
436     bool hw_vid_enc_read = false;
437 #endif // PLATFORM_SDK_VERSION
438 
439     // Keep around original requested format for later validation
440     int frameworkFormat = format;
441     // Pick the right concrete pixel format given the endpoints as encoded in
442     // the usage bits.  Every end-point pair needs explicit listing here.
443 #if PLATFORM_SDK_VERSION >= 17
444     if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
445         // Camera as producer
446         if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
447             if (usage & GRALLOC_USAGE_HW_TEXTURE) {
448                 // Camera-to-display is RGBA
449                 format = HAL_PIXEL_FORMAT_RGBA_8888;
450             } else if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
451                 // Camera-to-encoder is NV21
452                 format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
453             } else if ((usage & GRALLOC_USAGE_HW_CAMERA_MASK) ==
454                     GRALLOC_USAGE_HW_CAMERA_ZSL) {
455                 // Camera-to-ZSL-queue is RGB_888
456                 format = HAL_PIXEL_FORMAT_RGB_888;
457             }
458         }
459 
460         if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
461             ALOGE("gralloc_alloc: Requested auto format selection, "
462                     "but no known format for this usage: %d x %d, usage %x",
463                     w, h, usage);
464             return -EINVAL;
465         }
466     }
467     else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
468         ALOGW("gralloc_alloc: Requested YCbCr_420_888, taking experimental path. "
469                 "usage: %d x %d, usage %x",
470                 w, h, usage);
471     }
472 #endif // PLATFORM_SDK_VERSION >= 17
473     bool yuv_format = false;
474 
475     int ashmem_size = 0;
476     int stride = w;
477 
478     GLenum glFormat = 0;
479     GLenum glType = 0;
480     EmulatorFrameworkFormat selectedEmuFrameworkFormat = FRAMEWORK_FORMAT_GL_COMPATIBLE;
481 
482     int bpp = 0;
483     int align = 1;
484     switch (format) {
485         case HAL_PIXEL_FORMAT_RGBA_8888:
486         case HAL_PIXEL_FORMAT_RGBX_8888:
487         case HAL_PIXEL_FORMAT_BGRA_8888:
488             bpp = 4;
489             glFormat = GL_RGBA;
490             glType = GL_UNSIGNED_BYTE;
491             break;
492         case HAL_PIXEL_FORMAT_RGB_888:
493             bpp = 3;
494             glFormat = GL_RGB;
495             glType = GL_UNSIGNED_BYTE;
496             break;
497         case HAL_PIXEL_FORMAT_RGB_565:
498             bpp = 2;
499             glFormat = GL_RGB;
500             glType = GL_UNSIGNED_SHORT_5_6_5;
501             break;
502 #if PLATFORM_SDK_VERSION >= 26
503         case HAL_PIXEL_FORMAT_RGBA_FP16:
504             bpp = 8;
505             glFormat = GL_RGBA16F;
506             glType = GL_HALF_FLOAT;
507             break;
508         case HAL_PIXEL_FORMAT_RGBA_1010102:
509             bpp = 4;
510             glFormat = GL_RGBA;
511             glType = GL_UNSIGNED_INT_10_10_10_2;
512             break;
513 #endif // PLATFORM_SDK_VERSION >= 26
514 #if PLATFORM_SDK_VERSION >= 21
515         case HAL_PIXEL_FORMAT_RAW16:
516         case HAL_PIXEL_FORMAT_Y16:
517 #elif PLATFORM_SDK_VERSION >= 16
518         case HAL_PIXEL_FORMAT_RAW_SENSOR:
519 #endif
520             bpp = 2;
521             align = 16*bpp;
522             if (! ((sw_read || hw_cam_read) && (sw_write || hw_cam_write) ) ) {
523                 // Raw sensor data or Y16 only goes between camera and CPU
524                 return -EINVAL;
525             }
526             // Not expecting to actually create any GL surfaces for this
527             glFormat = GL_LUMINANCE;
528             glType = GL_UNSIGNED_SHORT;
529             break;
530 #if PLATFORM_SDK_VERSION >= 17
531         case HAL_PIXEL_FORMAT_BLOB:
532             bpp = 1;
533             if (! (sw_read) ) {
534                 // Blob data cannot be used by HW other than camera emulator
535                 // But there is a CTS test trying to have access to it
536                 // BUG: https://buganizer.corp.google.com/issues/37719518
537                 return -EINVAL;
538             }
539             // Not expecting to actually create any GL surfaces for this
540             glFormat = GL_LUMINANCE;
541             glType = GL_UNSIGNED_BYTE;
542             break;
543 #endif // PLATFORM_SDK_VERSION >= 17
544         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
545             align = 1;
546             bpp = 1; // per-channel bpp
547             yuv_format = true;
548             // Not expecting to actually create any GL surfaces for this
549             break;
550         case HAL_PIXEL_FORMAT_YV12:
551             align = 16;
552             bpp = 1; // per-channel bpp
553             yuv_format = true;
554             // We are going to use RGB888 on the host
555             glFormat = GL_RGB;
556             glType = GL_UNSIGNED_BYTE;
557             selectedEmuFrameworkFormat = FRAMEWORK_FORMAT_YV12;
558             break;
559         case HAL_PIXEL_FORMAT_YCbCr_420_888:
560             align = 1;
561             bpp = 1; // per-channel bpp
562             yuv_format = true;
563             // We are going to use RGB888 on the host
564             glFormat = GL_RGB;
565             glType = GL_UNSIGNED_BYTE;
566             selectedEmuFrameworkFormat = FRAMEWORK_FORMAT_YUV_420_888;
567             break;
568         default:
569             ALOGE("gralloc_alloc: Unknown format %d", format);
570             return -EINVAL;
571     }
572 
573     //
574     // Allocate ColorBuffer handle on the host (only if h/w access is allowed)
575     // Only do this for some h/w usages, not all.
576     // Also do this if we need to read from the surface, in this case the
577     // rendering will still happen on the host but we also need to be able to
578     // read back from the color buffer, which requires that there is a buffer
579     //
580     bool needHostCb = (!yuv_format ||
581                        frameworkFormat == HAL_PIXEL_FORMAT_YV12 ||
582                        frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) &&
583 #if PLATFORM_SDK_VERSION >= 15
584                       (usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER |
585                                 GRALLOC_USAGE_HW_2D | GRALLOC_USAGE_HW_COMPOSER |
586                                 GRALLOC_USAGE_HW_VIDEO_ENCODER |
587                                 GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_SW_READ_MASK))
588 #else // PLATFORM_SDK_VERSION
589                       (usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER |
590                                 GRALLOC_USAGE_HW_2D |
591                                 GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_SW_READ_MASK))
592 #endif // PLATFORM_SDK_VERSION
593                       ;
594 
595     if (isHidlGralloc) {
596         if (needHostCb || (usage & GRALLOC_USAGE_HW_FB)) {
597             // keep space for postCounter
598             // AND openCounter for all host cb
599             ashmem_size += sizeof(uint32_t) * 2;
600         }
601     } else {
602         if (usage & GRALLOC_USAGE_HW_FB) {
603             // keep space for postCounter
604             ashmem_size += sizeof(uint32_t) * 1;
605         }
606     }
607 
608     // API26 always expect at least one file descriptor is associated with
609     // one color buffer
610     // BUG: 37719038
611     if (PLATFORM_SDK_VERSION >= 26 ||
612         sw_read || sw_write || hw_cam_write || hw_vid_enc_read) {
613         // keep space for image on guest memory if SW access is needed
614         // or if the camera is doing writing
615         if (yuv_format) {
616             size_t yStride = (w*bpp + (align - 1)) & ~(align-1);
617             size_t uvStride = (yStride / 2 + (align - 1)) & ~(align-1);
618             size_t uvHeight = h / 2;
619             ashmem_size += yStride * h + 2 * (uvHeight * uvStride);
620             stride = yStride / bpp;
621         } else {
622             size_t bpr = (w*bpp + (align-1)) & ~(align-1);
623             ashmem_size += (bpr * h);
624             stride = bpr / bpp;
625         }
626     }
627 
628     D("gralloc_alloc format=%d, ashmem_size=%d, stride=%d, tid %d\n", format,
629             ashmem_size, stride, gettid());
630 
631     //
632     // Allocate space in ashmem if needed
633     //
634     int fd = -1;
635     if (ashmem_size > 0) {
636         // round to page size;
637         ashmem_size = (ashmem_size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
638 
639         ALOGD("%s: Creating ashmem region of size %lu\n", __FUNCTION__, ashmem_size);
640         fd = ashmem_create_region("gralloc-buffer", ashmem_size);
641         if (fd < 0) {
642             ALOGE("gralloc_alloc failed to create ashmem region: %s\n",
643                     strerror(errno));
644             return -errno;
645         }
646     }
647 
648     cb_handle_t *cb = new cb_handle_t(fd, ashmem_size, usage,
649                                       w, h, frameworkFormat, format,
650                                       glFormat, glType, selectedEmuFrameworkFormat);
651 
652     DEFINE_HOST_CONNECTION;
653     if (ashmem_size > 0) {
654 
655         //
656         // map ashmem region if exist
657         //
658         void *vaddr;
659         int err = map_buffer(cb, &vaddr);
660         if (err) {
661             close(fd);
662             delete cb;
663             return err;
664         }
665 
666         cb->setFd(fd);
667 
668         if (rcEnc->getDmaVersion() > 0) {
669             D("%s: creating goldfish dma region of size %lu (cb fd %d)\n", __FUNCTION__, ashmem_size, cb->fd);
670             init_gralloc_dmaregion();
671             get_gralloc_dmaregion();
672         } else {
673             cb->goldfish_dma.fd = -1;
674         }
675     } else {
676         cb->goldfish_dma.fd = -1;
677     }
678 
679     if (needHostCb) {
680         if (hostCon && rcEnc) {
681             if (s_grdma) {
682                 cb->hostHandle = rcEnc->rcCreateColorBufferDMA(rcEnc, w, h, glFormat, cb->emuFrameworkFormat);
683             } else {
684                 cb->hostHandle = rcEnc->rcCreateColorBuffer(rcEnc, w, h, glFormat);
685             }
686             D("Created host ColorBuffer 0x%x\n", cb->hostHandle);
687         }
688 
689         if (!cb->hostHandle) {
690             // Could not create colorbuffer on host !!!
691             close(fd);
692             delete cb;
693             ALOGD("%s: failed to create host cb! -EIO", __FUNCTION__);
694             return -EIO;
695         }
696 
697         if (isHidlGralloc) { *getOpenCountPtr(cb) = 0; }
698     }
699 
700     //
701     // alloc succeeded - insert the allocated handle to the allocated list
702     //
703     AllocListNode *node = new AllocListNode();
704     pthread_mutex_lock(&grdev->lock);
705     node->handle = cb;
706     node->next =  grdev->allocListHead;
707     node->prev =  NULL;
708     if (grdev->allocListHead) {
709         grdev->allocListHead->prev = node;
710     }
711     grdev->allocListHead = node;
712     pthread_mutex_unlock(&grdev->lock);
713 
714     *pHandle = cb;
715     D("%s: alloc succeded, new ashmem base and size: %p %d handle: %p",
716       __FUNCTION__, cb->ashmemBase, cb->ashmemSize, cb);
717     switch (frameworkFormat) {
718     case HAL_PIXEL_FORMAT_YCbCr_420_888:
719         *pStride = 0;
720         break;
721     default:
722         *pStride = stride;
723         break;
724     }
725     return 0;
726 }
727 
gralloc_free(alloc_device_t * dev,buffer_handle_t handle)728 static int gralloc_free(alloc_device_t* dev,
729                         buffer_handle_t handle)
730 {
731     cb_handle_t *cb = (cb_handle_t *)handle;
732     if (!cb_handle_t::validate((cb_handle_t*)cb)) {
733         ERR("gralloc_free: invalid handle");
734         return -EINVAL;
735     }
736 
737     D("%s: for buf %p ptr %p size %d\n",
738       __FUNCTION__, handle, cb->ashmemBase, cb->ashmemSize);
739 
740     if (cb->hostHandle) {
741         int32_t openCount = 1;
742         int32_t* openCountPtr = &openCount;
743 
744         if (isHidlGralloc) { openCountPtr = getOpenCountPtr(cb); }
745 
746         if (*openCountPtr > 0) {
747             DEFINE_AND_VALIDATE_HOST_CONNECTION;
748             D("Closing host ColorBuffer 0x%x\n", cb->hostHandle);
749             rcEnc->rcCloseColorBuffer(rcEnc, cb->hostHandle);
750         } else {
751             D("A rcCloseColorBuffer is owed!!! sdk ver: %d", PLATFORM_SDK_VERSION);
752             *openCountPtr = -1;
753         }
754     }
755 
756     //
757     // detach and unmap ashmem area if present
758     //
759     if (cb->fd > 0) {
760         if (cb->ashmemSize > 0 && cb->ashmemBase) {
761             D("%s: unmapped %p", __FUNCTION__, cb->ashmemBase);
762             munmap((void *)cb->ashmemBase, cb->ashmemSize);
763             put_gralloc_dmaregion();
764         }
765         close(cb->fd);
766     }
767 
768     D("%s: done", __FUNCTION__);
769     // remove it from the allocated list
770     gralloc_device_t *grdev = (gralloc_device_t *)dev;
771     pthread_mutex_lock(&grdev->lock);
772     AllocListNode *n = grdev->allocListHead;
773     while( n && n->handle != cb ) {
774         n = n->next;
775     }
776     if (n) {
777        // buffer found on list - remove it from list
778        if (n->next) {
779            n->next->prev = n->prev;
780        }
781        if (n->prev) {
782            n->prev->next = n->next;
783        }
784        else {
785            grdev->allocListHead = n->next;
786        }
787 
788        delete n;
789     }
790     pthread_mutex_unlock(&grdev->lock);
791 
792     delete cb;
793 
794     D("%s: exit", __FUNCTION__);
795     return 0;
796 }
797 
gralloc_device_close(struct hw_device_t * dev)798 static int gralloc_device_close(struct hw_device_t *dev)
799 {
800     gralloc_device_t* d = reinterpret_cast<gralloc_device_t*>(dev);
801     if (d) {
802 
803         // free still allocated buffers
804         while( d->allocListHead != NULL ) {
805             gralloc_free(&d->device, d->allocListHead->handle);
806         }
807 
808         // free device
809         free(d);
810     }
811     return 0;
812 }
813 
fb_compositionComplete(struct framebuffer_device_t * dev)814 static int fb_compositionComplete(struct framebuffer_device_t* dev)
815 {
816     (void)dev;
817 
818     return 0;
819 }
820 
821 //
822 // Framebuffer device functions
823 //
fb_post(struct framebuffer_device_t * dev,buffer_handle_t buffer)824 static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
825 {
826     fb_device_t *fbdev = (fb_device_t *)dev;
827     cb_handle_t *cb = (cb_handle_t *)buffer;
828 
829     if (!fbdev || !cb_handle_t::validate(cb) || !cb->canBePosted()) {
830         return -EINVAL;
831     }
832 
833     // Make sure we have host connection
834     DEFINE_AND_VALIDATE_HOST_CONNECTION;
835 
836     // increment the post count of the buffer
837     intptr_t *postCountPtr = (intptr_t *)cb->ashmemBase;
838     if (!postCountPtr) {
839         // This should not happen
840         return -EINVAL;
841     }
842     (*postCountPtr)++;
843 
844     // send post request to host
845     rcEnc->rcFBPost(rcEnc, cb->hostHandle);
846     hostCon->flush();
847 
848     return 0;
849 }
850 
fb_setUpdateRect(struct framebuffer_device_t * dev,int l,int t,int w,int h)851 static int fb_setUpdateRect(struct framebuffer_device_t* dev,
852         int l, int t, int w, int h)
853 {
854     fb_device_t *fbdev = (fb_device_t *)dev;
855 
856     (void)l;
857     (void)t;
858     (void)w;
859     (void)h;
860 
861     if (!fbdev) {
862         return -EINVAL;
863     }
864 
865     // Make sure we have host connection
866     DEFINE_AND_VALIDATE_HOST_CONNECTION;
867 
868     // send request to host
869     // TODO: XXX - should be implemented
870     //rcEnc->rc_XXX
871 
872     return 0;
873 }
874 
fb_setSwapInterval(struct framebuffer_device_t * dev,int interval)875 static int fb_setSwapInterval(struct framebuffer_device_t* dev,
876             int interval)
877 {
878     fb_device_t *fbdev = (fb_device_t *)dev;
879 
880     if (!fbdev) {
881         return -EINVAL;
882     }
883 
884     // Make sure we have host connection
885     DEFINE_AND_VALIDATE_HOST_CONNECTION;
886 
887     // send request to host
888     rcEnc->rcFBSetSwapInterval(rcEnc, interval);
889     hostCon->flush();
890 
891     return 0;
892 }
893 
fb_close(struct hw_device_t * dev)894 static int fb_close(struct hw_device_t *dev)
895 {
896     fb_device_t *fbdev = (fb_device_t *)dev;
897 
898     delete fbdev;
899 
900     return 0;
901 }
902 
903 
904 //
905 // gralloc module functions - refcount + locking interface
906 //
gralloc_register_buffer(gralloc_module_t const * module,buffer_handle_t handle)907 static int gralloc_register_buffer(gralloc_module_t const* module,
908                                    buffer_handle_t handle)
909 {
910 
911     D("%s: start", __FUNCTION__);
912     pthread_once(&sFallbackOnce, fallback_init);
913     if (sFallback != NULL) {
914         return sFallback->registerBuffer(sFallback, handle);
915     }
916 
917     D("gralloc_register_buffer(%p) called", handle);
918 
919     private_module_t *gr = (private_module_t *)module;
920     cb_handle_t *cb = (cb_handle_t *)handle;
921 
922     if (!gr || !cb_handle_t::validate(cb)) {
923         ERR("gralloc_register_buffer(%p): invalid buffer", cb);
924         return -EINVAL;
925     }
926 
927     if (cb->hostHandle != 0) {
928         DEFINE_AND_VALIDATE_HOST_CONNECTION;
929         D("Opening host ColorBuffer 0x%x\n", cb->hostHandle);
930         rcEnc->rcOpenColorBuffer2(rcEnc, cb->hostHandle);
931     }
932 
933     //
934     // if the color buffer has ashmem region and it is not mapped in this
935     // process map it now.
936     //
937     if (cb->ashmemSize > 0 && cb->mappedPid != getpid()) {
938         void *vaddr;
939         int err = map_buffer(cb, &vaddr);
940         if (err) {
941             ERR("gralloc_register_buffer(%p): map failed: %s", cb, strerror(-err));
942             return -err;
943         }
944         cb->mappedPid = getpid();
945 
946         if (isHidlGralloc) {
947             int32_t* openCountPtr = getOpenCountPtr(cb);
948             if (!*openCountPtr) *openCountPtr = 1;
949         }
950 
951         DEFINE_AND_VALIDATE_HOST_CONNECTION;
952         if (rcEnc->getDmaVersion() > 0) {
953             init_gralloc_dmaregion();
954             gralloc_dmaregion_register_ashmem(cb->ashmemSize);
955         }
956 
957     }
958 
959     if (cb->ashmemSize > 0) {
960         GET_ASHMEM_REGION(cb);
961         get_gralloc_dmaregion();
962     }
963 
964     return 0;
965 }
966 
gralloc_unregister_buffer(gralloc_module_t const * module,buffer_handle_t handle)967 static int gralloc_unregister_buffer(gralloc_module_t const* module,
968                                      buffer_handle_t handle)
969 {
970     if (sFallback != NULL) {
971         return sFallback->unregisterBuffer(sFallback, handle);
972     }
973 
974     private_module_t *gr = (private_module_t *)module;
975     cb_handle_t *cb = (cb_handle_t *)handle;
976 
977     if (!gr || !cb_handle_t::validate(cb)) {
978         ERR("gralloc_unregister_buffer(%p): invalid buffer", cb);
979         return -EINVAL;
980     }
981 
982 
983     if (cb->hostHandle) {
984         D("Closing host ColorBuffer 0x%x\n", cb->hostHandle);
985         DEFINE_AND_VALIDATE_HOST_CONNECTION;
986         rcEnc->rcCloseColorBuffer(rcEnc, cb->hostHandle);
987 
988         if (isHidlGralloc) {
989             // Queue up another rcCloseColorBuffer if applicable.
990             // invariant: have ashmem.
991             if (cb->ashmemSize > 0 && cb->mappedPid == getpid()) {
992                 int32_t* openCountPtr = getOpenCountPtr(cb);
993                 if (*openCountPtr == -1) {
994                     D("%s: revenge of the rcCloseColorBuffer!", __func__);
995                     rcEnc->rcCloseColorBuffer(rcEnc, cb->hostHandle);
996                     *openCountPtr = -2;
997                 }
998             }
999         }
1000     }
1001 
1002     //
1003     // unmap ashmem region if it was previously mapped in this process
1004     // (through register_buffer)
1005     //
1006     if (cb->ashmemSize > 0 && cb->mappedPid == getpid()) {
1007 
1008         PUT_ASHMEM_REGION(cb);
1009         put_gralloc_dmaregion();
1010 
1011         if (!SHOULD_UNMAP) goto done;
1012 
1013         DEFINE_AND_VALIDATE_HOST_CONNECTION;
1014 
1015         void *vaddr;
1016         int err = munmap((void *)cb->ashmemBase, cb->ashmemSize);
1017         if (err) {
1018             ERR("gralloc_unregister_buffer(%p): unmap failed", cb);
1019             return -EINVAL;
1020         }
1021         cb->ashmemBase = 0;
1022         cb->mappedPid = 0;
1023         D("%s: Unregister buffer previous mapped to pid %d", __FUNCTION__, getpid());
1024     }
1025 
1026 done:
1027     D("gralloc_unregister_buffer(%p) done\n", cb);
1028     return 0;
1029 }
1030 
1031 
1032 
gralloc_lock(gralloc_module_t const * module,buffer_handle_t handle,int usage,int l,int t,int w,int h,void ** vaddr)1033 static int gralloc_lock(gralloc_module_t const* module,
1034                         buffer_handle_t handle, int usage,
1035                         int l, int t, int w, int h,
1036                         void** vaddr)
1037 {
1038     if (sFallback != NULL) {
1039         return sFallback->lock(sFallback, handle, usage, l, t, w, h, vaddr);
1040     }
1041 
1042     private_module_t *gr = (private_module_t *)module;
1043     cb_handle_t *cb = (cb_handle_t *)handle;
1044 
1045     if (!gr || !cb_handle_t::validate(cb)) {
1046         ALOGE("gralloc_lock bad handle\n");
1047         return -EINVAL;
1048     }
1049 
1050     // Validate usage,
1051     //   1. cannot be locked for hw access
1052     //   2. lock for either sw read or write.
1053     //   3. locked sw access must match usage during alloc time.
1054     bool sw_read = (0 != (usage & GRALLOC_USAGE_SW_READ_MASK));
1055     bool sw_write = (0 != (usage & GRALLOC_USAGE_SW_WRITE_MASK));
1056     bool hw_read = (usage & GRALLOC_USAGE_HW_TEXTURE);
1057     bool hw_write = (usage & GRALLOC_USAGE_HW_RENDER);
1058 #if PLATFORM_SDK_VERSION >= 17
1059     bool hw_cam_write = (usage & GRALLOC_USAGE_HW_CAMERA_WRITE);
1060     bool hw_cam_read = (usage & GRALLOC_USAGE_HW_CAMERA_READ);
1061 #else // PLATFORM_SDK_VERSION
1062     bool hw_cam_write = false;
1063     bool hw_cam_read = false;
1064 #endif // PLATFORM_SDK_VERSION
1065 
1066 #if PLATFORM_SDK_VERSION >= 15
1067     bool hw_vid_enc_read = (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER);
1068 #else // PLATFORM_SDK_VERSION
1069     bool hw_vid_enc_read = false;
1070 #endif // PLATFORM_SDK_VERSION
1071 
1072     bool sw_read_allowed = (0 != (cb->usage & GRALLOC_USAGE_SW_READ_MASK));
1073 
1074 #if PLATFORM_SDK_VERSION >= 15
1075     // bug: 30088791
1076     // a buffer was created for GRALLOC_USAGE_HW_VIDEO_ENCODER usage but
1077     // later a software encoder is reading this buffer: this is actually
1078     // legit usage.
1079     sw_read_allowed = sw_read_allowed || (cb->usage & GRALLOC_USAGE_HW_VIDEO_ENCODER);
1080 #endif // PLATFORM_SDK_VERSION >= 15
1081 
1082     bool sw_write_allowed = (0 != (cb->usage & GRALLOC_USAGE_SW_WRITE_MASK));
1083 
1084     if ( (hw_read || hw_write) ||
1085          (!sw_read && !sw_write &&
1086                  !hw_cam_write && !hw_cam_read &&
1087                  !hw_vid_enc_read) ||
1088          (sw_read && !sw_read_allowed) ||
1089          (sw_write && !sw_write_allowed) ) {
1090         ALOGE("gralloc_lock usage mismatch usage=0x%x cb->usage=0x%x\n", usage,
1091                 cb->usage);
1092         //This is not exactly an error and loose it up.
1093         //bug: 30784436
1094         //return -EINVAL;
1095     }
1096 
1097     intptr_t postCount = 0;
1098     void *cpu_addr = NULL;
1099 
1100     //
1101     // make sure ashmem area is mapped if needed
1102     //
1103     if (cb->canBePosted() || sw_read || sw_write ||
1104             hw_cam_write || hw_cam_read ||
1105             hw_vid_enc_read) {
1106         if (cb->ashmemBasePid != getpid() || !cb->ashmemBase) {
1107             return -EACCES;
1108         }
1109 
1110         cpu_addr = (void *)(cb->ashmemBase + getAshmemColorOffset(cb));
1111     }
1112 
1113     if (cb->hostHandle) {
1114         // Make sure we have host connection
1115         DEFINE_AND_VALIDATE_HOST_CONNECTION;
1116 
1117         //
1118         // flush color buffer write cache on host and get its sync status.
1119         //
1120         int hostSyncStatus = rcEnc->rcColorBufferCacheFlush(rcEnc, cb->hostHandle,
1121                                                             postCount,
1122                                                             sw_read);
1123         if (hostSyncStatus < 0) {
1124             // host failed the color buffer sync - probably since it was already
1125             // locked for write access. fail the lock.
1126             ALOGE("gralloc_lock cacheFlush failed postCount=%d sw_read=%d\n",
1127                  postCount, sw_read);
1128             return -EBUSY;
1129         }
1130 
1131         if (sw_read) {
1132             void* rgb_addr = cpu_addr;
1133             char* tmpBuf = 0;
1134             if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YV12 ||
1135                 cb->frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) {
1136                 // We are using RGB888
1137                 tmpBuf = new char[cb->width * cb->height * 3];
1138                 rgb_addr = tmpBuf;
1139             }
1140             D("gralloc_lock read back color buffer %d %d ashmem base %p sz %d\n",
1141               cb->width, cb->height, cb->ashmemBase, cb->ashmemSize);
1142             rcEnc->rcReadColorBuffer(rcEnc, cb->hostHandle,
1143                     0, 0, cb->width, cb->height, cb->glFormat, cb->glType, rgb_addr);
1144             if (tmpBuf) {
1145                 if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YV12) {
1146                     rgb888_to_yv12((char*)cpu_addr, tmpBuf, cb->width, cb->height, l, t, l+w-1, t+h-1);
1147                 } else if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) {
1148                     rgb888_to_yuv420p((char*)cpu_addr, tmpBuf, cb->width, cb->height, l, t, l+w-1, t+h-1);
1149                 }
1150                 delete [] tmpBuf;
1151             }
1152         }
1153     }
1154 
1155     //
1156     // is virtual address required ?
1157     //
1158     if (sw_read || sw_write || hw_cam_write || hw_cam_read || hw_vid_enc_read) {
1159         *vaddr = cpu_addr;
1160     }
1161 
1162     if (sw_write || hw_cam_write) {
1163         //
1164         // Keep locked region if locked for s/w write access.
1165         //
1166         cb->lockedLeft = l;
1167         cb->lockedTop = t;
1168         cb->lockedWidth = w;
1169         cb->lockedHeight = h;
1170     }
1171 
1172     DD("gralloc_lock success. vaddr: %p, *vaddr: %p, usage: %x, cpu_addr: %p",
1173             vaddr, vaddr ? *vaddr : 0, usage, cpu_addr);
1174 
1175     return 0;
1176 }
1177 
gralloc_unlock(gralloc_module_t const * module,buffer_handle_t handle)1178 static int gralloc_unlock(gralloc_module_t const* module,
1179                           buffer_handle_t handle)
1180 {
1181     if (sFallback != NULL) {
1182         return sFallback->unlock(sFallback, handle);
1183     }
1184 
1185     private_module_t *gr = (private_module_t *)module;
1186     cb_handle_t *cb = (cb_handle_t *)handle;
1187 
1188     if (!gr || !cb_handle_t::validate(cb)) {
1189         ALOGD("%s: invalid gr or cb handle. -EINVAL", __FUNCTION__);
1190         return -EINVAL;
1191     }
1192 
1193     //
1194     // if buffer was locked for s/w write, we need to update the host with
1195     // the updated data
1196     //
1197     if (cb->hostHandle) {
1198 
1199         // Make sure we have host connection
1200         DEFINE_AND_VALIDATE_HOST_CONNECTION;
1201 
1202         void *cpu_addr = (void *)(cb->ashmemBase + getAshmemColorOffset(cb));
1203 
1204         char* rgb_addr = (char *)cpu_addr;
1205         if (cb->lockedWidth < cb->width || cb->lockedHeight < cb->height) {
1206             updateHostColorBuffer(cb, true, rgb_addr);
1207         }
1208         else {
1209             updateHostColorBuffer(cb, false, rgb_addr);
1210         }
1211 
1212         DD("gralloc_unlock success. cpu_addr: %p", cpu_addr);
1213     }
1214 
1215     cb->lockedWidth = cb->lockedHeight = 0;
1216     return 0;
1217 }
1218 
1219 #if PLATFORM_SDK_VERSION >= 18
gralloc_lock_ycbcr(gralloc_module_t const * module,buffer_handle_t handle,int usage,int l,int t,int w,int h,android_ycbcr * ycbcr)1220 static int gralloc_lock_ycbcr(gralloc_module_t const* module,
1221                         buffer_handle_t handle, int usage,
1222                         int l, int t, int w, int h,
1223                         android_ycbcr *ycbcr)
1224 {
1225     // Not supporting fallback module for YCbCr
1226     if (sFallback != NULL) {
1227         ALOGD("%s: has fallback, return -EINVAL", __FUNCTION__);
1228         return -EINVAL;
1229     }
1230 
1231     if (!ycbcr) {
1232         ALOGE("%s: got NULL ycbcr struct! -EINVAL", __FUNCTION__);
1233         return -EINVAL;
1234     }
1235 
1236     private_module_t *gr = (private_module_t *)module;
1237     cb_handle_t *cb = (cb_handle_t *)handle;
1238     if (!gr || !cb_handle_t::validate(cb)) {
1239         ALOGE("%s: bad colorbuffer handle. -EINVAL", __FUNCTION__);
1240         return -EINVAL;
1241     }
1242 
1243     if (cb->frameworkFormat != HAL_PIXEL_FORMAT_YV12 &&
1244         cb->frameworkFormat != HAL_PIXEL_FORMAT_YCbCr_420_888) {
1245         ALOGE("gralloc_lock_ycbcr can only be used with "
1246                 "HAL_PIXEL_FORMAT_YCbCr_420_888 or HAL_PIXEL_FORMAT_YV12, got %x instead. "
1247                 "-EINVAL",
1248                 cb->frameworkFormat);
1249         return -EINVAL;
1250     }
1251 
1252     // Make sure memory is mapped, get address
1253     if (cb->ashmemBasePid != getpid() || !cb->ashmemBase) {
1254         ALOGD("%s: ashmembase not mapped. -EACCESS", __FUNCTION__);
1255         return -EACCES;
1256     }
1257 
1258     uint8_t *cpu_addr = NULL;
1259     cpu_addr = (uint8_t *)(cb->ashmemBase) + getAshmemColorOffset(cb);
1260 
1261     // Calculate offsets to underlying YUV data
1262     size_t yStride;
1263     size_t cStride;
1264     size_t cSize;
1265     size_t yOffset;
1266     size_t uOffset;
1267     size_t vOffset;
1268     size_t cStep;
1269     size_t align;
1270     switch (cb->format) {
1271         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1272             yStride = cb->width;
1273             cStride = cb->width;
1274             yOffset = 0;
1275             vOffset = yStride * cb->height;
1276             uOffset = vOffset + 1;
1277             cStep = 2;
1278             break;
1279         case HAL_PIXEL_FORMAT_YV12:
1280             // https://developer.android.com/reference/android/graphics/ImageFormat.html#YV12
1281             align = 16;
1282             yStride = (cb->width + (align -1)) & ~(align-1);
1283             cStride = (yStride / 2 + (align - 1)) & ~(align-1);
1284             yOffset = 0;
1285             cSize = cStride * cb->height/2;
1286             vOffset = yStride * cb->height;
1287             uOffset = vOffset + cSize;
1288             cStep = 1;
1289             break;
1290         case HAL_PIXEL_FORMAT_YCbCr_420_888:
1291             align = 1;
1292             yStride = cb->width;
1293             cStride = yStride / 2;
1294             yOffset = 0;
1295             cSize = cStride * cb->height/2;
1296             uOffset = yStride * cb->height;
1297             vOffset = uOffset + cSize;
1298             cStep = 1;
1299             break;
1300         default:
1301             ALOGE("gralloc_lock_ycbcr unexpected internal format %x",
1302                     cb->format);
1303             return -EINVAL;
1304     }
1305 
1306     ycbcr->y = cpu_addr + yOffset;
1307     ycbcr->cb = cpu_addr + uOffset;
1308     ycbcr->cr = cpu_addr + vOffset;
1309     ycbcr->ystride = yStride;
1310     ycbcr->cstride = cStride;
1311     ycbcr->chroma_step = cStep;
1312 
1313     // Zero out reserved fields
1314     memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
1315 
1316     //
1317     // Keep locked region if locked for s/w write access.
1318     //
1319     cb->lockedLeft = l;
1320     cb->lockedTop = t;
1321     cb->lockedWidth = w;
1322     cb->lockedHeight = h;
1323 
1324     DD("gralloc_lock_ycbcr success. usage: %x, ycbcr.y: %p, .cb: %p, .cr: %p, "
1325             ".ystride: %d , .cstride: %d, .chroma_step: %d", usage,
1326             ycbcr->y, ycbcr->cb, ycbcr->cr, ycbcr->ystride, ycbcr->cstride,
1327             ycbcr->chroma_step);
1328 
1329     return 0;
1330 }
1331 #endif // PLATFORM_SDK_VERSION >= 18
1332 
gralloc_device_open(const hw_module_t * module,const char * name,hw_device_t ** device)1333 static int gralloc_device_open(const hw_module_t* module,
1334                                const char* name,
1335                                hw_device_t** device)
1336 {
1337     int status = -EINVAL;
1338 
1339     D("gralloc_device_open %s\n", name);
1340 
1341     pthread_once( &sFallbackOnce, fallback_init );
1342     if (sFallback != NULL) {
1343         return sFallback->common.methods->open(&sFallback->common, name, device);
1344     }
1345 
1346     if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
1347 
1348         // Create host connection and keep it in the TLS.
1349         // return error if connection with host can not be established
1350         HostConnection *hostCon = HostConnection::get();
1351         if (!hostCon) {
1352             ALOGE("gralloc: failed to get host connection while opening %s\n", name);
1353             return -EIO;
1354         }
1355 
1356         //
1357         // Allocate memory for the gralloc device (alloc interface)
1358         //
1359         gralloc_device_t *dev;
1360         dev = (gralloc_device_t*)malloc(sizeof(gralloc_device_t));
1361         if (NULL == dev) {
1362             return -ENOMEM;
1363         }
1364         memset(dev, 0, sizeof(gralloc_device_t));
1365 
1366         // Initialize our device structure
1367         //
1368         dev->device.common.tag = HARDWARE_DEVICE_TAG;
1369         dev->device.common.version = 0;
1370         dev->device.common.module = const_cast<hw_module_t*>(module);
1371         dev->device.common.close = gralloc_device_close;
1372 
1373         dev->device.alloc   = gralloc_alloc;
1374         dev->device.free    = gralloc_free;
1375         dev->allocListHead  = NULL;
1376         pthread_mutex_init(&dev->lock, NULL);
1377 
1378         *device = &dev->device.common;
1379         status = 0;
1380     }
1381     else if (!strcmp(name, GRALLOC_HARDWARE_FB0)) {
1382 
1383         // return error if connection with host can not be established
1384         DEFINE_AND_VALIDATE_HOST_CONNECTION;
1385 
1386         //
1387         // Query the host for Framebuffer attributes
1388         //
1389         D("gralloc: query Frabuffer attribs\n");
1390         EGLint width = rcEnc->rcGetFBParam(rcEnc, FB_WIDTH);
1391         D("gralloc: width=%d\n", width);
1392         EGLint height = rcEnc->rcGetFBParam(rcEnc, FB_HEIGHT);
1393         D("gralloc: height=%d\n", height);
1394         EGLint xdpi = rcEnc->rcGetFBParam(rcEnc, FB_XDPI);
1395         D("gralloc: xdpi=%d\n", xdpi);
1396         EGLint ydpi = rcEnc->rcGetFBParam(rcEnc, FB_YDPI);
1397         D("gralloc: ydpi=%d\n", ydpi);
1398         EGLint fps = rcEnc->rcGetFBParam(rcEnc, FB_FPS);
1399         D("gralloc: fps=%d\n", fps);
1400         EGLint min_si = rcEnc->rcGetFBParam(rcEnc, FB_MIN_SWAP_INTERVAL);
1401         D("gralloc: min_swap=%d\n", min_si);
1402         EGLint max_si = rcEnc->rcGetFBParam(rcEnc, FB_MAX_SWAP_INTERVAL);
1403         D("gralloc: max_swap=%d\n", max_si);
1404 
1405         //
1406         // Allocate memory for the framebuffer device
1407         //
1408         fb_device_t *dev;
1409         dev = (fb_device_t*)malloc(sizeof(fb_device_t));
1410         if (NULL == dev) {
1411             return -ENOMEM;
1412         }
1413         memset(dev, 0, sizeof(fb_device_t));
1414 
1415         // Initialize our device structure
1416         //
1417         dev->device.common.tag = HARDWARE_DEVICE_TAG;
1418         dev->device.common.version = 0;
1419         dev->device.common.module = const_cast<hw_module_t*>(module);
1420         dev->device.common.close = fb_close;
1421         dev->device.setSwapInterval = fb_setSwapInterval;
1422         dev->device.post            = fb_post;
1423         dev->device.setUpdateRect   = 0; //fb_setUpdateRect;
1424         dev->device.compositionComplete = fb_compositionComplete; //XXX: this is a dummy
1425 
1426         const_cast<uint32_t&>(dev->device.flags) = 0;
1427         const_cast<uint32_t&>(dev->device.width) = width;
1428         const_cast<uint32_t&>(dev->device.height) = height;
1429         const_cast<int&>(dev->device.stride) = width;
1430         const_cast<int&>(dev->device.format) = HAL_PIXEL_FORMAT_RGBA_8888;
1431         const_cast<float&>(dev->device.xdpi) = xdpi;
1432         const_cast<float&>(dev->device.ydpi) = ydpi;
1433         const_cast<float&>(dev->device.fps) = fps;
1434         const_cast<int&>(dev->device.minSwapInterval) = min_si;
1435         const_cast<int&>(dev->device.maxSwapInterval) = max_si;
1436         *device = &dev->device.common;
1437 
1438         status = 0;
1439     }
1440 
1441     return status;
1442 }
1443 
1444 //
1445 // define the HMI symbol - our module interface
1446 //
1447 static struct hw_module_methods_t gralloc_module_methods = {
1448         open: gralloc_device_open
1449 };
1450 
1451 struct private_module_t HAL_MODULE_INFO_SYM = {
1452     base: {
1453         common: {
1454             tag: HARDWARE_MODULE_TAG,
1455 #if PLATFORM_SDK_VERSION >= 18
1456             module_api_version: GRALLOC_MODULE_API_VERSION_0_2,
1457             hal_api_version: 0,
1458 #elif PLATFORM_SDK_VERSION >= 16
1459             module_api_version: 1,
1460             hal_api_version: 0,
1461 #else // PLATFORM_SDK_VERSION
1462             version_major: 1,
1463             version_minor: 0,
1464 #endif // PLATFORM_SDK_VERSION
1465             id: GRALLOC_HARDWARE_MODULE_ID,
1466             name: "Graphics Memory Allocator Module",
1467             author: "The Android Open Source Project",
1468             methods: &gralloc_module_methods,
1469             dso: NULL,
1470             reserved: {0, }
1471         },
1472         registerBuffer: gralloc_register_buffer,
1473         unregisterBuffer: gralloc_unregister_buffer,
1474         lock: gralloc_lock,
1475         unlock: gralloc_unlock,
1476         perform: NULL,
1477 #if PLATFORM_SDK_VERSION >= 18
1478         lock_ycbcr: gralloc_lock_ycbcr,
1479 #endif // PLATFORM_SDK_VERSION >= 18
1480     }
1481 };
1482 
1483 /* This function is called once to detect whether the emulator supports
1484  * GPU emulation (this is done by looking at the qemu.gles kernel
1485  * parameter, which must be == 1 if this is the case).
1486  *
1487  * If not, then load gralloc.default instead as a fallback.
1488  */
1489 
1490 #if __LP64__
1491 static const char kGrallocDefaultSystemPath[] = "/system/lib64/hw/gralloc.default.so";
1492 static const char kGrallocDefaultVendorPath[] = "/vendor/lib64/hw/gralloc.default.so";
1493 #else
1494 static const char kGrallocDefaultSystemPath[] = "/system/lib/hw/gralloc.default.so";
1495 static const char kGrallocDefaultVendorPath[] = "/vendor/lib/hw/gralloc.default.so";
1496 #endif
1497 
1498 static void
fallback_init(void)1499 fallback_init(void)
1500 {
1501     char  prop[PROPERTY_VALUE_MAX];
1502     void* module;
1503 
1504     // qemu.gles=0 -> no GLES 2.x support (only 1.x through software).
1505     // qemu.gles=1 -> host-side GPU emulation through EmuGL
1506     // qemu.gles=2 -> guest-side GPU emulation.
1507     property_get("ro.kernel.qemu.gles", prop, "0");
1508     if (atoi(prop) == 1) {
1509         return;
1510     }
1511     ALOGD("Emulator without host-side GPU emulation detected. "
1512           "Loading gralloc.default.so from %s...",
1513           kGrallocDefaultVendorPath);
1514     module = dlopen(kGrallocDefaultVendorPath, RTLD_LAZY | RTLD_LOCAL);
1515     if (!module) {
1516         // vendor folder didn't work. try system
1517         ALOGD("gralloc.default.so not found in /vendor. Trying %s...",
1518               kGrallocDefaultSystemPath);
1519         module = dlopen(kGrallocDefaultSystemPath, RTLD_LAZY | RTLD_LOCAL);
1520     }
1521 
1522     if (module != NULL) {
1523         sFallback = reinterpret_cast<gralloc_module_t*>(dlsym(module, HAL_MODULE_INFO_SYM_AS_STR));
1524         if (sFallback == NULL) {
1525             dlclose(module);
1526         }
1527     }
1528     if (sFallback == NULL) {
1529         ALOGE("FATAL: Could not find gralloc.default.so!");
1530     }
1531 }
1532