mapper.cpp revision 5d1d54ff7c44559f664fdf071164c56c740ab79a
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#include <linux/android_pmem.h> 38202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 39202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "gralloc_priv.h" 40202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "gr.h" 41202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "alloc_controller.h" 42202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "memalloc.h" 43c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan#include <qdMetaData.h> 44202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 45202a77d28ac251545f6f998a974690212309b927Iliyan Malchevusing namespace gralloc; 46202a77d28ac251545f6f998a974690212309b927Iliyan Malchev/*****************************************************************************/ 47202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 48202a77d28ac251545f6f998a974690212309b927Iliyan Malchev// Return the type of allocator - 49202a77d28ac251545f6f998a974690212309b927Iliyan Malchev// these are used for mapping/unmapping 5001d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmedstatic IMemAlloc* getAllocator(int flags) 51202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{ 5201d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed IMemAlloc* memalloc; 5301d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed IAllocController* alloc_ctrl = IAllocController::getInstance(); 54202a77d28ac251545f6f998a974690212309b927Iliyan Malchev memalloc = alloc_ctrl->getAllocator(flags); 55202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return memalloc; 56202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 57202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 58202a77d28ac251545f6f998a974690212309b927Iliyan Malchevstatic int gralloc_map(gralloc_module_t const* module, 59277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed buffer_handle_t handle) 60202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{ 61202a77d28ac251545f6f998a974690212309b927Iliyan Malchev private_handle_t* hnd = (private_handle_t*)handle; 62202a77d28ac251545f6f998a974690212309b927Iliyan Malchev void *mappedAddress; 63202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) && 64202a77d28ac251545f6f998a974690212309b927Iliyan Malchev !(hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER)) { 65202a77d28ac251545f6f998a974690212309b927Iliyan Malchev size_t size = hnd->size; 6601d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed IMemAlloc* memalloc = getAllocator(hnd->flags) ; 67202a77d28ac251545f6f998a974690212309b927Iliyan Malchev int err = memalloc->map_buffer(&mappedAddress, size, 6829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed hnd->offset, hnd->fd); 69c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan if(err || mappedAddress == MAP_FAILED) { 70202a77d28ac251545f6f998a974690212309b927Iliyan Malchev ALOGE("Could not mmap handle %p, fd=%d (%s)", 7129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed handle, hnd->fd, strerror(errno)); 72202a77d28ac251545f6f998a974690212309b927Iliyan Malchev hnd->base = 0; 73202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return -errno; 74202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 75202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 76202a77d28ac251545f6f998a974690212309b927Iliyan Malchev hnd->base = intptr_t(mappedAddress) + hnd->offset; 77c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan mappedAddress = MAP_FAILED; 78c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan size = ROUND_UP_PAGESIZE(sizeof(MetaData_t)); 79c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan err = memalloc->map_buffer(&mappedAddress, size, 80c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan hnd->offset_metadata, hnd->fd_metadata); 81c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan if(err || mappedAddress == MAP_FAILED) { 82c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan ALOGE("Could not mmap handle %p, fd=%d (%s)", 83c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan handle, hnd->fd_metadata, strerror(errno)); 84c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan hnd->base_metadata = 0; 85c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan return -errno; 86c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan } 87c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan hnd->base_metadata = intptr_t(mappedAddress) + hnd->offset_metadata; 88202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 89202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return 0; 90202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 91202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 92202a77d28ac251545f6f998a974690212309b927Iliyan Malchevstatic int gralloc_unmap(gralloc_module_t const* module, 9329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed buffer_handle_t handle) 94202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{ 95202a77d28ac251545f6f998a974690212309b927Iliyan Malchev private_handle_t* hnd = (private_handle_t*)handle; 96202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) { 97202a77d28ac251545f6f998a974690212309b927Iliyan Malchev int err = -EINVAL; 98202a77d28ac251545f6f998a974690212309b927Iliyan Malchev void* base = (void*)hnd->base; 99202a77d28ac251545f6f998a974690212309b927Iliyan Malchev size_t size = hnd->size; 10001d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed IMemAlloc* memalloc = getAllocator(hnd->flags) ; 101c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan if(memalloc != NULL) { 102202a77d28ac251545f6f998a974690212309b927Iliyan Malchev err = memalloc->unmap_buffer(base, size, hnd->offset); 103c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan if (err) { 104c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan ALOGE("Could not unmap memory at address %p", base); 105c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan } 106c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan base = (void*)hnd->base_metadata; 107c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan size = ROUND_UP_PAGESIZE(sizeof(MetaData_t)); 108c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan err = memalloc->unmap_buffer(base, size, hnd->offset_metadata); 109c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan if (err) { 110c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan ALOGE("Could not unmap memory at address %p", base); 111c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan } 112202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 113202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 114a93aa28712df9a9b148adb4311e4f9972c5561c4Ramkumar Radhakrishnan /* need to initialize the pointer to NULL otherwise unmapping for that 115a93aa28712df9a9b148adb4311e4f9972c5561c4Ramkumar Radhakrishnan * buffer happens twice which leads to crash */ 116202a77d28ac251545f6f998a974690212309b927Iliyan Malchev hnd->base = 0; 117a93aa28712df9a9b148adb4311e4f9972c5561c4Ramkumar Radhakrishnan hnd->base_metadata = 0; 118202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return 0; 119202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 120202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 121202a77d28ac251545f6f998a974690212309b927Iliyan Malchev/*****************************************************************************/ 122202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 123202a77d28ac251545f6f998a974690212309b927Iliyan Malchevstatic pthread_mutex_t sMapLock = PTHREAD_MUTEX_INITIALIZER; 124202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 125202a77d28ac251545f6f998a974690212309b927Iliyan Malchev/*****************************************************************************/ 126202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 127202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint gralloc_register_buffer(gralloc_module_t const* module, 12829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed buffer_handle_t handle) 129202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{ 130202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if (private_handle_t::validate(handle) < 0) 131202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return -EINVAL; 132202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 133202a77d28ac251545f6f998a974690212309b927Iliyan Malchev // In this implementation, we don't need to do anything here 134202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 135202a77d28ac251545f6f998a974690212309b927Iliyan Malchev /* NOTE: we need to initialize the buffer as not mapped/not locked 136202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * because it shouldn't when this function is called the first time 137202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * in a new process. Ideally these flags shouldn't be part of the 138202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * handle, but instead maintained in the kernel or at least 139202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * out-of-line 140202a77d28ac251545f6f998a974690212309b927Iliyan Malchev */ 141202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 142202a77d28ac251545f6f998a974690212309b927Iliyan Malchev private_handle_t* hnd = (private_handle_t*)handle; 143139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar hnd->base = 0; 144a93aa28712df9a9b148adb4311e4f9972c5561c4Ramkumar Radhakrishnan hnd->base_metadata = 0; 145277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed int err = gralloc_map(module, handle); 146139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar if (err) { 147139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar ALOGE("%s: gralloc_map failed", __FUNCTION__); 148139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar return err; 149139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar } 150202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 151202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return 0; 152202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 153202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 154202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint gralloc_unregister_buffer(gralloc_module_t const* module, 15529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed buffer_handle_t handle) 156202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{ 157202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if (private_handle_t::validate(handle) < 0) 158202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return -EINVAL; 159202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 160202a77d28ac251545f6f998a974690212309b927Iliyan Malchev /* 161202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * If the buffer has been mapped during a lock operation, it's time 162202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * to un-map it. It's an error to be here with a locked buffer. 163202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * NOTE: the framebuffer is handled differently and is never unmapped. 164202a77d28ac251545f6f998a974690212309b927Iliyan Malchev */ 165202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 166202a77d28ac251545f6f998a974690212309b927Iliyan Malchev private_handle_t* hnd = (private_handle_t*)handle; 167202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 168139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar if (hnd->base != 0) { 169139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar gralloc_unmap(module, handle); 170139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar } 171139e162e3457f86a7b4a6b4927c75c477ef98100Kinjal Bhavsar hnd->base = 0; 172a93aa28712df9a9b148adb4311e4f9972c5561c4Ramkumar Radhakrishnan hnd->base_metadata = 0; 173202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return 0; 174202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 175202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 176202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint terminateBuffer(gralloc_module_t const* module, 17729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed private_handle_t* hnd) 178202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{ 179202a77d28ac251545f6f998a974690212309b927Iliyan Malchev /* 180202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * If the buffer has been mapped during a lock operation, it's time 181202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * to un-map it. It's an error to be here with a locked buffer. 182202a77d28ac251545f6f998a974690212309b927Iliyan Malchev */ 183202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 184202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if (hnd->base != 0) { 185202a77d28ac251545f6f998a974690212309b927Iliyan Malchev // this buffer was mapped, unmap it now 186202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM | 187202a77d28ac251545f6f998a974690212309b927Iliyan Malchev private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP | 188202a77d28ac251545f6f998a974690212309b927Iliyan Malchev private_handle_t::PRIV_FLAGS_USES_ASHMEM | 189202a77d28ac251545f6f998a974690212309b927Iliyan Malchev private_handle_t::PRIV_FLAGS_USES_ION)) { 190202a77d28ac251545f6f998a974690212309b927Iliyan Malchev gralloc_unmap(module, hnd); 191202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } else { 19229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed ALOGE("terminateBuffer: unmapping a non pmem/ashmem buffer flags = 0x%x", 19329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed hnd->flags); 194202a77d28ac251545f6f998a974690212309b927Iliyan Malchev gralloc_unmap(module, hnd); 195202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 196202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 197202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 198202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return 0; 199202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 200202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 201277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmedstatic int gralloc_map_and_invalidate (gralloc_module_t const* module, 202277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed buffer_handle_t handle, int usage, 203277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed int l, int t, int w, int h) 204202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{ 205202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if (private_handle_t::validate(handle) < 0) 206202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return -EINVAL; 207202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 208202a77d28ac251545f6f998a974690212309b927Iliyan Malchev int err = 0; 209202a77d28ac251545f6f998a974690212309b927Iliyan Malchev private_handle_t* hnd = (private_handle_t*)handle; 210202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) { 211202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if (hnd->base == 0) { 212202a77d28ac251545f6f998a974690212309b927Iliyan Malchev // we need to map for real 213202a77d28ac251545f6f998a974690212309b927Iliyan Malchev pthread_mutex_t* const lock = &sMapLock; 214202a77d28ac251545f6f998a974690212309b927Iliyan Malchev pthread_mutex_lock(lock); 215277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed err = gralloc_map(module, handle); 216202a77d28ac251545f6f998a974690212309b927Iliyan Malchev pthread_mutex_unlock(lock); 217202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 2180b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed //Invalidate if reading in software. No need to do this for the metadata 2190b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed //buffer as it is only read/written in software. 2200b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed IMemAlloc* memalloc = getAllocator(hnd->flags) ; 2210b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed err = memalloc->clean_buffer((void*)hnd->base, 2220b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed hnd->size, hnd->offset, hnd->fd, 2230b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed CACHE_INVALIDATE); 224202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) && 225202a77d28ac251545f6f998a974690212309b927Iliyan Malchev !(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) { 226202a77d28ac251545f6f998a974690212309b927Iliyan Malchev // Mark the buffer to be flushed after cpu read/write 227202a77d28ac251545f6f998a974690212309b927Iliyan Malchev hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; 228202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 2290b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed } else { 2300b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed hnd->flags |= private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH; 231202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 232202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return err; 233202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 234202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 235277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmedint gralloc_lock(gralloc_module_t const* module, 236277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed buffer_handle_t handle, int usage, 237277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed int l, int t, int w, int h, 238277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed void** vaddr) 239277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed{ 240277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed private_handle_t* hnd = (private_handle_t*)handle; 241277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed int err = gralloc_map_and_invalidate(module, handle, usage, l, t, w, h); 242277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed if(!err) 243277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed *vaddr = (void*)hnd->base; 244277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed return err; 245277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed} 246277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed 247277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmedint gralloc_lock_ycbcr(gralloc_module_t const* module, 248277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed buffer_handle_t handle, int usage, 249277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed int l, int t, int w, int h, 250277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed struct android_ycbcr *ycbcr) 251277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed{ 252277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed private_handle_t* hnd = (private_handle_t*)handle; 253277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed int err = gralloc_map_and_invalidate(module, handle, usage, l, t, w, h); 254277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed int ystride; 255277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed if(!err) { 256277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed //hnd->format holds our implementation defined format 257277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed //HAL_PIXEL_FORMAT_YCrCb_420_SP is the only one set right now. 258277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed switch (hnd->format) { 259277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed case HAL_PIXEL_FORMAT_YCrCb_420_SP: 260277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed ystride = ALIGN(hnd->width, 16); 261277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed ycbcr->y = (void*)hnd->base; 262277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed ycbcr->cr = (void*)(hnd->base + ystride * hnd->height); 263277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed ycbcr->cb = (void*)(hnd->base + ystride * hnd->height + 1); 264277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed ycbcr->ystride = ystride; 265277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed ycbcr->cstride = ystride; 266277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed ycbcr->chroma_step = 2; 26751df3027a4a0fdeef0a3ce2220d71adb537acf35Eino-Ville Talvala memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved)); 268277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed break; 269277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed default: 270277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, 271277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed hnd->format); 272277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed err = -EINVAL; 273277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed } 274277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed } 275277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed return err; 276277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed} 277277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed 278202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint gralloc_unlock(gralloc_module_t const* module, 27929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed buffer_handle_t handle) 280202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{ 281202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if (private_handle_t::validate(handle) < 0) 282202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return -EINVAL; 2830b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed int err = 0; 284202a77d28ac251545f6f998a974690212309b927Iliyan Malchev private_handle_t* hnd = (private_handle_t*)handle; 2850b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed IMemAlloc* memalloc = getAllocator(hnd->flags); 286202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 287202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) { 288202a77d28ac251545f6f998a974690212309b927Iliyan Malchev err = memalloc->clean_buffer((void*)hnd->base, 2890b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed hnd->size, hnd->offset, hnd->fd, 2900b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed CACHE_CLEAN_AND_INVALIDATE); 291202a77d28ac251545f6f998a974690212309b927Iliyan Malchev hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; 2920b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed } else if(hnd->flags & private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH) { 2930b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed hnd->flags &= ~private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH; 2940b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed } else { 2950b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed //Probably a round about way to do this, but this avoids adding new 2960b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed //flags 2970b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed err = memalloc->clean_buffer((void*)hnd->base, 2980b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed hnd->size, hnd->offset, hnd->fd, 2990b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed CACHE_INVALIDATE); 300202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 301202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 3020b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed return err; 303202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 304202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 305202a77d28ac251545f6f998a974690212309b927Iliyan Malchev/*****************************************************************************/ 306202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 307202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint gralloc_perform(struct gralloc_module_t const* module, 30829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed 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( 32729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed private_handle_t::sNumFds, private_handle_t::sNumInts); 328202a77d28ac251545f6f998a974690212309b927Iliyan Malchev hnd->magic = private_handle_t::sMagic; 329202a77d28ac251545f6f998a974690212309b927Iliyan Malchev hnd->fd = fd; 33001d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION; 331202a77d28ac251545f6f998a974690212309b927Iliyan Malchev hnd->size = size; 332202a77d28ac251545f6f998a974690212309b927Iliyan Malchev hnd->offset = offset; 333202a77d28ac251545f6f998a974690212309b927Iliyan Malchev hnd->base = intptr_t(base) + offset; 334202a77d28ac251545f6f998a974690212309b927Iliyan Malchev hnd->gpuaddr = 0; 335202a77d28ac251545f6f998a974690212309b927Iliyan Malchev hnd->width = width; 336202a77d28ac251545f6f998a974690212309b927Iliyan Malchev hnd->height = height; 337202a77d28ac251545f6f998a974690212309b927Iliyan Malchev hnd->format = format; 338202a77d28ac251545f6f998a974690212309b927Iliyan Malchev *handle = (native_handle_t *)hnd; 339202a77d28ac251545f6f998a974690212309b927Iliyan Malchev res = 0; 340202a77d28ac251545f6f998a974690212309b927Iliyan Malchev break; 341202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 342202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 343da429776b96f9e81aee0b250ab3c0fb9cdcd3254Naseer Ahmed#ifdef QCOM_BSP 344e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan case GRALLOC_MODULE_PERFORM_UPDATE_BUFFER_GEOMETRY: 345e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan { 346e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan int width = va_arg(args, int); 347e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan int height = va_arg(args, int); 348e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan int format = va_arg(args, int); 349e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan private_handle_t* hnd = va_arg(args, private_handle_t*); 350e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan if (private_handle_t::validate(hnd)) { 351e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan return res; 352e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan } 353e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan hnd->width = width; 354e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan hnd->height = height; 355e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan hnd->format = format; 356e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan res = 0; 357e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan } 358e15a1a9ff2891695fbea56ecb8339e8dd06a0eefRamkumar Radhakrishnan break; 359d10d759bf645a36b34ef77932083a15eda50cc89Naseer Ahmed#endif 360bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis case GRALLOC_MODULE_PERFORM_GET_STRIDE: 361bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis { 362bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis int width = va_arg(args, int); 363bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis int format = va_arg(args, int); 364bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis int *stride = va_arg(args, int *); 365bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis *stride = AdrenoMemInfo::getInstance().getStride(width, format); 366bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis res = 0; 367bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis } break; 3685d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE: 3695d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed { 3705d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed private_handle_t* hnd = va_arg(args, private_handle_t*); 3715d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed int *stride = va_arg(args, int *); 3725d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed if (private_handle_t::validate(hnd)) { 3735d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed return res; 3745d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed } 3755d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed MetaData_t *metadata = (MetaData_t *)hnd->base_metadata; 3765d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) { 3775d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed *stride = metadata->bufferDim.sliceWidth; 3785d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed } else { 3795d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed *stride = hnd->width; 3805d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed } 3815d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed res = 0; 3825d1d54ff7c44559f664fdf071164c56c740ab79aNaseer Ahmed } break; 383202a77d28ac251545f6f998a974690212309b927Iliyan Malchev default: 384202a77d28ac251545f6f998a974690212309b927Iliyan Malchev break; 385202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 386202a77d28ac251545f6f998a974690212309b927Iliyan Malchev va_end(args); 387202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return res; 388202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 389