int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage, buffer_handle_t* pHandle) { int err = 0; int flags = 0; int fd = -1; void* base = 0; // XXX JMG: This should change to just get an address from // the PmemAllocator rather than getting the base & offset separately int offset = 0; int lockState = 0; size = roundUpToPageSize(size); #ifndef USE_ASHMEM if (usage & GRALLOC_USAGE_HW_TEXTURE) { // enable pmem in that case, so our software GL can fallback to // the copybit module. flags |= private_handle_t::PRIV_FLAGS_USES_PMEM; } if (usage & GRALLOC_USAGE_HW_2D) { flags |= private_handle_t::PRIV_FLAGS_USES_PMEM; } #else if (usage & GRALLOC_USAGE_PRIVATE_PMEM){ flags |= private_handle_t::PRIV_FLAGS_USES_PMEM; } #endif if (usage & GRALLOC_USAGE_PRIVATE_PMEM_ADSP) { flags |= private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP; flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM; } private_module_t* m = reinterpret_cast<private_module_t*>(common.module); if((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) == 0 && (flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) == 0) { flags |= private_handle_t::PRIV_FLAGS_USES_ASHMEM; err = alloc_ashmem_buffer(size, (unsigned int)pHandle, &base, &offset, &fd); if(err >= 0) lockState |= private_handle_t::LOCK_STATE_MAPPED; } else if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) != 0 || (flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) != 0) { PmemAllocator* pma = 0; if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) != 0) { if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) != 0) { LOGE("attempting to allocate a gralloc buffer with both the " "USES_PMEM and USES_PMEM_ADSP flags. Unsetting the " "USES_PMEM_ADSP flag."); flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP; } pma = &pmemAllocator; } else { // (flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) != 0 pma = &pmemAdspAllocator; } // PMEM buffers are always mmapped lockState |= private_handle_t::LOCK_STATE_MAPPED; // Allocate the buffer from pmem err = pma->alloc_pmem_buffer(size, usage, &base, &offset, &fd); if (err < 0) { if (((usage & GRALLOC_USAGE_HW_MASK) == 0) && ((usage & GRALLOC_USAGE_PRIVATE_PMEM_ADSP) == 0)) { // the caller didn't request PMEM, so we can try something else flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM; err = 0; goto try_ashmem; } else { LOGE("couldn't open pmem (%s)", strerror(errno)); } } } else { try_ashmem: fd = deps.ashmem_create_region("gralloc-buffer", size); if (fd < 0) { LOGE("couldn't create ashmem (%s)", strerror(errno)); err = -errno; } } if (err == 0) { private_handle_t* hnd = new private_handle_t(fd, size, flags); hnd->offset = offset; hnd->base = int(base)+offset; hnd->lockState = lockState; *pHandle = hnd; } LOGE_IF(err, "gralloc failed err=%s", strerror(-err)); return err; }
int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage, buffer_handle_t* pHandle, int bufferType, int format, int width, int height) { int err = 0; int flags = 0; int fd = -1; void* base = 0; // XXX JMG: This should change to just get an address from // the PmemAllocator rather than getting the base & offset separately int offset = 0; int lockState = 0; size = roundUpToPageSize(size); #ifndef USE_ASHMEM if (usage & GRALLOC_USAGE_HW_TEXTURE) { // enable pmem in that case, so our software GL can fallback to // the copybit module. flags |= private_handle_t::PRIV_FLAGS_USES_PMEM; } if (usage & GRALLOC_USAGE_HW_2D) { flags |= private_handle_t::PRIV_FLAGS_USES_PMEM; } #else // Enable use of PMEM only when MDP composition is used (and other conditions apply). // Else fall back on using ASHMEM if ((get_composition_type() == MDP_COMPOSITION) && ((usage & GRALLOC_USAGE_HW_TEXTURE) || (usage & GRALLOC_USAGE_HW_2D)) ) { flags |= private_handle_t::PRIV_FLAGS_USES_PMEM; } if (usage & GRALLOC_USAGE_PRIVATE_PMEM) { flags |= private_handle_t::PRIV_FLAGS_USES_PMEM; } #endif if ((usage & GRALLOC_USAGE_PRIVATE_PMEM_ADSP) || (usage & GRALLOC_USAGE_PRIVATE_PMEM_SMIPOOL) || (usage & GRALLOC_USAGE_EXTERNAL_DISP) || (usage & GRALLOC_USAGE_PROTECTED)) { flags |= private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP; flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM; } private_module_t* m = reinterpret_cast<private_module_t*>(common.module); if((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) == 0 && (flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) == 0) { flags |= private_handle_t::PRIV_FLAGS_USES_ASHMEM; err = alloc_ashmem_buffer(size, (unsigned int)pHandle, &base, &offset, &fd); if(err >= 0) lockState |= private_handle_t::LOCK_STATE_MAPPED; } else if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) != 0 || (flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) != 0) { PmemAllocator* pma = 0; if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) != 0) { if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) != 0) { LOGE("attempting to allocate a gralloc buffer with both the " "USES_PMEM and USES_PMEM_ADSP flags. Unsetting the " "USES_PMEM_ADSP flag."); flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP; } pma = &pmemAllocator; } else { // (flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) != 0 pma = &pmemAdspAllocator; } // PMEM buffers are always mmapped lockState |= private_handle_t::LOCK_STATE_MAPPED; err = pma->alloc_pmem_buffer(size, usage, &base, &offset, &fd, format); if (err < 0) { // Pmem allocation failed. Try falling back to ashmem iff we are: // a. not using MDP composition // b. not allocating memory for a buffer to be used by overlays // c. The client has not explicitly requested a PMEM buffer if ((get_composition_type() != MDP_COMPOSITION) && (bufferType != BUFFER_TYPE_VIDEO) && ((usage & GRALLOC_USAGE_PRIVATE_PMEM) == 0) && ((usage & GRALLOC_USAGE_PRIVATE_PMEM_ADSP) == 0)) { // the caller didn't request PMEM, so we can try something else flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM; err = 0; LOGE("Pmem allocation failed. Trying ashmem"); goto try_ashmem; } else { LOGE("couldn't open pmem (%s)", strerror(errno)); } } } else { try_ashmem: err = alloc_ashmem_buffer(size, (unsigned int)pHandle, &base, &offset, &fd); if (err >= 0) { lockState |= private_handle_t::LOCK_STATE_MAPPED; flags |= private_handle_t::PRIV_FLAGS_USES_ASHMEM; } else { LOGE("Ashmem fallback failed"); } } if (err == 0) { private_handle_t* hnd = new private_handle_t(fd, size, flags, bufferType, format, width, height); hnd->offset = offset; hnd->base = int(base)+offset; hnd->lockState = lockState; *pHandle = hnd; } LOGE_IF(err, "gralloc failed err=%s", strerror(-err)); return err; }