mapper.cpp revision 67aa558115b4d484ff2328ca19387613bde57ed2
1a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev/*
2a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * Copyright (C) 2008 The Android Open Source Project
383b98f3b7c3c458707c95b854a3669c98d28d1f5Naseer Ahmed * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
4a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev *
5a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * Licensed under the Apache License, Version 2.0 (the "License");
6a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * you may not use this file except in compliance with the License.
7a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * You may obtain a copy of the License at
8a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev *
9a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev *      http://www.apache.org/licenses/LICENSE-2.0
10a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev *
11a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * Unless required by applicable law or agreed to in writing, software
12a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * distributed under the License is distributed on an "AS IS" BASIS,
13a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * See the License for the specific language governing permissions and
15a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * limitations under the License.
16a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev */
17a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
18a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <limits.h>
19a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <errno.h>
20a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <pthread.h>
21a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <unistd.h>
22a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <string.h>
23a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <stdarg.h>
24a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
25a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <sys/mman.h>
26a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <sys/stat.h>
27a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <sys/types.h>
28a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <sys/ioctl.h>
29a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <linux/ashmem.h>
30a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
31a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <cutils/log.h>
32a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <cutils/atomic.h>
33a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <cutils/ashmem.h>
34a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
35a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <hardware/hardware.h>
36a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <hardware/gralloc.h>
37a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <linux/android_pmem.h>
38a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
39a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include "gralloc_priv.h"
40a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include "gr.h"
41a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include "alloc_controller.h"
42a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include "memalloc.h"
43591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan#include <qdMetaData.h>
44a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
45a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchevusing namespace gralloc;
46a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev/*****************************************************************************/
47a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
48a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev// Return the type of allocator -
49a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev// these are used for mapping/unmapping
50be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmedstatic IMemAlloc* getAllocator(int flags)
51a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev{
52be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmed    IMemAlloc* memalloc;
53be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmed    IAllocController* alloc_ctrl = IAllocController::getInstance();
54a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    memalloc = alloc_ctrl->getAllocator(flags);
55a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    return memalloc;
56a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev}
57a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
58a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchevstatic int gralloc_map(gralloc_module_t const* module,
59befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                       buffer_handle_t handle,
60befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                       void** vaddr)
61a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev{
62a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    private_handle_t* hnd = (private_handle_t*)handle;
63a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    void *mappedAddress;
64a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) &&
65a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev        !(hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER)) {
66a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev        size_t size = hnd->size;
67be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmed        IMemAlloc* memalloc = getAllocator(hnd->flags) ;
68a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev        int err = memalloc->map_buffer(&mappedAddress, size,
69befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                       hnd->offset, hnd->fd);
70591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan        if(err || mappedAddress == MAP_FAILED) {
71a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev            ALOGE("Could not mmap handle %p, fd=%d (%s)",
72befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                  handle, hnd->fd, strerror(errno));
73a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev            hnd->base = 0;
74a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev            return -errno;
75a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev        }
76a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
77a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev        hnd->base = intptr_t(mappedAddress) + hnd->offset;
78befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        //LOGD("gralloc_map() succeeded fd=%d, off=%d, size=%d, vaddr=%p",
79a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev        //        hnd->fd, hnd->offset, hnd->size, mappedAddress);
80591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan        mappedAddress = MAP_FAILED;
81591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan        size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
82591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan        err = memalloc->map_buffer(&mappedAddress, size,
83591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan                                       hnd->offset_metadata, hnd->fd_metadata);
84591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan        if(err || mappedAddress == MAP_FAILED) {
85591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan            ALOGE("Could not mmap handle %p, fd=%d (%s)",
86591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan                  handle, hnd->fd_metadata, strerror(errno));
87591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan            hnd->base_metadata = 0;
88591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan            return -errno;
89591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan        }
90591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan        hnd->base_metadata = intptr_t(mappedAddress) + hnd->offset_metadata;
91a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    }
92a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    *vaddr = (void*)hnd->base;
93a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    return 0;
94a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev}
95a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
96a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchevstatic int gralloc_unmap(gralloc_module_t const* module,
97befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                         buffer_handle_t handle)
98a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev{
99a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    private_handle_t* hnd = (private_handle_t*)handle;
100a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
101a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev        int err = -EINVAL;
102a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev        void* base = (void*)hnd->base;
103a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev        size_t size = hnd->size;
104be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmed        IMemAlloc* memalloc = getAllocator(hnd->flags) ;
105591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan        if(memalloc != NULL) {
106a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev            err = memalloc->unmap_buffer(base, size, hnd->offset);
107591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan            if (err) {
108591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan                ALOGE("Could not unmap memory at address %p", base);
109591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan            }
110591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan            base = (void*)hnd->base_metadata;
111591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan            size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
112591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan            err = memalloc->unmap_buffer(base, size, hnd->offset_metadata);
113591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan            if (err) {
114591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan                ALOGE("Could not unmap memory at address %p", base);
115591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan            }
116a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev        }
117a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    }
118a0b7f4e1300ee86ca60c40fb238ed5d3f518941eRamkumar Radhakrishnan    /* need to initialize the pointer to NULL otherwise unmapping for that
119a0b7f4e1300ee86ca60c40fb238ed5d3f518941eRamkumar Radhakrishnan     * buffer happens twice which leads to crash */
120a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    hnd->base = 0;
121a0b7f4e1300ee86ca60c40fb238ed5d3f518941eRamkumar Radhakrishnan    hnd->base_metadata = 0;
122a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    return 0;
123a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev}
124a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
125a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev/*****************************************************************************/
126a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
127a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchevstatic pthread_mutex_t sMapLock = PTHREAD_MUTEX_INITIALIZER;
128a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
129a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev/*****************************************************************************/
130a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
131a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchevint gralloc_register_buffer(gralloc_module_t const* module,
132befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                            buffer_handle_t handle)
133a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev{
134a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    if (private_handle_t::validate(handle) < 0)
135a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev        return -EINVAL;
136a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
137a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    // In this implementation, we don't need to do anything here
138a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
139a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    /* NOTE: we need to initialize the buffer as not mapped/not locked
140a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev     * because it shouldn't when this function is called the first time
141a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev     * in a new process. Ideally these flags shouldn't be part of the
142a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev     * handle, but instead maintained in the kernel or at least
143a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev     * out-of-line
144a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev     */
145a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
146a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    private_handle_t* hnd = (private_handle_t*)handle;
14777a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar    hnd->base = 0;
148a0b7f4e1300ee86ca60c40fb238ed5d3f518941eRamkumar Radhakrishnan    hnd->base_metadata = 0;
14977a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar    void *vaddr;
15077a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar    int err = gralloc_map(module, handle, &vaddr);
15177a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar    if (err) {
15277a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar        ALOGE("%s: gralloc_map failed", __FUNCTION__);
15377a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar        return err;
15477a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar    }
155a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
156a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    return 0;
157a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev}
158a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
159a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchevint gralloc_unregister_buffer(gralloc_module_t const* module,
160befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              buffer_handle_t handle)
161a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev{
162a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    if (private_handle_t::validate(handle) < 0)
163a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev        return -EINVAL;
164a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
165a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    /*
166a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev     * If the buffer has been mapped during a lock operation, it's time
167a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev     * to un-map it. It's an error to be here with a locked buffer.
168a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev     * NOTE: the framebuffer is handled differently and is never unmapped.
169a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev     */
170a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
171a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    private_handle_t* hnd = (private_handle_t*)handle;
172a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
17377a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar    if (hnd->base != 0) {
17477a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar        gralloc_unmap(module, handle);
17577a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar    }
17677a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar    hnd->base = 0;
177a0b7f4e1300ee86ca60c40fb238ed5d3f518941eRamkumar Radhakrishnan    hnd->base_metadata = 0;
178a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    return 0;
179a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev}
180a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
181a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchevint terminateBuffer(gralloc_module_t const* module,
182befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                    private_handle_t* hnd)
183a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev{
184a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    /*
185a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev     * If the buffer has been mapped during a lock operation, it's time
186a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev     * to un-map it. It's an error to be here with a locked buffer.
187a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev     */
188a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
189a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    if (hnd->base != 0) {
190a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev        // this buffer was mapped, unmap it now
191a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev        if (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM |
192a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                          private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP |
193a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                          private_handle_t::PRIV_FLAGS_USES_ASHMEM |
194a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                          private_handle_t::PRIV_FLAGS_USES_ION)) {
195a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                gralloc_unmap(module, hnd);
196a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev        } else {
197befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("terminateBuffer: unmapping a non pmem/ashmem buffer flags = 0x%x",
198befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                  hnd->flags);
199a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev            gralloc_unmap(module, hnd);
200a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev        }
201a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    }
202a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
203a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    return 0;
204a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev}
205a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
206a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchevint gralloc_lock(gralloc_module_t const* module,
207befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                 buffer_handle_t handle, int usage,
208befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                 int l, int t, int w, int h,
209befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                 void** vaddr)
210a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev{
211a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    if (private_handle_t::validate(handle) < 0)
212a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev        return -EINVAL;
213a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
214a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    int err = 0;
215a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    private_handle_t* hnd = (private_handle_t*)handle;
216a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
217a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev        if (hnd->base == 0) {
218a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev            // we need to map for real
219a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev            pthread_mutex_t* const lock = &sMapLock;
220a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev            pthread_mutex_lock(lock);
221a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev            err = gralloc_map(module, handle, vaddr);
222a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev            pthread_mutex_unlock(lock);
223a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev        }
224a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev        *vaddr = (void*)hnd->base;
225d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed        if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) {
226d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed            //Invalidate if reading in software. No need to do this for the
227d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed            //metadata buffer as it is only read/written in software.
228d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed            IMemAlloc* memalloc = getAllocator(hnd->flags) ;
229d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed            err = memalloc->clean_buffer((void*)hnd->base,
230d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed                                         hnd->size, hnd->offset, hnd->fd,
231d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed                                         CACHE_INVALIDATE);
232d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed            if (usage & GRALLOC_USAGE_SW_WRITE_MASK) {
233d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed                // Mark the buffer to be flushed after cpu read/write
234d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed                hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
235d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed            }
236a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev        }
2372a0417549a81c49b4826c27edd90e0bae3902233Naseer Ahmed    } else {
2382a0417549a81c49b4826c27edd90e0bae3902233Naseer Ahmed        hnd->flags |= private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH;
239a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    }
240a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    return err;
241a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev}
242a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
243a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchevint gralloc_unlock(gralloc_module_t const* module,
244befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                   buffer_handle_t handle)
245a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev{
246a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    if (private_handle_t::validate(handle) < 0)
247a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev        return -EINVAL;
2482a0417549a81c49b4826c27edd90e0bae3902233Naseer Ahmed    int err = 0;
249a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    private_handle_t* hnd = (private_handle_t*)handle;
250a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
251d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed    if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) {
25267aa558115b4d484ff2328ca19387613bde57ed2Naseer Ahmed        IMemAlloc* memalloc = getAllocator(hnd->flags);
253d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed        if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
254d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed            err = memalloc->clean_buffer((void*)hnd->base,
255d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed                                         hnd->size, hnd->offset, hnd->fd,
256d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed                                         CACHE_CLEAN_AND_INVALIDATE);
257d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed            hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
258d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed        } else if(hnd->flags & private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH) {
259d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed            hnd->flags &= ~private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH;
260d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed        } else {
261d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed            //Probably a round about way to do this, but this avoids adding new
262d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed            //flags
263d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed            err = memalloc->clean_buffer((void*)hnd->base,
264d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed                                         hnd->size, hnd->offset, hnd->fd,
265d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed                                         CACHE_INVALIDATE);
266d2b1b25bd45c1135668ce06b7643b5bb72b23200Naseer Ahmed        }
267a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    }
268a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
2692a0417549a81c49b4826c27edd90e0bae3902233Naseer Ahmed    return err;
270a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev}
271a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
272a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev/*****************************************************************************/
273a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
274a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchevint gralloc_perform(struct gralloc_module_t const* module,
275befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                    int operation, ... )
276a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev{
277a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    int res = -EINVAL;
278a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    va_list args;
279a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    va_start(args, operation);
280a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    switch (operation) {
281a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev        case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER:
282a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev            {
283a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                int fd = va_arg(args, int);
284a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                size_t size = va_arg(args, size_t);
285a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                size_t offset = va_arg(args, size_t);
286a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                void* base = va_arg(args, void*);
287a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                int width = va_arg(args, int);
288a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                int height = va_arg(args, int);
289a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                int format = va_arg(args, int);
290a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
291a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                native_handle_t** handle = va_arg(args, native_handle_t**);
292a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                int memoryFlags = va_arg(args, int);
293a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                private_handle_t* hnd = (private_handle_t*)native_handle_create(
294befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                    private_handle_t::sNumFds, private_handle_t::sNumInts);
295a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                hnd->magic = private_handle_t::sMagic;
296a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                hnd->fd = fd;
297be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmed                hnd->flags =  private_handle_t::PRIV_FLAGS_USES_ION;
298a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                hnd->size = size;
299a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                hnd->offset = offset;
300a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                hnd->base = intptr_t(base) + offset;
301a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                hnd->gpuaddr = 0;
302a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                hnd->width = width;
303a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                hnd->height = height;
304a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                hnd->format = format;
305a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                *handle = (native_handle_t *)hnd;
306a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                res = 0;
307a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev                break;
308a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev
309a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev            }
31059644b2127280052ca410cb053f0a41c3181a97aNaseer Ahmed#ifdef QCOM_BSP
3115fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan        case GRALLOC_MODULE_PERFORM_UPDATE_BUFFER_GEOMETRY:
3125fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan            {
3135fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan                int width = va_arg(args, int);
3145fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan                int height = va_arg(args, int);
3155fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan                int format = va_arg(args, int);
3165fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan                private_handle_t* hnd =  va_arg(args, private_handle_t*);
3175fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan                if (private_handle_t::validate(hnd)) {
3185fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan                    return res;
3195fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan                }
3205fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan                hnd->width = width;
3215fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan                hnd->height = height;
3225fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan                hnd->format = format;
3235fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan                res = 0;
3245fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan            }
3255fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan            break;
32617412ead5d762cfc0c8f9c9c15a8c9ab3e8f7e33Naseer Ahmed#endif
327b178eeae07d5fdd3c6e5fa0bf1360143cc4e2c70Naomi Luis        case GRALLOC_MODULE_PERFORM_GET_STRIDE:
328b178eeae07d5fdd3c6e5fa0bf1360143cc4e2c70Naomi Luis            {
329b178eeae07d5fdd3c6e5fa0bf1360143cc4e2c70Naomi Luis                int width   = va_arg(args, int);
330b178eeae07d5fdd3c6e5fa0bf1360143cc4e2c70Naomi Luis                int format  = va_arg(args, int);
331b178eeae07d5fdd3c6e5fa0bf1360143cc4e2c70Naomi Luis                int *stride = va_arg(args, int *);
332b178eeae07d5fdd3c6e5fa0bf1360143cc4e2c70Naomi Luis                *stride = AdrenoMemInfo::getInstance().getStride(width, format);
333b178eeae07d5fdd3c6e5fa0bf1360143cc4e2c70Naomi Luis                res = 0;
334b178eeae07d5fdd3c6e5fa0bf1360143cc4e2c70Naomi Luis            } break;
335a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev        default:
336a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev            break;
337a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    }
338a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    va_end(args);
339a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev    return res;
340a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev}
341