/*=========================================================================== * FUNCTION : allocate * * DESCRIPTION: allocate requested number of buffers of certain size * * PARAMETERS : * @size : lenght of the buffer to be allocated * * RETURN : int32_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ int QCamera3HeapMemory::allocate(size_t size) { unsigned int heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID; uint32_t i; int rc = NO_ERROR; //Note that now we allow incremental allocation. In other words, we allow //multiple alloc being called as long as the sum of count does not exceed //mMaxCnt. if (mBufferCount > 0) { ALOGE("%s: There is already buffer allocated.", __func__); return BAD_INDEX; } for (i = 0; i < mMaxCnt; i ++) { rc = allocOneBuffer(mMemInfo[i], heap_id_mask, size); if (rc < 0) { ALOGE("AllocateIonMemory failed"); goto ALLOC_FAILED; } void *vaddr = mmap(NULL, mMemInfo[i].size, PROT_READ | PROT_WRITE, MAP_SHARED, mMemInfo[i].fd, 0); if (vaddr == MAP_FAILED) { deallocOneBuffer(mMemInfo[i]); ALOGE("%s: mmap failed for buffer %d", __func__, i); goto ALLOC_FAILED; } else mPtr[i] = vaddr; } if (rc == 0) mBufferCount = mMaxCnt; return OK; ALLOC_FAILED: for (uint32_t j = 0; j < i; j++) { munmap(mPtr[j], mMemInfo[j].size); mPtr[j] = NULL; deallocOneBuffer(mMemInfo[j]); } return NO_MEMORY; }
/*=========================================================================== * FUNCTION : allocateOne * * DESCRIPTION: allocate one buffer * * PARAMETERS : * @size : lenght of the buffer to be allocated * * RETURN : int32_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ int QCamera3HeapMemory::allocateOne(size_t size) { unsigned int heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID; uint32_t i; int rc = NO_ERROR; //Note that now we allow incremental allocation. In other words, we allow //multiple alloc being called as long as the sum of count does not exceed //mMaxCnt. if (mBufferCount + 1 > mMaxCnt) { ALOGE("Buffer count %d + 1 out of bound. Max is %d", mBufferCount, mMaxCnt); return BAD_INDEX; } rc = allocOneBuffer(mMemInfo[mBufferCount], heap_id_mask, size); if (rc < 0) { ALOGE("AllocateIonMemory failed"); return NO_MEMORY; } void *vaddr = mmap(NULL, mMemInfo[mBufferCount].size, PROT_READ | PROT_WRITE, MAP_SHARED, mMemInfo[mBufferCount].fd, 0); if (vaddr == MAP_FAILED) { deallocOneBuffer(mMemInfo[mBufferCount]); ALOGE("%s: mmap failed for buffer", __func__); return NO_MEMORY; } else mPtr[mBufferCount] = vaddr; if (rc == 0) mBufferCount += 1; return mBufferCount-1; }
/*=========================================================================== * FUNCTION : alloc * * DESCRIPTION: allocate requested number of buffers of certain size * * PARAMETERS : * @count : number of buffers to be allocated * @size : lenght of the buffer to be allocated * @heap_id : heap id to indicate where the buffers will be allocated from * * RETURN : int32_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ int QCamera3HeapMemory::alloc(int count, int size, int heap_id) { int rc = OK; if (count > MM_CAMERA_MAX_NUM_FRAMES) { ALOGE("Buffer count %d out of bound. Max is %d", count, MM_CAMERA_MAX_NUM_FRAMES); return BAD_INDEX; } if (mBufferCount) { ALOGE("Allocating a already allocated heap memory"); return INVALID_OPERATION; } for (int i = 0; i < count; i ++) { rc = allocOneBuffer(mMemInfo[i], heap_id, size); if (rc < 0) { ALOGE("AllocateIonMemory failed"); for (int j = i-1; j >= 0; j--) deallocOneBuffer(mMemInfo[j]); break; } } return rc; }