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