gralloc.cpp revision bd80b38f2945ac918f66fb336c149b28b9dd030e
1a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian/* 2a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian * Copyright (C) 2008 The Android Open Source Project 3a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian * 4a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 5a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian * you may not use this file except in compliance with the License. 6a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian * You may obtain a copy of the License at 7a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian * 8a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 9a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian * 10a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian * Unless required by applicable law or agreed to in writing, software 11a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 12a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian * See the License for the specific language governing permissions and 14a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian * limitations under the License. 15a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian */ 16a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 17a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian#include <limits.h> 188c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian#include <unistd.h> 198c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian#include <fcntl.h> 208c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian#include <errno.h> 218c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian#include <pthread.h> 22a4b587cb063dfd1b11f0006b0149e5e3045cc873Marco Nelissen#include <stdlib.h> 23a4b587cb063dfd1b11f0006b0149e5e3045cc873Marco Nelissen#include <string.h> 24a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 25a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian#include <sys/mman.h> 26a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian#include <sys/stat.h> 27a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian#include <sys/types.h> 288c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian#include <sys/ioctl.h> 29a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 30a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian#include <cutils/ashmem.h> 31a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian#include <cutils/log.h> 328c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian#include <cutils/atomic.h> 33a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 34a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian#include <hardware/hardware.h> 35a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian#include <hardware/gralloc.h> 36a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 37a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian#include "gralloc_priv.h" 388c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian#include "allocator.h" 398c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian 408c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian#if HAVE_ANDROID_OS 418c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian#include <linux/android_pmem.h> 428c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian#endif 43a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 44a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian/*****************************************************************************/ 45a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 46a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstruct gralloc_context_t { 47a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian alloc_device_t device; 48a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian /* our private data here */ 49a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian}; 50a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 51a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstatic int gralloc_alloc_buffer(alloc_device_t* dev, 52a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian size_t size, int usage, buffer_handle_t* pHandle); 53a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 54a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian/*****************************************************************************/ 55a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 56a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianint fb_device_open(const hw_module_t* module, const char* name, 57a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian hw_device_t** device); 58a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 59a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstatic int gralloc_device_open(const hw_module_t* module, const char* name, 60a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian hw_device_t** device); 61a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 62a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianextern int gralloc_lock(gralloc_module_t const* module, 63a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian buffer_handle_t handle, int usage, 64988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian int l, int t, int w, int h, 65988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian void** vaddr); 66a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 67a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianextern int gralloc_unlock(gralloc_module_t const* module, 68a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian buffer_handle_t handle); 69a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 70988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopianextern int gralloc_register_buffer(gralloc_module_t const* module, 71988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian buffer_handle_t handle); 72988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian 73988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopianextern int gralloc_unregister_buffer(gralloc_module_t const* module, 74988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian buffer_handle_t handle); 75988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian 76a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian/*****************************************************************************/ 77a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 78a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstatic struct hw_module_methods_t gralloc_module_methods = { 79a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian open: gralloc_device_open 80a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian}; 81a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 82a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstruct private_module_t HAL_MODULE_INFO_SYM = { 83a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian base: { 84a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian common: { 85a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian tag: HARDWARE_MODULE_TAG, 86a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian version_major: 1, 87a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian version_minor: 0, 88a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian id: GRALLOC_HARDWARE_MODULE_ID, 89a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian name: "Graphics Memory Allocator Module", 90a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian author: "The Android Open Source Project", 91a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian methods: &gralloc_module_methods 92a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian }, 93988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian registerBuffer: gralloc_register_buffer, 94988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian unregisterBuffer: gralloc_unregister_buffer, 95a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian lock: gralloc_lock, 96a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian unlock: gralloc_unlock, 97a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian }, 98a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian framebuffer: 0, 99a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian flags: 0, 100a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian numBuffers: 0, 101a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian bufferMask: 0, 102a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian lock: PTHREAD_MUTEX_INITIALIZER, 1038c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian currentBuffer: 0, 1048c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian pmem_master: -1, 1058c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian pmem_master_base: 0 106a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian}; 107a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 108a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian/*****************************************************************************/ 109a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 110a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstatic int gralloc_alloc_framebuffer_locked(alloc_device_t* dev, 111a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian size_t size, int usage, buffer_handle_t* pHandle) 112a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian{ 113a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian private_module_t* m = reinterpret_cast<private_module_t*>( 114a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian dev->common.module); 115a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 116a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian // allocate the framebuffer 117a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian if (m->framebuffer == NULL) { 118988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian // initialize the framebuffer, the framebuffer is mapped once 119988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian // and forever. 120a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian int err = mapFrameBufferLocked(m); 121a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian if (err < 0) { 122a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian return err; 123a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian } 124a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian } 125a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 126a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian const uint32_t bufferMask = m->bufferMask; 127a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian const uint32_t numBuffers = m->numBuffers; 128a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian const size_t bufferSize = m->finfo.line_length * m->info.yres; 129a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian if (numBuffers == 1) { 130a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian // If we have only one buffer, we never use page-flipping. Instead, 131a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian // we return a regular buffer which will be memcpy'ed to the main 132a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian // screen when post is called. 133a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D; 134a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian return gralloc_alloc_buffer(dev, bufferSize, newUsage, pHandle); 135a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian } 136a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 137a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian if (bufferMask >= ((1LU<<numBuffers)-1)) { 138a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian // We ran out of buffers. 139a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian return -ENOMEM; 140a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian } 141a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 142a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian // create a "fake" handles for it 143a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian intptr_t vaddr = intptr_t(m->framebuffer->base); 144a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian private_handle_t* hnd = new private_handle_t(dup(m->framebuffer->fd), size, 145a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian private_handle_t::PRIV_FLAGS_USES_PMEM | 146a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian private_handle_t::PRIV_FLAGS_FRAMEBUFFER); 147a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 148a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian // find a free slot 149a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian for (uint32_t i=0 ; i<numBuffers ; i++) { 150a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian if ((bufferMask & (1LU<<i)) == 0) { 151a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian m->bufferMask |= (1LU<<i); 152a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian break; 153a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian } 154a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian vaddr += bufferSize; 155a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian } 156a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 157a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian hnd->base = vaddr; 15872c8508db9c3895a34437a3e780b90ec43a920a2Mathias Agopian hnd->offset = vaddr - intptr_t(m->framebuffer->base); 159a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian *pHandle = hnd; 160a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 161a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian return 0; 162a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian} 163a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 164a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstatic int gralloc_alloc_framebuffer(alloc_device_t* dev, 165a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian size_t size, int usage, buffer_handle_t* pHandle) 166a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian{ 167a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian private_module_t* m = reinterpret_cast<private_module_t*>( 168a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian dev->common.module); 169a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian pthread_mutex_lock(&m->lock); 170a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian int err = gralloc_alloc_framebuffer_locked(dev, size, usage, pHandle); 171a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian pthread_mutex_unlock(&m->lock); 172a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian return err; 173a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian} 174a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 1758c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopianstatic SimpleBestFitAllocator sAllocator(8*1024*1024); 1768c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian 17714784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopianstatic int init_pmem_area_locked(private_module_t* m) 1788c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian{ 1798c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian int err = 0; 1808c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian int master_fd = open("/dev/pmem", O_RDWR, 0); 1818c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian if (master_fd >= 0) { 1828c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian void* base = mmap(0, sAllocator.size(), 1838c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian PROT_READ|PROT_WRITE, MAP_SHARED, master_fd, 0); 1848c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian if (base == MAP_FAILED) { 1858c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian err = -errno; 1868c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian base = 0; 1878c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian close(master_fd); 1888c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian master_fd = -1; 1898c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian } 1908c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian m->pmem_master = master_fd; 1918c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian m->pmem_master_base = base; 1928c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian } else { 1938c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian err = -errno; 1948c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian } 1958c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian return err; 1968c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian} 197a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 19814784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopianstatic int init_pmem_area(private_module_t* m) 19914784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian{ 20014784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian pthread_mutex_lock(&m->lock); 2013d6ddfe77133198f48f0670d93172ee67d5b5ea7Mathias Agopian int err = m->pmem_master; 2023d6ddfe77133198f48f0670d93172ee67d5b5ea7Mathias Agopian if (err == -1) { 20385ce19a4d3d3204cb9829dd74ac5bc2ba28ea654Mathias Agopian // first time, try to initialize pmem 20414784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian err = init_pmem_area_locked(m); 20514784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian if (err) { 20614784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian m->pmem_master = err; 20714784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian } 20885ce19a4d3d3204cb9829dd74ac5bc2ba28ea654Mathias Agopian } else if (err < 0) { 20985ce19a4d3d3204cb9829dd74ac5bc2ba28ea654Mathias Agopian // pmem couldn't be initialized, never use it 21085ce19a4d3d3204cb9829dd74ac5bc2ba28ea654Mathias Agopian } else { 21185ce19a4d3d3204cb9829dd74ac5bc2ba28ea654Mathias Agopian // pmem OK 21285ce19a4d3d3204cb9829dd74ac5bc2ba28ea654Mathias Agopian err = 0; 21314784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian } 21414784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian pthread_mutex_unlock(&m->lock); 21514784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian return err; 21614784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian} 21714784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian 218a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstatic int gralloc_alloc_buffer(alloc_device_t* dev, 219a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian size_t size, int usage, buffer_handle_t* pHandle) 220a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian{ 2218c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian int err = 0; 222a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian int flags = 0; 2238c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian 2248c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian int fd = -1; 2258c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian void* base = 0; 2268c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian int offset = 0; 2278c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian int lockState = 0; 2288c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian 2298c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian size = roundUpToPageSize(size); 2308c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian 231bfc010a750eb091017e370640d5c1644d671c7e4Mathias Agopian#if HAVE_ANDROID_OS // should probably define HAVE_PMEM somewhere 232bfc010a750eb091017e370640d5c1644d671c7e4Mathias Agopian 2338c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian if (usage & GRALLOC_USAGE_HW_TEXTURE) { 2348c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian // enable pmem in that case, so our software GL can fallback to 2358c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian // the copybit module. 2368c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian flags |= private_handle_t::PRIV_FLAGS_USES_PMEM; 2378c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian } 2388c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian 239a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian if (usage & GRALLOC_USAGE_HW_2D) { 240a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian flags |= private_handle_t::PRIV_FLAGS_USES_PMEM; 241a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian } 2428c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian 243a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) == 0) { 24431802ca9c030b8f9a137f32826e9c9a76d0d6e17Mathias Agopiantry_ashmem: 245440d4e4741a2641173b44bd9b810c9a4960206c2Mathias Agopian fd = ashmem_create_region("gralloc-buffer", size); 2468c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian if (fd < 0) { 24731802ca9c030b8f9a137f32826e9c9a76d0d6e17Mathias Agopian LOGE("couldn't create ashmem (%s)", strerror(-errno)); 2488c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian err = -errno; 2498c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian } 250a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian } else { 2518c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian private_module_t* m = reinterpret_cast<private_module_t*>( 2528c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian dev->common.module); 25331802ca9c030b8f9a137f32826e9c9a76d0d6e17Mathias Agopian 25414784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian err = init_pmem_area(m); 25514784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian if (err == 0) { 2568c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian // PMEM buffers are always mmapped 2578c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian base = m->pmem_master_base; 2588c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian lockState |= private_handle_t::LOCK_STATE_MAPPED; 2598c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian 2608c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian offset = sAllocator.allocate(size); 2618c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian if (offset < 0) { 26214784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian // no more pmem memory 2638c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian err = -ENOMEM; 2648c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian } else { 26514784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian struct pmem_region sub = { offset, size }; 26614784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian 26714784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian // now create the "sub-heap" 2688c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian fd = open("/dev/pmem", O_RDWR, 0); 26914784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian err = fd < 0 ? fd : 0; 27014784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian 27114784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian // and connect to it 27214784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian if (err == 0) 27314784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian err = ioctl(fd, PMEM_CONNECT, m->pmem_master); 27414784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian 27514784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian // and make it available to the client process 27614784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian if (err == 0) 2778c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian err = ioctl(fd, PMEM_MAP, &sub); 27814784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian 2798c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian if (err < 0) { 28014784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian err = -errno; 2818c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian close(fd); 2828c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian sAllocator.deallocate(offset); 2838c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian fd = -1; 2848c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian } 285ed93e8b392e66e2a822f8b30ee7cefecd1036472Mathias Agopian //LOGD_IF(!err, "allocating pmem size=%d, offset=%d", size, offset); 2868c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian } 28731802ca9c030b8f9a137f32826e9c9a76d0d6e17Mathias Agopian } else { 28831802ca9c030b8f9a137f32826e9c9a76d0d6e17Mathias Agopian if ((usage & GRALLOC_USAGE_HW_2D) == 0) { 28931802ca9c030b8f9a137f32826e9c9a76d0d6e17Mathias Agopian // the caller didn't request PMEM, so we can try something else 29031802ca9c030b8f9a137f32826e9c9a76d0d6e17Mathias Agopian flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM; 29131802ca9c030b8f9a137f32826e9c9a76d0d6e17Mathias Agopian err = 0; 29231802ca9c030b8f9a137f32826e9c9a76d0d6e17Mathias Agopian goto try_ashmem; 29331802ca9c030b8f9a137f32826e9c9a76d0d6e17Mathias Agopian } else { 29431802ca9c030b8f9a137f32826e9c9a76d0d6e17Mathias Agopian LOGE("couldn't open pmem (%s)", strerror(-errno)); 29531802ca9c030b8f9a137f32826e9c9a76d0d6e17Mathias Agopian } 2968c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian } 297a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian } 2988c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian 299bfc010a750eb091017e370640d5c1644d671c7e4Mathias Agopian#else // HAVE_ANDROID_OS 300bfc010a750eb091017e370640d5c1644d671c7e4Mathias Agopian 301bfc010a750eb091017e370640d5c1644d671c7e4Mathias Agopian fd = ashmem_create_region("Buffer", size); 302bfc010a750eb091017e370640d5c1644d671c7e4Mathias Agopian if (fd < 0) { 303bfc010a750eb091017e370640d5c1644d671c7e4Mathias Agopian LOGE("couldn't create ashmem (%s)", strerror(-errno)); 304bfc010a750eb091017e370640d5c1644d671c7e4Mathias Agopian err = -errno; 305bfc010a750eb091017e370640d5c1644d671c7e4Mathias Agopian } 306bfc010a750eb091017e370640d5c1644d671c7e4Mathias Agopian 307bfc010a750eb091017e370640d5c1644d671c7e4Mathias Agopian#endif // HAVE_ANDROID_OS 308bfc010a750eb091017e370640d5c1644d671c7e4Mathias Agopian 3098c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian if (err == 0) { 3108c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian private_handle_t* hnd = new private_handle_t(fd, size, flags); 3118c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian hnd->offset = offset; 3128c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian hnd->base = int(base)+offset; 3138c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian hnd->lockState = lockState; 3148c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian *pHandle = hnd; 315a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian } 3168c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian 3178c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian LOGE_IF(err, "gralloc failed err=%s", strerror(-err)); 3188c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian 3198c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian return err; 320a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian} 321a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 322a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian/*****************************************************************************/ 323a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 324a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstatic int gralloc_alloc(alloc_device_t* dev, 325a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian int w, int h, int format, int usage, 326a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian buffer_handle_t* pHandle, int* pStride) 327a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian{ 328a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian if (!pHandle || !pStride) 329a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian return -EINVAL; 330a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 3318bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian size_t size, stride; 3328bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP || 3338bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian format == HAL_PIXEL_FORMAT_YCbCr_422_SP) 3348bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian { 3358bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian // FIXME: there is no way to return the vstride 3368bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian int vstride; 3378bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian stride = (w + 1) & ~1; 3388bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian switch (format) { 3398bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian case HAL_PIXEL_FORMAT_YCbCr_420_SP: 3408bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian size = stride * h * 2; 3418bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian break; 3428bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian case HAL_PIXEL_FORMAT_YCbCr_422_SP: 3438bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian vstride = (h+1) & ~1; 3448bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian size = (stride * vstride) + (w/2 * h/2) * 2; 3458bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian break; 3468bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian default: 3478bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian return -EINVAL; 3488bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian } 3498bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian } else { 3508bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian int align = 4; 3518bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian int bpp = 0; 3528bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian switch (format) { 3538bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian case HAL_PIXEL_FORMAT_RGBA_8888: 3548bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian case HAL_PIXEL_FORMAT_BGRA_8888: 3558bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian bpp = 4; 3568bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian break; 3578bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian case HAL_PIXEL_FORMAT_RGB_565: 3588bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian case HAL_PIXEL_FORMAT_RGBA_5551: 3598bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian case HAL_PIXEL_FORMAT_RGBA_4444: 3608bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian bpp = 2; 3618bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian break; 3628bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian default: 3638bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian return -EINVAL; 3648bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian } 3658bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian size_t bpr = (w*bpp + (align-1)) & ~(align-1); 3668bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian size = bpr * h; 3678bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian stride = bpr / bpp; 368a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian } 369a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 370a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian int err; 371a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian if (usage & GRALLOC_USAGE_HW_FB) { 372a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian err = gralloc_alloc_framebuffer(dev, size, usage, pHandle); 373a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian } else { 374a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian err = gralloc_alloc_buffer(dev, size, usage, pHandle); 375a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian } 3768bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian 377a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian if (err < 0) { 378a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian return err; 379a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian } 380a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 381a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian *pStride = stride; 382a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian return 0; 383a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian} 384a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 385a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstatic int gralloc_free(alloc_device_t* dev, 386a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian buffer_handle_t handle) 387a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian{ 388a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian if (private_handle_t::validate(handle) < 0) 389a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian return -EINVAL; 390a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 391a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(handle); 392bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) { 393a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian // free this buffer 394a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian private_module_t* m = reinterpret_cast<private_module_t*>( 395a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian dev->common.module); 396a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian const size_t bufferSize = m->finfo.line_length * m->info.yres; 397a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian int index = (hnd->base - m->framebuffer->base) / bufferSize; 398a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian m->bufferMask &= ~(1<<index); 399bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian } else { 400bfc010a750eb091017e370640d5c1644d671c7e4Mathias Agopian#if HAVE_ANDROID_OS 401bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_PMEM) { 402bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian if (hnd->fd >= 0) { 403bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian struct pmem_region sub = { hnd->offset, hnd->size }; 404bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian int err = ioctl(hnd->fd, PMEM_UNMAP, &sub); 405bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian LOGE_IF(err<0, "PMEM_UNMAP failed (%s), " 406bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian "fd=%d, sub.offset=%lu, sub.size=%lu", 407bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian strerror(errno), hnd->fd, hnd->offset, hnd->size); 408bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian if (err == 0) { 409bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian // we can't deallocate the memory in case of UNMAP failure 410bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian // because it would give that process access to someone else's 411bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian // surfaces, which would be a security breach. 412bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian sAllocator.deallocate(hnd->offset); 413bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian } 41414784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian } 41514784235ab872002e59a26a5c0f5b7edcf6ead4fMathias Agopian } 416bfc010a750eb091017e370640d5c1644d671c7e4Mathias Agopian#endif // HAVE_ANDROID_OS 417bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian gralloc_module_t* module = reinterpret_cast<gralloc_module_t*>( 418bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian dev->common.module); 419bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian terminateBuffer(module, const_cast<private_handle_t*>(hnd)); 420bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian } 421988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian 422a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian close(hnd->fd); 423a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian delete hnd; 424a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian return 0; 425a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian} 426a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 427a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian/*****************************************************************************/ 428a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 429a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstatic int gralloc_close(struct hw_device_t *dev) 430a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian{ 431a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian gralloc_context_t* ctx = reinterpret_cast<gralloc_context_t*>(dev); 432a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian if (ctx) { 433a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian /* TODO: keep a list of all buffer_handle_t created, and free them 434988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian * all here. 435a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian */ 436a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian free(ctx); 437a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian } 438a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian return 0; 439a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian} 440a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 441a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianint gralloc_device_open(const hw_module_t* module, const char* name, 442a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian hw_device_t** device) 443a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian{ 444a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian int status = -EINVAL; 445a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) { 446a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian gralloc_context_t *dev; 447a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian dev = (gralloc_context_t*)malloc(sizeof(*dev)); 448a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 449a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian /* initialize our state here */ 450a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian memset(dev, 0, sizeof(*dev)); 451a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 452a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian /* initialize the procs */ 453a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian dev->device.common.tag = HARDWARE_DEVICE_TAG; 454a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian dev->device.common.version = 0; 455a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian dev->device.common.module = const_cast<hw_module_t*>(module); 456a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian dev->device.common.close = gralloc_close; 457a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 458a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian dev->device.alloc = gralloc_alloc; 459a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian dev->device.free = gralloc_free; 460a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian 461a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian *device = &dev->device.common; 462a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian status = 0; 463a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian } else { 464a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian status = fb_device_open(module, name, device); 465a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian } 466a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian return status; 467a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian} 468