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"
38f96b2064d7753af7ab75f05eff9559f401e1a4adMathias Agopian#include "gr.h"
393e1f89bcca78fb5175043c76ff5a9310fae91829Mathias Agopian
403e1f89bcca78fb5175043c76ff5a9310fae91829Mathias Agopian/*****************************************************************************/
413e1f89bcca78fb5175043c76ff5a9310fae91829Mathias Agopian
42a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstruct gralloc_context_t {
43a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    alloc_device_t  device;
44a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    /* our private data here */
45a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian};
46a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
47a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstatic int gralloc_alloc_buffer(alloc_device_t* dev,
48a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        size_t size, int usage, buffer_handle_t* pHandle);
49a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
50a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian/*****************************************************************************/
51a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
52a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianint fb_device_open(const hw_module_t* module, const char* name,
53a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        hw_device_t** device);
54a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
55a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstatic int gralloc_device_open(const hw_module_t* module, const char* name,
56a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        hw_device_t** device);
57a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
58a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianextern int gralloc_lock(gralloc_module_t const* module,
59a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        buffer_handle_t handle, int usage,
60988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian        int l, int t, int w, int h,
61988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian        void** vaddr);
62a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
63a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianextern int gralloc_unlock(gralloc_module_t const* module,
64a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        buffer_handle_t handle);
65a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
66988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopianextern int gralloc_register_buffer(gralloc_module_t const* module,
67988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian        buffer_handle_t handle);
68988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian
69988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopianextern int gralloc_unregister_buffer(gralloc_module_t const* module,
70988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian        buffer_handle_t handle);
71988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian
72a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian/*****************************************************************************/
73a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
74a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstatic struct hw_module_methods_t gralloc_module_methods = {
75a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        open: gralloc_device_open
76a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian};
77a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
78a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstruct private_module_t HAL_MODULE_INFO_SYM = {
79a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    base: {
80a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        common: {
81a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian            tag: HARDWARE_MODULE_TAG,
82a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian            version_major: 1,
83a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian            version_minor: 0,
84a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian            id: GRALLOC_HARDWARE_MODULE_ID,
85a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian            name: "Graphics Memory Allocator Module",
86a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian            author: "The Android Open Source Project",
87a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian            methods: &gralloc_module_methods
88a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        },
89988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian        registerBuffer: gralloc_register_buffer,
90988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian        unregisterBuffer: gralloc_unregister_buffer,
91a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        lock: gralloc_lock,
92a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        unlock: gralloc_unlock,
93a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    },
94a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    framebuffer: 0,
95a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    flags: 0,
96a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    numBuffers: 0,
97a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    bufferMask: 0,
98a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    lock: PTHREAD_MUTEX_INITIALIZER,
998c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian    currentBuffer: 0,
100a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian};
101a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
102a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian/*****************************************************************************/
103a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
104a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstatic int gralloc_alloc_framebuffer_locked(alloc_device_t* dev,
105a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        size_t size, int usage, buffer_handle_t* pHandle)
106a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian{
107a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    private_module_t* m = reinterpret_cast<private_module_t*>(
108a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian            dev->common.module);
109a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
110a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    // allocate the framebuffer
111a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    if (m->framebuffer == NULL) {
112988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian        // initialize the framebuffer, the framebuffer is mapped once
113988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian        // and forever.
114a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        int err = mapFrameBufferLocked(m);
115a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        if (err < 0) {
116a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian            return err;
117a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        }
118a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    }
119a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
120a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    const uint32_t bufferMask = m->bufferMask;
121a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    const uint32_t numBuffers = m->numBuffers;
122a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    const size_t bufferSize = m->finfo.line_length * m->info.yres;
123a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    if (numBuffers == 1) {
124a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        // If we have only one buffer, we never use page-flipping. Instead,
125a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        // we return a regular buffer which will be memcpy'ed to the main
126a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        // screen when post is called.
127a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
128a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        return gralloc_alloc_buffer(dev, bufferSize, newUsage, pHandle);
129a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    }
130a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
131a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    if (bufferMask >= ((1LU<<numBuffers)-1)) {
132a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        // We ran out of buffers.
133a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        return -ENOMEM;
134a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    }
135a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
136a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    // create a "fake" handles for it
137a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    intptr_t vaddr = intptr_t(m->framebuffer->base);
138a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    private_handle_t* hnd = new private_handle_t(dup(m->framebuffer->fd), size,
139a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian            private_handle_t::PRIV_FLAGS_FRAMEBUFFER);
140a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
141a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    // find a free slot
142a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    for (uint32_t i=0 ; i<numBuffers ; i++) {
143a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        if ((bufferMask & (1LU<<i)) == 0) {
144a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian            m->bufferMask |= (1LU<<i);
145a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian            break;
146a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        }
147a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        vaddr += bufferSize;
148a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    }
149a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
150a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    hnd->base = vaddr;
15172c8508db9c3895a34437a3e780b90ec43a920a2Mathias Agopian    hnd->offset = vaddr - intptr_t(m->framebuffer->base);
152a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    *pHandle = hnd;
153a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
154a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    return 0;
155a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian}
156a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
157a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstatic int gralloc_alloc_framebuffer(alloc_device_t* dev,
158a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        size_t size, int usage, buffer_handle_t* pHandle)
159a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian{
160a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    private_module_t* m = reinterpret_cast<private_module_t*>(
161a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian            dev->common.module);
162a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    pthread_mutex_lock(&m->lock);
163a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    int err = gralloc_alloc_framebuffer_locked(dev, size, usage, pHandle);
164a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    pthread_mutex_unlock(&m->lock);
165a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    return err;
166a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian}
167a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
168a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstatic int gralloc_alloc_buffer(alloc_device_t* dev,
169a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        size_t size, int usage, buffer_handle_t* pHandle)
170a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian{
1718c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian    int err = 0;
1728c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian    int fd = -1;
1738c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian
1748c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian    size = roundUpToPageSize(size);
1758c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian
176f96b2064d7753af7ab75f05eff9559f401e1a4adMathias Agopian    fd = ashmem_create_region("gralloc-buffer", size);
177bfc010a750eb091017e370640d5c1644d671c7e4Mathias Agopian    if (fd < 0) {
17860d056bf2926357260592409dee31374fa8e301bSteve Block        ALOGE("couldn't create ashmem (%s)", strerror(-errno));
179bfc010a750eb091017e370640d5c1644d671c7e4Mathias Agopian        err = -errno;
180bfc010a750eb091017e370640d5c1644d671c7e4Mathias Agopian    }
181bfc010a750eb091017e370640d5c1644d671c7e4Mathias Agopian
1828c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian    if (err == 0) {
183f96b2064d7753af7ab75f05eff9559f401e1a4adMathias Agopian        private_handle_t* hnd = new private_handle_t(fd, size, 0);
184f96b2064d7753af7ab75f05eff9559f401e1a4adMathias Agopian        gralloc_module_t* module = reinterpret_cast<gralloc_module_t*>(
185f96b2064d7753af7ab75f05eff9559f401e1a4adMathias Agopian                dev->common.module);
186f96b2064d7753af7ab75f05eff9559f401e1a4adMathias Agopian        err = mapBuffer(module, hnd);
187f96b2064d7753af7ab75f05eff9559f401e1a4adMathias Agopian        if (err == 0) {
188f96b2064d7753af7ab75f05eff9559f401e1a4adMathias Agopian            *pHandle = hnd;
189f96b2064d7753af7ab75f05eff9559f401e1a4adMathias Agopian        }
190a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    }
1918c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian
19260d056bf2926357260592409dee31374fa8e301bSteve Block    ALOGE_IF(err, "gralloc failed err=%s", strerror(-err));
1938c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian
1948c4ab1fa14cc13c324bde91c0271f9ab5f4663d3Mathias Agopian    return err;
195a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian}
196a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
197a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian/*****************************************************************************/
198a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
199a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstatic int gralloc_alloc(alloc_device_t* dev,
200a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        int w, int h, int format, int usage,
201a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        buffer_handle_t* pHandle, int* pStride)
202a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian{
203a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    if (!pHandle || !pStride)
204a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        return -EINVAL;
205a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
2068bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian    size_t size, stride;
2079da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian
2089da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian    int align = 4;
2099da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian    int bpp = 0;
2109da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian    switch (format) {
2119da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian        case HAL_PIXEL_FORMAT_RGBA_8888:
2129da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian        case HAL_PIXEL_FORMAT_RGBX_8888:
2139da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian        case HAL_PIXEL_FORMAT_BGRA_8888:
2149da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian            bpp = 4;
2159da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian            break;
2169da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian        case HAL_PIXEL_FORMAT_RGB_888:
2179da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian            bpp = 3;
2189da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian            break;
2199da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian        case HAL_PIXEL_FORMAT_RGB_565:
2209da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian        case HAL_PIXEL_FORMAT_RGBA_5551:
2219da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian        case HAL_PIXEL_FORMAT_RGBA_4444:
222984272d92e40941f3d140f2cecb5f05986ac66b1Eino-Ville Talvala        case HAL_PIXEL_FORMAT_RAW_SENSOR:
2239da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian            bpp = 2;
2249da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian            break;
2259da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian        default:
2269da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian            return -EINVAL;
227a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    }
2289da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian    size_t bpr = (w*bpp + (align-1)) & ~(align-1);
2299da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian    size = bpr * h;
2309da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian    stride = bpr / bpp;
231a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
232a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    int err;
233a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    if (usage & GRALLOC_USAGE_HW_FB) {
234a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        err = gralloc_alloc_framebuffer(dev, size, usage, pHandle);
235a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    } else {
236a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        err = gralloc_alloc_buffer(dev, size, usage, pHandle);
237a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    }
2388bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian
239a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    if (err < 0) {
240a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        return err;
241a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    }
242a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
243a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    *pStride = stride;
244a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    return 0;
245a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian}
246a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
247a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstatic int gralloc_free(alloc_device_t* dev,
248a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        buffer_handle_t handle)
249a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian{
250a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    if (private_handle_t::validate(handle) < 0)
251a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        return -EINVAL;
252a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
253a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(handle);
254bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian    if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
255a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        // free this buffer
256a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        private_module_t* m = reinterpret_cast<private_module_t*>(
257a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian                dev->common.module);
258a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        const size_t bufferSize = m->finfo.line_length * m->info.yres;
259a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        int index = (hnd->base - m->framebuffer->base) / bufferSize;
260a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        m->bufferMask &= ~(1<<index);
261bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian    } else {
262bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian        gralloc_module_t* module = reinterpret_cast<gralloc_module_t*>(
263bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian                dev->common.module);
264bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian        terminateBuffer(module, const_cast<private_handle_t*>(hnd));
265bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian    }
266988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian
267a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    close(hnd->fd);
268a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    delete hnd;
269a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    return 0;
270a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian}
271a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
272a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian/*****************************************************************************/
273a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
274a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstatic int gralloc_close(struct hw_device_t *dev)
275a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian{
276a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    gralloc_context_t* ctx = reinterpret_cast<gralloc_context_t*>(dev);
277a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    if (ctx) {
278a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        /* TODO: keep a list of all buffer_handle_t created, and free them
279988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian         * all here.
280a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian         */
281a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        free(ctx);
282a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    }
283a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    return 0;
284a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian}
285a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
286a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianint gralloc_device_open(const hw_module_t* module, const char* name,
287a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        hw_device_t** device)
288a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian{
289a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    int status = -EINVAL;
290a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
291a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        gralloc_context_t *dev;
292a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        dev = (gralloc_context_t*)malloc(sizeof(*dev));
293a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
294a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        /* initialize our state here */
295a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        memset(dev, 0, sizeof(*dev));
296a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
297a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        /* initialize the procs */
298a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        dev->device.common.tag = HARDWARE_DEVICE_TAG;
299a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        dev->device.common.version = 0;
300a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        dev->device.common.module = const_cast<hw_module_t*>(module);
301a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        dev->device.common.close = gralloc_close;
302a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
303a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        dev->device.alloc   = gralloc_alloc;
304a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        dev->device.free    = gralloc_free;
305a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
306a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        *device = &dev->device.common;
307a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        status = 0;
308a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    } else {
309a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        status = fb_device_open(module, name, device);
310a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    }
311a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    return status;
312a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian}
313