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 = {
756abbed50934dab5d73cd9e06086e37ac8d87ef18synergy dev        .open = gralloc_device_open
76a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian};
77a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
78a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstruct private_module_t HAL_MODULE_INFO_SYM = {
796abbed50934dab5d73cd9e06086e37ac8d87ef18synergy dev    .base = {
806abbed50934dab5d73cd9e06086e37ac8d87ef18synergy dev        .common = {
816abbed50934dab5d73cd9e06086e37ac8d87ef18synergy dev            .tag = HARDWARE_MODULE_TAG,
826abbed50934dab5d73cd9e06086e37ac8d87ef18synergy dev            .version_major = 1,
836abbed50934dab5d73cd9e06086e37ac8d87ef18synergy dev            .version_minor = 0,
846abbed50934dab5d73cd9e06086e37ac8d87ef18synergy dev            .id = GRALLOC_HARDWARE_MODULE_ID,
856abbed50934dab5d73cd9e06086e37ac8d87ef18synergy dev            .name = "Graphics Memory Allocator Module",
866abbed50934dab5d73cd9e06086e37ac8d87ef18synergy dev            .author = "The Android Open Source Project",
876abbed50934dab5d73cd9e06086e37ac8d87ef18synergy dev            .methods = &gralloc_module_methods
88a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        },
896abbed50934dab5d73cd9e06086e37ac8d87ef18synergy dev        .registerBuffer = gralloc_register_buffer,
906abbed50934dab5d73cd9e06086e37ac8d87ef18synergy dev        .unregisterBuffer = gralloc_unregister_buffer,
916abbed50934dab5d73cd9e06086e37ac8d87ef18synergy dev        .lock = gralloc_lock,
926abbed50934dab5d73cd9e06086e37ac8d87ef18synergy dev        .unlock = gralloc_unlock,
93a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    },
946abbed50934dab5d73cd9e06086e37ac8d87ef18synergy dev    .framebuffer = 0,
956abbed50934dab5d73cd9e06086e37ac8d87ef18synergy dev    .flags = 0,
966abbed50934dab5d73cd9e06086e37ac8d87ef18synergy dev    .numBuffers = 0,
976abbed50934dab5d73cd9e06086e37ac8d87ef18synergy dev    .bufferMask = 0,
986abbed50934dab5d73cd9e06086e37ac8d87ef18synergy dev    .lock = PTHREAD_MUTEX_INITIALIZER,
996abbed50934dab5d73cd9e06086e37ac8d87ef18synergy dev    .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,
169febaaa937f2bb08197ab5636afce210028357888Colin Cross        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
199bd9860160a3004b769f2de9e435fb051d4fbb775Nicolas Capensinline size_t align(size_t value, size_t alignment)
200bd9860160a3004b769f2de9e435fb051d4fbb775Nicolas Capens{
201bd9860160a3004b769f2de9e435fb051d4fbb775Nicolas Capens    return ((value + alignment - 1) / alignment) * alignment;
202bd9860160a3004b769f2de9e435fb051d4fbb775Nicolas Capens}
203bd9860160a3004b769f2de9e435fb051d4fbb775Nicolas Capens
204a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstatic int gralloc_alloc(alloc_device_t* dev,
205bd9860160a3004b769f2de9e435fb051d4fbb775Nicolas Capens        int width, int height, int format, int usage,
206a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        buffer_handle_t* pHandle, int* pStride)
207a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian{
208a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    if (!pHandle || !pStride)
209a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        return -EINVAL;
210a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
211bd9860160a3004b769f2de9e435fb051d4fbb775Nicolas Capens    int bytesPerPixel = 0;
2129da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian    switch (format) {
213d0eb44c6da6a8b45f23c5818c999ee74bb0d0339Romain Guy        case HAL_PIXEL_FORMAT_RGBA_FP16:
214d0eb44c6da6a8b45f23c5818c999ee74bb0d0339Romain Guy            bytesPerPixel = 8;
215d0eb44c6da6a8b45f23c5818c999ee74bb0d0339Romain Guy            break;
2169da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian        case HAL_PIXEL_FORMAT_RGBA_8888:
2179da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian        case HAL_PIXEL_FORMAT_RGBX_8888:
2189da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian        case HAL_PIXEL_FORMAT_BGRA_8888:
219bd9860160a3004b769f2de9e435fb051d4fbb775Nicolas Capens            bytesPerPixel = 4;
2209da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian            break;
2219da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian        case HAL_PIXEL_FORMAT_RGB_888:
222bd9860160a3004b769f2de9e435fb051d4fbb775Nicolas Capens            bytesPerPixel = 3;
2239da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian            break;
2249da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian        case HAL_PIXEL_FORMAT_RGB_565:
225e69efbbabf26569ddd0ca12dda44d830a251a07fEino-Ville Talvala        case HAL_PIXEL_FORMAT_RAW16:
226bd9860160a3004b769f2de9e435fb051d4fbb775Nicolas Capens            bytesPerPixel = 2;
2279da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian            break;
2289da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian        default:
2299da751bbf7cc6db4a0156b92bb1d3ae585bcdf32Mathias Agopian            return -EINVAL;
230a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    }
231bd9860160a3004b769f2de9e435fb051d4fbb775Nicolas Capens
232bd9860160a3004b769f2de9e435fb051d4fbb775Nicolas Capens    const size_t tileWidth = 2;
233bd9860160a3004b769f2de9e435fb051d4fbb775Nicolas Capens    const size_t tileHeight = 2;
234bd9860160a3004b769f2de9e435fb051d4fbb775Nicolas Capens
235bd9860160a3004b769f2de9e435fb051d4fbb775Nicolas Capens    size_t stride = align(width, tileWidth);
236bd9860160a3004b769f2de9e435fb051d4fbb775Nicolas Capens    size_t size = align(height, tileHeight) * stride * bytesPerPixel + 4;
237a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
238a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    int err;
239a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    if (usage & GRALLOC_USAGE_HW_FB) {
240a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        err = gralloc_alloc_framebuffer(dev, size, usage, pHandle);
241a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    } else {
242a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        err = gralloc_alloc_buffer(dev, size, usage, pHandle);
243a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    }
2448bf1f752686a228256e2f3c29a374d76f42b126bMathias Agopian
245a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    if (err < 0) {
246a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        return err;
247a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    }
248a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
249a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    *pStride = stride;
250a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    return 0;
251a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian}
252a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
253a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstatic int gralloc_free(alloc_device_t* dev,
254a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        buffer_handle_t handle)
255a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian{
256a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    if (private_handle_t::validate(handle) < 0)
257a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        return -EINVAL;
258a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
259a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(handle);
260bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian    if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
261a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        // free this buffer
262a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        private_module_t* m = reinterpret_cast<private_module_t*>(
263a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian                dev->common.module);
264a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        const size_t bufferSize = m->finfo.line_length * m->info.yres;
265a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        int index = (hnd->base - m->framebuffer->base) / bufferSize;
266a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        m->bufferMask &= ~(1<<index);
267bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian    } else {
268bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian        gralloc_module_t* module = reinterpret_cast<gralloc_module_t*>(
269bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian                dev->common.module);
270bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian        terminateBuffer(module, const_cast<private_handle_t*>(hnd));
271bd80b38f2945ac918f66fb336c149b28b9dd030eMathias Agopian    }
272988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian
273a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    close(hnd->fd);
274a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    delete hnd;
275a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    return 0;
276a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian}
277a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
278a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian/*****************************************************************************/
279a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
280a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianstatic int gralloc_close(struct hw_device_t *dev)
281a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian{
282a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    gralloc_context_t* ctx = reinterpret_cast<gralloc_context_t*>(dev);
283a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    if (ctx) {
284a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        /* TODO: keep a list of all buffer_handle_t created, and free them
285988b8bd553180e8d71b4028ecb721f46312efe62Mathias Agopian         * all here.
286a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian         */
287a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        free(ctx);
288a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    }
289a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    return 0;
290a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian}
291a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
292a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopianint gralloc_device_open(const hw_module_t* module, const char* name,
293a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        hw_device_t** device)
294a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian{
295a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    int status = -EINVAL;
296a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
297a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        gralloc_context_t *dev;
298a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        dev = (gralloc_context_t*)malloc(sizeof(*dev));
299a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
300a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        /* initialize our state here */
301a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        memset(dev, 0, sizeof(*dev));
302a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
303a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        /* initialize the procs */
304a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        dev->device.common.tag = HARDWARE_DEVICE_TAG;
305a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        dev->device.common.version = 0;
306a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        dev->device.common.module = const_cast<hw_module_t*>(module);
307a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        dev->device.common.close = gralloc_close;
308a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
309a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        dev->device.alloc   = gralloc_alloc;
310a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        dev->device.free    = gralloc_free;
311a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian
312a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        *device = &dev->device.common;
313a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        status = 0;
314a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    } else {
315a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian        status = fb_device_open(module, name, device);
316a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    }
317a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian    return status;
318a8a75166a2d3c7639a7432a67075c98796165206Mathias Agopian}
319