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