Integrate from //sandbox/mathias/donut/...@145728

SurfaceFlinger rework for new EGL driver model support.
diff --git a/modules/gralloc/gralloc.cpp b/modules/gralloc/gralloc.cpp
new file mode 100644
index 0000000..67febd8
--- /dev/null
+++ b/modules/gralloc/gralloc.cpp
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <limits.h>
+
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <cutils/ashmem.h>
+#include <cutils/log.h>
+
+#include <hardware/hardware.h>
+#include <hardware/gralloc.h>
+
+#include <fcntl.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+
+#include "gralloc_priv.h"
+
+/*****************************************************************************/
+
+struct gralloc_context_t {
+    alloc_device_t  device;
+    /* our private data here */
+};
+
+static int gralloc_alloc_buffer(alloc_device_t* dev,
+        size_t size, int usage, buffer_handle_t* pHandle);
+
+/*****************************************************************************/
+
+int fb_device_open(const hw_module_t* module, const char* name,
+        hw_device_t** device);
+
+static int gralloc_device_open(const hw_module_t* module, const char* name,
+        hw_device_t** device);
+
+extern int gralloc_map(gralloc_module_t const* module,
+        buffer_handle_t handle, void** vaddr);
+
+extern int gralloc_unmap(gralloc_module_t const* module, 
+        buffer_handle_t handle);
+
+extern int gralloc_lock(gralloc_module_t const* module,
+        buffer_handle_t handle, int usage,
+        int l, int t, int w, int h);
+
+extern int gralloc_unlock(gralloc_module_t const* module, 
+        buffer_handle_t handle);
+
+/*****************************************************************************/
+
+static struct hw_module_methods_t gralloc_module_methods = {
+        open: gralloc_device_open
+};
+
+struct private_module_t HAL_MODULE_INFO_SYM = {
+    base: {
+        common: {
+            tag: HARDWARE_MODULE_TAG,
+            version_major: 1,
+            version_minor: 0,
+            id: GRALLOC_HARDWARE_MODULE_ID,
+            name: "Graphics Memory Allocator Module",
+            author: "The Android Open Source Project",
+            methods: &gralloc_module_methods
+        },
+        map: gralloc_map,
+        unmap: gralloc_unmap,
+        lock: gralloc_lock,
+        unlock: gralloc_unlock,
+    },
+    framebuffer: 0,
+    flags: 0,
+    numBuffers: 0,
+    bufferMask: 0,
+    lock: PTHREAD_MUTEX_INITIALIZER,
+    currentBuffer: 0
+};
+
+/*****************************************************************************/
+
+/*
+ * This function creates a buffer_handle_t initialized with the given fd.
+ * the offset passed in parameter is used to mmap() this fd later at this
+ * offset.
+ */
+
+static int gralloc_alloc_framebuffer_locked(alloc_device_t* dev,
+        size_t size, int usage, buffer_handle_t* pHandle)
+{
+    private_module_t* m = reinterpret_cast<private_module_t*>(
+            dev->common.module);
+
+    // allocate the framebuffer
+    if (m->framebuffer == NULL) {
+        // initialize the framebuffer
+        int err = mapFrameBufferLocked(m);
+        if (err < 0) {
+            return err;
+        }
+    }
+
+    if (m->framebuffer->base == 0) {
+        void *vaddr;
+        m->base.map(&m->base, m->framebuffer, &vaddr);
+    }
+    
+    const uint32_t bufferMask = m->bufferMask;
+    const uint32_t numBuffers = m->numBuffers;
+    const size_t bufferSize = m->finfo.line_length * m->info.yres;
+    if (numBuffers == 1) {
+        // If we have only one buffer, we never use page-flipping. Instead,
+        // we return a regular buffer which will be memcpy'ed to the main
+        // screen when post is called.
+        int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
+        return gralloc_alloc_buffer(dev, bufferSize, newUsage, pHandle);
+    }
+
+    if (bufferMask >= ((1LU<<numBuffers)-1)) {
+        // We ran out of buffers.
+        return -ENOMEM;
+    }
+
+    // create a "fake" handles for it
+    intptr_t vaddr = intptr_t(m->framebuffer->base);
+    private_handle_t* hnd = new private_handle_t(dup(m->framebuffer->fd), size,
+            private_handle_t::PRIV_FLAGS_USES_PMEM |
+            private_handle_t::PRIV_FLAGS_FRAMEBUFFER);
+
+    // find a free slot
+    for (uint32_t i=0 ; i<numBuffers ; i++) {
+        if ((bufferMask & (1LU<<i)) == 0) {
+            m->bufferMask |= (1LU<<i);
+            break;
+        }
+        vaddr += bufferSize;
+    }
+    
+    hnd->base = vaddr;
+    *pHandle = hnd;
+
+    return 0;
+}
+
+static int gralloc_alloc_framebuffer(alloc_device_t* dev,
+        size_t size, int usage, buffer_handle_t* pHandle)
+{
+    private_module_t* m = reinterpret_cast<private_module_t*>(
+            dev->common.module);
+    pthread_mutex_lock(&m->lock);
+    int err = gralloc_alloc_framebuffer_locked(dev, size, usage, pHandle);
+    pthread_mutex_unlock(&m->lock);
+    return err;
+}
+
+
+static int gralloc_alloc_buffer(alloc_device_t* dev,
+        size_t size, int usage, buffer_handle_t* pHandle)
+{
+    size = roundUpToPageSize(size);
+    int flags = 0;
+    if (usage & GRALLOC_USAGE_HW_2D) {
+        flags |= private_handle_t::PRIV_FLAGS_USES_PMEM;
+    }
+    int fd;
+    if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) == 0) {
+        fd = ashmem_create_region("Buffer", size);
+    } else {
+        fd = open("/dev/pmem", O_RDWR, 0);
+        // Note: Currently pmem get sized when it is mmaped.
+        // This means that just doing the open doesn't actually allocate
+        // anything. We basically need to do an implicit "mmap"
+        // (under the hood) for pmem regions. However, the current
+        // code will work okay for now thanks to the reference-counting.
+    }
+    if (fd < 0) {
+        return -errno;
+    }
+    private_handle_t* hnd = new private_handle_t(fd, size, flags);
+    *pHandle = hnd;
+    return 0;
+}
+
+/*****************************************************************************/
+
+static int gralloc_alloc(alloc_device_t* dev,
+        int w, int h, int format, int usage,
+        buffer_handle_t* pHandle, int* pStride)
+{
+    if (!pHandle || !pStride)
+        return -EINVAL;
+
+    int align = 4;
+    int bpp = 0;
+    switch (format) {
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+        case HAL_PIXEL_FORMAT_BGRA_8888:
+            bpp = 4;
+            break;
+        case HAL_PIXEL_FORMAT_RGB_565:
+        case HAL_PIXEL_FORMAT_RGBA_5551:
+        case HAL_PIXEL_FORMAT_RGBA_4444:
+            bpp = 2;
+            break;
+        default:
+            return -EINVAL;
+    }
+
+    size_t bpr = (w*bpp + (align-1)) & ~(align-1);
+    size_t size = bpr * h;
+    size_t stride = bpr / bpp;
+
+    int err;
+    if (usage & GRALLOC_USAGE_HW_FB) {
+        err = gralloc_alloc_framebuffer(dev, size, usage, pHandle);
+    } else {
+        err = gralloc_alloc_buffer(dev, size, usage, pHandle);
+    }
+    if (err < 0) {
+        return err;
+    }
+
+    *pStride = stride;
+    return 0;
+}
+
+static int gralloc_free(alloc_device_t* dev,
+        buffer_handle_t handle)
+{
+    if (private_handle_t::validate(handle) < 0)
+        return -EINVAL;
+
+    private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(handle);
+    if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
+        // free this buffer
+        private_module_t* m = reinterpret_cast<private_module_t*>(
+                dev->common.module);
+        const size_t bufferSize = m->finfo.line_length * m->info.yres;
+        int index = (hnd->base - m->framebuffer->base) / bufferSize;
+        m->bufferMask &= ~(1<<index); 
+    }
+    
+    if (hnd->base) {
+        LOGW("Freeing mapped handle %p", hnd);
+        gralloc_unmap((gralloc_module_t*) dev->common.module, handle);
+    }
+    
+    close(hnd->fd);
+    delete hnd;
+    return 0;
+}
+
+/*****************************************************************************/
+
+static int gralloc_close(struct hw_device_t *dev)
+{
+    gralloc_context_t* ctx = reinterpret_cast<gralloc_context_t*>(dev);
+    if (ctx) {
+        /* TODO: keep a list of all buffer_handle_t created, and free them
+         * all here
+         */
+
+        private_module_t* m = reinterpret_cast<private_module_t*>(dev->module);
+        pthread_mutex_lock(&m->lock);
+        if (m->framebuffer) {
+            m->base.unmap(&m->base, m->framebuffer);
+        }
+        pthread_mutex_unlock(&m->lock);
+
+        free(ctx);
+    }
+    return 0;
+}
+
+int gralloc_device_open(const hw_module_t* module, const char* name,
+        hw_device_t** device)
+{
+    int status = -EINVAL;
+    if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
+        gralloc_context_t *dev;
+        dev = (gralloc_context_t*)malloc(sizeof(*dev));
+
+        /* initialize our state here */
+        memset(dev, 0, sizeof(*dev));
+
+        /* initialize the procs */
+        dev->device.common.tag = HARDWARE_DEVICE_TAG;
+        dev->device.common.version = 0;
+        dev->device.common.module = const_cast<hw_module_t*>(module);
+        dev->device.common.close = gralloc_close;
+
+        dev->device.alloc   = gralloc_alloc;
+        dev->device.free    = gralloc_free;
+
+        *device = &dev->device.common;
+        status = 0;
+    } else {
+        status = fb_device_open(module, name, device);
+    }
+    return status;
+}