PmemPool::~PmemPool() { ALOGI("%s: %s E", __FUNCTION__, mName); #if 0 if (mHeap != NULL) { // Unregister preview buffers with the camera drivers. // Only Unregister the preview, snapshot and thumbnail // buffers with the kernel. if( (strcmp("postview", mName) != 0) ){ int num_buffers = mNumBuffers; if(!strcmp("preview", mName)) num_buffers = PREVIEW_BUFFER_COUNT; for (int cnt = 0; cnt < num_buffers; ++cnt) { register_buf(mBufferSize, mFrameSize, mCbCrOffset, myOffset, mHeap->getHeapID(), mAlignedBufferSize * cnt, (uint8_t *)mHeap->base() + mAlignedBufferSize * cnt, mPmemType, false, false /* unregister */); } } } mMMCameraDLRef.clear(); #endif ALOGI("%s: %s X", __FUNCTION__, mName); }
/*=========================================================================== Function : apr_pmem_free_ion Description : Free ion memory Input parameter(s) : Ion structure to the allocated memory block Output parameter(s) : None =========================================================================== */ void apr_pmem_free_ion(struct mmap_info_ion mapion) { int32_t rc = 0; struct ion_handle_data handle_data; uint32_t bufsize; if (mapion.pVirtualAddr == NULL) { return; } register_buf(mapion.pVirtualAddr, mapion.bufsize, -1); bufsize = (mapion.bufsize + 4095) & (~4095); rc = munmap(mapion.pVirtualAddr, bufsize); close(mapion.ion_info_fd.fd); handle_data.handle = mapion.ion_info_fd.handle; ioctl(mapion.ion_fd, ION_IOC_FREE, &handle_data); close(mapion.ion_fd); }
void apr_pmem_alloc_ion_cached(struct mmap_info_ion *pmapion, uint32_t ionheapid) { struct ion_handle_data handle_data; struct ion_allocation_data alloc; struct ion_client *ion_client; struct ion_handle *ion_handle; int32_t rc; int32_t ion_fd; uint32_t ret; int32_t p_pmem_fd; struct ion_fd_data ion_info_fd; struct ion_fd_data test_fd; struct ion_custom_data data; ion_fd = open("/dev/ion", O_RDONLY); if (ion_fd < 0) { CDBG_ERROR("\n apr_pmem_alloc_ion : Open ion device failed"); pmapion->pVirtualAddr = NULL; return; } alloc.len = pmapion->bufsize; alloc.align = 4096; alloc.heap_mask = ionheapid; if (ionheapid == ION_HEAP(ION_CP_MM_HEAP_ID)) { alloc.flags = ION_SECURE | ION_FLAG_CACHED; } else { alloc.flags = ION_FLAG_CACHED; } rc = ioctl(ion_fd, ION_IOC_ALLOC, &alloc); if (rc < 0) { handle_data.handle = (pmapion->ion_info_fd). handle; CDBG_ERROR("\n apr_pmem_alloc_ion : ION alloc length %d %d", rc, alloc.len); close(ion_fd); pmapion->pVirtualAddr = NULL; return; } else { pmapion->ion_info_fd.handle = alloc.handle; rc = ioctl(ion_fd, ION_IOC_SHARE, &(pmapion->ion_info_fd)); if (rc < 0) { CDBG_ERROR("\n apr_pmem_alloc_ion : ION map call failed %d", rc); handle_data.handle = pmapion->ion_info_fd.handle; ioctl(ion_fd, ION_IOC_FREE, &handle_data); close(ion_fd); pmapion->pVirtualAddr = NULL; return; } else { p_pmem_fd = pmapion->ion_info_fd.fd; ret = (uint32_t)mmap(NULL, alloc.len, PROT_READ | PROT_WRITE, MAP_SHARED, p_pmem_fd, 0); if (ret == (uint32_t)MAP_FAILED) { CDBG_ERROR("\n apr_pmem_alloc_ion : mmap call failed %d", rc); handle_data.handle = (pmapion->ion_info_fd).handle; ioctl(ion_fd, ION_IOC_FREE, &handle_data); close(ion_fd); pmapion->pVirtualAddr = NULL; return; } else { CDBG_ERROR("\n Ion allocation success virtaddr : %u fd %u", (uint32_t)ret, (uint32_t)p_pmem_fd); data.cmd = p_pmem_fd; pmapion->pVirtualAddr = (void *)ret; pmapion->ion_fd = ion_fd; } } } register_buf(pmapion->pVirtualAddr, alloc.len, p_pmem_fd); return; }
PmemPool::PmemPool(const char *pmem_pool, int flags, int pmem_type, int buffer_size, int num_buffers, int frame_size, int cbcr_offset, int yOffset, const char *name) : MemPool(buffer_size,num_buffers,frame_size,name), mPmemType(pmem_type), mCbCrOffset(cbcr_offset), myOffset(yOffset) { ALOGI("constructing MemPool %s backed by pmem pool %s: " "%d frames @ %d bytes, buffer size %d", mName, pmem_pool, num_buffers, frame_size, buffer_size); //mMMCameraDLRef = MMCameraDL::getInstance(); // Make a new mmap'ed heap that can be shared across processes. // mAlignedBufferSize is already in 4k aligned. (do we need total size necessary to be in power of 2??) mAlignedSize = mAlignedBufferSize * num_buffers; sp<MemoryHeapBase> masterHeap = new MemoryHeapBase(pmem_pool, mAlignedSize, flags); if (masterHeap->getHeapID() < 0) { ALOGE("failed to construct master heap for pmem pool %s", pmem_pool); masterHeap.clear(); return; } sp<MemoryHeapPmem> pmemHeap = new MemoryHeapPmem(masterHeap, flags); if (pmemHeap->getHeapID() >= 0) { pmemHeap->slap(); masterHeap.clear(); mHeap = pmemHeap; pmemHeap.clear(); mFd = mHeap->getHeapID(); if (::ioctl(mFd, PMEM_GET_SIZE, &mSize)) { ALOGE("pmem pool %s ioctl(PMEM_GET_SIZE) error %s (%d)", pmem_pool, ::strerror(errno), errno); mHeap.clear(); return; } ALOGE("pmem pool %s ioctl(fd = %d, PMEM_GET_SIZE) is %ld", pmem_pool, mFd, mSize.len); ALOGE("mBufferSize=%d, mAlignedBufferSize=%d\n", mBufferSize, mAlignedBufferSize); #if 0 // Unregister preview buffers with the camera drivers. Allow the VFE to write // to all preview buffers except for the last one. // Only Register the preview, snapshot and thumbnail buffers with the kernel. if( (strcmp("postview", mName) != 0) ){ int num_buf = num_buffers; if(!strcmp("preview", mName)) num_buf = kPreviewBufferCount; ALOGD("num_buffers = %d", num_buf); for (int cnt = 0; cnt < num_buf; ++cnt) { int active = 1; if(pmem_type == MSM_PMEM_VIDEO){ active = (cnt<ACTIVE_VIDEO_BUFFERS); //When VPE is enabled, set the last record //buffer as active and pmem type as PMEM_VIDEO_VPE //as this is a requirement from VPE operation. //No need to set this pmem type to VIDEO_VPE while unregistering, //because as per camera stack design: "the VPE AXI is also configured //when VFE is configured for VIDEO, which is as part of preview //initialization/start. So during this VPE AXI config camera stack //will lookup the PMEM_VIDEO_VPE buffer and give it as o/p of VPE and //change it's type to PMEM_VIDEO". if( (mVpeEnabled) && (cnt == kRecordBufferCount-1)) { active = 1; pmem_type = MSM_PMEM_VIDEO_VPE; } ALOGV(" pmempool creating video buffers : active %d ", active); } else if (pmem_type == MSM_PMEM_PREVIEW){ active = (cnt < ACTIVE_PREVIEW_BUFFERS); } else if ((pmem_type == MSM_PMEM_MAINIMG) || (pmem_type == MSM_PMEM_THUMBNAIL)){ active = (cnt < ACTIVE_ZSL_BUFFERS); } register_buf(mBufferSize, mFrameSize, mCbCrOffset, myOffset, mHeap->getHeapID(), mAlignedBufferSize * cnt, (uint8_t *)mHeap->base() + mAlignedBufferSize * cnt, pmem_type, active); } } #endif completeInitialization(); } else ALOGE("pmem pool %s error: could not create master heap!", pmem_pool); ALOGI("%s: (%s) X ", __FUNCTION__, mName); }