mapper.cpp revision a93aa28712df9a9b148adb4311e4f9972c5561c4
1202a77d28ac251545f6f998a974690212309b927Iliyan Malchev/*
2202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * Copyright (C) 2008 The Android Open Source Project
329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
4202a77d28ac251545f6f998a974690212309b927Iliyan Malchev *
5202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * Licensed under the Apache License, Version 2.0 (the "License");
6202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * you may not use this file except in compliance with the License.
7202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * You may obtain a copy of the License at
8202a77d28ac251545f6f998a974690212309b927Iliyan Malchev *
9202a77d28ac251545f6f998a974690212309b927Iliyan Malchev *      http://www.apache.org/licenses/LICENSE-2.0
10202a77d28ac251545f6f998a974690212309b927Iliyan Malchev *
11202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * Unless required by applicable law or agreed to in writing, software
12202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * distributed under the License is distributed on an "AS IS" BASIS,
13202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * See the License for the specific language governing permissions and
15202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * limitations under the License.
16202a77d28ac251545f6f998a974690212309b927Iliyan Malchev */
17202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
18202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <limits.h>
19202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <errno.h>
20202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <pthread.h>
21202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <unistd.h>
22202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <string.h>
23202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <stdarg.h>
24202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
25202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <sys/mman.h>
26202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <sys/stat.h>
27202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <sys/types.h>
28202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <sys/ioctl.h>
29202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <linux/ashmem.h>
30202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
31202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <cutils/log.h>
32202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <cutils/atomic.h>
33202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <cutils/ashmem.h>
34202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
35202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <hardware/hardware.h>
36202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <hardware/gralloc.h>
37202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <genlock.h>
38202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
39202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <linux/android_pmem.h>
40202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
41202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "gralloc_priv.h"
42202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "gr.h"
43202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "alloc_controller.h"
44202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "memalloc.h"
45c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan#include <qdMetaData.h>
46202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
47202a77d28ac251545f6f998a974690212309b927Iliyan Malchevusing namespace gralloc;
48202a77d28ac251545f6f998a974690212309b927Iliyan Malchev/*****************************************************************************/
49202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
50202a77d28ac251545f6f998a974690212309b927Iliyan Malchev// Return the type of allocator -
51202a77d28ac251545f6f998a974690212309b927Iliyan Malchev// these are used for mapping/unmapping
5201d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmedstatic IMemAlloc* getAllocator(int flags)
53202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
5401d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed    IMemAlloc* memalloc;
5501d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed    IAllocController* alloc_ctrl = IAllocController::getInstance();
56202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    memalloc = alloc_ctrl->getAllocator(flags);
57202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return memalloc;
58202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
59202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
60202a77d28ac251545f6f998a974690212309b927Iliyan Malchevstatic int gralloc_map(gralloc_module_t const* module,
6129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                       buffer_handle_t handle,
6229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                       void** vaddr)
63202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
64202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    private_handle_t* hnd = (private_handle_t*)handle;
65202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    void *mappedAddress;
66202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) &&
67202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        !(hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER)) {
68202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        size_t size = hnd->size;
6901d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed        IMemAlloc* memalloc = getAllocator(hnd->flags) ;
70202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        int err = memalloc->map_buffer(&mappedAddress, size,
7129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                       hnd->offset, hnd->fd);
72c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan        if(err || mappedAddress == MAP_FAILED) {
73202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            ALOGE("Could not mmap handle %p, fd=%d (%s)",
7429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  handle, hnd->fd, strerror(errno));
75202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            hnd->base = 0;
76202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            return -errno;
77202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
78202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
79202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        hnd->base = intptr_t(mappedAddress) + hnd->offset;
8029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        //LOGD("gralloc_map() succeeded fd=%d, off=%d, size=%d, vaddr=%p",
81202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        //        hnd->fd, hnd->offset, hnd->size, mappedAddress);
82c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan        mappedAddress = MAP_FAILED;
83c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan        size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
84c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan        err = memalloc->map_buffer(&mappedAddress, size,
85c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan                                       hnd->offset_metadata, hnd->fd_metadata);
86c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan        if(err || mappedAddress == MAP_FAILED) {
87c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan            ALOGE("Could not mmap handle %p, fd=%d (%s)",
88c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan                  handle, hnd->fd_metadata, strerror(errno));
89c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan            hnd->base_metadata = 0;
90c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan            return -errno;
91c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan        }
92c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan        hnd->base_metadata = intptr_t(mappedAddress) + hnd->offset_metadata;
93202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
94202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    *vaddr = (void*)hnd->base;
95202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return 0;
96202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
97202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
98202a77d28ac251545f6f998a974690212309b927Iliyan Malchevstatic int gralloc_unmap(gralloc_module_t const* module,
9929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                         buffer_handle_t handle)
100202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
101202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    private_handle_t* hnd = (private_handle_t*)handle;
102202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
103202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        int err = -EINVAL;
104202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        void* base = (void*)hnd->base;
105202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        size_t size = hnd->size;
10601d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed        IMemAlloc* memalloc = getAllocator(hnd->flags) ;
107c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan        if(memalloc != NULL) {
108202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            err = memalloc->unmap_buffer(base, size, hnd->offset);
109c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan            if (err) {
110c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan                ALOGE("Could not unmap memory at address %p", base);
111c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan            }
112c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan            base = (void*)hnd->base_metadata;
113c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan            size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
114c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan            err = memalloc->unmap_buffer(base, size, hnd->offset_metadata);
115c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan            if (err) {
116c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan                ALOGE("Could not unmap memory at address %p", base);
117c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan            }
118202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
119202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
120a93aa28712df9a9b148adb4311e4f9972c5561c4Ramkumar Radhakrishnan    /* need to initialize the pointer to NULL otherwise unmapping for that
121a93aa28712df9a9b148adb4311e4f9972c5561c4Ramkumar Radhakrishnan     * buffer happens twice which leads to crash */
122202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    hnd->base = 0;
123a93aa28712df9a9b148adb4311e4f9972c5561c4Ramkumar Radhakrishnan    hnd->base_metadata = 0;
124202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return 0;
125202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
126202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
127202a77d28ac251545f6f998a974690212309b927Iliyan Malchev/*****************************************************************************/
128202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
129202a77d28ac251545f6f998a974690212309b927Iliyan Malchevstatic pthread_mutex_t sMapLock = PTHREAD_MUTEX_INITIALIZER;
130202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
131202a77d28ac251545f6f998a974690212309b927Iliyan Malchev/*****************************************************************************/
132202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
133202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint gralloc_register_buffer(gralloc_module_t const* module,
13429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                            buffer_handle_t handle)
135202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
136202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (private_handle_t::validate(handle) < 0)
137202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return -EINVAL;
138202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
139202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // In this implementation, we don't need to do anything here
140202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
141202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    /* NOTE: we need to initialize the buffer as not mapped/not locked
142202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * because it shouldn't when this function is called the first time
143202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * in a new process. Ideally these flags shouldn't be part of the
144202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * handle, but instead maintained in the kernel or at least
145202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * out-of-line
146202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     */
147202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
148202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    private_handle_t* hnd = (private_handle_t*)handle;
149139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar    hnd->base = 0;
150a93aa28712df9a9b148adb4311e4f9972c5561c4Ramkumar Radhakrishnan    hnd->base_metadata = 0;
151139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar    void *vaddr;
152139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar    int err = gralloc_map(module, handle, &vaddr);
153139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar    if (err) {
154139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar        ALOGE("%s: gralloc_map failed", __FUNCTION__);
155139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar        return err;
156139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar    }
157202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
158139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar    // Reset the genlock private fd flag in the handle
159139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar    hnd->genlockPrivFd = -1;
160202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
161139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar    // Check if there is a valid lock attached to the handle.
162139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar    if (-1 == hnd->genlockHandle) {
163139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar        ALOGE("%s: the lock is invalid.", __FUNCTION__);
164139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar        gralloc_unmap(module, handle);
165139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar        hnd->base = 0;
166139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar        return -EINVAL;
167139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar    }
168202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
169139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar    // Attach the genlock handle
170139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar    if (GENLOCK_NO_ERROR != genlock_attach_lock((native_handle_t *)handle)) {
171139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar        ALOGE("%s: genlock_attach_lock failed", __FUNCTION__);
172139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar        gralloc_unmap(module, handle);
173139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar        hnd->base = 0;
174139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar        return -EINVAL;
175202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
176202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return 0;
177202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
178202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
179202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint gralloc_unregister_buffer(gralloc_module_t const* module,
18029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                              buffer_handle_t handle)
181202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
182202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (private_handle_t::validate(handle) < 0)
183202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return -EINVAL;
184202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
185202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    /*
186202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * If the buffer has been mapped during a lock operation, it's time
187202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * to un-map it. It's an error to be here with a locked buffer.
188202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * NOTE: the framebuffer is handled differently and is never unmapped.
189202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     */
190202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
191202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    private_handle_t* hnd = (private_handle_t*)handle;
192202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
193139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar    if (hnd->base != 0) {
194139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar        gralloc_unmap(module, handle);
195139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar    }
196139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar    hnd->base = 0;
197a93aa28712df9a9b148adb4311e4f9972c5561c4Ramkumar Radhakrishnan    hnd->base_metadata = 0;
198139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar    // Release the genlock
199139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar    if (-1 != hnd->genlockHandle) {
200139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar        return genlock_release_lock((native_handle_t *)handle);
201139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar    } else {
202139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar        ALOGE("%s: there was no genlock attached to this buffer", __FUNCTION__);
203139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar        return -EINVAL;
204202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
205202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return 0;
206202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
207202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
208202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint terminateBuffer(gralloc_module_t const* module,
20929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    private_handle_t* hnd)
210202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
211202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    /*
212202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * If the buffer has been mapped during a lock operation, it's time
213202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * to un-map it. It's an error to be here with a locked buffer.
214202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     */
215202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
216202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (hnd->base != 0) {
217202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        // this buffer was mapped, unmap it now
218202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM |
219202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                          private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP |
220202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                          private_handle_t::PRIV_FLAGS_USES_ASHMEM |
221202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                          private_handle_t::PRIV_FLAGS_USES_ION)) {
222202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                gralloc_unmap(module, hnd);
223202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        } else {
22429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE("terminateBuffer: unmapping a non pmem/ashmem buffer flags = 0x%x",
22529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  hnd->flags);
226202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            gralloc_unmap(module, hnd);
227202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
228202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
229202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
230202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return 0;
231202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
232202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
233202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint gralloc_lock(gralloc_module_t const* module,
23429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                 buffer_handle_t handle, int usage,
23529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                 int l, int t, int w, int h,
23629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                 void** vaddr)
237202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
238202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (private_handle_t::validate(handle) < 0)
239202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return -EINVAL;
240202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
241202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    int err = 0;
242202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    private_handle_t* hnd = (private_handle_t*)handle;
243202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
244202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if (hnd->base == 0) {
245202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            // we need to map for real
246202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            pthread_mutex_t* const lock = &sMapLock;
247202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            pthread_mutex_lock(lock);
248202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            err = gralloc_map(module, handle, vaddr);
249202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            pthread_mutex_unlock(lock);
250202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
251202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        *vaddr = (void*)hnd->base;
252202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
253202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        // Lock the buffer for read/write operation as specified. Write lock
254202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        // has a higher priority over read lock.
255202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        int lockType = 0;
256202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if (usage & GRALLOC_USAGE_SW_WRITE_MASK) {
257202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            lockType = GENLOCK_WRITE_LOCK;
258202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        } else if (usage & GRALLOC_USAGE_SW_READ_MASK) {
259202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            lockType = GENLOCK_READ_LOCK;
260202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
261202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
262202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        int timeout = GENLOCK_MAX_TIMEOUT;
263202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if (GENLOCK_NO_ERROR != genlock_lock_buffer((native_handle_t *)handle,
26429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                                    (genlock_lock_type)lockType,
26529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                                    timeout)) {
266202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            ALOGE("%s: genlock_lock_buffer (lockType=0x%x) failed", __FUNCTION__,
26729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  lockType);
268202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            return -EINVAL;
269202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        } else {
270202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            // Mark this buffer as locked for SW read/write operation.
271202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            hnd->flags |= private_handle_t::PRIV_FLAGS_SW_LOCK;
272202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
273202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
274202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) &&
275202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            !(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
276202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            // Mark the buffer to be flushed after cpu read/write
277202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
278202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
279202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
280202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return err;
281202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
282202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
283202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint gralloc_unlock(gralloc_module_t const* module,
28429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                   buffer_handle_t handle)
285202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
286202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (private_handle_t::validate(handle) < 0)
287202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return -EINVAL;
288202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
289202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    private_handle_t* hnd = (private_handle_t*)handle;
290202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
291202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
292202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        int err;
29301d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed        IMemAlloc* memalloc = getAllocator(hnd->flags) ;
294202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        err = memalloc->clean_buffer((void*)hnd->base,
29529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                     hnd->size, hnd->offset, hnd->fd);
296202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ALOGE_IF(err < 0, "cannot flush handle %p (offs=%x len=%x, flags = 0x%x) err=%s\n",
29729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                 hnd, hnd->offset, hnd->size, hnd->flags, strerror(errno));
298c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan        unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
299c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan        err = memalloc->clean_buffer((void*)hnd->base_metadata, size,
300c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan                hnd->offset_metadata, hnd->fd_metadata);
301c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan        ALOGE_IF(err < 0, "cannot flush handle %p (offs=%x len=%lu, "
302c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan                "flags = 0x%x) err=%s\n", hnd, hnd->offset_metadata, size,
303c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan                hnd->flags, strerror(errno));
304202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
305202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
306202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
307202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if ((hnd->flags & private_handle_t::PRIV_FLAGS_SW_LOCK)) {
308202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        // Unlock the buffer.
309202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if (GENLOCK_NO_ERROR != genlock_unlock_buffer((native_handle_t *)handle)) {
310202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
311202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            return -EINVAL;
312202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        } else
313202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            hnd->flags &= ~private_handle_t::PRIV_FLAGS_SW_LOCK;
314202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
315202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return 0;
316202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
317202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
318202a77d28ac251545f6f998a974690212309b927Iliyan Malchev/*****************************************************************************/
319202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
320202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint gralloc_perform(struct gralloc_module_t const* module,
32129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    int operation, ... )
322202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
323202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    int res = -EINVAL;
324202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    va_list args;
325202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    va_start(args, operation);
326202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    switch (operation) {
327202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER:
328202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            {
329202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                int fd = va_arg(args, int);
330202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                size_t size = va_arg(args, size_t);
331202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                size_t offset = va_arg(args, size_t);
332202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                void* base = va_arg(args, void*);
333202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                int width = va_arg(args, int);
334202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                int height = va_arg(args, int);
335202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                int format = va_arg(args, int);
336202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
337202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                native_handle_t** handle = va_arg(args, native_handle_t**);
338202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                int memoryFlags = va_arg(args, int);
339202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                private_handle_t* hnd = (private_handle_t*)native_handle_create(
34029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    private_handle_t::sNumFds, private_handle_t::sNumInts);
341202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->magic = private_handle_t::sMagic;
342202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->fd = fd;
34301d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed                hnd->flags =  private_handle_t::PRIV_FLAGS_USES_ION;
344202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->size = size;
345202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->offset = offset;
346202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->base = intptr_t(base) + offset;
347202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->gpuaddr = 0;
348202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->width = width;
349202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->height = height;
350202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->format = format;
351202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                *handle = (native_handle_t *)hnd;
352202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                res = 0;
353202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                break;
354202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
355202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            }
356e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan        case GRALLOC_MODULE_PERFORM_UPDATE_BUFFER_GEOMETRY:
357e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan            {
358e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan                int width = va_arg(args, int);
359e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan                int height = va_arg(args, int);
360e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan                int format = va_arg(args, int);
361e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan                private_handle_t* hnd =  va_arg(args, private_handle_t*);
362e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan                if (private_handle_t::validate(hnd)) {
363e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan                    return res;
364e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan                }
365e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan                hnd->width = width;
366e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan                hnd->height = height;
367e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan                hnd->format = format;
368e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan                res = 0;
369e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan            }
370e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan            break;
371202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        default:
372202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
373202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
374202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    va_end(args);
375202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return res;
376202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
377