From d74d6633746470095387bfd3ec9138ae9a33d6c0 Mon Sep 17 00:00:00 2001 From: Naomi Luis Date: Tue, 5 Jul 2011 15:48:18 -0700 Subject: [PATCH] libgralloc-qsd8k: Fallback to ashmem in case of pmem failure Add a fallback mechanism to allocate memory from ashmem if pmem allocation fails. Do not fallback in the following cases: - MDP composition is being used. - Client has explicitly requested that the memory be allocated from pmem. - Buffer will not be sent to the overlay. Change-Id: Ic690af48f81914cb4c9a102cb386356797451141 --- libgralloc-qsd8k/gpu.cpp | 54 ++++++++++++++++++++++++++++++--- libgralloc-qsd8k/gpu.h | 2 ++ libgralloc-qsd8k/gralloc_priv.h | 8 +++++ 3 files changed, 59 insertions(+), 5 deletions(-) diff --git a/libgralloc-qsd8k/gpu.cpp b/libgralloc-qsd8k/gpu.cpp index d0d4fa4..cca91b1 100755 --- a/libgralloc-qsd8k/gpu.cpp +++ b/libgralloc-qsd8k/gpu.cpp @@ -20,6 +20,8 @@ #include +#include + #include "gr.h" #include "gpu.h" @@ -37,6 +39,28 @@ gpu_context_t::gpu_context_t(Deps& deps, PmemAllocator& pmemAllocator, // Zero out the alloc_device_t memset(static_cast(this), 0, sizeof(alloc_device_t)); + char property[PROPERTY_VALUE_MAX]; + if (property_get("debug.sf.hw", property, NULL) > 0) { + if(atoi(property) == 0) { + //debug.sf.hw = 0 + compositionType = CPU_COMPOSITION; + } else { //debug.sf.hw = 1 + // Get the composition type + property_get("debug.composition.type", property, NULL); + if (property == NULL) { + compositionType = GPU_COMPOSITION; + } else if ((strncmp(property, "mdp", 3)) == 0) { + compositionType = MDP_COMPOSITION; + } else if ((strncmp(property, "c2d", 3)) == 0) { + compositionType = C2D_COMPOSITION; + } else { + compositionType = GPU_COMPOSITION; + } + } + } else { //debug.sf.hw is not set. Use cpu composition + compositionType = CPU_COMPOSITION; + } + // Initialize the procs common.tag = HARDWARE_DEVICE_TAG; common.version = 0; @@ -181,6 +205,17 @@ int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage, buffer_handle_t* 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)) { @@ -218,11 +253,18 @@ int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage, buffer_handle_t* err = pma->alloc_pmem_buffer(size, usage, &base, &offset, &fd, format); if (err < 0) { - if (((usage & GRALLOC_USAGE_HW_MASK) == 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)); @@ -230,10 +272,12 @@ int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage, buffer_handle_t* } } else { try_ashmem: - fd = deps.ashmem_create_region("gralloc-buffer", size); - if (fd < 0) { - LOGE("couldn't create ashmem (%s)", strerror(errno)); - err = -errno; + 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"); } } diff --git a/libgralloc-qsd8k/gpu.h b/libgralloc-qsd8k/gpu.h index dc0f96c..3ef57d3 100755 --- a/libgralloc-qsd8k/gpu.h +++ b/libgralloc-qsd8k/gpu.h @@ -68,12 +68,14 @@ class gpu_context_t : public alloc_device_t { static int gralloc_alloc_size(alloc_device_t* dev, int w, int h, int format, int usage, buffer_handle_t* pHandle, int* pStride, int bufferSize); static int gralloc_close(struct hw_device_t *dev); + int get_composition_type() const { return compositionType; } private: Deps& deps; PmemAllocator& pmemAllocator; PmemAllocator& pmemAdspAllocator; + int compositionType; int alloc_ashmem_buffer(size_t size, unsigned int postfix, void** pBase, int* pOffset, int* pFd); void getGrallocInformationFromFormat(int inputFormat, int *colorFormat, int *bufferType); diff --git a/libgralloc-qsd8k/gralloc_priv.h b/libgralloc-qsd8k/gralloc_priv.h index 6804c41..c6780ef 100755 --- a/libgralloc-qsd8k/gralloc_priv.h +++ b/libgralloc-qsd8k/gralloc_priv.h @@ -39,6 +39,14 @@ enum { /* gralloc usage bit indicating a pmem_adsp allocation should be used */ GRALLOC_USAGE_PRIVATE_PMEM_ADSP = GRALLOC_USAGE_PRIVATE_0, GRALLOC_USAGE_PRIVATE_PMEM_SMIPOOL = GRALLOC_USAGE_PRIVATE_1, + GRALLOC_USAGE_PRIVATE_PMEM = GRALLOC_USAGE_PRIVATE_2, +}; + +enum { + GPU_COMPOSITION, + C2D_COMPOSITION, + MDP_COMPOSITION, + CPU_COMPOSITION, }; /* numbers of max buffers for page flipping */