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