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 <errno.h>
18 #include <fcntl.h>
19 #include <limits.h>
20 #include <pthread.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <sys/ioctl.h>
24 #include <sys/mman.h>
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28 
29 #include <cutils/ashmem.h>
30 #include <cutils/atomic.h>
31 #include <log/log.h>
32 
33 #include <hardware/gralloc.h>
34 #include <hardware/hardware.h>
35 
36 #include "gralloc_priv.h"
37 #include "gr.h"
38 
39 /*****************************************************************************/
40 
41 struct gralloc_context_t {
42     alloc_device_t  device;
43     /* our private data here */
44 };
45 
46 static int gralloc_alloc_buffer(alloc_device_t* dev,
47         size_t size, int usage, buffer_handle_t* pHandle);
48 
49 /*****************************************************************************/
50 
51 int fb_device_open(const hw_module_t* module, const char* name,
52         hw_device_t** device);
53 
54 static int gralloc_device_open(const hw_module_t* module, const char* name,
55         hw_device_t** device);
56 
57 extern int gralloc_lock(gralloc_module_t const* module,
58         buffer_handle_t handle, int usage,
59         int l, int t, int w, int h,
60         void** vaddr);
61 
62 extern int gralloc_unlock(gralloc_module_t const* module,
63         buffer_handle_t handle);
64 
65 extern int gralloc_register_buffer(gralloc_module_t const* module,
66         buffer_handle_t handle);
67 
68 extern int gralloc_unregister_buffer(gralloc_module_t const* module,
69         buffer_handle_t handle);
70 
71 /*****************************************************************************/
72 
73 static struct hw_module_methods_t gralloc_module_methods = {
74         .open = gralloc_device_open
75 };
76 
77 struct private_module_t HAL_MODULE_INFO_SYM = {
78     .base = {
79         .common = {
80             .tag = HARDWARE_MODULE_TAG,
81             .version_major = 1,
82             .version_minor = 0,
83             .id = GRALLOC_HARDWARE_MODULE_ID,
84             .name = "Graphics Memory Allocator Module",
85             .author = "The Android Open Source Project",
86             .methods = &gralloc_module_methods
87         },
88         .registerBuffer = gralloc_register_buffer,
89         .unregisterBuffer = gralloc_unregister_buffer,
90         .lock = gralloc_lock,
91         .unlock = gralloc_unlock,
92     },
93     .framebuffer = 0,
94     .flags = 0,
95     .numBuffers = 0,
96     .bufferMask = 0,
97     .lock = PTHREAD_MUTEX_INITIALIZER,
98     .currentBuffer = 0,
99 };
100 
101 /*****************************************************************************/
102 
gralloc_alloc_framebuffer_locked(alloc_device_t * dev,size_t size,int format,int usage,buffer_handle_t * pHandle)103 static int gralloc_alloc_framebuffer_locked(alloc_device_t* dev,
104         size_t size, int format, int usage, buffer_handle_t* pHandle)
105 {
106     private_module_t* m = reinterpret_cast<private_module_t*>(
107             dev->common.module);
108 
109     // allocate the framebuffer
110     if (m->framebuffer == NULL) {
111         // initialize the framebuffer, the framebuffer is mapped once
112         // and forever.
113         int err = mapFrameBufferLocked(m, format);
114         if (err < 0) {
115             return err;
116         }
117     }
118 
119     const uint32_t bufferMask = m->bufferMask;
120     const uint32_t numBuffers = m->numBuffers;
121     const size_t bufferSize = m->finfo.line_length * m->info.yres;
122     if (numBuffers == 1) {
123         // If we have only one buffer, we never use page-flipping. Instead,
124         // we return a regular buffer which will be memcpy'ed to the main
125         // screen when post is called.
126         int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
127         return gralloc_alloc_buffer(dev, bufferSize, newUsage, pHandle);
128     }
129 
130     if (bufferMask >= ((1LU<<numBuffers)-1)) {
131         // We ran out of buffers.
132         return -ENOMEM;
133     }
134 
135     // create a "fake" handles for it
136     intptr_t vaddr = intptr_t(m->framebuffer->base);
137     private_handle_t* hnd = new private_handle_t(dup(m->framebuffer->fd), size,
138             private_handle_t::PRIV_FLAGS_FRAMEBUFFER);
139 
140     // find a free slot
141     for (uint32_t i=0 ; i<numBuffers ; i++) {
142         if ((bufferMask & (1LU<<i)) == 0) {
143             m->bufferMask |= (1LU<<i);
144             break;
145         }
146         vaddr += bufferSize;
147     }
148 
149     hnd->base = vaddr;
150     hnd->offset = vaddr - intptr_t(m->framebuffer->base);
151     *pHandle = hnd;
152 
153     return 0;
154 }
155 
gralloc_alloc_framebuffer(alloc_device_t * dev,size_t size,int format,int usage,buffer_handle_t * pHandle)156 static int gralloc_alloc_framebuffer(alloc_device_t* dev,
157         size_t size, int format, int usage, buffer_handle_t* pHandle)
158 {
159     private_module_t* m = reinterpret_cast<private_module_t*>(
160             dev->common.module);
161     pthread_mutex_lock(&m->lock);
162     int err = gralloc_alloc_framebuffer_locked(dev, size, format, usage, pHandle);
163     pthread_mutex_unlock(&m->lock);
164     return err;
165 }
166 
gralloc_alloc_buffer(alloc_device_t * dev,size_t size,int,buffer_handle_t * pHandle)167 static int gralloc_alloc_buffer(alloc_device_t* dev,
168         size_t size, int /*usage*/, buffer_handle_t* pHandle)
169 {
170     int err = 0;
171     int fd = -1;
172 
173     size = roundUpToPageSize(size);
174 
175     fd = ashmem_create_region("gralloc-buffer", size);
176     if (fd < 0) {
177         ALOGE("couldn't create ashmem (%s)", strerror(-errno));
178         err = -errno;
179     }
180 
181     if (err == 0) {
182         private_handle_t* hnd = new private_handle_t(fd, size, 0);
183         gralloc_module_t* module = reinterpret_cast<gralloc_module_t*>(
184                 dev->common.module);
185         err = mapBuffer(module, hnd);
186         if (err == 0) {
187             *pHandle = hnd;
188         }
189     }
190 
191     ALOGE_IF(err, "gralloc failed err=%s", strerror(-err));
192 
193     return err;
194 }
195 
196 /*****************************************************************************/
197 
align(size_t value,size_t alignment)198 inline size_t align(size_t value, size_t alignment)
199 {
200     return ((value + alignment - 1) / alignment) * alignment;
201 }
202 
gralloc_alloc(alloc_device_t * dev,int width,int height,int format,int usage,buffer_handle_t * pHandle,int * pStride)203 static int gralloc_alloc(alloc_device_t* dev,
204         int width, int height, int format, int usage,
205         buffer_handle_t* pHandle, int* pStride)
206 {
207     if (!pHandle || !pStride)
208         return -EINVAL;
209 
210     int bytesPerPixel = 0;
211     switch (format) {
212         case HAL_PIXEL_FORMAT_RGBA_FP16:
213             bytesPerPixel = 8;
214             break;
215         case HAL_PIXEL_FORMAT_RGBA_8888:
216         case HAL_PIXEL_FORMAT_RGBX_8888:
217         case HAL_PIXEL_FORMAT_BGRA_8888:
218             bytesPerPixel = 4;
219             break;
220         case HAL_PIXEL_FORMAT_RGB_888:
221             bytesPerPixel = 3;
222             break;
223         case HAL_PIXEL_FORMAT_RGB_565:
224         case HAL_PIXEL_FORMAT_RAW16:
225             bytesPerPixel = 2;
226             break;
227         default:
228             return -EINVAL;
229     }
230 
231     const size_t tileWidth = 2;
232     const size_t tileHeight = 2;
233 
234     size_t stride = align(width, tileWidth);
235     size_t size = align(height, tileHeight) * stride * bytesPerPixel + 4;
236 
237     int err;
238     if (usage & GRALLOC_USAGE_HW_FB) {
239         err = gralloc_alloc_framebuffer(dev, size, format, usage, pHandle);
240     } else {
241         err = gralloc_alloc_buffer(dev, size, usage, pHandle);
242     }
243 
244     if (err < 0) {
245         return err;
246     }
247 
248     *pStride = stride;
249     return 0;
250 }
251 
gralloc_free(alloc_device_t * dev,buffer_handle_t handle)252 static int gralloc_free(alloc_device_t* dev,
253         buffer_handle_t handle)
254 {
255     if (private_handle_t::validate(handle) < 0)
256         return -EINVAL;
257 
258     private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(handle);
259     if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
260         // free this buffer
261         private_module_t* m = reinterpret_cast<private_module_t*>(
262                 dev->common.module);
263         const size_t bufferSize = m->finfo.line_length * m->info.yres;
264         int index = (hnd->base - m->framebuffer->base) / bufferSize;
265         m->bufferMask &= ~(1<<index);
266     } else {
267         gralloc_module_t* module = reinterpret_cast<gralloc_module_t*>(
268                 dev->common.module);
269         terminateBuffer(module, const_cast<private_handle_t*>(hnd));
270     }
271 
272     close(hnd->fd);
273     delete hnd;
274     return 0;
275 }
276 
277 /*****************************************************************************/
278 
gralloc_close(struct hw_device_t * dev)279 static int gralloc_close(struct hw_device_t *dev)
280 {
281     gralloc_context_t* ctx = reinterpret_cast<gralloc_context_t*>(dev);
282     if (ctx) {
283         /* TODO: keep a list of all buffer_handle_t created, and free them
284          * all here.
285          */
286         free(ctx);
287     }
288     return 0;
289 }
290 
gralloc_device_open(const hw_module_t * module,const char * name,hw_device_t ** device)291 int gralloc_device_open(const hw_module_t* module, const char* name,
292         hw_device_t** device)
293 {
294     int status = -EINVAL;
295     if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
296         gralloc_context_t *dev;
297         dev = (gralloc_context_t*)malloc(sizeof(*dev));
298 
299         /* initialize our state here */
300         memset(dev, 0, sizeof(*dev));
301 
302         /* initialize the procs */
303         dev->device.common.tag = HARDWARE_DEVICE_TAG;
304         dev->device.common.version = 0;
305         dev->device.common.module = const_cast<hw_module_t*>(module);
306         dev->device.common.close = gralloc_close;
307 
308         dev->device.alloc   = gralloc_alloc;
309         dev->device.free    = gralloc_free;
310 
311         *device = &dev->device.common;
312         status = 0;
313     } else {
314         status = fb_device_open(module, name, device);
315     }
316     return status;
317 }
318