mapper.cpp revision 202a77d28ac251545f6f998a974690212309b927
1202a77d28ac251545f6f998a974690212309b927Iliyan Malchev/*
2202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * Copyright (C) 2008 The Android Open Source Project
3202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * Copyright (c) 2011 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"
45202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
46202a77d28ac251545f6f998a974690212309b927Iliyan Malchevusing namespace gralloc;
47202a77d28ac251545f6f998a974690212309b927Iliyan Malchevusing android::sp;
48202a77d28ac251545f6f998a974690212309b927Iliyan Malchev/*****************************************************************************/
49202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
50202a77d28ac251545f6f998a974690212309b927Iliyan Malchev// Return the type of allocator -
51202a77d28ac251545f6f998a974690212309b927Iliyan Malchev// these are used for mapping/unmapping
52202a77d28ac251545f6f998a974690212309b927Iliyan Malchevstatic sp<IMemAlloc> getAllocator(int flags)
53202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
54202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    sp<IMemAlloc> memalloc;
55202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    sp<IAllocController> alloc_ctrl = IAllocController::getInstance(true);
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,
61202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        buffer_handle_t handle,
62202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        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;
69202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        sp<IMemAlloc> memalloc = getAllocator(hnd->flags) ;
70202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        int err = memalloc->map_buffer(&mappedAddress, size,
71202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->offset, hnd->fd);
72202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if(err) {
73202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            ALOGE("Could not mmap handle %p, fd=%d (%s)",
74202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                    handle, hnd->fd, strerror(errno));
75202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            hnd->base = 0;
76202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            return -errno;
77202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
78202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
79202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if (mappedAddress == MAP_FAILED) {
80202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            ALOGE("Could not mmap handle %p, fd=%d (%s)",
81202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                    handle, hnd->fd, strerror(errno));
82202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            hnd->base = 0;
83202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            return -errno;
84202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
85202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        hnd->base = intptr_t(mappedAddress) + hnd->offset;
86202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        //ALOGD("gralloc_map() succeeded fd=%d, off=%d, size=%d, vaddr=%p",
87202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        //        hnd->fd, hnd->offset, hnd->size, mappedAddress);
88202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
89202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    *vaddr = (void*)hnd->base;
90202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return 0;
91202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
92202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
93202a77d28ac251545f6f998a974690212309b927Iliyan Malchevstatic int gralloc_unmap(gralloc_module_t const* module,
94202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        buffer_handle_t handle)
95202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
96202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    private_handle_t* hnd = (private_handle_t*)handle;
97202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
98202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        int err = -EINVAL;
99202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        void* base = (void*)hnd->base;
100202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        size_t size = hnd->size;
101202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        sp<IMemAlloc> memalloc = getAllocator(hnd->flags) ;
102202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if(memalloc != NULL)
103202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            err = memalloc->unmap_buffer(base, size, hnd->offset);
104202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if (err) {
105202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            ALOGE("Could not unmap memory at address %p", base);
106202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
107202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
108202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    hnd->base = 0;
109202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return 0;
110202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
111202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
112202a77d28ac251545f6f998a974690212309b927Iliyan Malchev/*****************************************************************************/
113202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
114202a77d28ac251545f6f998a974690212309b927Iliyan Malchevstatic pthread_mutex_t sMapLock = PTHREAD_MUTEX_INITIALIZER;
115202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
116202a77d28ac251545f6f998a974690212309b927Iliyan Malchev/*****************************************************************************/
117202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
118202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint gralloc_register_buffer(gralloc_module_t const* module,
119202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        buffer_handle_t handle)
120202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
121202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (private_handle_t::validate(handle) < 0)
122202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return -EINVAL;
123202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
124202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // In this implementation, we don't need to do anything here
125202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
126202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    /* NOTE: we need to initialize the buffer as not mapped/not locked
127202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * because it shouldn't when this function is called the first time
128202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * in a new process. Ideally these flags shouldn't be part of the
129202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * handle, but instead maintained in the kernel or at least
130202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * out-of-line
131202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     */
132202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
133202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // if this handle was created in this process, then we keep it as is.
134202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    private_handle_t* hnd = (private_handle_t*)handle;
135202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (hnd->pid != getpid()) {
136202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        hnd->base = 0;
137202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        void *vaddr;
138202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        int err = gralloc_map(module, handle, &vaddr);
139202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if (err) {
140202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            ALOGE("%s: gralloc_map failed", __FUNCTION__);
141202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            return err;
142202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
143202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
144202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        // Reset the genlock private fd flag in the handle
145202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        hnd->genlockPrivFd = -1;
146202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
147202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        // Check if there is a valid lock attached to the handle.
148202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if (-1 == hnd->genlockHandle) {
149202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            ALOGE("%s: the lock is invalid.", __FUNCTION__);
150202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            gralloc_unmap(module, handle);
151202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            hnd->base = 0;
152202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            return -EINVAL;
153202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
154202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
155202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        // Attach the genlock handle
156202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if (GENLOCK_NO_ERROR != genlock_attach_lock((native_handle_t *)handle)) {
157202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            ALOGE("%s: genlock_attach_lock failed", __FUNCTION__);
158202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            gralloc_unmap(module, handle);
159202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            hnd->base = 0;
160202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            return -EINVAL;
161202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
162202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
163202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return 0;
164202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
165202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
166202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint gralloc_unregister_buffer(gralloc_module_t const* module,
167202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        buffer_handle_t handle)
168202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
169202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (private_handle_t::validate(handle) < 0)
170202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return -EINVAL;
171202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
172202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    /*
173202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * If the buffer has been mapped during a lock operation, it's time
174202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * to un-map it. It's an error to be here with a locked buffer.
175202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * NOTE: the framebuffer is handled differently and is never unmapped.
176202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     */
177202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
178202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    private_handle_t* hnd = (private_handle_t*)handle;
179202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
180202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // never unmap buffers that were created in this process
181202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (hnd->pid != getpid()) {
182202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if (hnd->base != 0) {
183202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            gralloc_unmap(module, handle);
184202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
185202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        hnd->base = 0;
186202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        // Release the genlock
187202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if (-1 != hnd->genlockHandle) {
188202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            return genlock_release_lock((native_handle_t *)handle);
189202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        } else {
190202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            ALOGE("%s: there was no genlock attached to this buffer", __FUNCTION__);
191202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            return -EINVAL;
192202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
193202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
194202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return 0;
195202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
196202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
197202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint terminateBuffer(gralloc_module_t const* module,
198202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        private_handle_t* hnd)
199202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
200202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    /*
201202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * If the buffer has been mapped during a lock operation, it's time
202202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * to un-map it. It's an error to be here with a locked buffer.
203202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     */
204202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
205202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (hnd->base != 0) {
206202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        // this buffer was mapped, unmap it now
207202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM |
208202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                          private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP |
209202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                          private_handle_t::PRIV_FLAGS_USES_ASHMEM |
210202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                          private_handle_t::PRIV_FLAGS_USES_ION)) {
211202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            if (hnd->pid != getpid()) {
212202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                // ... unless it's a "master" pmem buffer, that is a buffer
213202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                // mapped in the process it's been allocated.
214202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                // (see gralloc_alloc_buffer())
215202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                gralloc_unmap(module, hnd);
216202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            }
217202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        } else {
218202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            ALOGE("terminateBuffer: unmapping a non pmem/ashmem buffer flags = 0x%x", hnd->flags);
219202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            gralloc_unmap(module, hnd);
220202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
221202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
222202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
223202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return 0;
224202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
225202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
226202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint gralloc_lock(gralloc_module_t const* module,
227202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        buffer_handle_t handle, int usage,
228202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        int l, int t, int w, int h,
229202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        void** vaddr)
230202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
231202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (private_handle_t::validate(handle) < 0)
232202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return -EINVAL;
233202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
234202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    int err = 0;
235202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    private_handle_t* hnd = (private_handle_t*)handle;
236202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
237202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if (hnd->base == 0) {
238202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            // we need to map for real
239202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            pthread_mutex_t* const lock = &sMapLock;
240202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            pthread_mutex_lock(lock);
241202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            err = gralloc_map(module, handle, vaddr);
242202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            pthread_mutex_unlock(lock);
243202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
244202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        *vaddr = (void*)hnd->base;
245202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
246202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        // Lock the buffer for read/write operation as specified. Write lock
247202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        // has a higher priority over read lock.
248202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        int lockType = 0;
249202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if (usage & GRALLOC_USAGE_SW_WRITE_MASK) {
250202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            lockType = GENLOCK_WRITE_LOCK;
251202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        } else if (usage & GRALLOC_USAGE_SW_READ_MASK) {
252202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            lockType = GENLOCK_READ_LOCK;
253202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
254202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
255202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        int timeout = GENLOCK_MAX_TIMEOUT;
256202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if (GENLOCK_NO_ERROR != genlock_lock_buffer((native_handle_t *)handle,
257202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                                                   (genlock_lock_type)lockType,
258202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                                                   timeout)) {
259202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            ALOGE("%s: genlock_lock_buffer (lockType=0x%x) failed", __FUNCTION__,
260202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                lockType);
261202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            return -EINVAL;
262202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        } else {
263202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            // Mark this buffer as locked for SW read/write operation.
264202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            hnd->flags |= private_handle_t::PRIV_FLAGS_SW_LOCK;
265202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
266202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
267202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) &&
268202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            !(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
269202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            // Mark the buffer to be flushed after cpu read/write
270202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
271202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
272202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
273202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return err;
274202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
275202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
276202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint gralloc_unlock(gralloc_module_t const* module,
277202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        buffer_handle_t handle)
278202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
279202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (private_handle_t::validate(handle) < 0)
280202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return -EINVAL;
281202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
282202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    private_handle_t* hnd = (private_handle_t*)handle;
283202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
284202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
285202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        int err;
286202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        sp<IMemAlloc> memalloc = getAllocator(hnd->flags) ;
287202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        err = memalloc->clean_buffer((void*)hnd->base,
288202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->size, hnd->offset, hnd->fd);
289202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ALOGE_IF(err < 0, "cannot flush handle %p (offs=%x len=%x, flags = 0x%x) err=%s\n",
290202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd, hnd->offset, hnd->size, hnd->flags, strerror(errno));
291202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
292202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
293202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
294202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if ((hnd->flags & private_handle_t::PRIV_FLAGS_SW_LOCK)) {
295202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        // Unlock the buffer.
296202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if (GENLOCK_NO_ERROR != genlock_unlock_buffer((native_handle_t *)handle)) {
297202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
298202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            return -EINVAL;
299202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        } else
300202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            hnd->flags &= ~private_handle_t::PRIV_FLAGS_SW_LOCK;
301202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
302202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return 0;
303202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
304202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
305202a77d28ac251545f6f998a974690212309b927Iliyan Malchev/*****************************************************************************/
306202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
307202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint gralloc_perform(struct gralloc_module_t const* module,
308202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        int operation, ... )
309202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
310202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    int res = -EINVAL;
311202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    va_list args;
312202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    va_start(args, operation);
313202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    switch (operation) {
314202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER:
315202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            {
316202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                int fd = va_arg(args, int);
317202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                size_t size = va_arg(args, size_t);
318202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                size_t offset = va_arg(args, size_t);
319202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                void* base = va_arg(args, void*);
320202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                int width = va_arg(args, int);
321202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                int height = va_arg(args, int);
322202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                int format = va_arg(args, int);
323202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
324202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                native_handle_t** handle = va_arg(args, native_handle_t**);
325202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                int memoryFlags = va_arg(args, int);
326202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                private_handle_t* hnd = (private_handle_t*)native_handle_create(
327202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                        private_handle_t::sNumFds, private_handle_t::sNumInts);
328202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->magic = private_handle_t::sMagic;
329202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->fd = fd;
330202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                unsigned int contigFlags = GRALLOC_USAGE_PRIVATE_ADSP_HEAP |
331202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                                  GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP |
332202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                                  GRALLOC_USAGE_PRIVATE_SMI_HEAP;
333202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
334202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                if (memoryFlags & contigFlags) {
335202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                    // check if the buffer is a pmem buffer
336202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                    pmem_region region;
337202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                    if (ioctl(fd, PMEM_GET_SIZE, &region) < 0)
338202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                        hnd->flags =  private_handle_t::PRIV_FLAGS_USES_ION;
339202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                    else
340202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                        hnd->flags =  private_handle_t::PRIV_FLAGS_USES_PMEM |
341202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                                      private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH;
342202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                } else {
343202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                    if (memoryFlags & GRALLOC_USAGE_PRIVATE_ION)
344202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                        hnd->flags =  private_handle_t::PRIV_FLAGS_USES_ION;
345202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                    else
346202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                        hnd->flags =  private_handle_t::PRIV_FLAGS_USES_ASHMEM;
347202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                }
348202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
349202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->size = size;
350202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->offset = offset;
351202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->base = intptr_t(base) + offset;
352202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->gpuaddr = 0;
353202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->width = width;
354202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->height = height;
355202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->format = format;
356202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                *handle = (native_handle_t *)hnd;
357202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                res = 0;
358202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                break;
359202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
360202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            }
361202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        default:
362202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
363202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
364202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    va_end(args);
365202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return res;
366202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
367