Merge "hwc: Avoid redoing GPU comp under certain conditions"
diff --git a/common.mk b/common.mk
index 768696a..464f296 100644
--- a/common.mk
+++ b/common.mk
@@ -27,7 +27,6 @@
ifeq ($(call is-board-platform-in-list, $(MSM_VIDC_TARGET_LIST)), true)
common_flags += -DVENUS_COLOR_FORMAT
- common_flags += -DMDSS_TARGET
endif
common_deps :=
diff --git a/displayengine/include/core/display_interface.h b/displayengine/include/core/display_interface.h
index c054fae..9aae0a1 100644
--- a/displayengine/include/core/display_interface.h
+++ b/displayengine/include/core/display_interface.h
@@ -314,6 +314,14 @@
*/
virtual void SetIdleTimeoutMs(uint32_t timeout_ms) = 0;
+ /*! @brief Method to set maximum number of mixer stages for each display.
+
+ @param[in] max_mixer_stages maximum number of mixer stages.
+
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages) = 0;
+
protected:
virtual ~DisplayInterface() { }
};
diff --git a/displayengine/libs/core/comp_manager.cpp b/displayengine/libs/core/comp_manager.cpp
index 06028a2..cc58465 100644
--- a/displayengine/libs/core/comp_manager.cpp
+++ b/displayengine/libs/core/comp_manager.cpp
@@ -318,6 +318,20 @@
return false;
}
+DisplayError CompManager::SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages) {
+ SCOPE_LOCK(locker_);
+
+ DisplayError error = kErrorNone;
+ DisplayCompositionContext *display_comp_ctx =
+ reinterpret_cast<DisplayCompositionContext *>(display_ctx);
+
+ if (display_comp_ctx) {
+ error = res_mgr_.SetMaxMixerStages(display_comp_ctx->display_resource_ctx, max_mixer_stages);
+ }
+
+ return error;
+}
+
void CompManager::AppendDump(char *buffer, uint32_t length) {
SCOPE_LOCK(locker_);
}
diff --git a/displayengine/libs/core/comp_manager.h b/displayengine/libs/core/comp_manager.h
index 24a0fff..0a21ee0 100644
--- a/displayengine/libs/core/comp_manager.h
+++ b/displayengine/libs/core/comp_manager.h
@@ -48,6 +48,7 @@
DisplayError PostCommit(Handle display_ctx, HWLayers *hw_layers);
void Purge(Handle display_ctx);
bool ProcessIdleTimeout(Handle display_ctx);
+ DisplayError SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages);
// DumpImpl method
virtual void AppendDump(char *buffer, uint32_t length);
diff --git a/displayengine/libs/core/display_base.cpp b/displayengine/libs/core/display_base.cpp
index d403450..8bfc6dd 100644
--- a/displayengine/libs/core/display_base.cpp
+++ b/displayengine/libs/core/display_base.cpp
@@ -409,6 +409,18 @@
hw_intf_->SetIdleTimeoutMs(hw_device_, timeout_ms);
}
+DisplayError DisplayBase::SetMaxMixerStages(uint32_t max_mixer_stages) {
+ SCOPE_LOCK(locker_);
+
+ DisplayError error = kErrorNone;
+
+ if (comp_manager_) {
+ error = comp_manager_->SetMaxMixerStages(display_comp_ctx_, max_mixer_stages);
+ }
+
+ return error;
+}
+
DisplayError DisplayBase::VSync(int64_t timestamp) {
if (vsync_enable_) {
DisplayEventVSync vsync;
diff --git a/displayengine/libs/core/display_base.h b/displayengine/libs/core/display_base.h
index d2b67e3..10e11f8 100644
--- a/displayengine/libs/core/display_base.h
+++ b/displayengine/libs/core/display_base.h
@@ -60,6 +60,7 @@
virtual DisplayError SetActiveConfig(uint32_t index);
virtual DisplayError SetVSyncState(bool enable);
virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
+ virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages);
// Implement the HWEventHandlers
virtual DisplayError VSync(int64_t timestamp);
diff --git a/displayengine/libs/core/hw_interface.h b/displayengine/libs/core/hw_interface.h
index b92846f..0d1634c 100644
--- a/displayengine/libs/core/hw_interface.h
+++ b/displayengine/libs/core/hw_interface.h
@@ -141,8 +141,8 @@
struct HWLayerConfig {
bool use_non_dma_pipe; // set by client
- HWPipeInfo left_pipe; // pipe for left side of the buffer
- HWPipeInfo right_pipe; // pipe for right side of the buffer
+ HWPipeInfo left_pipe; // pipe for left side of output
+ HWPipeInfo right_pipe; // pipe for right side of output
uint32_t num_rotate; // number of rotate
HWRotateInfo rotates[kMaxRotatePerLayer]; // rotation for the buffer
diff --git a/displayengine/libs/core/res_config.cpp b/displayengine/libs/core/res_config.cpp
index 27a4e41..037bf58 100644
--- a/displayengine/libs/core/res_config.cpp
+++ b/displayengine/libs/core/res_config.cpp
@@ -325,8 +325,9 @@
layer_config->right_pipe.z_order = z_order;
}
z_order++;
- if (z_order >= hw_res_info_.num_blending_stages) {
- DLOGV_IF(kTagResources, "z_order is over the limit: z_order = %d", z_order);
+ if (z_order > display_resource_ctx->max_mixer_stages) {
+ DLOGV_IF(kTagResources, "z_order is over the limit of max_mixer_stages = %d",
+ display_resource_ctx->max_mixer_stages);
return kErrorResources;
}
}
@@ -560,46 +561,33 @@
dst_width = ROUND_UP_ALIGN_DOWN(dst_width * src_width / src_width_ori, 1);
if (flip_horizontal) {
- src_left->top = src_rect.top;
- src_left->left = src_rect.left;
- src_left->right = src_rect.left + src_width;
- src_left->bottom = src_rect.bottom;
+ src_left->left = src_rect.right - src_width;
+ src_left->right = src_rect.right;
- dst_left->top = dst_rect.top;
- dst_left->left = dst_rect.left + dst_width;
- dst_left->right = dst_rect.right;
- dst_left->bottom = dst_rect.bottom;
-
- src_right->top = src_rect.top;
- src_right->left = src_left->right;
- src_right->right = src_rect.right;
- src_right->bottom = src_rect.bottom;
-
- dst_right->top = dst_rect.top;
- dst_right->left = dst_rect.left;
- dst_right->right = dst_left->left;
- dst_right->bottom = dst_rect.bottom;
+ src_right->left = src_rect.left;
+ src_right->right = src_left->left;
} else {
- src_left->top = src_rect.top;
src_left->left = src_rect.left;
src_left->right = src_rect.left + src_width;
- src_left->bottom = src_rect.bottom;
- dst_left->top = dst_rect.top;
- dst_left->left = dst_rect.left;
- dst_left->right = dst_rect.left + dst_width;
- dst_left->bottom = dst_rect.bottom;
-
- src_right->top = src_rect.top;
src_right->left = src_left->right;
src_right->right = src_rect.right;
- src_right->bottom = src_rect.bottom;
-
- dst_right->top = dst_rect.top;
- dst_right->left = dst_left->right;
- dst_right->right = dst_rect.right;
- dst_right->bottom = dst_rect.bottom;
}
+
+ src_left->top = src_rect.top;
+ src_left->bottom = src_rect.bottom;
+ dst_left->top = dst_rect.top;
+ dst_left->bottom = dst_rect.bottom;
+
+ src_right->top = src_rect.top;
+ src_right->bottom = src_rect.bottom;
+ dst_right->top = dst_rect.top;
+ dst_right->bottom = dst_rect.bottom;
+
+ dst_left->left = dst_rect.left;
+ dst_left->right = dst_rect.left + dst_width;
+ dst_right->left = dst_left->right;
+ dst_right->right = dst_rect.right;
}
DisplayError ResManager::AlignPipeConfig(const Layer &layer, const LayerTransform &transform,
@@ -625,12 +613,12 @@
if (right_pipe->valid) {
// Make sure the left and right ROI are conjunct
- right_pipe->src_roi.left = left_pipe->src_roi.right;
if (transform.flip_horizontal) {
- right_pipe->dst_roi.right = left_pipe->dst_roi.left;
+ left_pipe->src_roi.left = right_pipe->src_roi.right;
} else {
- right_pipe->dst_roi.left = left_pipe->dst_roi.right;
+ right_pipe->src_roi.left = left_pipe->src_roi.right;
}
+ right_pipe->dst_roi.left = left_pipe->dst_roi.right;
}
error = ValidateScaling(layer, left_pipe->src_roi, left_pipe->dst_roi, NULL);
if (error != kErrorNone) {
diff --git a/displayengine/libs/core/res_manager.cpp b/displayengine/libs/core/res_manager.cpp
index 14cf11f..238dfa8 100644
--- a/displayengine/libs/core/res_manager.cpp
+++ b/displayengine/libs/core/res_manager.cpp
@@ -186,6 +186,8 @@
display_resource_ctx->display_attributes.split_left =
display_resource_ctx->display_attributes.x_pixels;
+ display_resource_ctx->max_mixer_stages = hw_res_info_.num_blending_stages;
+
*display_ctx = display_resource_ctx;
return error;
}
@@ -271,8 +273,15 @@
DLOGV_IF(kTagResources, "==== Resource reserving start: hw_block = %d ====", hw_block_id);
- if (layer_info.count > num_pipe_ || layer_info.count >= hw_res_info_.num_blending_stages) {
- DLOGV_IF(kTagResources, "layer count is over the limit: layer count = %d", layer_info.count);
+ if (layer_info.count > num_pipe_) {
+ DLOGV_IF(kTagResources, "layer count exceeds pipe limit of %d, layer count %d", num_pipe_,
+ layer_info.count);
+ return kErrorResources;
+ }
+
+ if (layer_info.count > display_resource_ctx->max_mixer_stages) {
+ DLOGV_IF(kTagResources, "layer count exceeds max mixer stage limit of %d, layer count %d",
+ display_resource_ctx->max_mixer_stages, layer_info.count);
return kErrorResources;
}
@@ -811,6 +820,26 @@
DLOGV_IF(kTagResources, "display id = %d", display_resource_ctx->hw_block_id);
}
+DisplayError ResManager::SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages) {
+ SCOPE_LOCK(locker_);
+
+ if (max_mixer_stages < 1 || max_mixer_stages > hw_res_info_.num_blending_stages) {
+ DLOGE("Max mixer stages = %d and that should be in between 1 to %d", max_mixer_stages,
+ hw_res_info_.num_blending_stages);
+
+ return kErrorParameters;
+ }
+
+ DisplayResourceContext *display_resource_ctx =
+ reinterpret_cast<DisplayResourceContext *>(display_ctx);
+
+ if (display_resource_ctx) {
+ display_resource_ctx->max_mixer_stages = max_mixer_stages;
+ }
+
+ return kErrorNone;
+}
+
uint32_t ResManager::GetMdssPipeId(PipeType type, uint32_t index) {
uint32_t mdss_id = kPipeIdMax;
switch (type) {
diff --git a/displayengine/libs/core/res_manager.h b/displayengine/libs/core/res_manager.h
index d21984e..8cf08f5 100644
--- a/displayengine/libs/core/res_manager.h
+++ b/displayengine/libs/core/res_manager.h
@@ -49,6 +49,7 @@
DisplayError PostPrepare(Handle display_ctx, HWLayers *hw_layers);
DisplayError PostCommit(Handle display_ctx, HWLayers *hw_layers);
void Purge(Handle display_ctx);
+ DisplayError SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages);
// DumpImpl method
virtual void AppendDump(char *buffer, uint32_t length);
@@ -122,9 +123,10 @@
int32_t session_id; // applicable for virtual display sessions only
uint32_t rotate_count;
bool frame_start;
+ uint32_t max_mixer_stages;
DisplayResourceContext() : hw_block_id(kHWBlockMax), frame_count(0), session_id(-1),
- rotate_count(0), frame_start(false) { }
+ rotate_count(0), frame_start(false), max_mixer_stages(0) { }
~DisplayResourceContext() {
if (buffer_manager) {
diff --git a/displayengine/libs/hwc/hwc_display.cpp b/displayengine/libs/hwc/hwc_display.cpp
index dd1beac..1be682d 100644
--- a/displayengine/libs/hwc/hwc_display.cpp
+++ b/displayengine/libs/hwc/hwc_display.cpp
@@ -600,6 +600,16 @@
}
}
+DisplayError HWCDisplay::SetMaxMixerStages(uint32_t max_mixer_stages) {
+ DisplayError error = kErrorNone;
+
+ if (display_intf_) {
+ error = display_intf_->SetMaxMixerStages(max_mixer_stages);
+ }
+
+ return error;
+}
+
LayerBufferFormat HWCDisplay::GetSDEFormat(const int32_t &source, const int flags) {
LayerBufferFormat format = kFormatInvalid;
if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
diff --git a/displayengine/libs/hwc/hwc_display.h b/displayengine/libs/hwc/hwc_display.h
index a574d6b..8feddf6 100644
--- a/displayengine/libs/hwc/hwc_display.h
+++ b/displayengine/libs/hwc/hwc_display.h
@@ -45,6 +45,7 @@
virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
virtual int SetActiveConfig(hwc_display_contents_1_t *content_list);
virtual void SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type);
+ virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages);
protected:
// Maximum number of layers supported by display engine.
diff --git a/displayengine/libs/hwc/hwc_session.cpp b/displayengine/libs/hwc/hwc_session.cpp
index 40eae99..b6d0c18 100644
--- a/displayengine/libs/hwc/hwc_session.cpp
+++ b/displayengine/libs/hwc/hwc_session.cpp
@@ -562,6 +562,8 @@
android::Parcel */*output_parcel*/) {
SEQUENCE_WAIT_SCOPE_LOCK(locker_);
+ android::status_t status = 0;
+
switch (command) {
case qService::IQService::DYNAMIC_DEBUG:
DynamicDebug(input_parcel);
@@ -573,7 +575,7 @@
case qService::IQService::SET_IDLE_TIMEOUT:
if (display_primary_) {
- uint32_t timeout = (uint32_t)input_parcel->readInt32();
+ uint32_t timeout = UINT32(input_parcel->readInt32());
display_primary_->SetIdleTimeoutMs(timeout);
}
break;
@@ -582,11 +584,50 @@
SetFrameDumpConfig(input_parcel);
break;
+ case qService::IQService::SET_MAX_PIPES_PER_MIXER:
+ status = SetMaxMixerStages(input_parcel);
+ break;
+
default:
DLOGW("QService command = %d is not supported", command);
return -EINVAL;
}
+ return status;
+}
+
+android::status_t HWCSession::SetMaxMixerStages(const android::Parcel *input_parcel) {
+ DisplayError error = kErrorNone;
+ uint32_t bit_mask_display_type = UINT32(input_parcel->readInt32());
+ uint32_t max_mixer_stages = UINT32(input_parcel->readInt32());
+
+ if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_PRIMARY)) {
+ if (display_primary_) {
+ error = display_primary_->SetMaxMixerStages(max_mixer_stages);
+ if (error != kErrorNone) {
+ return -EINVAL;
+ }
+ }
+ }
+
+ if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_EXTERNAL)) {
+ if (display_external_) {
+ error = display_external_->SetMaxMixerStages(max_mixer_stages);
+ if (error != kErrorNone) {
+ return -EINVAL;
+ }
+ }
+ }
+
+ if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_VIRTUAL)) {
+ if (display_virtual_) {
+ error = display_virtual_->SetMaxMixerStages(max_mixer_stages);
+ if (error != kErrorNone) {
+ return -EINVAL;
+ }
+ }
+ }
+
return 0;
}
@@ -595,19 +636,19 @@
uint32_t bit_mask_display_type = UINT32(input_parcel->readInt32());
uint32_t bit_mask_layer_type = UINT32(input_parcel->readInt32());
- if (bit_mask_display_type & (1 << qService::IQService::DUMP_PRIMARY_DISPLAY)) {
+ if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_PRIMARY)) {
if (display_primary_) {
display_primary_->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
}
}
- if (bit_mask_display_type & (1 << qService::IQService::DUMP_HDMI_DISPLAY)) {
+ if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_EXTERNAL)) {
if (display_external_) {
display_external_->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
}
}
- if (bit_mask_display_type & (1 << qService::IQService::DUMP_VIRTUAL_DISPLAY)) {
+ if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_VIRTUAL)) {
if (display_virtual_) {
display_virtual_->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
}
diff --git a/displayengine/libs/hwc/hwc_session.h b/displayengine/libs/hwc/hwc_session.h
index 4b8c8ce..1608ce5 100644
--- a/displayengine/libs/hwc/hwc_session.h
+++ b/displayengine/libs/hwc/hwc_session.h
@@ -85,6 +85,7 @@
android::Parcel *output_parcel);
void DynamicDebug(const android::Parcel *input_parcel);
void SetFrameDumpConfig(const android::Parcel *input_parcel);
+ android::status_t SetMaxMixerStages(const android::Parcel *input_parcel);
static Locker locker_;
CoreInterface *core_intf_;
diff --git a/hdmi_cec/qhdmi_cec.cpp b/hdmi_cec/qhdmi_cec.cpp
index 6e46254..1bc7df6 100644
--- a/hdmi_cec/qhdmi_cec.cpp
+++ b/hdmi_cec/qhdmi_cec.cpp
@@ -369,11 +369,11 @@
}
static void cec_set_audio_return_channel(const struct hdmi_cec_device* dev,
- int flag)
+ int port, int flag)
{
cec_context_t* ctx = (cec_context_t*)(dev);
ctx->arc_enabled = flag ? true : false;
- ALOGD_IF(DEBUG, "%s: ARC flag: %d", __FUNCTION__, flag);
+ ALOGD_IF(DEBUG, "%s: ARC flag: %d port: %d", __FUNCTION__, flag, port);
}
static int cec_is_connected(const struct hdmi_cec_device* dev, int port_id)
diff --git a/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp
index 3807f33..cc13fec 100644
--- a/libcopybit/copybit_c2d.cpp
+++ b/libcopybit/copybit_c2d.cpp
@@ -350,12 +350,7 @@
if(!handle)
return 0;
- if (handle->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM |
- private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP))
- memtype = KGSL_USER_MEM_TYPE_PMEM;
- else if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ASHMEM)
- memtype = KGSL_USER_MEM_TYPE_ASHMEM;
- else if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ION)
+ if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ION)
memtype = KGSL_USER_MEM_TYPE_ION;
else {
ALOGE("Invalid handle flags: 0x%x", handle->flags);
@@ -1005,7 +1000,7 @@
data.size = get_size(info);
data.align = getpagesize();
data.uncached = true;
- int allocFlags = GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP;
+ int allocFlags = 0;
if (sAlloc == 0) {
sAlloc = gralloc::IAllocController::getInstance();
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 508564a..1d0a40a 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -58,27 +58,6 @@
static unsigned int getUBwcSize(int, int, int, const int, const int);
//Common functions
-static bool canFallback(int usage, bool triedSystem)
-{
- // Fallback to system heap when alloc fails unless
- // 1. Composition type is MDP
- // 2. Alloc from system heap was already tried
- // 3. The heap type is requsted explicitly
- // 4. The heap type is protected
- // 5. The buffer is meant for external display only
-
- if(QCCompositionType::getInstance().getCompositionType() &
- COMPOSITION_TYPE_MDP)
- return false;
- if(triedSystem)
- return false;
- if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PROTECTED))
- return false;
- if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY))
- return false;
- //Return true by default
- return true;
-}
/* The default policy is to return cached buffers unless the client explicity
* sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely
@@ -344,20 +323,15 @@
int IonController::allocate(alloc_data& data, int usage)
{
int ionFlags = 0;
+ int ionHeapId = 0;
int ret;
data.uncached = useUncached(usage);
data.allocType = 0;
- if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP)
- ionFlags |= ION_HEAP(ION_SYSTEM_HEAP_ID);
-
- if(usage & GRALLOC_USAGE_PRIVATE_IOMMU_HEAP)
- ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
-
if(usage & GRALLOC_USAGE_PROTECTED) {
if (usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
- ionFlags |= ION_HEAP(ION_CP_MM_HEAP_ID);
+ ionHeapId |= ION_HEAP(ION_CP_MM_HEAP_ID);
ionFlags |= ION_SECURE;
#ifdef ION_FLAG_ALLOW_NON_CONTIG
if (!(usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY)) {
@@ -366,8 +340,8 @@
#endif
} else {
// for targets/OEMs which do not need HW level protection
- // do not set ion secure flag & MM heap. Fallback to IOMMU heap.
- ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
+ // do not set ion secure flag & MM heap. Fallback to system heap.
+ ionHeapId |= ION_HEAP(ION_SYSTEM_HEAP_ID);
data.allocType |= private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER;
}
} else if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
@@ -375,40 +349,33 @@
//If it is used for non secure cases, fallback to IOMMU heap
ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \
cannot be used as an insecure heap!\
- trying to use IOMMU instead !!");
- ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
+ trying to use system heap instead !!");
+ ionHeapId |= ION_HEAP(ION_SYSTEM_HEAP_ID);
}
if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
- ionFlags |= ION_HEAP(ION_CAMERA_HEAP_ID);
+ ionHeapId |= ION_HEAP(ION_CAMERA_HEAP_ID);
if(usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP)
- ionFlags |= ION_HEAP(ION_ADSP_HEAP_ID);
+ ionHeapId |= ION_HEAP(ION_ADSP_HEAP_ID);
if(ionFlags & ION_SECURE)
data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
- // if no flags are set, default to
- // SF + IOMMU heaps, so that bypass can work
- // we can fall back to system heap if
- // we run out.
- if(!ionFlags)
- ionFlags = ION_HEAP(ION_SF_HEAP_ID) | ION_HEAP(ION_IOMMU_HEAP_ID);
+ // if no ion heap flags are set, default to system heap
+ if(!ionHeapId)
+ ionHeapId = ION_HEAP(ION_SYSTEM_HEAP_ID);
+ //At this point we should have the right heap set, there is no fallback
data.flags = ionFlags;
+ data.heapId = ionHeapId;
ret = mIonAlloc->alloc_buffer(data);
- // Fallback
- if(ret < 0 && canFallback(usage,
- (ionFlags & ION_SYSTEM_HEAP_ID)))
- {
- ALOGW("Falling back to system heap");
- data.flags = ION_HEAP(ION_SYSTEM_HEAP_ID);
- ret = mIonAlloc->alloc_buffer(data);
- }
-
if(ret >= 0 ) {
data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION;
+ } else {
+ ALOGE("%s: Failed to allocate buffer - heap: 0x%x flags: 0x%x",
+ __FUNCTION__, ionHeapId, ionFlags);
}
return ret;
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index df7be41..9be93d6 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -65,13 +65,11 @@
data.align = getpagesize();
/* force 1MB alignment selectively for secure buffers, MDP5 onwards */
-#ifdef MDSS_TARGET
if ((usage & GRALLOC_USAGE_PROTECTED) &&
(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP)) {
data.align = ALIGN((int) data.align, SZ_1M);
size = ALIGN(size, data.align);
}
-#endif
data.size = size;
data.pHandle = (uintptr_t) pHandle;
@@ -86,7 +84,7 @@
eData.size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
eData.pHandle = data.pHandle;
eData.align = getpagesize();
- int eDataUsage = GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP;
+ int eDataUsage = 0;
int eDataErr = mAllocCtrl->allocate(eData, eDataUsage);
ALOGE_IF(eDataErr, "gralloc failed for eDataErr=%s",
strerror(-eDataErr));
@@ -99,10 +97,6 @@
flags |= private_handle_t::PRIV_FLAGS_ITU_R_601;
if (bufferType == BUFFER_TYPE_VIDEO) {
if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
-#ifndef MDSS_TARGET
- colorSpace = ITU_R_601_FR;
- flags |= private_handle_t::PRIV_FLAGS_ITU_R_601_FR;
-#else
// Per the camera spec ITU 709 format should be set only for
// video encoding.
// It should be set to ITU 601 full range format for any other
@@ -117,7 +111,6 @@
colorSpace = ITU_R_601_FR;
}
}
-#endif
}
}
@@ -207,10 +200,7 @@
{
private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
- // we don't support framebuffer allocations with graphics heap flags
- if (usage & GRALLOC_HEAP_MASK) {
- return -EINVAL;
- }
+ // This allocation will only happen when gralloc is in fb mode
if (m->framebuffer == NULL) {
ALOGE("%s: Invalid framebuffer", __FUNCTION__);
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index f973b76..676c3bc 100755
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -34,9 +34,11 @@
(~(PAGE_SIZE-1)) )
/* Gralloc usage bits indicating the type of allocation that should be used */
-/* SYSTEM heap comes from kernel vmalloc, can never be uncached,
+/* SYSTEM heap comes from kernel vmalloc (ION_SYSTEM_HEAP_ID)
+ * is cached by default and
* is not secured */
-#define GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP GRALLOC_USAGE_PRIVATE_0
+
+/* GRALLOC_USAGE_PRIVATE_0 is unused */
/* Non linear, Universal Bandwidth Compression */
#define GRALLOC_USAGE_PRIVATE_ALLOC_UBWC GRALLOC_USAGE_PRIVATE_1
@@ -84,14 +86,6 @@
#define GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO 8
#define GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG 9
-#define GRALLOC_HEAP_MASK (GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP |\
- GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |\
- GRALLOC_USAGE_PRIVATE_MM_HEAP |\
- GRALLOC_USAGE_PRIVATE_ADSP_HEAP)
-
-#define INTERLACE_MASK 0x80
-/*****************************************************************************/
-
/* OEM specific HAL formats */
#define HAL_PIXEL_FORMAT_RGBA_5551 6
@@ -165,8 +159,6 @@
BUFFER_TYPE_VIDEO
};
-/*****************************************************************************/
-
#ifdef __cplusplus
struct private_handle_t : public native_handle {
#else
@@ -175,8 +167,6 @@
#endif
enum {
PRIV_FLAGS_FRAMEBUFFER = 0x00000001,
- PRIV_FLAGS_USES_PMEM = 0x00000002,
- PRIV_FLAGS_USES_PMEM_ADSP = 0x00000004,
PRIV_FLAGS_USES_ION = 0x00000008,
PRIV_FLAGS_USES_ASHMEM = 0x00000010,
PRIV_FLAGS_NEEDS_FLUSH = 0x00000020,
@@ -184,10 +174,6 @@
PRIV_FLAGS_NONCONTIGUOUS_MEM = 0x00000100,
PRIV_FLAGS_CACHED = 0x00000200,
PRIV_FLAGS_SECURE_BUFFER = 0x00000400,
- // For explicit synchronization
- PRIV_FLAGS_UNSYNCHRONIZED = 0x00000800,
- // Not mapped in userspace
- PRIV_FLAGS_NOT_MAPPED = 0x00001000,
// Display on external only
PRIV_FLAGS_EXTERNAL_ONLY = 0x00002000,
// Set by HWC for protected non secure buffers
@@ -252,10 +238,6 @@
magic = 0;
}
- bool usesPhysicallyContiguousMemory() {
- return (flags & PRIV_FLAGS_USES_PMEM) != 0;
- }
-
static int validate(const native_handle* h) {
const private_handle_t* hnd = (const private_handle_t*)h;
if (!h || h->version != sizeof(native_handle) ||
diff --git a/libgralloc/ionalloc.cpp b/libgralloc/ionalloc.cpp
index 91a930c..96e0e3e 100644
--- a/libgralloc/ionalloc.cpp
+++ b/libgralloc/ionalloc.cpp
@@ -76,19 +76,9 @@
ionAllocData.len = data.size;
ionAllocData.align = data.align;
- ionAllocData.heap_id_mask = data.flags & ~ION_SECURE;
-#ifdef ION_FLAG_ALLOW_NON_CONTIG
- ionAllocData.heap_id_mask &= (data.flags & ~ION_FLAG_ALLOW_NON_CONTIG);
-#endif
- ionAllocData.flags = data.uncached ? 0 : ION_FLAG_CACHED;
- // ToDo: replace usage of alloc data structure with
- // ionallocdata structure.
- if (data.flags & ION_SECURE)
- ionAllocData.flags |= ION_SECURE;
-#ifdef ION_FLAG_ALLOW_NON_CONTIG
- if (data.flags & ION_FLAG_ALLOW_NON_CONTIG)
- ionAllocData.flags |= ION_FLAG_ALLOW_NON_CONTIG;
-#endif
+ ionAllocData.heap_id_mask = data.heapId;
+ ionAllocData.flags = data.flags;
+ ionAllocData.flags |= data.uncached ? 0 : ION_FLAG_CACHED;
err = open_device();
if (err)
return err;
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index 5382300..8b38952 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -204,10 +204,7 @@
if (hnd->base != 0) {
// this buffer was mapped, unmap it now
- if (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM |
- private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP |
- private_handle_t::PRIV_FLAGS_USES_ASHMEM |
- private_handle_t::PRIV_FLAGS_USES_ION)) {
+ if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) {
gralloc_unmap(module, hnd);
} else {
ALOGE("terminateBuffer: unmapping a non pmem/ashmem buffer flags = 0x%x",
diff --git a/libgralloc/memalloc.h b/libgralloc/memalloc.h
index 2bc1ddf..598d983 100644
--- a/libgralloc/memalloc.h
+++ b/libgralloc/memalloc.h
@@ -49,6 +49,7 @@
uintptr_t pHandle;
bool uncached;
unsigned int flags;
+ unsigned int heapId;
int allocType;
};
diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk
index df3e464..c344045 100644
--- a/libhwcomposer/Android.mk
+++ b/libhwcomposer/Android.mk
@@ -13,11 +13,14 @@
libdl libmemalloc libqservice libsync \
libbinder libmedia
+LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdhwcomposer\"
ifeq ($(TARGET_USES_QCOM_BSP),true)
LOCAL_SHARED_LIBRARIES += libskia
+ifeq ($(GET_FRAMEBUFFER_FORMAT_FROM_HWC),true)
+ LOCAL_CFLAGS += -DGET_FRAMEBUFFER_FORMAT_FROM_HWC
+endif
endif #TARGET_USES_QCOM_BSP
-LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdhwcomposer\"
#Enable Dynamic FPS if PHASE_OFFSET is not set
ifeq ($(VSYNC_EVENT_PHASE_OFFSET_NS),)
LOCAL_CFLAGS += -DDYNAMIC_FPS
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index f3b34c3..3026d99 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -836,6 +836,9 @@
HWC_DISPLAY_DPI_X,
HWC_DISPLAY_DPI_Y,
HWC_DISPLAY_SECURE,
+#ifdef GET_FRAMEBUFFER_FORMAT_FROM_HWC
+ HWC_DISPLAY_FBFORMAT,
+#endif
HWC_DISPLAY_NO_ATTRIBUTE,
};
@@ -886,6 +889,11 @@
case HWC_DISPLAY_SECURE:
values[i] = (int32_t) (ctx->dpyAttr[disp].secure);
break;
+#ifdef GET_FRAMEBUFFER_FORMAT_FROM_HWC
+ case HWC_DISPLAY_FBFORMAT:
+ values[i] = ctx->dpyAttr[disp].fbformat;
+ break;
+#endif
default:
ALOGE("Unknown display attribute %d",
attributes[i]);
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 744195f..7244562 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -189,9 +189,10 @@
return -1;
}
}
- if(mFbCache.getUnchangedFbDRCount(dirtyRect) <
+ hwc_rect_t displayRect = list->hwLayers[changingLayerIndex].displayFrame;
+ if(mFbCache.getUnchangedFbDRCount(dirtyRect, displayRect) <
NUM_RENDER_BUFFERS) {
- mFbCache.insertAndUpdateFbCache(dirtyRect);
+ mFbCache.insertAndUpdateFbCache(dirtyRect, displayRect);
changingLayerIndex = -1;
}
} else {
@@ -979,7 +980,7 @@
ALOGD("%s:%d::tmp_w = %d,tmp_h = %d",__FUNCTION__,__LINE__,tmp_w,tmp_h);
- int usage = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
+ int usage = 0;
int format = fbHandle->format;
// We do not want copybit to generate alpha values from nothing
@@ -1030,6 +1031,14 @@
}
// Copybit region
hwc_region_t region = layer->visibleRegionScreen;
+ //Do not use visible regions in case of scaling
+ if (region.numRects > 1) {
+ if (needsScaling(layer)) {
+ region.numRects = 1;
+ region.rects = &layer->displayFrame;
+ }
+ }
+
region_iterator copybitRegion(region);
copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_WIDTH,
@@ -1145,8 +1154,7 @@
for (int i = 0; i < NUM_RENDER_BUFFERS; i++) {
if (mRenderBuffer[i] == NULL) {
ret = alloc_buffer(&mRenderBuffer[i],
- w, h, f,
- GRALLOC_USAGE_PRIVATE_IOMMU_HEAP);
+ w, h, f, 0);
}
if(ret < 0) {
freeRenderBuffers();
@@ -1260,19 +1268,24 @@
}
void CopyBit::FbCache::reset() {
memset(&FbdirtyRect, 0, sizeof(FbdirtyRect));
+ memset(&FbdisplayRect, 0, sizeof(FbdisplayRect));
FbIndex =0;
}
-void CopyBit::FbCache::insertAndUpdateFbCache(hwc_rect_t dirtyRect) {
+void CopyBit::FbCache::insertAndUpdateFbCache(hwc_rect_t dirtyRect,
+ hwc_rect_t displayRect) {
FbIndex = FbIndex % NUM_RENDER_BUFFERS;
FbdirtyRect[FbIndex] = dirtyRect;
+ FbdisplayRect[FbIndex] = displayRect;
FbIndex++;
}
-int CopyBit::FbCache::getUnchangedFbDRCount(hwc_rect_t dirtyRect){
+int CopyBit::FbCache::getUnchangedFbDRCount(hwc_rect_t dirtyRect,
+ hwc_rect_t displayRect){
int sameDirtyCount = 0;
for (int i = 0 ; i < NUM_RENDER_BUFFERS ; i++ ){
- if( FbdirtyRect[i] == dirtyRect)
+ if( FbdirtyRect[i] == dirtyRect &&
+ FbdisplayRect[i] == displayRect)
sameDirtyCount++;
}
return sameDirtyCount;
diff --git a/libhwcomposer/hwc_copybit.h b/libhwcomposer/hwc_copybit.h
index 4442afc..eaf015f 100644
--- a/libhwcomposer/hwc_copybit.h
+++ b/libhwcomposer/hwc_copybit.h
@@ -72,11 +72,14 @@
/* framebuffer cache*/
struct FbCache {
hwc_rect_t FbdirtyRect[NUM_RENDER_BUFFERS];
+ hwc_rect_t FbdisplayRect[NUM_RENDER_BUFFERS];
int FbIndex;
FbCache();
void reset();
- void insertAndUpdateFbCache(hwc_rect_t dirtyRect);
- int getUnchangedFbDRCount(hwc_rect_t dirtyRect);
+ void insertAndUpdateFbCache(hwc_rect_t dirtyRect,
+ hwc_rect_t displayRect);
+ int getUnchangedFbDRCount(hwc_rect_t dirtyRect,
+ hwc_rect_t displayRect);
};
// holds the copybit device
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 692ce29..74d95e7 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -54,7 +54,7 @@
yres = ctx->dpyAttr[mDpy].yresFB;
}
getBufferAttributes((int)xres, (int)yres,
- HAL_PIXEL_FORMAT_RGBA_8888,
+ ctx->dpyAttr[mDpy].fbformat,
0,
mAlignedFBWidth,
mAlignedFBHeight,
@@ -134,7 +134,7 @@
int flags = mTileEnabled ?
private_handle_t::PRIV_FLAGS_TILE_RENDERED : 0;
ovutils::Whf info(mAlignedFBWidth, mAlignedFBHeight,
- ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888, flags));
+ ovutils::getMdpFormat(ctx->dpyAttr[mDpy].fbformat, flags));
Overlay::PipeSpecs pipeSpecs;
pipeSpecs.formatClass = Overlay::FORMAT_RGB;
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index f6d8276..fb69fdd 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -1150,8 +1150,8 @@
bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
{
- if(!sEnableMixedMode) {
- //Mixed mode is disabled. No need to even try caching.
+ if(!sEnableMixedMode || !isAlphaPresentinFB(ctx, mDpy)) {
+ //Mixed mode is disabled/can't be used. No need to even try caching.
return false;
}
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 2d4363e..27243c4 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -86,6 +86,32 @@
// Std refresh rates for digital videos- 24p, 30p, 48p and 60p
uint32_t stdRefreshRates[] = { 30, 24, 48, 60 };
+static uint32_t getFBformat(fb_var_screeninfo vinfo) {
+ uint32_t fbformat = HAL_PIXEL_FORMAT_RGBA_8888;
+
+#ifdef GET_FRAMEBUFFER_FORMAT_FROM_HWC
+ // Here, we are adding the formats that are supported by both GPU and MDP.
+ // The formats that fall in this category are RGBA_8888, RGB_565, RGB_888
+ switch(vinfo.bits_per_pixel) {
+ case 16:
+ fbformat = HAL_PIXEL_FORMAT_RGB_565;
+ break;
+ case 24:
+ if ((vinfo.transp.offset == 0) && (vinfo.transp.length == 0))
+ fbformat = HAL_PIXEL_FORMAT_RGB_888;
+ break;
+ case 32:
+ if ((vinfo.red.offset == 0) && (vinfo.green.offset == 8) &&
+ (vinfo.blue.offset == 16) && (vinfo.transp.offset == 24))
+ fbformat = HAL_PIXEL_FORMAT_RGBA_8888;
+ break;
+ default:
+ fbformat = HAL_PIXEL_FORMAT_RGBA_8888;
+ }
+#endif
+ return fbformat;
+}
+
bool isValidResolution(hwc_context_t *ctx, uint32_t xres, uint32_t yres)
{
return !((xres > qdutils::MDPVersion::getInstance().getMaxPipeWidth() &&
@@ -130,6 +156,14 @@
// Initialize hdmi display attributes based on
// hdmi display class state
void updateDisplayInfo(hwc_context_t* ctx, int dpy) {
+ struct fb_var_screeninfo info;
+
+ if (ioctl(ctx->mHDMIDisplay->getFd(), FBIOGET_VSCREENINFO, &info) == -1) {
+ ALOGE("%s:Error in ioctl FBIOGET_VSCREENINFO: %s",
+ __FUNCTION__, strerror(errno));
+ }
+
+ ctx->dpyAttr[dpy].fbformat = getFBformat(info);
ctx->dpyAttr[dpy].fd = ctx->mHDMIDisplay->getFd();
ctx->dpyAttr[dpy].xres = ctx->mHDMIDisplay->getWidth();
ctx->dpyAttr[dpy].yres = ctx->mHDMIDisplay->getHeight();
@@ -238,6 +272,7 @@
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].secure = true;
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period =
(uint32_t)(1000000000l / fps);
+ ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fbformat = getFBformat(info);
handleFbScaling(ctx, info.xres, info.yres, info.width, info.height);
@@ -992,6 +1027,16 @@
return false;
}
+bool isAlphaPresentinFB(hwc_context_t *ctx, int dpy) {
+ switch(ctx->dpyAttr[dpy].fbformat) {
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ return true;
+ default : return false;
+ }
+ return false;
+}
+
static void trimLayer(hwc_context_t *ctx, const int& dpy, const int& transform,
hwc_rect_t& crop, hwc_rect_t& dst) {
int hw_w = ctx->dpyAttr[dpy].xres;
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 26d036f..f290dc8 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -91,6 +91,7 @@
float xdpi;
float ydpi;
bool secure;
+ uint32_t fbformat;
int fd;
bool connected; //Applies only to pluggable disp.
//Connected does not mean it ready to use.
@@ -307,6 +308,7 @@
void sanitizeSourceCrop(hwc_rect_t& cropL, hwc_rect_t& cropR,
private_handle_t *hnd);
bool isAlphaPresent(hwc_layer_1_t const* layer);
+bool isAlphaPresentinFB(hwc_context_t* ctx, int dpy);
int hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable);
int getBlending(int blending);
bool isGLESOnlyComp(hwc_context_t *ctx, const int& dpy);
diff --git a/libhwcomposer/hwc_virtual.cpp b/libhwcomposer/hwc_virtual.cpp
index a294a75..fa40370 100644
--- a/libhwcomposer/hwc_virtual.cpp
+++ b/libhwcomposer/hwc_virtual.cpp
@@ -90,6 +90,7 @@
// it up to the consumer to decide how fast to consume frames.
ctx->dpyAttr[dpy].vsync_period
= ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period;
+ ctx->dpyAttr[dpy].fbformat = HAL_PIXEL_FORMAT_RGBA_8888;
init(ctx);
// Do one padding round for cases where primary has all pipes
// The virtual composition falls back to GPU in such cases.
diff --git a/liboverlay/overlayMem.h b/liboverlay/overlayMem.h
index f0a1922..abdd402 100644
--- a/liboverlay/overlayMem.h
+++ b/liboverlay/overlayMem.h
@@ -121,7 +121,7 @@
uint32_t bufSz, bool isSecure)
{
alloc_data data;
- int allocFlags = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
+ int allocFlags = 0;
int err = 0;
OVASSERT(numbufs && bufSz, "numbufs=%d bufSz=%d", numbufs, bufSz);
mBufSz = bufSz;
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index 932d670..6a9d7f8 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -91,12 +91,6 @@
ENABLE_PARTIAL_UPDATE,
};
- enum {
- DUMP_PRIMARY_DISPLAY,
- DUMP_HDMI_DISPLAY,
- DUMP_VIRTUAL_DISPLAY,
- };
-
// Register a HWC client that can be notified
// This client is generic and is intended to get
// dispatches of all events calling into QService