Merge "hwc: Set min panel refresh rate during idle timeout"
diff --git a/common.mk b/common.mk
index a2283c4..cdac0fa 100644
--- a/common.mk
+++ b/common.mk
@@ -7,11 +7,6 @@
common_includes += $(LOCAL_PATH)/../libhdmi
common_includes += $(LOCAL_PATH)/../libqservice
-ifeq ($(TARGET_USES_POST_PROCESSING),true)
- common_flags += -DUSES_POST_PROCESSING
- common_includes += $(TARGET_OUT_HEADERS)/pp/inc
-endif
-
common_header_export_path := qcom/display
#Common libraries external to display HAL
@@ -21,6 +16,11 @@
common_flags := -DDEBUG_CALC_FPS -Wno-missing-field-initializers
common_flags += -Wconversion -Wall -Werror
+ifeq ($(TARGET_USES_POST_PROCESSING),true)
+ common_flags += -DUSES_POST_PROCESSING
+ common_includes += $(TARGET_OUT_HEADERS)/pp/inc
+endif
+
ifeq ($(ARCH_ARM_HAVE_NEON),true)
common_flags += -D__ARM_HAVE_NEON
endif
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index 9e2a6cf..17e7722 100644
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -70,20 +70,17 @@
GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY = 0x00800000,
};
-enum {
- /* Gralloc perform enums
- */
- GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER = 1,
- // This will be deprecated from latest graphics drivers. This is kept
- // for those backward compatibility i.e., newer Display HAL + older graphics
- // libraries
- GRALLOC_MODULE_PERFORM_GET_STRIDE,
- GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE,
- GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE,
- GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES,
- GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE,
- GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO,
-};
+/* define Gralloc perform */
+#define GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER 1
+// This will be used by the graphics drivers to know if certain features
+// are defined in this display HAL.
+// Ex: Newer GFX libraries + Older Display HAL
+#define GRALLOC_MODULE_PERFORM_GET_STRIDE 2
+#define GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE 3
+#define GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE 4
+#define GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES 5
+#define GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE 6
+#define GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO 7
#define GRALLOC_HEAP_MASK (GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP |\
GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP |\
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index c96eb1e..2bf421f 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -257,7 +257,8 @@
bool fbComp = false;
if (LIKELY(list && list->numHwLayers > 1) &&
(ctx->dpyAttr[dpy].isActive ||
- ctx->mHDMIDisplay->isHDMIPrimaryDisplay())) {
+ ctx->mHDMIDisplay->isHDMIPrimaryDisplay())
+ && !ctx->dpyAttr[dpy].isPause) {
// When HDMI is primary we should rely on the first valid
// draw call in order to activate the display
@@ -475,10 +476,11 @@
return -errno;
}
- if(mode == HWC_POWER_MODE_NORMAL) {
+ if(mode == HWC_POWER_MODE_NORMAL && !ctx->mHPDEnabled) {
// Enable HPD here, as during bootup POWER_MODE_NORMAL is set
// when SF is completely initialized
ctx->mHDMIDisplay->setHPD(1);
+ ctx->mHPDEnabled = true;
}
ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF);
@@ -585,7 +587,8 @@
ATRACE_CALL();
int ret = 0;
const int dpy = HWC_DISPLAY_PRIMARY;
- if (LIKELY(list) && ctx->dpyAttr[dpy].isActive) {
+ if (LIKELY(list) && ctx->dpyAttr[dpy].isActive
+ && !ctx->dpyAttr[dpy].isPause) {
size_t last = list->numHwLayers - 1;
hwc_layer_1_t *fbLayer = &list->hwLayers[last];
int fd = -1; //FenceFD from the Copybit(valid in async mode)
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 79a4249..e32ebbb 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -754,11 +754,11 @@
return false;
}
- // No Idle fall back, if secure display or secure RGB layers are present or
- // if there's only a single layer being composed
- if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
- !ctx->listStats[mDpy].secureRGBCount) &&
- (ctx->listStats[mDpy].numAppLayers != 1)) {
+ /* No Idle fall back if secure display or secure RGB layers are present
+ * or if there is only a single layer being composed */
+ if(sIdleFallBack && !ctx->listStats[mDpy].secureUI &&
+ !ctx->listStats[mDpy].secureRGBCount &&
+ (ctx->listStats[mDpy].numAppLayers > 1)) {
ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
return false;
}
@@ -1285,7 +1285,22 @@
hwc_display_contents_1_t* list, bool secureOnly) {
if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
return false;
+
int numAppLayers = ctx->listStats[mDpy].numAppLayers;
+ if(!isSecurePresent(ctx, mDpy)) {
+ /* Bail out if we are processing only secured video layers
+ * and we dont have any */
+ if(secureOnly) {
+ ALOGD_IF(isDebug(),"%s: No Secure Video Layers", __FUNCTION__);
+ return false;
+ }
+ /* No Idle fall back for secure video layers and if there is only
+ * single layer being composed. */
+ if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
+ ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
+ return false;
+ }
+ }
mCurrentFrame.reset(numAppLayers);
mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
@@ -1297,13 +1312,6 @@
return false;
}
- /* Bail out if we are processing only secured video layers
- * and we dont have any */
- if(!isSecurePresent(ctx, mDpy) && secureOnly){
- reset(ctx);
- return false;
- }
-
if(mCurrentFrame.fbCount)
mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
@@ -1344,14 +1352,22 @@
if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
return false;
- /* Bail out if we are processing only secured video layers
- * and we dont have any */
- if(!isSecurePresent(ctx, mDpy) && secureOnly){
- reset(ctx);
- return false;
+ int numAppLayers = ctx->listStats[mDpy].numAppLayers;
+ if(!isSecurePresent(ctx, mDpy) && !ctx->listStats[mDpy].secureUI) {
+ /* Bail out if we are processing only secured video/ui layers
+ * and we dont have any */
+ if(secureOnly) {
+ ALOGD_IF(isDebug(), "%s: No secure video/ui layers");
+ return false;
+ }
+ /* No Idle fall back for secure video/ui layers and if there is only
+ * single layer being composed. */
+ if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
+ ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
+ return false;
+ }
}
- int numAppLayers = ctx->listStats[mDpy].numAppLayers;
mCurrentFrame.reset(numAppLayers);
mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
diff --git a/libhwcomposer/hwc_qclient.cpp b/libhwcomposer/hwc_qclient.cpp
index add5dc8..1a29b89 100644
--- a/libhwcomposer/hwc_qclient.cpp
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -313,6 +313,23 @@
return NO_ERROR;
}
+static void toggleScreenUpdate(hwc_context_t* ctx, uint32_t on) {
+ ALOGD("%s: toggle update: %d", __FUNCTION__, on);
+ Locker::Autolock _sl(ctx->mDrawLock);
+ if (on == 0) {
+ ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isPause = true;
+ ctx->mOverlay->configBegin();
+ ctx->mOverlay->configDone();
+ ctx->mRotMgr->clear();
+ if(!Overlay::displayCommit(ctx->dpyAttr[0].fd)) {
+ ALOGE("%s: Display commit failed", __FUNCTION__);
+ }
+ } else {
+ ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isPause = false;
+ ctx->proc->invalidate(ctx->proc);
+ }
+}
+
status_t QClient::notifyCallback(uint32_t command, const Parcel* inParcel,
Parcel* outParcel) {
status_t ret = NO_ERROR;
@@ -369,6 +386,9 @@
case IQService::CONFIGURE_DYN_REFRESH_RATE:
configureDynRefreshRate(mHwcContext, inParcel);
break;
+ case IQService::TOGGLE_SCREEN_UPDATE:
+ toggleScreenUpdate(mHwcContext, inParcel->readInt32());
+ break;
default:
ret = NO_ERROR;
}
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index ace0017..bcac4be 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -413,6 +413,7 @@
}
memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
+ ctx->mHPDEnabled = false;
ALOGI("Initializing Qualcomm Hardware Composer");
ALOGI("MDP version: %d", ctx->mMDP.version);
}
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 11aa86d..18de082 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -96,7 +96,7 @@
//It should be active also. (UNBLANKED)
bool isActive;
// In pause state, composition is bypassed
- // used for WFD displays only
+ // used for WFD displays and in QDCM calibration mode
bool isPause;
// To trigger padding round to clean up mdp
// pipes
@@ -639,6 +639,8 @@
bool mBWCEnabled;
// Provides a way for OEM's to disable setting dynfps via metadata.
bool mUseMetaDataRefreshRate;
+ // Stores the hpd enabled status- avoids re-enabling HDP on suspend resume.
+ bool mHPDEnabled;
};
namespace qhwc {
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index e9c0a13..c250919 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -47,6 +47,9 @@
initScalar();
setDMAMultiplexingSupported();
+#ifdef USES_POST_PROCESSING
+ initPostProc();
+#endif
}
Overlay::~Overlay() {
@@ -54,6 +57,9 @@
mPipeBook[i].destroy();
}
destroyScalar();
+#ifdef USES_POST_PROCESSING
+ destroyPostProc();
+#endif
}
void Overlay::configBegin() {
@@ -526,6 +532,23 @@
}
}
+void Overlay::initPostProc() {
+ sLibAblHandle = dlopen("libmm-abl.so", RTLD_NOW);
+ if (sLibAblHandle) {
+ *(void **)&sFnppParams = dlsym(sLibAblHandle,
+ "display_pp_compute_params");
+ } else {
+ ALOGE("%s: Not able to load libmm-abl.so", __FUNCTION__);
+ }
+}
+
+void Overlay::destroyPostProc() {
+ if (sLibAblHandle) {
+ dlclose(sLibAblHandle);
+ sLibAblHandle = NULL;
+ }
+}
+
void Overlay::PipeBook::init() {
mPipe = NULL;
mDisplay = DPY_UNUSED;
@@ -557,5 +580,9 @@
{utils::OV_MDP_PIPE_ANY};
void *Overlay::sLibScaleHandle = NULL;
int (*Overlay::sFnProgramScale)(struct mdp_overlay_list *) = NULL;
+/* Dynamically link ABL library */
+void *Overlay::sLibAblHandle = NULL;
+int (*Overlay::sFnppParams)(const struct compute_params *,
+ struct mdp_overlay_pp_params *) = NULL;
}; // namespace overlay
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index 665e23f..984b439 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -33,6 +33,9 @@
#include "overlayUtils.h"
#include "mdp_version.h"
#include "utils/threads.h"
+#ifdef USES_POST_PROCESSING
+#include "lib-postproc.h"
+#endif
struct MetaData_t;
@@ -186,6 +189,12 @@
/* Sets the pipe type RGB/VG/DMA*/
void setPipeType(utils::eDest pipeIndex, const utils::eMdpPipeType pType);
+ /* Dynamically link ABL library */
+ static void initPostProc();
+ static void destroyPostProc();
+ static int (*getFnPpParams())(const struct compute_params *,
+ struct mdp_overlay_pp_params *);
+
/* Just like a Facebook for pipes, but much less profile info */
struct PipeBook {
void init();
@@ -251,6 +260,10 @@
static bool sDMAMultiplexingSupported;
static void *sLibScaleHandle;
static int (*sFnProgramScale)(struct mdp_overlay_list *);
+ /* Dynamically link ABL library */
+ static void *sLibAblHandle;
+ static int (*sFnppParams)(const struct compute_params *,
+ struct mdp_overlay_pp_params *);
static bool sDebugPipeLifecycle;
friend class MdpCtrl;
@@ -345,6 +358,11 @@
return sFnProgramScale;
}
+inline int (*Overlay::getFnPpParams())(const struct compute_params *,
+ struct mdp_overlay_pp_params *) {
+ return sFnppParams;
+}
+
inline void Overlay::debugPipeLifecycle(const bool& enable) {
sDebugPipeLifecycle = enable;
}
diff --git a/liboverlay/overlayMdp.cpp b/liboverlay/overlayMdp.cpp
index 4cd52a7..3932c4c 100644
--- a/liboverlay/overlayMdp.cpp
+++ b/liboverlay/overlayMdp.cpp
@@ -21,6 +21,7 @@
#include "overlayMdp.h"
#include "mdp_version.h"
#include <overlay.h>
+#include <dlfcn.h>
#define HSIC_SETTINGS_DEBUG 0
@@ -263,7 +264,7 @@
}
if (needUpdate) {
- mParams.params.pa_params.hue = data.hsicData.hue;
+ mParams.params.pa_params.hue = (float)data.hsicData.hue;
mParams.params.pa_params.sat = data.hsicData.saturation;
mParams.params.pa_params.intensity = data.hsicData.intensity;
mParams.params.pa_params.contrast = data.hsicData.contrast;
@@ -333,7 +334,15 @@
}
if (needUpdate) {
- display_pp_compute_params(&mParams, &mOVInfo.overlay_pp_cfg);
+ int (*sFnppParams)(const struct compute_params *,
+ struct mdp_overlay_pp_params *) =
+ Overlay::getFnPpParams();
+ if(sFnppParams) {
+ int ret = sFnppParams(&mParams, &mOVInfo.overlay_pp_cfg);
+ if (ret) {
+ ALOGE("%s: Unable to set PP params", __FUNCTION__);
+ }
+ }
}
#endif
return true;
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index a935131..ef47475 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -55,9 +55,10 @@
DYNAMIC_DEBUG = 15, // Enable more logging on the fly
SET_IDLE_TIMEOUT = 16, // Set idle timeout for GPU fallback
TOGGLE_BWC = 17, // Toggle BWC On/Off on targets that support
- SET_PARTIAL_UPDATE = 18, // Preference on partial update feature
/* Enable/Disable/Set refresh rate dynamically */
- CONFIGURE_DYN_REFRESH_RATE = 19,
+ CONFIGURE_DYN_REFRESH_RATE = 18,
+ SET_PARTIAL_UPDATE = 19, // Preference on partial update feature
+ TOGGLE_SCREEN_UPDATE = 20, // Provides ability to disable screen updates
COMMAND_LIST_END = 400,
};
diff --git a/libqservice/QServiceUtils.h b/libqservice/QServiceUtils.h
index 5b61c8e..71277e8 100644
--- a/libqservice/QServiceUtils.h
+++ b/libqservice/QServiceUtils.h
@@ -74,6 +74,10 @@
return sendSingleParam(qService::IQService::SCREEN_REFRESH, 1);
}
+inline android::status_t toggleScreenUpdate(uint32_t on) {
+ return sendSingleParam(qService::IQService::TOGGLE_SCREEN_UPDATE, on);
+}
+
inline android::status_t setPartialUpdate(uint32_t enable) {
return sendSingleParam(qService::IQService::SET_PARTIAL_UPDATE, enable);
}