diff options
| author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2013-03-01 17:08:40 +0100 | 
|---|---|---|
| committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2013-03-01 17:08:40 +0100 | 
| commit | c8998259fd683e7cc7c6dee88067baa9af477a03 (patch) | |
| tree | 2dd7840302b795bebaee4852ba92e064d6ecb855 /hardware | |
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'hardware')
| -rw-r--r-- | hardware/renesas/0001-hardware-renesas-DRM-gralloc-module.patch | 1006 | 
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 +  | 
