1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <unistd.h> 18 #include <fcntl.h> 19 20 #include <sys/mman.h> 21 #include <sys/stat.h> 22 #include <sys/types.h> 23 #include <sys/ioctl.h> 24 25 #include <linux/android_pmem.h> 26 27 #include "allocator.h" 28 #include "gr.h" 29 #include "gpu.h" 30 31 /*****************************************************************************/ 32 33 static int gralloc_alloc_buffer(alloc_device_t* dev, 34 size_t size, int usage, buffer_handle_t* pHandle); 35 36 /*****************************************************************************/ 37 38 int fb_device_open(const hw_module_t* module, const char* name, 39 hw_device_t** device); 40 41 static int gralloc_device_open(const hw_module_t* module, const char* name, 42 hw_device_t** device); 43 44 extern int gralloc_lock(gralloc_module_t const* module, 45 buffer_handle_t handle, int usage, 46 int l, int t, int w, int h, 47 void** vaddr); 48 49 extern int gralloc_unlock(gralloc_module_t const* module, 50 buffer_handle_t handle); 51 52 extern int gralloc_register_buffer(gralloc_module_t const* module, 53 buffer_handle_t handle); 54 55 extern int gralloc_unregister_buffer(gralloc_module_t const* module, 56 buffer_handle_t handle); 57 58 extern int gralloc_perform(struct gralloc_module_t const* module, 59 int operation, ... ); 60 61 /*****************************************************************************/ 62 63 /* On-device dependency implementation */ 64 class PmemAllocatorDepsDeviceImpl : public PmemUserspaceAllocator::Deps, 65 public PmemKernelAllocator::Deps { 66 67 virtual size_t getPmemTotalSize(int fd, size_t* size) { 68 pmem_region region; 69 int err = ioctl(fd, PMEM_GET_TOTAL_SIZE, ®ion); 70 if (err == 0) { 71 *size = region.len; 72 } 73 return err; 74 } 75 76 virtual int connectPmem(int fd, int master_fd) { 77 return ioctl(fd, PMEM_CONNECT, master_fd); 78 } 79 80 virtual int mapPmem(int fd, int offset, size_t size) { 81 struct pmem_region sub = { offset, size }; 82 return ioctl(fd, PMEM_MAP, &sub); 83 } 84 85 virtual int unmapPmem(int fd, int offset, size_t size) { 86 struct pmem_region sub = { offset, size }; 87 return ioctl(fd, PMEM_UNMAP, &sub); 88 } 89 90 virtual int getErrno() { 91 return errno; 92 } 93 94 virtual void* mmap(void* start, size_t length, int prot, int flags, int fd, 95 off_t offset) { 96 return ::mmap(start, length, prot, flags, fd, offset); 97 } 98 99 virtual int munmap(void* start, size_t length) { 100 return ::munmap(start, length); 101 } 102 103 virtual int open(const char* pathname, int flags, int mode) { 104 return ::open(pathname, flags, mode); 105 } 106 107 virtual int close(int fd) { 108 return ::close(fd); 109 } 110 }; 111 112 class GpuContextDepsDeviceImpl : public gpu_context_t::Deps { 113 114 public: 115 116 virtual int ashmem_create_region(const char *name, size_t size) { 117 return ::ashmem_create_region(name, size); 118 } 119 120 virtual int mapFrameBufferLocked(struct private_module_t* module) { 121 return ::mapFrameBufferLocked(module); 122 } 123 124 virtual int terminateBuffer(gralloc_module_t const* module, 125 private_handle_t* hnd) { 126 return ::terminateBuffer(module, hnd); 127 } 128 129 virtual int close(int fd) { 130 return ::close(fd); 131 } 132 }; 133 134 static PmemAllocatorDepsDeviceImpl pmemAllocatorDeviceDepsImpl; 135 static GpuContextDepsDeviceImpl gpuContextDeviceDepsImpl; 136 137 /*****************************************************************************/ 138 139 static SimpleBestFitAllocator pmemAllocMgr; 140 static PmemUserspaceAllocator pmemAllocator(pmemAllocatorDeviceDepsImpl, pmemAllocMgr, 141 "/dev/pmem"); 142 143 static PmemKernelAllocator pmemAdspAllocator(pmemAllocatorDeviceDepsImpl, 144 "/dev/pmem_adsp"); 145 146 /*****************************************************************************/ 147 148 static struct hw_module_methods_t gralloc_module_methods = { 149 open: gralloc_device_open 150 }; 151 152 struct private_module_t HAL_MODULE_INFO_SYM = { 153 base: { 154 common: { 155 tag: HARDWARE_MODULE_TAG, 156 version_major: 1, 157 version_minor: 0, 158 id: GRALLOC_HARDWARE_MODULE_ID, 159 name: "Graphics Memory Allocator Module", 160 author: "The Android Open Source Project", 161 methods: &gralloc_module_methods 162 }, 163 registerBuffer: gralloc_register_buffer, 164 unregisterBuffer: gralloc_unregister_buffer, 165 lock: gralloc_lock, 166 unlock: gralloc_unlock, 167 perform: gralloc_perform, 168 }, 169 framebuffer: 0, 170 fbFormat: 0, 171 flags: 0, 172 numBuffers: 0, 173 bufferMask: 0, 174 lock: PTHREAD_MUTEX_INITIALIZER, 175 currentBuffer: 0, 176 }; 177 178 /*****************************************************************************/ 179 180 int gralloc_device_open(const hw_module_t* module, const char* name, 181 hw_device_t** device) 182 { 183 int status = -EINVAL; 184 if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) { 185 const private_module_t* m = reinterpret_cast<const private_module_t*>( 186 module); 187 gpu_context_t *dev; 188 dev = new gpu_context_t(gpuContextDeviceDepsImpl, pmemAllocator, 189 pmemAdspAllocator, m); 190 *device = &dev->common; 191 status = 0; 192 } else { 193 status = fb_device_open(module, name, device); 194 } 195 return status; 196 } 197