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