static int gralloc_map(gralloc_module_t const* module, buffer_handle_t handle) { private_handle_t* hnd = (private_handle_t*)handle; void *mappedAddress; if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) && !(hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER)) { size_t size = hnd->size; IMemAlloc* memalloc = getAllocator(hnd->flags) ; int err = memalloc->map_buffer(&mappedAddress, size, hnd->offset, hnd->fd); if(err || mappedAddress == MAP_FAILED) { ALOGE("Could not mmap handle %p, fd=%d (%s)", handle, hnd->fd, strerror(errno)); hnd->base = 0; return -errno; } hnd->base = intptr_t(mappedAddress) + hnd->offset; mappedAddress = MAP_FAILED; size = ROUND_UP_PAGESIZE(sizeof(MetaData_t)); err = memalloc->map_buffer(&mappedAddress, size, hnd->offset_metadata, hnd->fd_metadata); if(err || mappedAddress == MAP_FAILED) { ALOGE("Could not mmap handle %p, fd=%d (%s)", handle, hnd->fd_metadata, strerror(errno)); hnd->base_metadata = 0; return -errno; } hnd->base_metadata = intptr_t(mappedAddress) + hnd->offset_metadata; } return 0; }
int PmemKernelController::allocate(alloc_data& data, int usage) { int ret = 0; bool adspFallback = false; if (!(usage & GRALLOC_USAGE_PRIVATE_SMI_HEAP)) adspFallback = true; // Try SMI first if ((usage & GRALLOC_USAGE_PRIVATE_SMI_HEAP) || (usage & GRALLOC_USAGE_EXTERNAL_DISP) || (usage & GRALLOC_USAGE_PROTECTED)) { int tempFd = open(DEVICE_PMEM_SMIPOOL, O_RDWR, 0); if(tempFd > 0) { close(tempFd); IMemAlloc* memalloc; memalloc = new PmemKernelAlloc(DEVICE_PMEM_SMIPOOL); ret = memalloc->alloc_buffer(data); if(ret >= 0) return ret; else { if(adspFallback) ALOGW("Allocation from SMI failed, trying ADSP"); } } } if ((usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP) || adspFallback) { ret = mPmemAdspAlloc->alloc_buffer(data); } return ret; }
static int gralloc_map(gralloc_module_t const* module, buffer_handle_t handle, void** vaddr) { private_handle_t* hnd = (private_handle_t*)handle; void *mappedAddress; if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) && !(hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER)) { size_t size = hnd->size; IMemAlloc* memalloc = getAllocator(hnd->flags) ; int err = memalloc->map_buffer(&mappedAddress, size, hnd->offset, hnd->fd); if(err) { ALOGE("Could not mmap handle %p, fd=%d (%s)", handle, hnd->fd, strerror(errno)); hnd->base = 0; return -errno; } if (mappedAddress == MAP_FAILED) { ALOGE("Could not mmap handle %p, fd=%d (%s)", handle, hnd->fd, strerror(errno)); hnd->base = 0; return -errno; } hnd->base = intptr_t(mappedAddress) + hnd->offset; //LOGD("gralloc_map() succeeded fd=%d, off=%d, size=%d, vaddr=%p", // hnd->fd, hnd->offset, hnd->size, mappedAddress); } *vaddr = (void*)hnd->base; return 0; }
int gpu_context_t::free_impl(private_handle_t const* hnd) { private_module_t* m = reinterpret_cast<private_module_t*>(common.module); if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) { const size_t bufferSize = m->finfo.line_length * m->info.yres; int index = (hnd->base - m->framebuffer->base) / bufferSize; m->bufferMask &= ~(1<<index); } else { terminateBuffer(&m->base, const_cast<private_handle_t*>(hnd)); IMemAlloc* memalloc = mAllocCtrl->getAllocator(hnd->flags); int err = memalloc->free_buffer((void*)hnd->base, (size_t) hnd->size, hnd->offset, hnd->fd); if(err) return err; // free the metadata space unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t)); err = memalloc->free_buffer((void*)hnd->base_metadata, (size_t) size, hnd->offset_metadata, hnd->fd_metadata); if (err) return err; } delete hnd; return 0; }
static int gralloc_unmap(gralloc_module_t const* module, buffer_handle_t handle) { if(!module) return -EINVAL; private_handle_t* hnd = (private_handle_t*)handle; if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) { int err = -EINVAL; void* base = (void*)hnd->base; size_t size = hnd->size; IMemAlloc* memalloc = getAllocator(hnd->flags) ; if(memalloc != NULL) { err = memalloc->unmap_buffer(base, size, hnd->offset); if (err) { ALOGE("Could not unmap memory at address %p", base); } base = (void*)hnd->base_metadata; size = ROUND_UP_PAGESIZE(sizeof(MetaData_t)); err = memalloc->unmap_buffer(base, size, hnd->offset_metadata); if (err) { ALOGE("Could not unmap memory at address %p", base); } } } /* need to initialize the pointer to NULL otherwise unmapping for that * buffer happens twice which leads to crash */ hnd->base = 0; hnd->base_metadata = 0; return 0; }
static int gralloc_unmap(gralloc_module_t const* module, buffer_handle_t handle) { private_handle_t* hnd = (private_handle_t*)handle; if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) { int err = -EINVAL; void* base = (void*)hnd->base; size_t size = hnd->size; IMemAlloc* memalloc = getAllocator(hnd->flags) ; if(memalloc != NULL) { err = memalloc->unmap_buffer(base, size, hnd->offset); if (err) { ALOGE("Could not unmap memory at address %p", base); } base = (void*)hnd->base_metadata; size = ROUND_UP_PAGESIZE(sizeof(MetaData_t)); err = memalloc->unmap_buffer(base, size, hnd->offset_metadata); if (err) { ALOGE("Could not unmap memory at address %p", base); } } } hnd->base = 0; return 0; }
int gralloc_unlock(gralloc_module_t const* module, buffer_handle_t handle) { if (private_handle_t::validate(handle) < 0) return -EINVAL; private_handle_t* hnd = (private_handle_t*)handle; if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) { int err; IMemAlloc* memalloc = getAllocator(hnd->flags) ; err = memalloc->clean_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd); ALOGE_IF(err < 0, "cannot flush handle %p (offs=%x len=%x, flags = 0x%x) err=%s\n", hnd, hnd->offset, hnd->size, hnd->flags, strerror(errno)); unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t)); err = memalloc->clean_buffer((void*)hnd->base_metadata, size, hnd->offset_metadata, hnd->fd_metadata); ALOGE_IF(err < 0, "cannot flush handle %p (offs=%x len=%lu, " "flags = 0x%x) err=%s\n", hnd, hnd->offset_metadata, size, hnd->flags, strerror(errno)); hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; } if ((hnd->flags & private_handle_t::PRIV_FLAGS_SW_LOCK)) { // Unlock the buffer. if (GENLOCK_NO_ERROR != genlock_unlock_buffer((native_handle_t *)handle)) { ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__); return -EINVAL; } else hnd->flags &= ~private_handle_t::PRIV_FLAGS_SW_LOCK; } return 0; }
static int gralloc_map_and_invalidate (gralloc_module_t const* module, buffer_handle_t handle, int usage, int l, int t, int w, int h) { if (private_handle_t::validate(handle) < 0) return -EINVAL; int err = 0; private_handle_t* hnd = (private_handle_t*)handle; if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) { if (hnd->base == 0) { // we need to map for real pthread_mutex_t* const lock = &sMapLock; pthread_mutex_lock(lock); err = gralloc_map(module, handle); pthread_mutex_unlock(lock); } //Invalidate if reading in software. No need to do this for the metadata //buffer as it is only read/written in software. IMemAlloc* memalloc = getAllocator(hnd->flags) ; err = memalloc->clean_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd, CACHE_INVALIDATE); if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) && !(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) { // Mark the buffer to be flushed after cpu read/write hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; } } else { hnd->flags |= private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH; } return err; }
int gralloc_unlock(gralloc_module_t const* module, buffer_handle_t handle) { if (!module || private_handle_t::validate(handle) < 0) return -EINVAL; int err = 0; private_handle_t* hnd = (private_handle_t*)handle; if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) { IMemAlloc* memalloc = getAllocator(hnd->flags); if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) { err = memalloc->clean_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd, CACHE_CLEAN_AND_INVALIDATE); hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; } else if(hnd->flags & private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH) { hnd->flags &= ~private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH; } else { //Probably a round about way to do this, but this avoids adding new //flags err = memalloc->clean_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd, CACHE_INVALIDATE); } } return err; }
int gpu_context_t::free_impl(private_handle_t const* hnd) { private_module_t* m = reinterpret_cast<private_module_t*>(common.module); if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) { // free this buffer const size_t bufferSize = m->finfo.line_length * m->info.yres; int index = (hnd->base - m->framebuffer->base) / bufferSize; m->bufferMask &= ~(1<<index); } else { terminateBuffer(&m->base, const_cast<private_handle_t*>(hnd)); IMemAlloc* memalloc = mAllocCtrl->getAllocator(hnd->flags); int err = memalloc->free_buffer((void*)hnd->base, (size_t) hnd->size, hnd->offset, hnd->fd); if(err) return err; } // Release the genlock int err = genlock_release_lock((native_handle_t*)hnd); if (err) { ALOGE("%s: genlock_release_lock failed", __FUNCTION__); } delete hnd; return 0; }
static int gralloc_map_and_invalidate (gralloc_module_t const* module, buffer_handle_t handle, int usage, int l, int t, int w, int h) { if (private_handle_t::validate(handle) < 0) return -EINVAL; int err = 0; private_handle_t* hnd = (private_handle_t*)handle; if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) { if (hnd->base == 0) { // we need to map for real pthread_mutex_t* const lock = &sMapLock; pthread_mutex_lock(lock); err = gralloc_map(module, handle); pthread_mutex_unlock(lock); } #ifdef QCOM_BSP_WITH_GENLOCK // Lock the buffer for read/write operation as specified. Write lock // has a higher priority over read lock. int lockType = 0; if (usage & GRALLOC_USAGE_SW_WRITE_MASK) { lockType = GENLOCK_WRITE_LOCK; } else if (usage & GRALLOC_USAGE_SW_READ_MASK) { lockType = GENLOCK_READ_LOCK; } int timeout = GENLOCK_MAX_TIMEOUT; if (GENLOCK_NO_ERROR != genlock_lock_buffer((native_handle_t *)handle, (genlock_lock_type)lockType, timeout)) { ALOGE("%s: genlock_lock_buffer (lockType=0x%x) failed", __FUNCTION__, lockType); return -EINVAL; } else { // Mark this buffer as locked for SW read/write operation. hnd->flags |= private_handle_t::PRIV_FLAGS_SW_LOCK; } #endif if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) { //Invalidate if reading in software. No need to do this for the //metadata buffer as it is only read/written in software. IMemAlloc* memalloc = getAllocator(hnd->flags) ; err = memalloc->clean_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd, CACHE_INVALIDATE); if (usage & GRALLOC_USAGE_SW_WRITE_MASK) { // Mark the buffer to be flushed after cpu read/write hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; } } } else { hnd->flags |= private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH; } return err; }
void free_buffer(private_handle_t *hnd) { gralloc::IAllocController* sAlloc = gralloc::IAllocController::getInstance(); if (hnd && hnd->fd > 0) { IMemAlloc* memalloc = sAlloc->getAllocator(hnd->flags); memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd); } if(hnd) delete hnd; }
static int gralloc_map(gralloc_module_t const* module, buffer_handle_t handle) { ATRACE_CALL(); if(!module) return -EINVAL; private_handle_t* hnd = (private_handle_t*)handle; unsigned int size = 0; int err = 0; IMemAlloc* memalloc = getAllocator(hnd->flags) ; void *mappedAddress; // Dont map FRAMEBUFFER and SECURE_BUFFERS if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) && !(hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER)) { size = hnd->size; err = memalloc->map_buffer(&mappedAddress, size, hnd->offset, hnd->fd); if(err || mappedAddress == MAP_FAILED) { ALOGE("Could not mmap handle %p, fd=%d (%s)", handle, hnd->fd, strerror(errno)); hnd->base = 0; return -errno; } hnd->base = uint64_t(mappedAddress) + hnd->offset; } //Allow mapping of metadata for all buffers and SECURE_BUFFER if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) { mappedAddress = MAP_FAILED; size = ROUND_UP_PAGESIZE(sizeof(MetaData_t)); err = memalloc->map_buffer(&mappedAddress, size, hnd->offset_metadata, hnd->fd_metadata); if(err || mappedAddress == MAP_FAILED) { ALOGE("Could not mmap handle %p, fd=%d (%s)", handle, hnd->fd_metadata, strerror(errno)); hnd->base_metadata = 0; return -errno; } hnd->base_metadata = uint64_t(mappedAddress) + hnd->offset_metadata; } return 0; }
static int gralloc_map(gralloc_module_t const* module, buffer_handle_t handle) { ATRACE_CALL(); if(!module) return -EINVAL; private_handle_t* hnd = (private_handle_t*)handle; unsigned int size = 0; int err = 0; IMemAlloc* memalloc = getAllocator(hnd->flags) ; void *mappedAddress = MAP_FAILED; hnd->base = 0; // Dont map framebuffer and secure buffers if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) && !(hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER)) { size = hnd->size; err = memalloc->map_buffer(&mappedAddress, size, hnd->offset, hnd->fd); if(err || mappedAddress == MAP_FAILED) { ALOGE("Could not mmap handle %p, fd=%d (%s)", handle, hnd->fd, strerror(errno)); return -errno; } hnd->base = uint64_t(mappedAddress); } else { // Cannot map secure buffers or framebuffers, but still need to map // metadata for secure buffers. // If mapping a secure buffers fails, the framework needs to get // an error code. err = -EACCES; } //Allow mapping of metadata for all buffers including secure ones, but not //of framebuffer int metadata_err = gralloc_map_metadata(handle); if(!err) { err = metadata_err; } return err; }
int gralloc_unlock(gralloc_module_t const* module, buffer_handle_t handle) { ATRACE_CALL(); if (!module || private_handle_t::validate(handle) < 0) return -EINVAL; int err = 0; private_handle_t* hnd = (private_handle_t*)handle; IMemAlloc* memalloc = getAllocator(hnd->flags); if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) { err = memalloc->clean_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd, CACHE_CLEAN); hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; } return err; }
static int gralloc_map_metadata(buffer_handle_t handle) { private_handle_t* hnd = (private_handle_t*)handle; hnd->base_metadata = 0; IMemAlloc* memalloc = getAllocator(hnd->flags) ; void *mappedAddress = MAP_FAILED; unsigned int size = 0; if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) { mappedAddress = MAP_FAILED; size = ROUND_UP_PAGESIZE(sizeof(MetaData_t)); int ret = memalloc->map_buffer(&mappedAddress, size, hnd->offset_metadata, hnd->fd_metadata); if(ret || mappedAddress == MAP_FAILED) { ALOGE("Could not mmap metadata for handle %p, fd=%d (%s)", hnd, hnd->fd_metadata, strerror(errno)); return -errno; } hnd->base_metadata = uint64_t(mappedAddress); } return 0; }
static int gralloc_map_and_invalidate (gralloc_module_t const* module, buffer_handle_t handle, int usage) { ATRACE_CALL(); if (!module || private_handle_t::validate(handle) < 0) return -EINVAL; int err = 0; private_handle_t* hnd = (private_handle_t*)handle; if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) { if (hnd->base == 0) { // we need to map for real pthread_mutex_t* const lock = &sMapLock; pthread_mutex_lock(lock); err = gralloc_map(module, handle); pthread_mutex_unlock(lock); } if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION and hnd->flags & private_handle_t::PRIV_FLAGS_CACHED) { //Invalidate if CPU reads in software and there are non-CPU //writers. No need to do this for the metadata buffer as it is //only read/written in software. if ((usage & GRALLOC_USAGE_SW_READ_MASK) and (hnd->flags & private_handle_t::PRIV_FLAGS_NON_CPU_WRITER)) { IMemAlloc* memalloc = getAllocator(hnd->flags) ; err = memalloc->clean_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd, CACHE_INVALIDATE); } //Mark the buffer to be flushed after CPU write. if (usage & GRALLOC_USAGE_SW_WRITE_MASK) { hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; } } } return err; }
int gralloc_unlock(gralloc_module_t const* module, buffer_handle_t handle) { if (private_handle_t::validate(handle) < 0) return -EINVAL; int err = 0; private_handle_t* hnd = (private_handle_t*)handle; IMemAlloc* memalloc = getAllocator(hnd->flags); if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) { err = memalloc->clean_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd, CACHE_CLEAN_AND_INVALIDATE); hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; } else if(hnd->flags & private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH) { hnd->flags &= ~private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH; } else { //Probably a round about way to do this, but this avoids adding new //flags err = memalloc->clean_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd, CACHE_INVALIDATE); } #ifndef QCOM_BSP if ((hnd->flags & private_handle_t::PRIV_FLAGS_SW_LOCK)) { // Unlock the buffer. if (GENLOCK_NO_ERROR != genlock_unlock_buffer((native_handle_t *)handle)) { ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__); return -EINVAL; } else hnd->flags &= ~private_handle_t::PRIV_FLAGS_SW_LOCK; } #endif return err; }
static int gralloc_unmap(gralloc_module_t const* module, buffer_handle_t handle) { ATRACE_CALL(); int err = -EINVAL; if(!module) return err; private_handle_t* hnd = (private_handle_t*)handle; IMemAlloc* memalloc = getAllocator(hnd->flags) ; if(!memalloc) return err; if(hnd->base) { err = memalloc->unmap_buffer((void*)hnd->base, hnd->size, hnd->offset); if (err) { ALOGE("Could not unmap memory at address %p, %s", (void*) hnd->base, strerror(errno)); return -errno; } hnd->base = 0; } if(hnd->base_metadata) { unsigned int size = ROUND_UP_PAGESIZE(sizeof(MetaData_t)); err = memalloc->unmap_buffer((void*)hnd->base_metadata, size, hnd->offset_metadata); if (err) { ALOGE("Could not unmap memory at address %p, %s", (void*) hnd->base_metadata, strerror(errno)); return -errno; } hnd->base_metadata = 0; } return 0; }