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