From c2e6b1f62eb4c0f02d65582336cc904e996794cd Mon Sep 17 00:00:00 2001 From: Naseer Ahmed Date: Wed, 7 Dec 2011 10:51:40 +0530 Subject: [PATCH] display: Use bypass only for contiguous memory Since composition bypass uses MDP overlays, which need physically contiguous memory, we cannot use bypass in cases where the buffers are using ashmem or other virtual memory. Hence, avoid bypass in such cases. Change-Id: I5c6d20e68e15719295373a1b0f3b930536336c43 --- libgralloc/alloc_controller.cpp | 19 +++++++++++++++---- libgralloc/gralloc_priv.h | 1 + libhwcomposer/hwcomposer.cpp | 24 ++++++++++++++++++++++-- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp index b7ec509..a549766 100644 --- a/libgralloc/alloc_controller.cpp +++ b/libgralloc/alloc_controller.cpp @@ -88,6 +88,7 @@ int IonController::allocate(alloc_data& data, int usage, { int ionFlags = 0; int ret; + bool noncontig = false; //System heap cannot be uncached if (usage & GRALLOC_USAGE_PRIVATE_UNCACHED && @@ -105,8 +106,10 @@ int IonController::allocate(alloc_data& data, int usage, if(usage & GRALLOC_USAGE_PRIVATE_EBI_HEAP) ionFlags |= 1 << ION_HEAP_EBI_ID; - if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP) + if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP) { ionFlags |= 1 << ION_HEAP_SYSTEM_ID; + noncontig = true; + } // if no flags are set, default to // EBI heap, so that bypass can work @@ -125,11 +128,15 @@ int IonController::allocate(alloc_data& data, int usage, { LOGW("Falling back to system heap"); data.flags = 1 << ION_HEAP_SYSTEM_ID; + noncontig = true; ret = mIonAlloc->alloc_buffer(data); } - if(ret >= 0 ) + if(ret >= 0 ) { data.allocType = private_handle_t::PRIV_FLAGS_USES_ION; + if(noncontig) + data.allocType |= private_handle_t::PRIV_FLAGS_NONCONTIGUOUS_MEM; + } return ret; } @@ -252,8 +259,10 @@ int PmemAshmemController::allocate(alloc_data& data, int usage, if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP) { ret = mAshmemAlloc->alloc_buffer(data); - if(ret >= 0) + if(ret >= 0) { data.allocType = private_handle_t::PRIV_FLAGS_USES_ASHMEM; + data.allocType |= private_handle_t::PRIV_FLAGS_NONCONTIGUOUS_MEM; + } return ret; } @@ -269,8 +278,10 @@ int PmemAshmemController::allocate(alloc_data& data, int usage, } else if(ret < 0 && canFallback(compositionType, usage, false)) { LOGW("Falling back to ashmem"); ret = mAshmemAlloc->alloc_buffer(data); - if(ret >= 0) + if(ret >= 0) { data.allocType = private_handle_t::PRIV_FLAGS_USES_ASHMEM; + data.allocType |= private_handle_t::PRIV_FLAGS_NONCONTIGUOUS_MEM; + } } return ret; diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h index 0e45e4a..6f109a1 100644 --- a/libgralloc/gralloc_priv.h +++ b/libgralloc/gralloc_priv.h @@ -284,6 +284,7 @@ struct private_handle_t { PRIV_FLAGS_NEEDS_FLUSH = 0x00000020, PRIV_FLAGS_DO_NOT_FLUSH = 0x00000040, PRIV_FLAGS_SW_LOCK = 0x00000080, + PRIV_FLAGS_NONCONTIGUOUS_MEM = 0x00000100, }; // file-descriptors diff --git a/libhwcomposer/hwcomposer.cpp b/libhwcomposer/hwcomposer.cpp index 46962af..6905453 100755 --- a/libhwcomposer/hwcomposer.cpp +++ b/libhwcomposer/hwcomposer.cpp @@ -546,9 +546,26 @@ static bool isDisjoint(const hwc_layer_list_t* list) { return true; } +static bool usesContiguousMemory(const hwc_layer_list_t* list) { + for(int i = 0; i < list->numHwLayers; i++) { + const private_handle_t *hnd = + reinterpret_cast(list->hwLayers[i].handle); + if(hnd != NULL && (hnd->flags & + private_handle_t::PRIV_FLAGS_NONCONTIGUOUS_MEM + )) { + // Bypass cannot work for non contiguous buffers + return false; + } + } + return true; +} + /* - * Checks if doing comp. bypass is possible. If video is not on and there - * are 2 layers then its doable. + * Checks if doing comp. bypass is possible. + * It is possible if + * 1. If video is not on + * 2. There are 2 layers + * 3. The memory type is contiguous */ inline static bool isBypassDoable(hwc_composer_device_t *dev, const int yuvCount, const hwc_layer_list_t* list) { @@ -559,6 +576,9 @@ inline static bool isBypassDoable(hwc_composer_device_t *dev, const int yuvCount if(hwcModule->isBypassEnabled == false) { return false; } + // Check if memory type is contiguous + if(!usesContiguousMemory(list)) + return false; //Disable bypass during animation if(UNLIKELY(ctx->animCount)) { --(ctx->animCount);