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