• 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 "HostConnection.h"
26 #include "glUtils.h"
27 #include <cutils/log.h>
28 #include <cutils/properties.h>
29 
30 /* Set to 1 or 2 to enable debug traces */
31 #define DEBUG  0
32 
33 #if DEBUG >= 1
34 #  define D(...)   ALOGD(__VA_ARGS__)
35 #else
36 #  define D(...)   ((void)0)
37 #endif
38 
39 #if DEBUG >= 2
40 #  define DD(...)  ALOGD(__VA_ARGS__)
41 #else
42 #  define DD(...)  ((void)0)
43 #endif
44 
45 #define DBG_FUNC DBG("%s\n", __FUNCTION__)
46 //
47 // our private gralloc module structure
48 //
49 struct private_module_t {
50     gralloc_module_t base;
51 };
52 
53 /* If not NULL, this is a pointer to the fallback module.
54  * This really is gralloc.default, which we'll use if we detect
55  * that the emulator we're running in does not support GPU emulation.
56  */
57 static gralloc_module_t*  sFallback;
58 static pthread_once_t     sFallbackOnce = PTHREAD_ONCE_INIT;
59 
60 static void fallback_init(void);  // forward
61 
62 
63 typedef struct _alloc_list_node {
64     buffer_handle_t handle;
65     _alloc_list_node *next;
66     _alloc_list_node *prev;
67 } AllocListNode;
68 
69 //
70 // Our gralloc device structure (alloc interface)
71 //
72 struct gralloc_device_t {
73     alloc_device_t  device;
74 
75     AllocListNode *allocListHead;    // double linked list of allocated buffers
76     pthread_mutex_t lock;
77 };
78 
79 //
80 // Our framebuffer device structure
81 //
82 struct fb_device_t {
83     framebuffer_device_t  device;
84 };
85 
map_buffer(cb_handle_t * cb,void ** vaddr)86 static int map_buffer(cb_handle_t *cb, void **vaddr)
87 {
88     if (cb->fd < 0 || cb->ashmemSize <= 0) {
89         return -EINVAL;
90     }
91 
92     void *addr = mmap(0, cb->ashmemSize, PROT_READ | PROT_WRITE,
93                       MAP_SHARED, cb->fd, 0);
94     if (addr == MAP_FAILED) {
95         return -errno;
96     }
97 
98     cb->ashmemBase = intptr_t(addr);
99     cb->ashmemBasePid = getpid();
100 
101     *vaddr = addr;
102     return 0;
103 }
104 
105 #define DEFINE_HOST_CONNECTION \
106     HostConnection *hostCon = HostConnection::get(); \
107     renderControl_encoder_context_t *rcEnc = (hostCon ? hostCon->rcEncoder() : NULL)
108 
109 #define DEFINE_AND_VALIDATE_HOST_CONNECTION \
110     HostConnection *hostCon = HostConnection::get(); \
111     if (!hostCon) { \
112         ALOGE("gralloc: Failed to get host connection\n"); \
113         return -EIO; \
114     } \
115     renderControl_encoder_context_t *rcEnc = hostCon->rcEncoder(); \
116     if (!rcEnc) { \
117         ALOGE("gralloc: Failed to get renderControl encoder context\n"); \
118         return -EIO; \
119     }
120 
121 
122 //
123 // gralloc device functions (alloc interface)
124 //
gralloc_alloc(alloc_device_t * dev,int w,int h,int format,int usage,buffer_handle_t * pHandle,int * pStride)125 static int gralloc_alloc(alloc_device_t* dev,
126                          int w, int h, int format, int usage,
127                          buffer_handle_t* pHandle, int* pStride)
128 {
129     D("gralloc_alloc w=%d h=%d usage=0x%x\n", w, h, usage);
130 
131     gralloc_device_t *grdev = (gralloc_device_t *)dev;
132     if (!grdev || !pHandle || !pStride) {
133         ALOGE("gralloc_alloc: Bad inputs (grdev: %p, pHandle: %p, pStride: %p",
134                 grdev, pHandle, pStride);
135         return -EINVAL;
136     }
137 
138     //
139     // Validate usage: buffer cannot be written both by s/w and h/w access.
140     //
141     bool sw_write = (0 != (usage & GRALLOC_USAGE_SW_WRITE_MASK));
142     bool hw_write = (usage & GRALLOC_USAGE_HW_RENDER);
143     if (hw_write && sw_write) {
144         ALOGE("gralloc_alloc: Mismatched usage flags: %d x %d, usage %x",
145                 w, h, usage);
146         return -EINVAL;
147     }
148     bool sw_read = (0 != (usage & GRALLOC_USAGE_SW_READ_MASK));
149     bool hw_cam_write = usage & GRALLOC_USAGE_HW_CAMERA_WRITE;
150     bool hw_cam_read = usage & GRALLOC_USAGE_HW_CAMERA_READ;
151     bool hw_vid_enc_read = usage & GRALLOC_USAGE_HW_VIDEO_ENCODER;
152 
153     // Keep around original requested format for later validation
154     int frameworkFormat = format;
155     // Pick the right concrete pixel format given the endpoints as encoded in
156     // the usage bits.  Every end-point pair needs explicit listing here.
157     if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
158         // Camera as producer
159         if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
160             if (usage & GRALLOC_USAGE_HW_TEXTURE) {
161                 // Camera-to-display is RGBA
162                 format = HAL_PIXEL_FORMAT_RGBA_8888;
163             } else if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
164                 // Camera-to-encoder is NV21
165                 format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
166             } else if ((usage & GRALLOC_USAGE_HW_CAMERA_MASK) ==
167                     GRALLOC_USAGE_HW_CAMERA_ZSL) {
168                 // Camera-to-ZSL-queue is RGB_888
169                 format = HAL_PIXEL_FORMAT_RGB_888;
170             }
171         }
172 
173         if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
174             ALOGE("gralloc_alloc: Requested auto format selection, "
175                     "but no known format for this usage: %d x %d, usage %x",
176                     w, h, usage);
177             return -EINVAL;
178         }
179     } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
180         // Flexible framework-accessible YUV format; map to NV21 for now
181         if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
182             format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
183         }
184         if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
185             ALOGE("gralloc_alloc: Requested YCbCr_420_888, but no known "
186                     "specific format for this usage: %d x %d, usage %x",
187                     w, h, usage);
188         }
189     }
190     bool yuv_format = false;
191 
192     int ashmem_size = 0;
193     int stride = w;
194 
195     GLenum glFormat = 0;
196     GLenum glType = 0;
197 
198     int bpp = 0;
199     int align = 1;
200     switch (format) {
201         case HAL_PIXEL_FORMAT_RGBA_8888:
202         case HAL_PIXEL_FORMAT_RGBX_8888:
203         case HAL_PIXEL_FORMAT_BGRA_8888:
204             bpp = 4;
205             glFormat = GL_RGBA;
206             glType = GL_UNSIGNED_BYTE;
207             break;
208         case HAL_PIXEL_FORMAT_RGB_888:
209             bpp = 3;
210             glFormat = GL_RGB;
211             glType = GL_UNSIGNED_BYTE;
212             break;
213         case HAL_PIXEL_FORMAT_RGB_565:
214             bpp = 2;
215             glFormat = GL_RGB;
216             glType = GL_UNSIGNED_SHORT_5_6_5;
217             break;
218         case HAL_PIXEL_FORMAT_RAW_SENSOR:
219             bpp = 2;
220             align = 16*bpp;
221             if (! ((sw_read || hw_cam_read) && (sw_write || hw_cam_write) ) ) {
222                 // Raw sensor data only goes between camera and CPU
223                 return -EINVAL;
224             }
225             // Not expecting to actually create any GL surfaces for this
226             glFormat = GL_LUMINANCE;
227             glType = GL_UNSIGNED_SHORT;
228             break;
229         case HAL_PIXEL_FORMAT_BLOB:
230             bpp = 1;
231             if (! (sw_read && hw_cam_write) ) {
232                 // Blob data cannot be used by HW other than camera emulator
233                 return -EINVAL;
234             }
235             // Not expecting to actually create any GL surfaces for this
236             glFormat = GL_LUMINANCE;
237             glType = GL_UNSIGNED_BYTE;
238             break;
239         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
240             align = 1;
241             bpp = 1; // per-channel bpp
242             yuv_format = true;
243             // Not expecting to actually create any GL surfaces for this
244             break;
245         case HAL_PIXEL_FORMAT_YV12:
246             align = 16;
247             bpp = 1; // per-channel bpp
248             yuv_format = true;
249             // Not expecting to actually create any GL surfaces for this
250             break;
251         default:
252             ALOGE("gralloc_alloc: Unknown format %d", format);
253             return -EINVAL;
254     }
255 
256     if (usage & GRALLOC_USAGE_HW_FB) {
257         // keep space for postCounter
258         ashmem_size += sizeof(uint32_t);
259     }
260 
261     if (sw_read || sw_write || hw_cam_write || hw_vid_enc_read) {
262         // keep space for image on guest memory if SW access is needed
263         // or if the camera is doing writing
264         if (yuv_format) {
265             size_t yStride = (w*bpp + (align - 1)) & ~(align-1);
266             size_t uvStride = (yStride / 2 + (align - 1)) & ~(align-1);
267             size_t uvHeight = h / 2;
268             ashmem_size += yStride * h + 2 * (uvHeight * uvStride);
269             stride = yStride / bpp;
270         } else {
271             size_t bpr = (w*bpp + (align-1)) & ~(align-1);
272             ashmem_size += (bpr * h);
273             stride = bpr / bpp;
274         }
275     }
276 
277     D("gralloc_alloc format=%d, ashmem_size=%d, stride=%d, tid %d\n", format,
278             ashmem_size, stride, gettid());
279 
280     //
281     // Allocate space in ashmem if needed
282     //
283     int fd = -1;
284     if (ashmem_size > 0) {
285         // round to page size;
286         ashmem_size = (ashmem_size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
287 
288         fd = ashmem_create_region("gralloc-buffer", ashmem_size);
289         if (fd < 0) {
290             ALOGE("gralloc_alloc failed to create ashmem region: %s\n",
291                     strerror(errno));
292             return -errno;
293         }
294     }
295 
296     cb_handle_t *cb = new cb_handle_t(fd, ashmem_size, usage,
297                                       w, h, frameworkFormat, format,
298                                       glFormat, glType);
299 
300     if (ashmem_size > 0) {
301         //
302         // map ashmem region if exist
303         //
304         void *vaddr;
305         int err = map_buffer(cb, &vaddr);
306         if (err) {
307             close(fd);
308             delete cb;
309             return err;
310         }
311 
312         cb->setFd(fd);
313     }
314 
315     //
316     // Allocate ColorBuffer handle on the host (only if h/w access is allowed)
317     // Only do this for some h/w usages, not all.
318     //
319     if (usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER |
320                     GRALLOC_USAGE_HW_2D | GRALLOC_USAGE_HW_COMPOSER |
321                     GRALLOC_USAGE_HW_FB) ) {
322         DEFINE_HOST_CONNECTION;
323         if (hostCon && rcEnc) {
324             cb->hostHandle = rcEnc->rcCreateColorBuffer(rcEnc, w, h, glFormat);
325             D("Created host ColorBuffer 0x%x\n", cb->hostHandle);
326         }
327 
328         if (!cb->hostHandle) {
329            // Could not create colorbuffer on host !!!
330            close(fd);
331            delete cb;
332            return -EIO;
333         }
334     }
335 
336     //
337     // alloc succeeded - insert the allocated handle to the allocated list
338     //
339     AllocListNode *node = new AllocListNode();
340     pthread_mutex_lock(&grdev->lock);
341     node->handle = cb;
342     node->next =  grdev->allocListHead;
343     node->prev =  NULL;
344     if (grdev->allocListHead) {
345         grdev->allocListHead->prev = node;
346     }
347     grdev->allocListHead = node;
348     pthread_mutex_unlock(&grdev->lock);
349 
350     *pHandle = cb;
351     if (frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) {
352         *pStride = 0;
353     } else {
354         *pStride = stride;
355     }
356     return 0;
357 }
358 
gralloc_free(alloc_device_t * dev,buffer_handle_t handle)359 static int gralloc_free(alloc_device_t* dev,
360                         buffer_handle_t handle)
361 {
362     const cb_handle_t *cb = (const cb_handle_t *)handle;
363     if (!cb_handle_t::validate((cb_handle_t*)cb)) {
364         ERR("gralloc_free: invalid handle");
365         return -EINVAL;
366     }
367 
368     if (cb->hostHandle != 0) {
369         DEFINE_AND_VALIDATE_HOST_CONNECTION;
370         D("Closing host ColorBuffer 0x%x\n", cb->hostHandle);
371         rcEnc->rcCloseColorBuffer(rcEnc, cb->hostHandle);
372     }
373 
374     //
375     // detach and unmap ashmem area if present
376     //
377     if (cb->fd > 0) {
378         if (cb->ashmemSize > 0 && cb->ashmemBase) {
379             munmap((void *)cb->ashmemBase, cb->ashmemSize);
380         }
381         close(cb->fd);
382     }
383 
384     // remove it from the allocated list
385     gralloc_device_t *grdev = (gralloc_device_t *)dev;
386     pthread_mutex_lock(&grdev->lock);
387     AllocListNode *n = grdev->allocListHead;
388     while( n && n->handle != cb ) {
389         n = n->next;
390     }
391     if (n) {
392        // buffer found on list - remove it from list
393        if (n->next) {
394            n->next->prev = n->prev;
395        }
396        if (n->prev) {
397            n->prev->next = n->next;
398        }
399        else {
400            grdev->allocListHead = n->next;
401        }
402 
403        delete n;
404     }
405     pthread_mutex_unlock(&grdev->lock);
406 
407     delete cb;
408 
409     return 0;
410 }
411 
gralloc_device_close(struct hw_device_t * dev)412 static int gralloc_device_close(struct hw_device_t *dev)
413 {
414     gralloc_device_t* d = reinterpret_cast<gralloc_device_t*>(dev);
415     if (d) {
416 
417         // free still allocated buffers
418         while( d->allocListHead != NULL ) {
419             gralloc_free(&d->device, d->allocListHead->handle);
420         }
421 
422         // free device
423         free(d);
424     }
425     return 0;
426 }
427 
fb_compositionComplete(struct framebuffer_device_t * dev)428 static int fb_compositionComplete(struct framebuffer_device_t* dev)
429 {
430     return 0;
431 }
432 
433 //
434 // Framebuffer device functions
435 //
fb_post(struct framebuffer_device_t * dev,buffer_handle_t buffer)436 static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
437 {
438     fb_device_t *fbdev = (fb_device_t *)dev;
439     cb_handle_t *cb = (cb_handle_t *)buffer;
440 
441     if (!fbdev || !cb_handle_t::validate(cb) || !cb->canBePosted()) {
442         return -EINVAL;
443     }
444 
445     // Make sure we have host connection
446     DEFINE_AND_VALIDATE_HOST_CONNECTION;
447 
448     // increment the post count of the buffer
449     intptr_t *postCountPtr = (intptr_t *)cb->ashmemBase;
450     if (!postCountPtr) {
451         // This should not happen
452         return -EINVAL;
453     }
454     (*postCountPtr)++;
455 
456     // send post request to host
457     rcEnc->rcFBPost(rcEnc, cb->hostHandle);
458     hostCon->flush();
459 
460     return 0;
461 }
462 
fb_setUpdateRect(struct framebuffer_device_t * dev,int l,int t,int w,int h)463 static int fb_setUpdateRect(struct framebuffer_device_t* dev,
464         int l, int t, int w, int h)
465 {
466     fb_device_t *fbdev = (fb_device_t *)dev;
467 
468     if (!fbdev) {
469         return -EINVAL;
470     }
471 
472     // Make sure we have host connection
473     DEFINE_AND_VALIDATE_HOST_CONNECTION;
474 
475     // send request to host
476     // TODO: XXX - should be implemented
477     //rcEnc->rc_XXX
478 
479     return 0;
480 }
481 
fb_setSwapInterval(struct framebuffer_device_t * dev,int interval)482 static int fb_setSwapInterval(struct framebuffer_device_t* dev,
483             int interval)
484 {
485     fb_device_t *fbdev = (fb_device_t *)dev;
486 
487     if (!fbdev) {
488         return -EINVAL;
489     }
490 
491     // Make sure we have host connection
492     DEFINE_AND_VALIDATE_HOST_CONNECTION;
493 
494     // send request to host
495     rcEnc->rcFBSetSwapInterval(rcEnc, interval);
496     hostCon->flush();
497 
498     return 0;
499 }
500 
fb_close(struct hw_device_t * dev)501 static int fb_close(struct hw_device_t *dev)
502 {
503     fb_device_t *fbdev = (fb_device_t *)dev;
504 
505     delete fbdev;
506 
507     return 0;
508 }
509 
510 
511 //
512 // gralloc module functions - refcount + locking interface
513 //
gralloc_register_buffer(gralloc_module_t const * module,buffer_handle_t handle)514 static int gralloc_register_buffer(gralloc_module_t const* module,
515                                    buffer_handle_t handle)
516 {
517     pthread_once(&sFallbackOnce, fallback_init);
518     if (sFallback != NULL) {
519         return sFallback->registerBuffer(sFallback, handle);
520     }
521 
522     D("gralloc_register_buffer(%p) called", handle);
523 
524     private_module_t *gr = (private_module_t *)module;
525     cb_handle_t *cb = (cb_handle_t *)handle;
526     if (!gr || !cb_handle_t::validate(cb)) {
527         ERR("gralloc_register_buffer(%p): invalid buffer", cb);
528         return -EINVAL;
529     }
530 
531     if (cb->hostHandle != 0) {
532         DEFINE_AND_VALIDATE_HOST_CONNECTION;
533         D("Opening host ColorBuffer 0x%x\n", cb->hostHandle);
534         rcEnc->rcOpenColorBuffer2(rcEnc, cb->hostHandle);
535     }
536 
537     //
538     // if the color buffer has ashmem region and it is not mapped in this
539     // process map it now.
540     //
541     if (cb->ashmemSize > 0 && cb->mappedPid != getpid()) {
542         void *vaddr;
543         int err = map_buffer(cb, &vaddr);
544         if (err) {
545             ERR("gralloc_register_buffer(%p): map failed: %s", cb, strerror(-err));
546             return -err;
547         }
548         cb->mappedPid = getpid();
549     }
550 
551     return 0;
552 }
553 
gralloc_unregister_buffer(gralloc_module_t const * module,buffer_handle_t handle)554 static int gralloc_unregister_buffer(gralloc_module_t const* module,
555                                      buffer_handle_t handle)
556 {
557     if (sFallback != NULL) {
558         return sFallback->unregisterBuffer(sFallback, handle);
559     }
560 
561     private_module_t *gr = (private_module_t *)module;
562     cb_handle_t *cb = (cb_handle_t *)handle;
563     if (!gr || !cb_handle_t::validate(cb)) {
564         ERR("gralloc_unregister_buffer(%p): invalid buffer", cb);
565         return -EINVAL;
566     }
567 
568     if (cb->hostHandle != 0) {
569         DEFINE_AND_VALIDATE_HOST_CONNECTION;
570         D("Closing host ColorBuffer 0x%x\n", cb->hostHandle);
571         rcEnc->rcCloseColorBuffer(rcEnc, cb->hostHandle);
572     }
573 
574     //
575     // unmap ashmem region if it was previously mapped in this process
576     // (through register_buffer)
577     //
578     if (cb->ashmemSize > 0 && cb->mappedPid == getpid()) {
579         void *vaddr;
580         int err = munmap((void *)cb->ashmemBase, cb->ashmemSize);
581         if (err) {
582             ERR("gralloc_unregister_buffer(%p): unmap failed", cb);
583             return -EINVAL;
584         }
585         cb->ashmemBase = 0;
586         cb->mappedPid = 0;
587     }
588 
589     D("gralloc_unregister_buffer(%p) done\n", cb);
590 
591     return 0;
592 }
593 
gralloc_lock(gralloc_module_t const * module,buffer_handle_t handle,int usage,int l,int t,int w,int h,void ** vaddr)594 static int gralloc_lock(gralloc_module_t const* module,
595                         buffer_handle_t handle, int usage,
596                         int l, int t, int w, int h,
597                         void** vaddr)
598 {
599     if (sFallback != NULL) {
600         return sFallback->lock(sFallback, handle, usage, l, t, w, h, vaddr);
601     }
602 
603     private_module_t *gr = (private_module_t *)module;
604     cb_handle_t *cb = (cb_handle_t *)handle;
605     if (!gr || !cb_handle_t::validate(cb)) {
606         ALOGE("gralloc_lock bad handle\n");
607         return -EINVAL;
608     }
609 
610     // validate format
611     if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) {
612         ALOGE("gralloc_lock can't be used with YCbCr_420_888 format");
613         return -EINVAL;
614     }
615 
616     // Validate usage,
617     //   1. cannot be locked for hw access
618     //   2. lock for either sw read or write.
619     //   3. locked sw access must match usage during alloc time.
620     bool sw_read = (0 != (usage & GRALLOC_USAGE_SW_READ_MASK));
621     bool sw_write = (0 != (usage & GRALLOC_USAGE_SW_WRITE_MASK));
622     bool hw_read = (usage & GRALLOC_USAGE_HW_TEXTURE);
623     bool hw_write = (usage & GRALLOC_USAGE_HW_RENDER);
624     bool hw_vid_enc_read = (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER);
625     bool hw_cam_write = (usage & GRALLOC_USAGE_HW_CAMERA_WRITE);
626     bool hw_cam_read = (usage & GRALLOC_USAGE_HW_CAMERA_READ);
627     bool sw_read_allowed = (0 != (cb->usage & GRALLOC_USAGE_SW_READ_MASK));
628     bool sw_write_allowed = (0 != (cb->usage & GRALLOC_USAGE_SW_WRITE_MASK));
629 
630     if ( (hw_read || hw_write) ||
631          (!sw_read && !sw_write &&
632                  !hw_cam_write && !hw_cam_read &&
633                  !hw_vid_enc_read) ||
634          (sw_read && !sw_read_allowed) ||
635          (sw_write && !sw_write_allowed) ) {
636         ALOGE("gralloc_lock usage mismatch usage=0x%x cb->usage=0x%x\n", usage,
637                 cb->usage);
638         return -EINVAL;
639     }
640 
641     intptr_t postCount = 0;
642     void *cpu_addr = NULL;
643 
644     //
645     // make sure ashmem area is mapped if needed
646     //
647     if (cb->canBePosted() || sw_read || sw_write ||
648             hw_cam_write || hw_cam_read ||
649             hw_vid_enc_read) {
650         if (cb->ashmemBasePid != getpid() || !cb->ashmemBase) {
651             return -EACCES;
652         }
653 
654         if (cb->canBePosted()) {
655             postCount = *((intptr_t *)cb->ashmemBase);
656             cpu_addr = (void *)(cb->ashmemBase + sizeof(intptr_t));
657         }
658         else {
659             cpu_addr = (void *)(cb->ashmemBase);
660         }
661     }
662 
663     if (cb->hostHandle) {
664         // Make sure we have host connection
665         DEFINE_AND_VALIDATE_HOST_CONNECTION;
666 
667         //
668         // flush color buffer write cache on host and get its sync status.
669         //
670         int hostSyncStatus = rcEnc->rcColorBufferCacheFlush(rcEnc, cb->hostHandle,
671                                                             postCount,
672                                                             sw_read);
673         if (hostSyncStatus < 0) {
674             // host failed the color buffer sync - probably since it was already
675             // locked for write access. fail the lock.
676             ALOGE("gralloc_lock cacheFlush failed postCount=%d sw_read=%d\n",
677                  postCount, sw_read);
678             return -EBUSY;
679         }
680 
681     }
682 
683     //
684     // is virtual address required ?
685     //
686     if (sw_read || sw_write || hw_cam_write || hw_cam_read || hw_vid_enc_read) {
687         *vaddr = cpu_addr;
688     }
689 
690     if (sw_write || hw_cam_write) {
691         //
692         // Keep locked region if locked for s/w write access.
693         //
694         cb->lockedLeft = l;
695         cb->lockedTop = t;
696         cb->lockedWidth = w;
697         cb->lockedHeight = h;
698     }
699 
700     DD("gralloc_lock success. vaddr: %p, *vaddr: %p, usage: %x, cpu_addr: %p",
701             vaddr, vaddr ? *vaddr : 0, usage, cpu_addr);
702 
703     return 0;
704 }
705 
gralloc_unlock(gralloc_module_t const * module,buffer_handle_t handle)706 static int gralloc_unlock(gralloc_module_t const* module,
707                           buffer_handle_t handle)
708 {
709     if (sFallback != NULL) {
710         return sFallback->unlock(sFallback, handle);
711     }
712 
713     private_module_t *gr = (private_module_t *)module;
714     cb_handle_t *cb = (cb_handle_t *)handle;
715     if (!gr || !cb_handle_t::validate(cb)) {
716         return -EINVAL;
717     }
718 
719     //
720     // if buffer was locked for s/w write, we need to update the host with
721     // the updated data
722     //
723     if (cb->lockedWidth > 0 && cb->lockedHeight > 0 && cb->hostHandle) {
724 
725         // Make sure we have host connection
726         DEFINE_AND_VALIDATE_HOST_CONNECTION;
727 
728         void *cpu_addr;
729         if (cb->canBePosted()) {
730             cpu_addr = (void *)(cb->ashmemBase + sizeof(int));
731         }
732         else {
733             cpu_addr = (void *)(cb->ashmemBase);
734         }
735 
736         if (cb->lockedWidth < cb->width || cb->lockedHeight < cb->height) {
737             int bpp = glUtilsPixelBitSize(cb->glFormat, cb->glType) >> 3;
738             char *tmpBuf = new char[cb->lockedWidth * cb->lockedHeight * bpp];
739 
740             int dst_line_len = cb->lockedWidth * bpp;
741             int src_line_len = cb->width * bpp;
742             char *src = (char *)cpu_addr + cb->lockedTop*src_line_len + cb->lockedLeft*bpp;
743             char *dst = tmpBuf;
744             for (int y=0; y<cb->lockedHeight; y++) {
745                 memcpy(dst, src, dst_line_len);
746                 src += src_line_len;
747                 dst += dst_line_len;
748             }
749 
750             rcEnc->rcUpdateColorBuffer(rcEnc, cb->hostHandle,
751                                        cb->lockedLeft, cb->lockedTop,
752                                        cb->lockedWidth, cb->lockedHeight,
753                                        cb->glFormat, cb->glType,
754                                        tmpBuf);
755 
756             delete [] tmpBuf;
757         }
758         else {
759             rcEnc->rcUpdateColorBuffer(rcEnc, cb->hostHandle, 0, 0,
760                                        cb->width, cb->height,
761                                        cb->glFormat, cb->glType,
762                                        cpu_addr);
763         }
764     }
765 
766     cb->lockedWidth = cb->lockedHeight = 0;
767     return 0;
768 }
769 
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)770 static int gralloc_lock_ycbcr(gralloc_module_t const* module,
771                         buffer_handle_t handle, int usage,
772                         int l, int t, int w, int h,
773                         android_ycbcr *ycbcr)
774 {
775     // Not supporting fallback module for YCbCr
776     if (sFallback != NULL) {
777         return -EINVAL;
778     }
779 
780     if (!ycbcr) {
781         ALOGE("gralloc_lock_ycbcr got NULL ycbcr struct");
782         return -EINVAL;
783     }
784 
785     private_module_t *gr = (private_module_t *)module;
786     cb_handle_t *cb = (cb_handle_t *)handle;
787     if (!gr || !cb_handle_t::validate(cb)) {
788         ALOGE("gralloc_lock_ycbcr bad handle\n");
789         return -EINVAL;
790     }
791 
792     if (cb->frameworkFormat != HAL_PIXEL_FORMAT_YCbCr_420_888) {
793         ALOGE("gralloc_lock_ycbcr can only be used with "
794                 "HAL_PIXEL_FORMAT_YCbCr_420_888, got %x instead",
795                 cb->frameworkFormat);
796         return -EINVAL;
797     }
798 
799     // Validate usage
800     // For now, only allow camera write, software read.
801     bool sw_read = (0 != (usage & GRALLOC_USAGE_SW_READ_MASK));
802     bool hw_cam_write = (usage & GRALLOC_USAGE_HW_CAMERA_WRITE);
803     bool sw_read_allowed = (0 != (cb->usage & GRALLOC_USAGE_SW_READ_MASK));
804 
805     if ( (!hw_cam_write && !sw_read) ||
806             (sw_read && !sw_read_allowed) ) {
807         ALOGE("gralloc_lock_ycbcr usage mismatch usage:0x%x cb->usage:0x%x\n",
808                 usage, cb->usage);
809         return -EINVAL;
810     }
811 
812     // Make sure memory is mapped, get address
813     if (cb->ashmemBasePid != getpid() || !cb->ashmemBase) {
814         return -EACCES;
815     }
816 
817     uint8_t *cpu_addr = NULL;
818 
819     if (cb->canBePosted()) {
820         cpu_addr = (uint8_t *)(cb->ashmemBase + sizeof(int));
821     }
822     else {
823         cpu_addr = (uint8_t *)(cb->ashmemBase);
824     }
825 
826     // Calculate offsets to underlying YUV data
827     size_t yStride;
828     size_t cStride;
829     size_t yOffset;
830     size_t uOffset;
831     size_t vOffset;
832     size_t cStep;
833     switch (cb->format) {
834         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
835             yStride = cb->width;
836             cStride = cb->width;
837             yOffset = 0;
838             vOffset = yStride * cb->height;
839             uOffset = vOffset + 1;
840             cStep = 2;
841             break;
842         default:
843             ALOGE("gralloc_lock_ycbcr unexpected internal format %x",
844                     cb->format);
845             return -EINVAL;
846     }
847 
848     ycbcr->y = cpu_addr + yOffset;
849     ycbcr->cb = cpu_addr + uOffset;
850     ycbcr->cr = cpu_addr + vOffset;
851     ycbcr->ystride = yStride;
852     ycbcr->cstride = cStride;
853     ycbcr->chroma_step = cStep;
854 
855     // Zero out reserved fields
856     memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
857 
858     //
859     // Keep locked region if locked for s/w write access.
860     //
861     cb->lockedLeft = l;
862     cb->lockedTop = t;
863     cb->lockedWidth = w;
864     cb->lockedHeight = h;
865 
866     DD("gralloc_lock_ycbcr success. usage: %x, ycbcr.y: %p, .cb: %p, .cr: %p, "
867             ".ystride: %d , .cstride: %d, .chroma_step: %d", usage,
868             ycbcr->y, ycbcr->cb, ycbcr->cr, ycbcr->ystride, ycbcr->cstride,
869             ycbcr->chroma_step);
870 
871     return 0;
872 }
873 
gralloc_device_open(const hw_module_t * module,const char * name,hw_device_t ** device)874 static int gralloc_device_open(const hw_module_t* module,
875                                const char* name,
876                                hw_device_t** device)
877 {
878     int status = -EINVAL;
879 
880     D("gralloc_device_open %s\n", name);
881 
882     pthread_once( &sFallbackOnce, fallback_init );
883     if (sFallback != NULL) {
884         return sFallback->common.methods->open(&sFallback->common, name, device);
885     }
886 
887     if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
888 
889         // Create host connection and keep it in the TLS.
890         // return error if connection with host can not be established
891         HostConnection *hostCon = HostConnection::get();
892         if (!hostCon) {
893             ALOGE("gralloc: failed to get host connection while opening %s\n", name);
894             return -EIO;
895         }
896 
897         //
898         // Allocate memory for the gralloc device (alloc interface)
899         //
900         gralloc_device_t *dev;
901         dev = (gralloc_device_t*)malloc(sizeof(gralloc_device_t));
902         if (NULL == dev) {
903             return -ENOMEM;
904         }
905 
906         // Initialize our device structure
907         //
908         dev->device.common.tag = HARDWARE_DEVICE_TAG;
909         dev->device.common.version = 0;
910         dev->device.common.module = const_cast<hw_module_t*>(module);
911         dev->device.common.close = gralloc_device_close;
912 
913         dev->device.alloc   = gralloc_alloc;
914         dev->device.free    = gralloc_free;
915         dev->allocListHead  = NULL;
916         pthread_mutex_init(&dev->lock, NULL);
917 
918         *device = &dev->device.common;
919         status = 0;
920     }
921     else if (!strcmp(name, GRALLOC_HARDWARE_FB0)) {
922 
923         // return error if connection with host can not be established
924         DEFINE_AND_VALIDATE_HOST_CONNECTION;
925 
926         //
927         // Query the host for Framebuffer attributes
928         //
929         D("gralloc: query Frabuffer attribs\n");
930         EGLint width = rcEnc->rcGetFBParam(rcEnc, FB_WIDTH);
931         D("gralloc: width=%d\n", width);
932         EGLint height = rcEnc->rcGetFBParam(rcEnc, FB_HEIGHT);
933         D("gralloc: height=%d\n", height);
934         EGLint xdpi = rcEnc->rcGetFBParam(rcEnc, FB_XDPI);
935         D("gralloc: xdpi=%d\n", xdpi);
936         EGLint ydpi = rcEnc->rcGetFBParam(rcEnc, FB_YDPI);
937         D("gralloc: ydpi=%d\n", ydpi);
938         EGLint fps = rcEnc->rcGetFBParam(rcEnc, FB_FPS);
939         D("gralloc: fps=%d\n", fps);
940         EGLint min_si = rcEnc->rcGetFBParam(rcEnc, FB_MIN_SWAP_INTERVAL);
941         D("gralloc: min_swap=%d\n", min_si);
942         EGLint max_si = rcEnc->rcGetFBParam(rcEnc, FB_MAX_SWAP_INTERVAL);
943         D("gralloc: max_swap=%d\n", max_si);
944 
945         //
946         // Allocate memory for the framebuffer device
947         //
948         fb_device_t *dev;
949         dev = (fb_device_t*)malloc(sizeof(fb_device_t));
950         if (NULL == dev) {
951             return -ENOMEM;
952         }
953         memset(dev, 0, sizeof(fb_device_t));
954 
955         // Initialize our device structure
956         //
957         dev->device.common.tag = HARDWARE_DEVICE_TAG;
958         dev->device.common.version = 0;
959         dev->device.common.module = const_cast<hw_module_t*>(module);
960         dev->device.common.close = fb_close;
961         dev->device.setSwapInterval = fb_setSwapInterval;
962         dev->device.post            = fb_post;
963         dev->device.setUpdateRect   = 0; //fb_setUpdateRect;
964         dev->device.compositionComplete = fb_compositionComplete; //XXX: this is a dummy
965 
966         const_cast<uint32_t&>(dev->device.flags) = 0;
967         const_cast<uint32_t&>(dev->device.width) = width;
968         const_cast<uint32_t&>(dev->device.height) = height;
969         const_cast<int&>(dev->device.stride) = width;
970         const_cast<int&>(dev->device.format) = HAL_PIXEL_FORMAT_RGBA_8888;
971         const_cast<float&>(dev->device.xdpi) = xdpi;
972         const_cast<float&>(dev->device.ydpi) = ydpi;
973         const_cast<float&>(dev->device.fps) = fps;
974         const_cast<int&>(dev->device.minSwapInterval) = min_si;
975         const_cast<int&>(dev->device.maxSwapInterval) = max_si;
976         *device = &dev->device.common;
977 
978         status = 0;
979     }
980 
981     return status;
982 }
983 
984 //
985 // define the HMI symbol - our module interface
986 //
987 static struct hw_module_methods_t gralloc_module_methods = {
988         open: gralloc_device_open
989 };
990 
991 struct private_module_t HAL_MODULE_INFO_SYM = {
992     base: {
993         common: {
994             tag: HARDWARE_MODULE_TAG,
995             module_api_version: GRALLOC_MODULE_API_VERSION_0_2,
996             hal_api_version: 0,
997             id: GRALLOC_HARDWARE_MODULE_ID,
998             name: "Graphics Memory Allocator Module",
999             author: "The Android Open Source Project",
1000             methods: &gralloc_module_methods,
1001             dso: NULL,
1002             reserved: {0, }
1003         },
1004         registerBuffer: gralloc_register_buffer,
1005         unregisterBuffer: gralloc_unregister_buffer,
1006         lock: gralloc_lock,
1007         unlock: gralloc_unlock,
1008         perform: NULL,
1009         lock_ycbcr: gralloc_lock_ycbcr,
1010     }
1011 };
1012 
1013 /* This function is called once to detect whether the emulator supports
1014  * GPU emulation (this is done by looking at the qemu.gles kernel
1015  * parameter, which must be > 0 if this is the case).
1016  *
1017  * If not, then load gralloc.default instead as a fallback.
1018  */
1019 static void
fallback_init(void)1020 fallback_init(void)
1021 {
1022     char  prop[PROPERTY_VALUE_MAX];
1023     void* module;
1024 
1025     property_get("ro.kernel.qemu.gles", prop, "0");
1026     if (atoi(prop) > 0) {
1027         return;
1028     }
1029     ALOGD("Emulator without GPU emulation detected.");
1030 #if __LP64__
1031     module = dlopen("/system/lib64/hw/gralloc.default.so", RTLD_LAZY|RTLD_LOCAL);
1032 #else
1033     module = dlopen("/system/lib/hw/gralloc.default.so", RTLD_LAZY|RTLD_LOCAL);
1034 #endif
1035     if (module != NULL) {
1036         sFallback = reinterpret_cast<gralloc_module_t*>(dlsym(module, HAL_MODULE_INFO_SYM_AS_STR));
1037         if (sFallback == NULL) {
1038             dlclose(module);
1039         }
1040     }
1041     if (sFallback == NULL) {
1042         ALOGE("Could not find software fallback module!?");
1043     }
1044 }
1045