mapper.cpp revision 59644b2127280052ca410cb053f0a41c3181a97a
1a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev/* 2a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * Copyright (C) 2008 The Android Open Source Project 3befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved. 4a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * 5a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * Licensed under the Apache License, Version 2.0 (the "License"); 6a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * you may not use this file except in compliance with the License. 7a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * You may obtain a copy of the License at 8a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * 9a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * http://www.apache.org/licenses/LICENSE-2.0 10a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * 11a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * Unless required by applicable law or agreed to in writing, software 12a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * distributed under the License is distributed on an "AS IS" BASIS, 13a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * See the License for the specific language governing permissions and 15a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * limitations under the License. 16a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev */ 17a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 18a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <limits.h> 19a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <errno.h> 20a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <pthread.h> 21a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <unistd.h> 22a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <string.h> 23a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <stdarg.h> 24a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 25a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <sys/mman.h> 26a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <sys/stat.h> 27a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <sys/types.h> 28a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <sys/ioctl.h> 29a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <linux/ashmem.h> 30a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 31a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <cutils/log.h> 32a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <cutils/atomic.h> 33a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <cutils/ashmem.h> 34a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 35a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <hardware/hardware.h> 36a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <hardware/gralloc.h> 37a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <genlock.h> 38a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 39a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include <linux/android_pmem.h> 40a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 41a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include "gralloc_priv.h" 42a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include "gr.h" 43a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include "alloc_controller.h" 44a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev#include "memalloc.h" 45591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan#include <qdMetaData.h> 46a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 47a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchevusing namespace gralloc; 48a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev/*****************************************************************************/ 49a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 50a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev// Return the type of allocator - 51a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev// these are used for mapping/unmapping 52be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmedstatic IMemAlloc* getAllocator(int flags) 53a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev{ 54be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmed IMemAlloc* memalloc; 55be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmed IAllocController* alloc_ctrl = IAllocController::getInstance(); 56a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev memalloc = alloc_ctrl->getAllocator(flags); 57a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev return memalloc; 58a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev} 59a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 60a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchevstatic int gralloc_map(gralloc_module_t const* module, 61befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed buffer_handle_t handle, 62befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed void** vaddr) 63a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev{ 64a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev private_handle_t* hnd = (private_handle_t*)handle; 65a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev void *mappedAddress; 66a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) && 67a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev !(hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER)) { 68a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev size_t size = hnd->size; 69be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmed IMemAlloc* memalloc = getAllocator(hnd->flags) ; 70a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev int err = memalloc->map_buffer(&mappedAddress, size, 71befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed hnd->offset, hnd->fd); 72591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan if(err || mappedAddress == MAP_FAILED) { 73a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev ALOGE("Could not mmap handle %p, fd=%d (%s)", 74befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed handle, hnd->fd, strerror(errno)); 75a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev hnd->base = 0; 76a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev return -errno; 77a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev } 78a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 79a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev hnd->base = intptr_t(mappedAddress) + hnd->offset; 80befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed //LOGD("gralloc_map() succeeded fd=%d, off=%d, size=%d, vaddr=%p", 81a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev // hnd->fd, hnd->offset, hnd->size, mappedAddress); 82591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan mappedAddress = MAP_FAILED; 83591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan size = ROUND_UP_PAGESIZE(sizeof(MetaData_t)); 84591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan err = memalloc->map_buffer(&mappedAddress, size, 85591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan hnd->offset_metadata, hnd->fd_metadata); 86591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan if(err || mappedAddress == MAP_FAILED) { 87591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan ALOGE("Could not mmap handle %p, fd=%d (%s)", 88591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan handle, hnd->fd_metadata, strerror(errno)); 89591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan hnd->base_metadata = 0; 90591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan return -errno; 91591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan } 92591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan hnd->base_metadata = intptr_t(mappedAddress) + hnd->offset_metadata; 93a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev } 94a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev *vaddr = (void*)hnd->base; 95a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev return 0; 96a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev} 97a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 98a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchevstatic int gralloc_unmap(gralloc_module_t const* module, 99befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed buffer_handle_t handle) 100a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev{ 101a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev private_handle_t* hnd = (private_handle_t*)handle; 102a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) { 103a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev int err = -EINVAL; 104a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev void* base = (void*)hnd->base; 105a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev size_t size = hnd->size; 106be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmed IMemAlloc* memalloc = getAllocator(hnd->flags) ; 107591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan if(memalloc != NULL) { 108a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev err = memalloc->unmap_buffer(base, size, hnd->offset); 109591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan if (err) { 110591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan ALOGE("Could not unmap memory at address %p", base); 111591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan } 112591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan base = (void*)hnd->base_metadata; 113591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan size = ROUND_UP_PAGESIZE(sizeof(MetaData_t)); 114591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan err = memalloc->unmap_buffer(base, size, hnd->offset_metadata); 115591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan if (err) { 116591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan ALOGE("Could not unmap memory at address %p", base); 117591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan } 118a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev } 119a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev } 120a0b7f4e1300ee86ca60c40fb238ed5d3f518941eRamkumar Radhakrishnan /* need to initialize the pointer to NULL otherwise unmapping for that 121a0b7f4e1300ee86ca60c40fb238ed5d3f518941eRamkumar Radhakrishnan * buffer happens twice which leads to crash */ 122a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev hnd->base = 0; 123a0b7f4e1300ee86ca60c40fb238ed5d3f518941eRamkumar Radhakrishnan hnd->base_metadata = 0; 124a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev return 0; 125a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev} 126a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 127a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev/*****************************************************************************/ 128a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 129a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchevstatic pthread_mutex_t sMapLock = PTHREAD_MUTEX_INITIALIZER; 130a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 131a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev/*****************************************************************************/ 132a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 133a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchevint gralloc_register_buffer(gralloc_module_t const* module, 134befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed buffer_handle_t handle) 135a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev{ 136a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev if (private_handle_t::validate(handle) < 0) 137a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev return -EINVAL; 138a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 139a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev // In this implementation, we don't need to do anything here 140a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 141a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev /* NOTE: we need to initialize the buffer as not mapped/not locked 142a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * because it shouldn't when this function is called the first time 143a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * in a new process. Ideally these flags shouldn't be part of the 144a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * handle, but instead maintained in the kernel or at least 145a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * out-of-line 146a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev */ 147a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 148a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev private_handle_t* hnd = (private_handle_t*)handle; 14977a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar hnd->base = 0; 150a0b7f4e1300ee86ca60c40fb238ed5d3f518941eRamkumar Radhakrishnan hnd->base_metadata = 0; 15177a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar void *vaddr; 15277a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar int err = gralloc_map(module, handle, &vaddr); 15377a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar if (err) { 15477a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar ALOGE("%s: gralloc_map failed", __FUNCTION__); 15577a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar return err; 15677a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar } 157a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 15877a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar // Reset the genlock private fd flag in the handle 15977a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar hnd->genlockPrivFd = -1; 160a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 16177a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar // Check if there is a valid lock attached to the handle. 16277a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar if (-1 == hnd->genlockHandle) { 16377a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar ALOGE("%s: the lock is invalid.", __FUNCTION__); 16477a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar gralloc_unmap(module, handle); 16577a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar hnd->base = 0; 16677a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar return -EINVAL; 16777a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar } 168a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 16977a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar // Attach the genlock handle 17077a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar if (GENLOCK_NO_ERROR != genlock_attach_lock((native_handle_t *)handle)) { 17177a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar ALOGE("%s: genlock_attach_lock failed", __FUNCTION__); 17277a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar gralloc_unmap(module, handle); 17377a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar hnd->base = 0; 17477a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar return -EINVAL; 175a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev } 176a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev return 0; 177a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev} 178a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 179a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchevint gralloc_unregister_buffer(gralloc_module_t const* module, 180befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed buffer_handle_t handle) 181a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev{ 182a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev if (private_handle_t::validate(handle) < 0) 183a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev return -EINVAL; 184a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 185a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev /* 186a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * If the buffer has been mapped during a lock operation, it's time 187a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * to un-map it. It's an error to be here with a locked buffer. 188a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * NOTE: the framebuffer is handled differently and is never unmapped. 189a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev */ 190a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 191a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev private_handle_t* hnd = (private_handle_t*)handle; 192a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 19377a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar if (hnd->base != 0) { 19477a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar gralloc_unmap(module, handle); 19577a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar } 19677a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar hnd->base = 0; 197a0b7f4e1300ee86ca60c40fb238ed5d3f518941eRamkumar Radhakrishnan hnd->base_metadata = 0; 19877a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar // Release the genlock 19977a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar if (-1 != hnd->genlockHandle) { 20077a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar return genlock_release_lock((native_handle_t *)handle); 20177a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar } else { 20277a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar ALOGE("%s: there was no genlock attached to this buffer", __FUNCTION__); 20377a5ae0adc2e220228a988c65696757b37d0826eKinjal Bhavsar return -EINVAL; 204a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev } 205a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev return 0; 206a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev} 207a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 208a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchevint terminateBuffer(gralloc_module_t const* module, 209befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed private_handle_t* hnd) 210a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev{ 211a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev /* 212a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * If the buffer has been mapped during a lock operation, it's time 213a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev * to un-map it. It's an error to be here with a locked buffer. 214a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev */ 215a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 216a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev if (hnd->base != 0) { 217a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev // this buffer was mapped, unmap it now 218a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev if (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM | 219a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP | 220a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev private_handle_t::PRIV_FLAGS_USES_ASHMEM | 221a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev private_handle_t::PRIV_FLAGS_USES_ION)) { 222a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev gralloc_unmap(module, hnd); 223a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev } else { 224befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed ALOGE("terminateBuffer: unmapping a non pmem/ashmem buffer flags = 0x%x", 225befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed hnd->flags); 226a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev gralloc_unmap(module, hnd); 227a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev } 228a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev } 229a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 230a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev return 0; 231a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev} 232a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 233a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchevint gralloc_lock(gralloc_module_t const* module, 234befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed buffer_handle_t handle, int usage, 235befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed int l, int t, int w, int h, 236befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed void** vaddr) 237a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev{ 238a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev if (private_handle_t::validate(handle) < 0) 239a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev return -EINVAL; 240a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 241a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev int err = 0; 242a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev private_handle_t* hnd = (private_handle_t*)handle; 243a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) { 244a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev if (hnd->base == 0) { 245a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev // we need to map for real 246a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev pthread_mutex_t* const lock = &sMapLock; 247a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev pthread_mutex_lock(lock); 248a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev err = gralloc_map(module, handle, vaddr); 249a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev pthread_mutex_unlock(lock); 250a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev } 251a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev *vaddr = (void*)hnd->base; 252a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 253a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev // Lock the buffer for read/write operation as specified. Write lock 254a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev // has a higher priority over read lock. 255a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev int lockType = 0; 256a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev if (usage & GRALLOC_USAGE_SW_WRITE_MASK) { 257a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev lockType = GENLOCK_WRITE_LOCK; 258a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev } else if (usage & GRALLOC_USAGE_SW_READ_MASK) { 259a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev lockType = GENLOCK_READ_LOCK; 260a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev } 261a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 262a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev int timeout = GENLOCK_MAX_TIMEOUT; 263a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev if (GENLOCK_NO_ERROR != genlock_lock_buffer((native_handle_t *)handle, 264befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed (genlock_lock_type)lockType, 265befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed timeout)) { 266a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev ALOGE("%s: genlock_lock_buffer (lockType=0x%x) failed", __FUNCTION__, 267befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed lockType); 268a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev return -EINVAL; 269a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev } else { 270a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev // Mark this buffer as locked for SW read/write operation. 271a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev hnd->flags |= private_handle_t::PRIV_FLAGS_SW_LOCK; 272a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev } 273a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 274a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) && 275a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev !(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) { 276a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev // Mark the buffer to be flushed after cpu read/write 277a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; 278a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev } 279a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev } 280a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev return err; 281a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev} 282a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 283a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchevint gralloc_unlock(gralloc_module_t const* module, 284befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed buffer_handle_t handle) 285a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev{ 286a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev if (private_handle_t::validate(handle) < 0) 287a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev return -EINVAL; 288a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 289a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev private_handle_t* hnd = (private_handle_t*)handle; 290a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 291a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) { 292a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev int err; 293be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmed IMemAlloc* memalloc = getAllocator(hnd->flags) ; 294a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev err = memalloc->clean_buffer((void*)hnd->base, 295befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed hnd->size, hnd->offset, hnd->fd); 296a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev ALOGE_IF(err < 0, "cannot flush handle %p (offs=%x len=%x, flags = 0x%x) err=%s\n", 297befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed hnd, hnd->offset, hnd->size, hnd->flags, strerror(errno)); 298591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t)); 299591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan err = memalloc->clean_buffer((void*)hnd->base_metadata, size, 300591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan hnd->offset_metadata, hnd->fd_metadata); 301591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan ALOGE_IF(err < 0, "cannot flush handle %p (offs=%x len=%lu, " 302591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan "flags = 0x%x) err=%s\n", hnd, hnd->offset_metadata, size, 303591f83eb35f33cf108720d9bb30cb56933e1e724Ramkumar Radhakrishnan hnd->flags, strerror(errno)); 304a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; 305a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev } 306a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 307a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev if ((hnd->flags & private_handle_t::PRIV_FLAGS_SW_LOCK)) { 308a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev // Unlock the buffer. 309a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev if (GENLOCK_NO_ERROR != genlock_unlock_buffer((native_handle_t *)handle)) { 310a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__); 311a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev return -EINVAL; 312a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev } else 313a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev hnd->flags &= ~private_handle_t::PRIV_FLAGS_SW_LOCK; 314a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev } 315a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev return 0; 316a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev} 317a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 318a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev/*****************************************************************************/ 319a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 320a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchevint gralloc_perform(struct gralloc_module_t const* module, 321befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed int operation, ... ) 322a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev{ 323a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev int res = -EINVAL; 324a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev va_list args; 325a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev va_start(args, operation); 326a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev switch (operation) { 327a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER: 328a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev { 329a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev int fd = va_arg(args, int); 330a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev size_t size = va_arg(args, size_t); 331a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev size_t offset = va_arg(args, size_t); 332a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev void* base = va_arg(args, void*); 333a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev int width = va_arg(args, int); 334a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev int height = va_arg(args, int); 335a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev int format = va_arg(args, int); 336a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 337a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev native_handle_t** handle = va_arg(args, native_handle_t**); 338a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev int memoryFlags = va_arg(args, int); 339a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev private_handle_t* hnd = (private_handle_t*)native_handle_create( 340befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed private_handle_t::sNumFds, private_handle_t::sNumInts); 341a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev hnd->magic = private_handle_t::sMagic; 342a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev hnd->fd = fd; 343be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmed hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION; 344a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev hnd->size = size; 345a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev hnd->offset = offset; 346a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev hnd->base = intptr_t(base) + offset; 347a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev hnd->gpuaddr = 0; 348a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev hnd->width = width; 349a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev hnd->height = height; 350a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev hnd->format = format; 351a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev *handle = (native_handle_t *)hnd; 352a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev res = 0; 353a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev break; 354a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev 355a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev } 35659644b2127280052ca410cb053f0a41c3181a97aNaseer Ahmed#ifdef QCOM_BSP 3575fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan case GRALLOC_MODULE_PERFORM_UPDATE_BUFFER_GEOMETRY: 3585fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan { 3595fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan int width = va_arg(args, int); 3605fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan int height = va_arg(args, int); 3615fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan int format = va_arg(args, int); 3625fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan private_handle_t* hnd = va_arg(args, private_handle_t*); 3635fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan if (private_handle_t::validate(hnd)) { 3645fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan return res; 3655fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan } 3665fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan hnd->width = width; 3675fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan hnd->height = height; 3685fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan hnd->format = format; 3695fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan res = 0; 3705fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan } 3715fd30e6b24fdb48b95c1aab8546da63a07a58043Ramkumar Radhakrishnan break; 37259644b2127280052ca410cb053f0a41c3181a97aNaseer Ahmed#endif 373a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev default: 374a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev break; 375a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev } 376a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev va_end(args); 377a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev return res; 378a19f21d925628239ef52c8ce392fa4ada91df6fcIliyan Malchev} 379