1202a77d28ac251545f6f998a974690212309b927Iliyan Malchev/*
2202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * Copyright (C) 2008 The Android Open Source Project
3aee73e2656d1176ee29d20218947fc3a379818b3Naseer Ahmed * Copyright (c) 2011-2013, The Linux Foundation. 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
38202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "gralloc_priv.h"
39202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "gr.h"
40202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "alloc_controller.h"
41202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "memalloc.h"
42c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan#include <qdMetaData.h>
43202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
44202a77d28ac251545f6f998a974690212309b927Iliyan Malchevusing namespace gralloc;
45202a77d28ac251545f6f998a974690212309b927Iliyan Malchev/*****************************************************************************/
46202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
47202a77d28ac251545f6f998a974690212309b927Iliyan Malchev// Return the type of allocator -
48202a77d28ac251545f6f998a974690212309b927Iliyan Malchev// these are used for mapping/unmapping
4901d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmedstatic IMemAlloc* getAllocator(int flags)
50202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
5101d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed    IMemAlloc* memalloc;
5201d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed    IAllocController* alloc_ctrl = IAllocController::getInstance();
53202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    memalloc = alloc_ctrl->getAllocator(flags);
54202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return memalloc;
55202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
56202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
57202a77d28ac251545f6f998a974690212309b927Iliyan Malchevstatic int gralloc_map(gralloc_module_t const* module,
58277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed                       buffer_handle_t handle)
59202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
60202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    private_handle_t* hnd = (private_handle_t*)handle;
61202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    void *mappedAddress;
62202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) &&
63202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        !(hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER)) {
64202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        size_t size = hnd->size;
6501d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed        IMemAlloc* memalloc = getAllocator(hnd->flags) ;
66202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        int err = memalloc->map_buffer(&mappedAddress, size,
6729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                       hnd->offset, hnd->fd);
68c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan        if(err || mappedAddress == MAP_FAILED) {
69202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            ALOGE("Could not mmap handle %p, fd=%d (%s)",
7029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  handle, hnd->fd, strerror(errno));
71202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            hnd->base = 0;
72202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            return -errno;
73202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
74202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
75202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        hnd->base = intptr_t(mappedAddress) + hnd->offset;
76c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan        mappedAddress = MAP_FAILED;
77c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan        size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
78c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan        err = memalloc->map_buffer(&mappedAddress, size,
79c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan                                       hnd->offset_metadata, hnd->fd_metadata);
80c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan        if(err || mappedAddress == MAP_FAILED) {
81c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan            ALOGE("Could not mmap handle %p, fd=%d (%s)",
82c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan                  handle, hnd->fd_metadata, strerror(errno));
83c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan            hnd->base_metadata = 0;
84c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan            return -errno;
85c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan        }
86c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan        hnd->base_metadata = intptr_t(mappedAddress) + hnd->offset_metadata;
87202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
88202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return 0;
89202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
90202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
91202a77d28ac251545f6f998a974690212309b927Iliyan Malchevstatic int gralloc_unmap(gralloc_module_t const* module,
9229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                         buffer_handle_t handle)
93202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
94202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    private_handle_t* hnd = (private_handle_t*)handle;
95202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
96202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        int err = -EINVAL;
97202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        void* base = (void*)hnd->base;
98202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        size_t size = hnd->size;
9901d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed        IMemAlloc* memalloc = getAllocator(hnd->flags) ;
100c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan        if(memalloc != NULL) {
101202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            err = memalloc->unmap_buffer(base, size, hnd->offset);
102c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan            if (err) {
103c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan                ALOGE("Could not unmap memory at address %p", base);
104c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan            }
105c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan            base = (void*)hnd->base_metadata;
106c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan            size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
107c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan            err = memalloc->unmap_buffer(base, size, hnd->offset_metadata);
108c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan            if (err) {
109c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan                ALOGE("Could not unmap memory at address %p", base);
110c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan            }
111202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
112202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
113a93aa28712df9a9b148adb4311e4f9972c5561c4Ramkumar Radhakrishnan    /* need to initialize the pointer to NULL otherwise unmapping for that
114a93aa28712df9a9b148adb4311e4f9972c5561c4Ramkumar Radhakrishnan     * buffer happens twice which leads to crash */
115202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    hnd->base = 0;
116a93aa28712df9a9b148adb4311e4f9972c5561c4Ramkumar Radhakrishnan    hnd->base_metadata = 0;
117202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return 0;
118202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
119202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
120202a77d28ac251545f6f998a974690212309b927Iliyan Malchev/*****************************************************************************/
121202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
122202a77d28ac251545f6f998a974690212309b927Iliyan Malchevstatic pthread_mutex_t sMapLock = PTHREAD_MUTEX_INITIALIZER;
123202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
124202a77d28ac251545f6f998a974690212309b927Iliyan Malchev/*****************************************************************************/
125202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
126202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint gralloc_register_buffer(gralloc_module_t const* module,
12729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                            buffer_handle_t handle)
128202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
129202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (private_handle_t::validate(handle) < 0)
130202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return -EINVAL;
131202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
132202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // In this implementation, we don't need to do anything here
133202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
134202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    /* NOTE: we need to initialize the buffer as not mapped/not locked
135202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * because it shouldn't when this function is called the first time
136202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * in a new process. Ideally these flags shouldn't be part of the
137202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * handle, but instead maintained in the kernel or at least
138202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * out-of-line
139202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     */
140202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
141202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    private_handle_t* hnd = (private_handle_t*)handle;
142139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar    hnd->base = 0;
143a93aa28712df9a9b148adb4311e4f9972c5561c4Ramkumar Radhakrishnan    hnd->base_metadata = 0;
144277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed    int err = gralloc_map(module, handle);
145139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar    if (err) {
146139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar        ALOGE("%s: gralloc_map failed", __FUNCTION__);
147139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar        return err;
148139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar    }
149202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
150202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return 0;
151202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
152202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
153202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint gralloc_unregister_buffer(gralloc_module_t const* module,
15429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                              buffer_handle_t handle)
155202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
156202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (private_handle_t::validate(handle) < 0)
157202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return -EINVAL;
158202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
159202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    /*
160202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * If the buffer has been mapped during a lock operation, it's time
161202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * to un-map it. It's an error to be here with a locked buffer.
162202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * NOTE: the framebuffer is handled differently and is never unmapped.
163202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     */
164202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
165202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    private_handle_t* hnd = (private_handle_t*)handle;
166202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
167139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar    if (hnd->base != 0) {
168139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar        gralloc_unmap(module, handle);
169139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar    }
170139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar    hnd->base = 0;
171a93aa28712df9a9b148adb4311e4f9972c5561c4Ramkumar Radhakrishnan    hnd->base_metadata = 0;
172202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return 0;
173202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
174202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
175202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint terminateBuffer(gralloc_module_t const* module,
17629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    private_handle_t* hnd)
177202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
178202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    /*
179202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * If the buffer has been mapped during a lock operation, it's time
180202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     * to un-map it. It's an error to be here with a locked buffer.
181202a77d28ac251545f6f998a974690212309b927Iliyan Malchev     */
182202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
183202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (hnd->base != 0) {
184202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        // this buffer was mapped, unmap it now
185202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM |
186202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                          private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP |
187202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                          private_handle_t::PRIV_FLAGS_USES_ASHMEM |
188202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                          private_handle_t::PRIV_FLAGS_USES_ION)) {
189202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                gralloc_unmap(module, hnd);
190202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        } else {
19129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE("terminateBuffer: unmapping a non pmem/ashmem buffer flags = 0x%x",
19229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  hnd->flags);
193202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            gralloc_unmap(module, hnd);
194202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
195202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
196202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
197202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return 0;
198202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
199202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
200277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmedstatic int gralloc_map_and_invalidate (gralloc_module_t const* module,
201277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed                                       buffer_handle_t handle, int usage,
202277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed                                       int l, int t, int w, int h)
203202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
204202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (private_handle_t::validate(handle) < 0)
205202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return -EINVAL;
206202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
207202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    int err = 0;
208202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    private_handle_t* hnd = (private_handle_t*)handle;
209202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
210202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if (hnd->base == 0) {
211202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            // we need to map for real
212202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            pthread_mutex_t* const lock = &sMapLock;
213202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            pthread_mutex_lock(lock);
214277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed            err = gralloc_map(module, handle);
215202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            pthread_mutex_unlock(lock);
216202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
2170b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed        //Invalidate if reading in software. No need to do this for the metadata
2180b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed        //buffer as it is only read/written in software.
2190b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed        IMemAlloc* memalloc = getAllocator(hnd->flags) ;
2200b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed        err = memalloc->clean_buffer((void*)hnd->base,
2210b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed                                     hnd->size, hnd->offset, hnd->fd,
2220b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed                                     CACHE_INVALIDATE);
223202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) &&
224202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            !(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
225202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            // Mark the buffer to be flushed after cpu read/write
226202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
227202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        }
2280b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed    } else {
2290b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed        hnd->flags |= private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH;
230202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
231202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return err;
232202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
233202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
234277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmedint gralloc_lock(gralloc_module_t const* module,
235277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed                 buffer_handle_t handle, int usage,
236277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed                 int l, int t, int w, int h,
237277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed                 void** vaddr)
238277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed{
239277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed    private_handle_t* hnd = (private_handle_t*)handle;
240277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed    int err = gralloc_map_and_invalidate(module, handle, usage, l, t, w, h);
241277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed    if(!err)
242277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed        *vaddr = (void*)hnd->base;
243277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed    return err;
244277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed}
245277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed
246277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmedint gralloc_lock_ycbcr(gralloc_module_t const* module,
247277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed                 buffer_handle_t handle, int usage,
248277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed                 int l, int t, int w, int h,
249277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed                 struct android_ycbcr *ycbcr)
250277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed{
251277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed    private_handle_t* hnd = (private_handle_t*)handle;
252277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed    int err = gralloc_map_and_invalidate(module, handle, usage, l, t, w, h);
253d6e36fa315e667055d8f51fcbf9b496737636d60Lajos Molnar    int ystride, cstride;
254277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed    if(!err) {
255277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed        //hnd->format holds our implementation defined format
256277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed        //HAL_PIXEL_FORMAT_YCrCb_420_SP is the only one set right now.
257277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed        switch (hnd->format) {
258277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed            case HAL_PIXEL_FORMAT_YCrCb_420_SP:
259277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed                ystride = ALIGN(hnd->width, 16);
260277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed                ycbcr->y  = (void*)hnd->base;
261277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed                ycbcr->cr = (void*)(hnd->base + ystride * hnd->height);
262277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed                ycbcr->cb = (void*)(hnd->base + ystride * hnd->height + 1);
263277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed                ycbcr->ystride = ystride;
264277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed                ycbcr->cstride = ystride;
265277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed                ycbcr->chroma_step = 2;
26651df3027a4a0fdeef0a3ce2220d71adb537acf35Eino-Ville Talvala                memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
267277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed                break;
26841b4b6aab2c756c15dbe43d912674e394a02be79Praveen Chavan            // YCbCr_420_SP
26941b4b6aab2c756c15dbe43d912674e394a02be79Praveen Chavan            case HAL_PIXEL_FORMAT_NV12:
27041b4b6aab2c756c15dbe43d912674e394a02be79Praveen Chavan                ystride = ALIGN(hnd->width, 16);
27141b4b6aab2c756c15dbe43d912674e394a02be79Praveen Chavan                ycbcr->y  = (void*)hnd->base;
27241b4b6aab2c756c15dbe43d912674e394a02be79Praveen Chavan                ycbcr->cb = (void*)(hnd->base + ystride * hnd->height);
27341b4b6aab2c756c15dbe43d912674e394a02be79Praveen Chavan                ycbcr->cr = (void*)(hnd->base + ystride * hnd->height + 1);
27441b4b6aab2c756c15dbe43d912674e394a02be79Praveen Chavan                ycbcr->ystride = ystride;
27541b4b6aab2c756c15dbe43d912674e394a02be79Praveen Chavan                ycbcr->cstride = ystride;
27641b4b6aab2c756c15dbe43d912674e394a02be79Praveen Chavan                ycbcr->chroma_step = 2;
27741b4b6aab2c756c15dbe43d912674e394a02be79Praveen Chavan                memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
27841b4b6aab2c756c15dbe43d912674e394a02be79Praveen Chavan                break;
279d6e36fa315e667055d8f51fcbf9b496737636d60Lajos Molnar            // YCrCb_420_P
280d6e36fa315e667055d8f51fcbf9b496737636d60Lajos Molnar            case HAL_PIXEL_FORMAT_YV12:
281d6e36fa315e667055d8f51fcbf9b496737636d60Lajos Molnar                ystride = ALIGN(hnd->width, 16);
282d6e36fa315e667055d8f51fcbf9b496737636d60Lajos Molnar                cstride = ALIGN(ystride / 2, 16);
283d6e36fa315e667055d8f51fcbf9b496737636d60Lajos Molnar                ycbcr->y  = (void*)hnd->base;
284d6e36fa315e667055d8f51fcbf9b496737636d60Lajos Molnar                ycbcr->cr = (void*)(hnd->base + ystride * hnd->height);
285d6e36fa315e667055d8f51fcbf9b496737636d60Lajos Molnar                ycbcr->cb = (void*)(hnd->base + ystride * hnd->height
286d6e36fa315e667055d8f51fcbf9b496737636d60Lajos Molnar                                              + cstride * hnd->height / 2);
287d6e36fa315e667055d8f51fcbf9b496737636d60Lajos Molnar                ycbcr->ystride = ystride;
288d6e36fa315e667055d8f51fcbf9b496737636d60Lajos Molnar                ycbcr->cstride = cstride;
289d6e36fa315e667055d8f51fcbf9b496737636d60Lajos Molnar                ycbcr->chroma_step = 1;
290d6e36fa315e667055d8f51fcbf9b496737636d60Lajos Molnar                memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
291d6e36fa315e667055d8f51fcbf9b496737636d60Lajos Molnar                break;
292277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed            default:
293277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed                ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__,
294277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed                      hnd->format);
295277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed                err = -EINVAL;
296277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed        }
297277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed    }
298277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed    return err;
299277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed}
300277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed
301202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint gralloc_unlock(gralloc_module_t const* module,
30229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                   buffer_handle_t handle)
303202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
304202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (private_handle_t::validate(handle) < 0)
305202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return -EINVAL;
3060b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed    int err = 0;
307202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    private_handle_t* hnd = (private_handle_t*)handle;
3080b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed    IMemAlloc* memalloc = getAllocator(hnd->flags);
309202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
310202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
311202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        err = memalloc->clean_buffer((void*)hnd->base,
3120b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed                                     hnd->size, hnd->offset, hnd->fd,
3130b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed                                     CACHE_CLEAN_AND_INVALIDATE);
314202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
3150b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed    } else if(hnd->flags & private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH) {
3160b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed        hnd->flags &= ~private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH;
3170b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed    } else {
3180b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed        //Probably a round about way to do this, but this avoids adding new
3190b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed        //flags
3200b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed        err = memalloc->clean_buffer((void*)hnd->base,
3210b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed                                     hnd->size, hnd->offset, hnd->fd,
3220b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed                                     CACHE_INVALIDATE);
323202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
324202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
3250b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed    return err;
326202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
327202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
328202a77d28ac251545f6f998a974690212309b927Iliyan Malchev/*****************************************************************************/
329202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
330202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint gralloc_perform(struct gralloc_module_t const* module,
33129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    int operation, ... )
332202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
333202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    int res = -EINVAL;
334202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    va_list args;
335202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    va_start(args, operation);
336202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    switch (operation) {
337202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER:
338202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            {
339202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                int fd = va_arg(args, int);
340202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                size_t size = va_arg(args, size_t);
341202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                size_t offset = va_arg(args, size_t);
342202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                void* base = va_arg(args, void*);
343202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                int width = va_arg(args, int);
344202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                int height = va_arg(args, int);
345202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                int format = va_arg(args, int);
346202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
347202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                native_handle_t** handle = va_arg(args, native_handle_t**);
3486d5467dc95f3e970eb81d6a7ea5b3bcc3b015078Andreas Gampe                int memoryFlags __attribute__((__unused__)) = va_arg(args, int);
349202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                private_handle_t* hnd = (private_handle_t*)native_handle_create(
35029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    private_handle_t::sNumFds, private_handle_t::sNumInts);
351202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->magic = private_handle_t::sMagic;
352202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->fd = fd;
35301d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed                hnd->flags =  private_handle_t::PRIV_FLAGS_USES_ION;
354202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->size = size;
355202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->offset = offset;
356202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->base = intptr_t(base) + offset;
357202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->gpuaddr = 0;
358202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->width = width;
359202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->height = height;
360202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                hnd->format = format;
361202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                *handle = (native_handle_t *)hnd;
362202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                res = 0;
363202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                break;
364202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
365202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            }
366da429776b96f9e81aee0b250ab3c0fb9cdcd3254Naseer Ahmed#ifdef QCOM_BSP
367e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan        case GRALLOC_MODULE_PERFORM_UPDATE_BUFFER_GEOMETRY:
368e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan            {
369e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan                int width = va_arg(args, int);
370e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan                int height = va_arg(args, int);
371e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan                int format = va_arg(args, int);
372e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan                private_handle_t* hnd =  va_arg(args, private_handle_t*);
373e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan                if (private_handle_t::validate(hnd)) {
374e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan                    return res;
375e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan                }
376e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan                hnd->width = width;
377e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan                hnd->height = height;
378e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan                hnd->format = format;
379e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan                res = 0;
380e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan            }
381e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan            break;
382d10d759bf645a36b34ef77932083a15eda50cc89Naseer Ahmed#endif
383bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis        case GRALLOC_MODULE_PERFORM_GET_STRIDE:
384bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis            {
385bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis                int width   = va_arg(args, int);
386bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis                int format  = va_arg(args, int);
387bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis                int *stride = va_arg(args, int *);
388bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis                *stride = AdrenoMemInfo::getInstance().getStride(width, format);
389bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis                res = 0;
390bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis            } break;
3915d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed        case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE:
3925d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed            {
3935d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed                private_handle_t* hnd =  va_arg(args, private_handle_t*);
3945d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed                int *stride = va_arg(args, int *);
3955d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed                if (private_handle_t::validate(hnd)) {
3965d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed                    return res;
3975d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed                }
3985d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed                MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
3995d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed                if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
4005d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed                    *stride = metadata->bufferDim.sliceWidth;
4015d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed                } else {
4025d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed                    *stride = hnd->width;
4035d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed                }
4045d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed                res = 0;
4055d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed            } break;
406202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        default:
407202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
408202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
409202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    va_end(args);
410202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return res;
411202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
412