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);