summaryrefslogtreecommitdiff
path: root/hardware/renesas/0001-hardware-renesas-DRM-gralloc-module.patch
diff options
context:
space:
mode:
Diffstat (limited to 'hardware/renesas/0001-hardware-renesas-DRM-gralloc-module.patch')
-rw-r--r--hardware/renesas/0001-hardware-renesas-DRM-gralloc-module.patch1006
1 files changed, 1006 insertions, 0 deletions
diff --git a/hardware/renesas/0001-hardware-renesas-DRM-gralloc-module.patch b/hardware/renesas/0001-hardware-renesas-DRM-gralloc-module.patch
new file mode 100644
index 0000000..dcecb0b
--- /dev/null
+++ b/hardware/renesas/0001-hardware-renesas-DRM-gralloc-module.patch
@@ -0,0 +1,1006 @@
+From a559a2fd009a33aafdf0f6a6e3fd83a8f55c71e4 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Sat, 15 Sep 2012 04:36:43 +0200
+Subject: [PATCH] hardware/renesas: DRM gralloc module
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+---
+ libgralloc/Android.mk | 34 ++++
+ libgralloc/framebuffer.cpp | 393 ++++++++++++++++++++++++++++++++++++++++++
+ libgralloc/gralloc.cpp | 412 ++++++++++++++++++++++++++++++++++++++++++++
+ libgralloc/gralloc_priv.h | 123 +++++++++++++
+ 4 files changed, 962 insertions(+), 0 deletions(-)
+ create mode 100644 libgralloc/Android.mk
+ create mode 100644 libgralloc/framebuffer.cpp
+ create mode 100644 libgralloc/gralloc.cpp
+ create mode 100644 libgralloc/gralloc_priv.h
+
+diff --git a/libgralloc/Android.mk b/libgralloc/Android.mk
+new file mode 100644
+index 0000000..ee81ca3
+--- /dev/null
++++ b/libgralloc/Android.mk
+@@ -0,0 +1,34 @@
++# 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.
++
++
++LOCAL_PATH := $(call my-dir)
++
++# HAL module implemenation stored in
++# hw/<OVERLAY_HARDWARE_MODULE_ID>.<ro.product.board>.so
++include $(CLEAR_VARS)
++
++LOCAL_MODULE_TAGS := optional
++LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
++LOCAL_SHARED_LIBRARIES := liblog libcutils libdrm libkms
++
++LOCAL_SRC_FILES := \
++ gralloc.cpp \
++ framebuffer.cpp
++
++LOCAL_MODULE := gralloc.drm
++LOCAL_CFLAGS := -DLOG_TAG=\"gralloc\"
++LOCAL_C_INCLUDES := external/drm/include/drm
++
++include $(BUILD_SHARED_LIBRARY)
+diff --git a/libgralloc/framebuffer.cpp b/libgralloc/framebuffer.cpp
+new file mode 100644
+index 0000000..b81e540
+--- /dev/null
++++ b/libgralloc/framebuffer.cpp
+@@ -0,0 +1,393 @@
++/*
++ * 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 <dlfcn.h>
++#include <errno.h>
++#include <fcntl.h>
++#include <stdlib.h>
++#include <string.h>
++
++#include <sys/ioctl.h>
++#include <sys/mman.h>
++
++#include <cutils/ashmem.h>
++#include <cutils/atomic.h>
++#include <cutils/log.h>
++
++#include <hardware/hardware.h>
++#include <hardware/gralloc.h>
++
++#if HAVE_ANDROID_OS
++#include <libdrm/drm_fourcc.h>
++#include <libdrm/xf86drm.h>
++#include <libdrm/xf86drmMode.h>
++#include <libdrm/libkms.h>
++#endif
++
++#include "gralloc_priv.h"
++
++// Numbers of buffers for page flipping.
++#define FB_NUM_BUFFERS 2
++#define FB_FORMAT DRM_FORMAT_RGB565
++
++enum {
++ PAGE_FLIP = 0x00000001,
++ LOCKED = 0x00000002
++};
++
++struct fb_context_t {
++ framebuffer_device_t device;
++};
++
++/* -----------------------------------------------------------------------------
++ *
++ */
++
++static int fb_setSwapInterval(struct framebuffer_device_t *dev, int interval)
++{
++ fb_context_t *ctx = (fb_context_t *)dev;
++
++ if (interval < dev->minSwapInterval || interval > dev->maxSwapInterval)
++ return -EINVAL;
++
++ // FIXME: implement fb_setSwapInterval
++ return 0;
++}
++
++static int fb_post(struct framebuffer_device_t *dev, buffer_handle_t buffer)
++{
++ if (private_handle_t::validate(buffer) < 0)
++ return -EINVAL;
++
++ fb_context_t *ctx = (fb_context_t *)dev;
++
++ private_handle_t const *hnd =
++ static_cast<private_handle_t const *>(buffer);
++ private_module_t *m =
++ reinterpret_cast<private_module_t *>(dev->common.module);
++
++ if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
++ int err = drmModePageFlip(m->fd, m->crtc,
++ m->buffers[hnd->index].fb,
++ 0 /* DRM_MODE_PAGE_FLIP_EVENT */, 0);
++ if (err < 0) {
++ LOGE("drmModePageFlip failed (%d)", err);
++ m->base.unlock(&m->base, buffer);
++ return err;
++ }
++ } else {
++ /* If we can't do the page_flip, just copy the buffer to the
++ * front.
++ * FIXME: use copybit HAL instead of memcpy
++ */
++ void *buffer_vaddr;
++
++ m->base.lock(&m->base, buffer,
++ GRALLOC_USAGE_SW_READ_RARELY, 0, 0,
++ m->mode->hdisplay, m->mode->vdisplay,
++ &buffer_vaddr);
++
++ memcpy(m->buffers[0].vaddr, buffer_vaddr,
++ m->stride * m->mode->vdisplay);
++
++ m->base.unlock(&m->base, buffer);
++ }
++
++ return 0;
++}
++
++/* -----------------------------------------------------------------------------
++ *
++ */
++
++static void fb_free_buffer(struct private_module_t *module,
++ struct private_buffer_t *buffer)
++{
++ if (buffer->fb) {
++ drmModeRmFB(module->fd, buffer->fb);
++ buffer->fb = 0;
++ }
++ if (buffer->vaddr) {
++ kms_bo_unmap(buffer->bo);
++ buffer->vaddr = 0;
++ }
++ if (buffer->bo)
++ kms_bo_destroy(&buffer->bo);
++}
++
++static int fb_alloc_buffer(struct private_module_t *module,
++ struct private_buffer_t *buffer,
++ const drmModeModeInfo *mode)
++{
++ unsigned int bo_attrs[] = {
++ KMS_WIDTH, mode->hdisplay,
++ KMS_HEIGHT, mode->vdisplay,
++ KMS_BO_TYPE, KMS_BO_TYPE_SCANOUT_X8R8G8B8,
++ KMS_TERMINATE_PROP_LIST,
++ };
++ uint32_t handles[4] = { 0 };
++ uint32_t pitches[4] = { 0 };
++ uint32_t offsets[4] = { 0 };
++ int err;
++
++ err = kms_bo_create(module->kms, bo_attrs, &buffer->bo);
++ if (err < 0)
++ goto done;
++
++ err = kms_bo_map(buffer->bo, &buffer->vaddr);
++ if (err < 0)
++ goto done;
++
++ kms_bo_get_prop(buffer->bo, KMS_HANDLE, &buffer->handle);
++
++ handles[0] = buffer->handle;
++ pitches[0] = mode->hdisplay * 2;
++ err = drmModeAddFB2(module->fd, mode->hdisplay, mode->vdisplay,
++ FB_FORMAT, handles, pitches, offsets, &buffer->fb,
++ 0);
++
++done:
++ if (err < 0)
++ fb_free_buffer(module, buffer);
++
++ return err;
++}
++
++int fb_map_locked(struct private_module_t *module)
++{
++ int err;
++
++ // already initialized...
++ if (module->num_buffers)
++ return 0;
++
++ int fd = drmOpen("shmob-drm", 0);
++ if (fd < 0)
++ return -errno;
++
++ module->fd = fd;
++
++ drmModeModeInfo *mode = 0;
++ drmVersion *version = 0;
++ drmModeRes *resources = 0;
++ drmModeConnector *connector = 0;
++ drmModeEncoder *encoder = 0;
++
++ version = drmGetVersion(fd);
++ if (!version) {
++ err = -errno;
++ goto done;
++ }
++
++ resources = drmModeGetResources(fd);
++ if (!resources) {
++ err = -errno;
++ goto done;
++ }
++
++ /* Get the default mode associated with the first connector. */
++ if (resources->count_connectors == 0) {
++ err = -EINVAL;
++ goto done;
++ }
++
++ connector = drmModeGetConnector(fd, resources->connectors[0]);
++ if (!connector) {
++ err = -errno;
++ goto done;
++ }
++
++ if (connector->count_modes == 0) {
++ err = -EINVAL;
++ goto done;
++ }
++
++ if (connector->count_encoders == 0) {
++ err = -EINVAL;
++ goto done;
++ }
++
++ encoder = drmModeGetEncoder(fd, *connector->encoders);
++ if (!encoder) {
++ err = -errno;
++ goto done;
++ }
++
++ for (int i = 0; i < resources->count_crtcs; ++i) {
++ if (encoder->possible_crtcs & (1U << i)) {
++ module->crtc = resources->crtcs[i];
++ break;
++ }
++ }
++
++ if (module->crtc == 0) {
++ err = -EINVAL;
++ goto done;
++ }
++
++ float xdpi;
++ float ydpi;
++ float fps;
++
++ mode = &connector->modes[0];
++
++ if (connector->mmWidth == 0 || connector->mmHeight == 0) {
++ /* The driver doesn't return that information, default to
++ * 160 dpi.
++ */
++ xdpi = 160;
++ ydpi = 160;
++ } else {
++ xdpi = (mode->hdisplay * 25.4f) / connector->mmWidth;
++ ydpi = (mode->vdisplay * 25.4f) / connector->mmHeight;
++ }
++
++ if (mode->htotal && mode->vtotal)
++ fps = mode->clock * 1000.0f / (mode->htotal * mode->vtotal);
++ else
++ fps = 60.0;
++
++ /* Create two frame buffers. */
++ module->buffers = new private_buffer_t[FB_NUM_BUFFERS];
++ if (!module->buffers) {
++ err = -ENOMEM;
++ goto done;
++ }
++
++ memset(module->buffers, 0, FB_NUM_BUFFERS * sizeof *module->buffers);
++
++ err = kms_create(fd, &module->kms);
++ if (err < 0)
++ goto done;
++
++ for (unsigned int i = 0; i < FB_NUM_BUFFERS; ++i) {
++ err = fb_alloc_buffer(module, &module->buffers[i], mode);
++ if (err < 0)
++ goto done;
++ }
++
++ err = drmModeSetCrtc(fd, module->crtc, module->buffers[0].fb, 0, 0,
++ &connector->connector_id, 1, mode);
++ if (err < 0)
++ goto done;
++
++ LOGI("using (fd=%d)\n"
++ "desc = %s\n"
++ "hdisplay = %u px\n"
++ "vdisplay = %u px\n"
++ "format = 0x%08x\n",
++ fd, version->desc,
++ mode->hdisplay, mode->vdisplay,
++ FB_FORMAT);
++
++ LOGI("width = %d mm (%f dpi)\n"
++ "height = %d mm (%f dpi)\n"
++ "refresh rate = %.2f Hz\n",
++ connector->mmWidth, xdpi, connector->mmHeight, ydpi, fps);
++
++ module->flags = PAGE_FLIP;
++ module->num_buffers = FB_NUM_BUFFERS;
++ module->mode = mode;
++ module->xdpi = xdpi;
++ module->ydpi = ydpi;
++ module->fps = fps;
++ module->stride = mode->hdisplay * 2;
++
++done:
++ if (encoder)
++ drmModeFreeEncoder(encoder);
++ if (resources)
++ drmModeFreeResources(resources);
++ if (version)
++ drmFreeVersion(version);
++
++ if (err < 0) {
++ if (module->buffers) {
++ for (unsigned int i = 0; i < FB_NUM_BUFFERS; ++i)
++ fb_free_buffer(module, &module->buffers[i]);
++ delete[] module->buffers;
++ }
++ if (connector)
++ drmModeFreeConnector(connector);
++ if (fd != -1)
++ drmClose(fd);
++ }
++
++ return err;
++}
++
++static int fb_map(struct private_module_t *module)
++{
++ pthread_mutex_lock(&module->lock);
++ int err = fb_map_locked(module);
++ pthread_mutex_unlock(&module->lock);
++ return err;
++}
++
++/* -----------------------------------------------------------------------------
++ *
++ */
++
++static int fb_close(struct hw_device_t *dev)
++{
++ fb_context_t *ctx = (fb_context_t*)dev;
++ free(ctx);
++ return 0;
++}
++
++int fb_device_open(hw_module_t const *module, const char *name,
++ hw_device_t **device)
++{
++ alloc_device_t *gralloc_device;
++ int err;
++
++ err = gralloc_open(module, &gralloc_device);
++ if (err < 0)
++ return err;
++
++ /* Initialize our state here */
++ fb_context_t *dev = (fb_context_t *)malloc(sizeof *dev);
++ 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 = fb_close;
++ dev->device.setSwapInterval = fb_setSwapInterval;
++ dev->device.post = fb_post;
++ dev->device.setUpdateRect = 0;
++
++ private_module_t *m = (private_module_t*)module;
++ err = fb_map(m);
++ if (err < 0)
++ return err;
++
++ const_cast<uint32_t&>(dev->device.flags) = 0;
++ const_cast<uint32_t&>(dev->device.width) = m->mode->hdisplay;
++ const_cast<uint32_t&>(dev->device.height) = m->mode->vdisplay;
++ const_cast<int&>(dev->device.stride) = m->stride;
++ const_cast<int&>(dev->device.format) = HAL_PIXEL_FORMAT_RGB_565;
++ const_cast<float&>(dev->device.xdpi) = m->xdpi;
++ const_cast<float&>(dev->device.ydpi) = m->ydpi;
++ const_cast<float&>(dev->device.fps) = m->fps;
++ const_cast<int&>(dev->device.minSwapInterval) = 1;
++ const_cast<int&>(dev->device.maxSwapInterval) = 1;
++
++ *device = &dev->device.common;
++
++ return 0;
++}
+diff --git a/libgralloc/gralloc.cpp b/libgralloc/gralloc.cpp
+new file mode 100644
+index 0000000..03282b3
+--- /dev/null
++++ b/libgralloc/gralloc.cpp
+@@ -0,0 +1,412 @@
++/*
++ * 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 <errno.h>
++#include <fcntl.h>
++#include <limits.h>
++#include <pthread.h>
++#include <stdint.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++
++#include <sys/cdefs.h>
++#include <sys/ioctl.h>
++#include <sys/mman.h>
++#include <sys/stat.h>
++#include <sys/types.h>
++#ifdef HAVE_ANDROID_OS // just want PAGE_SIZE define
++# include <asm/page.h>
++#else
++# include <sys/user.h>
++#endif
++
++#include <cutils/ashmem.h>
++#include <cutils/atomic.h>
++#include <cutils/log.h>
++#include <cutils/native_handle.h>
++
++#include <hardware/gralloc.h>
++#include <hardware/hardware.h>
++
++#include "gralloc_priv.h"
++
++struct gralloc_context_t {
++ alloc_device_t device;
++ /* our private data here */
++};
++
++static size_t roundUpToPageSize(size_t x)
++{
++ return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
++}
++
++/* -----------------------------------------------------------------------------
++ * Map/unmap
++ */
++
++static int gralloc_map(gralloc_module_t const *module, private_handle_t *hnd,
++ void **vaddr)
++{
++ if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
++ void *addr;
++
++ addr = mmap(0, hnd->size, PROT_READ|PROT_WRITE, MAP_SHARED,
++ hnd->fd, 0);
++ if (addr == MAP_FAILED) {
++ LOGE("Could not mmap %s", strerror(errno));
++ return -errno;
++ }
++
++ hnd->base = intptr_t(addr);
++ }
++
++ *vaddr = (void *)hnd->base;
++ return 0;
++}
++
++static int gralloc_unmap(gralloc_module_t const *module, private_handle_t *hnd)
++{
++ if (hnd->base == 0)
++ return 0;
++
++ if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
++ if (munmap((void *)hnd->base, hnd->size) < 0)
++ LOGE("Could not unmap %s", strerror(errno));
++ }
++
++ hnd->base = 0;
++ return 0;
++}
++/* -----------------------------------------------------------------------------
++ * Buffer registration
++ */
++
++static int gralloc_register_buffer(gralloc_module_t const *module,
++ buffer_handle_t handle)
++{
++ if (private_handle_t::validate(handle) < 0)
++ return -EINVAL;
++
++ private_handle_t *hnd =
++ const_cast<private_handle_t *>(
++ static_cast<const private_handle_t *>(handle));
++
++ /* If this handle was created in this process, then we keep it as is. */
++ if (hnd->pid == getpid())
++ return 0;
++
++ void *vaddr;
++ return gralloc_map(module, hnd, &vaddr);
++}
++
++static int gralloc_unregister_buffer(gralloc_module_t const *module,
++ buffer_handle_t handle)
++{
++ if (private_handle_t::validate(handle) < 0)
++ return -EINVAL;
++
++ private_handle_t *hnd =
++ const_cast<private_handle_t *>(
++ static_cast<const private_handle_t *>(handle));
++
++ /* Never unmap buffers that were created in this process. */
++ if (hnd->pid == getpid())
++ return 0;
++
++ gralloc_unmap(module, hnd);
++ return 0;
++}
++
++/* -----------------------------------------------------------------------------
++ * Lock/unlock
++ */
++
++static int gralloc_lock(gralloc_module_t const *module,
++ buffer_handle_t handle, int usage, int l, int t,
++ int w, int h, void **vaddr)
++{
++ /* This is called when a buffer is being locked for software access. In
++ * this implementation we have nothing to do since not synchronization
++ * with the h/w is needed. Typically this is used to wait for the h/w to
++ * finish with this buffer if relevant. The data cache may need to be
++ * flushed or invalidated depending on the usage bits and the hardware.
++ */
++ if (private_handle_t::validate(handle) < 0)
++ return -EINVAL;
++
++ private_handle_t *hnd =
++ const_cast<private_handle_t *>(
++ static_cast<const private_handle_t *>(handle));
++ *vaddr = (void*)hnd->base;
++ return 0;
++}
++
++static int gralloc_unlock(gralloc_module_t const *module,
++ buffer_handle_t handle)
++{
++ /* We're done with a software buffer. Nothing to do in this
++ * implementation. Typically this is used to flush the data cache.
++ */
++ if (private_handle_t::validate(handle) < 0)
++ return -EINVAL;
++
++ return 0;
++}
++
++/* -----------------------------------------------------------------------------
++ * Alloc/free
++ */
++
++/* Allocate a buffer from system memory through ashmem. */
++static int gralloc_alloc_buffer(alloc_device_t *dev, size_t size, int usage,
++ buffer_handle_t *handle)
++{
++ void *vaddr;
++ int err;
++ int fd;
++
++ size = roundUpToPageSize(size);
++
++ fd = ashmem_create_region("gralloc-buffer", size);
++ if (fd < 0) {
++ LOGE("couldn't create ashmem (%s)", strerror(-errno));
++ return -errno;
++ }
++
++ private_handle_t *hnd = new private_handle_t(fd, size, 0);
++ gralloc_module_t *module =
++ reinterpret_cast<gralloc_module_t *>(dev->common.module);
++ err = gralloc_map(module, hnd, &vaddr);
++ if (err < 0) {
++ LOGE("gralloc failed err=%s", strerror(-err));
++ close(fd);
++ delete hnd;
++ return err;
++ }
++
++ *handle = hnd;
++ return 0;
++}
++
++/* Allocate a buffer from display memory. */
++static int gralloc_alloc_framebuffer_locked(alloc_device_t *dev, size_t size,
++ int usage, buffer_handle_t *handle)
++{
++ private_module_t *m =
++ reinterpret_cast<private_module_t *>(dev->common.module);
++
++ /* Allocate the framebuffer if not done already. The frame buffer is
++ * mapped once and forever.
++ */
++ int err = fb_map_locked(m);
++ if (err < 0)
++ return err;
++
++ if (m->num_buffers == 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.
++ */
++ usage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
++ return gralloc_alloc_buffer(dev, m->stride * m->mode->vdisplay,
++ usage, handle);
++ }
++
++ unsigned int index;
++
++ // Find a free slot.
++ for (index = 0; index < m->num_buffers ; index++) {
++ if (!m->buffers[index].busy) {
++ m->buffers[index].busy = true;
++ break;
++ }
++ }
++
++ if (index == m->num_buffers)
++ return -ENOMEM;
++
++ // Create a "fake" handle for it.
++ private_handle_t *hnd =
++ new private_handle_t(dup(m->fd), size,
++ private_handle_t::PRIV_FLAGS_FRAMEBUFFER);
++
++ hnd->index = index;
++ hnd->base = (int)m->buffers[index].vaddr;
++ *handle = hnd;
++
++ return 0;
++}
++
++static int gralloc_alloc_framebuffer(alloc_device_t *dev, size_t size,
++ int usage, buffer_handle_t *handle)
++{
++ 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, handle);
++ pthread_mutex_unlock(&m->lock);
++
++ return err;
++}
++
++static int gralloc_alloc(alloc_device_t *dev, int w, int h, int format,
++ int usage, buffer_handle_t *handle, int *stride)
++{
++ if (!handle || !stride)
++ return -EINVAL;
++
++ unsigned int align = 4;
++ unsigned int bpp;
++ size_t size;
++
++ switch (format) {
++ case HAL_PIXEL_FORMAT_RGBA_8888:
++ case HAL_PIXEL_FORMAT_RGBX_8888:
++ case HAL_PIXEL_FORMAT_BGRA_8888:
++ bpp = 4;
++ break;
++ case HAL_PIXEL_FORMAT_RGB_888:
++ bpp = 3;
++ 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 = bpr * h;
++ *stride = bpr / bpp;
++
++ if (usage & GRALLOC_USAGE_HW_FB)
++ return gralloc_alloc_framebuffer(dev, size, usage, handle);
++ else
++ return gralloc_alloc_buffer(dev, size, usage, handle);
++}
++
++static int gralloc_free(alloc_device_t *dev, buffer_handle_t handle)
++{
++ private_module_t *m =
++ reinterpret_cast<private_module_t *>(dev->common.module);
++ private_handle_t *hnd =
++ const_cast<private_handle_t *>(
++ static_cast<const private_handle_t *>(handle));
++
++ if (private_handle_t::validate(handle) < 0)
++ return -EINVAL;
++
++ if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
++ pthread_mutex_lock(&m->lock);
++ m->buffers[hnd->index].busy = false;
++ pthread_mutex_unlock(&m->lock);
++ } else {
++ gralloc_unmap(&m->base, hnd);
++ }
++
++ close(hnd->fd);
++ delete hnd;
++ return 0;
++}
++
++/* -----------------------------------------------------------------------------
++ * Open/close
++ */
++
++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.
++ */
++ delete ctx;
++ }
++
++ return 0;
++}
++
++static 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 = new(gralloc_context_t);
++ 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 if (!strcmp(name, GRALLOC_HARDWARE_FB0)) {
++ status = fb_device_open(module, name, device);
++ }
++
++ return status;
++}
++
++/* -----------------------------------------------------------------------------
++ * Module
++ */
++
++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: "Renesas Electronics Inc.",
++ methods: &gralloc_module_methods
++ },
++ registerBuffer: gralloc_register_buffer,
++ unregisterBuffer: gralloc_unregister_buffer,
++ lock: gralloc_lock,
++ unlock: gralloc_unlock,
++ },
++ lock: PTHREAD_MUTEX_INITIALIZER,
++ fd: -1,
++ crtc: 0,
++ mode: 0,
++ kms: 0,
++ num_buffers: 0,
++ buffers: 0,
++ xdpi: 0.0f,
++ ydpi: 0.0f,
++ fps: 0.0f,
++ stride: 0,
++ flags: 0,
++};
+diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
+new file mode 100644
+index 0000000..02854aa
+--- /dev/null
++++ b/libgralloc/gralloc_priv.h
+@@ -0,0 +1,123 @@
++/*
++ * 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.
++ */
++
++#ifndef GRALLOC_PRIV_H_
++#define GRALLOC_PRIV_H_
++
++#include <errno.h>
++#include <limits.h>
++#include <pthread.h>
++#include <stdint.h>
++#include <unistd.h>
++
++#include <sys/cdefs.h>
++
++#include <cutils/native_handle.h>
++
++#include <hardware/gralloc.h>
++
++#include <libdrm/xf86drmMode.h>
++
++int fb_device_open(const hw_module_t *module, const char *name,
++ hw_device_t **device);
++int fb_map_locked(struct private_module_t *module);
++
++/* -----------------------------------------------------------------------------
++ * Module
++ */
++
++struct private_buffer_t {
++ struct kms_bo *bo;
++ void *vaddr;
++ bool busy;
++ unsigned int handle;
++ uint32_t fb;
++};
++
++struct private_module_t {
++ gralloc_module_t base;
++ pthread_mutex_t lock;
++
++ int fd;
++ uint32_t crtc;
++ drmModeModeInfo *mode;
++ struct kms_driver *kms;
++
++ uint32_t num_buffers;
++ struct private_buffer_t *buffers;
++
++ float xdpi;
++ float ydpi;
++ float fps;
++ unsigned int stride;
++
++ uint32_t flags;
++};
++
++/* -----------------------------------------------------------------------------
++ * Handle
++ */
++
++struct private_handle_t : public native_handle {
++ enum {
++ PRIV_FLAGS_FRAMEBUFFER = 0x00000001
++ };
++
++ // File descriptors
++ int fd;
++
++ // Ints
++ int magic;
++ int flags;
++ int size;
++ int pid;
++
++ int index;
++ int base;
++
++ static const int sNumInts = 6;
++ static const int sNumFds = 1;
++ static const int sMagic = 0x3141592;
++
++ private_handle_t(int fd, int size, int flags) :
++ fd(fd), magic(sMagic), flags(flags), size(size), pid(getpid()),
++ index(0)
++ {
++ version = sizeof(native_handle);
++ numInts = sNumInts;
++ numFds = sNumFds;
++ }
++
++ ~private_handle_t() {
++ magic = 0;
++ }
++
++ static int validate(const native_handle *h) {
++ const private_handle_t *hnd = (const private_handle_t *)h;
++
++ if (!h || h->version != sizeof(native_handle) ||
++ h->numInts != sNumInts || h->numFds != sNumFds ||
++ hnd->magic != sMagic)
++ {
++ LOGE("invalid gralloc handle (at %p)", h);
++ return -EINVAL;
++ }
++
++ return 0;
++ }
++};
++
++#endif /* GRALLOC_PRIV_H_ */
+--
+1.7.8.6
+