Merge "sde: Add support for HDMI"
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/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 4167ae2..cd6d565 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -292,6 +292,11 @@
if (usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
ionFlags |= ION_HEAP(ION_CP_MM_HEAP_ID);
ionFlags |= ION_SECURE;
+#ifdef ION_FLAG_ALLOW_NON_CONTIG
+ if (!(usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY)) {
+ ionFlags |= ION_FLAG_ALLOW_NON_CONTIG;
+ }
+#endif
} else {
// for targets/OEMs which do not need HW level protection
// do not set ion secure flag & MM heap. Fallback to IOMMU heap.
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index 9b98f1b..551f188 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -141,6 +141,14 @@
flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
}
+ if (usage & GRALLOC_USAGE_HW_RENDER) {
+ flags |= private_handle_t::PRIV_FLAGS_HW_RENDER;
+ }
+
+ if (usage & GRALLOC_USAGE_HW_FB) {
+ flags |= private_handle_t::PRIV_FLAGS_HW_FB;
+ }
+
if(usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
}
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index d64914e..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 |\
@@ -182,10 +179,9 @@
PRIV_FLAGS_NEEDS_FLUSH = 0x00000020,
// Uncached memory or no CPU writers
PRIV_FLAGS_DO_NOT_FLUSH = 0x00000040,
- PRIV_FLAGS_SW_LOCK = 0x00000080,
+ PRIV_FLAGS_HW_RENDER = 0x00000080,
PRIV_FLAGS_NONCONTIGUOUS_MEM = 0x00000100,
- // Set by HWC when storing the handle
- PRIV_FLAGS_HWC_LOCK = 0x00000200,
+ PRIV_FLAGS_HW_FB = 0x00000200,
PRIV_FLAGS_SECURE_BUFFER = 0x00000400,
// For explicit synchronization
PRIV_FLAGS_UNSYNCHRONIZED = 0x00000800,
diff --git a/libgralloc/ionalloc.cpp b/libgralloc/ionalloc.cpp
index 23e225d..91a930c 100644
--- a/libgralloc/ionalloc.cpp
+++ b/libgralloc/ionalloc.cpp
@@ -77,12 +77,18 @@
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
err = open_device();
if (err)
return err;
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index 943e64f..3053d47 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -238,11 +238,11 @@
}
if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION and
not useUncached(usage)) {
- bool nonCPUWriters = usage & (
- GRALLOC_USAGE_HW_RENDER |
- GRALLOC_USAGE_HW_FB |
- GRALLOC_USAGE_HW_VIDEO_ENCODER |
- GRALLOC_USAGE_HW_CAMERA_WRITE);
+ bool nonCPUWriters = hnd->flags & (
+ private_handle_t::PRIV_FLAGS_HW_RENDER |
+ private_handle_t::PRIV_FLAGS_HW_FB |
+ private_handle_t::PRIV_FLAGS_VIDEO_ENCODER |
+ private_handle_t::PRIV_FLAGS_CAMERA_WRITE);
//Invalidate if CPU reads in software and there are non-CPU
//writers. No need to do this for the metadata buffer as it is
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 ba7793e..e32ebbb 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -192,6 +192,8 @@
enablePartialUpdateForMDP3 = true;
}
+ sIsPartialUpdateActive = getPartialUpdatePref(ctx);
+
return true;
}
@@ -752,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;
}
@@ -1283,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;
@@ -1295,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;
@@ -1342,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;
@@ -1873,6 +1891,33 @@
return true;
}
+void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
+ //For primary display, set the dynamic refreshrate
+ if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
+ ctx->mUseMetaDataRefreshRate) {
+ FrameInfo frame;
+ frame.reset(mCurrentFrame.layerCount);
+ memset(&frame.drop, 0, sizeof(frame.drop));
+ frame.dropCount = 0;
+ ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
+ __FUNCTION__);
+ updateLayerCache(ctx, list, frame);
+ updateYUV(ctx, list, false /*secure only*/, frame);
+ uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
+ MDPVersion& mdpHw = MDPVersion::getInstance();
+ if(sIdleFallBack) {
+ //Set minimum panel refresh rate during idle timeout
+ refreshRate = mdpHw.getMinFpsSupported();
+ } else if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
+ (frame.layerCount == 1)) {
+ //Set the new fresh rate, if there is only one updating YUV layer
+ //or there is one single RGB layer with this request
+ refreshRate = ctx->listStats[mDpy].refreshRateRequest;
+ }
+ setRefreshRate(ctx, mDpy, refreshRate);
+ }
+}
+
int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
int ret = 0;
char property[PROPERTY_VALUE_MAX];
@@ -1899,19 +1944,22 @@
if(!mDpy)
memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
+ //reset old data
+ mCurrentFrame.reset(numLayers);
+ memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
+ mCurrentFrame.dropCount = 0;
+
//Do not cache the information for next draw cycle.
if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
ALOGI("%s: Unsupported layer count for mdp composition",
__FUNCTION__);
mCachedFrame.reset();
+#ifdef DYNAMIC_FPS
+ setDynRefreshRate(ctx, list);
+#endif
return -1;
}
- //reset old data
- mCurrentFrame.reset(numLayers);
- memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
- mCurrentFrame.dropCount = 0;
-
// Detect the start of animation and fall back to GPU only once to cache
// all the layers in FB and display FB content untill animation completes.
if(ctx->listStats[mDpy].isDisplayAnimating) {
@@ -1922,6 +1970,9 @@
}
setMDPCompLayerFlags(ctx, list);
mCachedFrame.updateCounts(mCurrentFrame);
+#ifdef DYNAMIC_FPS
+ setDynRefreshRate(ctx, list);
+#endif
ret = -1;
return ret;
} else {
@@ -1974,26 +2025,7 @@
}
#ifdef DYNAMIC_FPS
- //For primary display, set the dynamic refreshrate
- if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
- ctx->mUseMetaDataRefreshRate) {
- FrameInfo frame;
- frame.reset(mCurrentFrame.layerCount);
- memset(&frame.drop, 0, sizeof(frame.drop));
- frame.dropCount = 0;
- ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
- __FUNCTION__);
- updateLayerCache(ctx, list, frame);
- updateYUV(ctx, list, false /*secure only*/, frame);
- uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
- //Set the new fresh rate, if there is only one updating YUV layer
- //or there is one single RGB layer with this request
- if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
- (frame.layerCount == 1)) {
- refreshRate = ctx->listStats[mDpy].refreshRateRequest;
- }
- setRefreshRate(ctx, mDpy, refreshRate);
- }
+ setDynRefreshRate(ctx, list);
#endif
mCachedFrame.cacheAll(list);
@@ -2737,6 +2769,28 @@
return 0;
}
+bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
+ Locker::Autolock _l(ctx->mDrawLock);
+ const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
+ char path[MAX_SYSFS_FILE_PATH];
+ snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
+ int fd = open(path, O_RDONLY);
+ if(fd < 0) {
+ ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
+ return -1;
+ }
+ char value[4];
+ ssize_t size_read = read(fd, value, sizeof(value)-1);
+ if(size_read <= 0) {
+ ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
+ close(fd);
+ return -1;
+ }
+ close(fd);
+ value[size_read] = '\0';
+ return atoi(value);
+}
+
int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
Locker::Autolock _l(ctx->mDrawLock);
const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
@@ -2744,14 +2798,14 @@
snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
int fd = open(path, O_WRONLY);
if(fd < 0) {
- ALOGE("%s: Failed to open sysfd node", __FUNCTION__);
+ ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
return -1;
}
char value[4];
snprintf(value, sizeof(value), "%d", (int)enable);
ssize_t ret = write(fd, value, strlen(value));
if(ret <= 0) {
- ALOGE("%s: Failed to write to sysfd nodes", __FUNCTION__);
+ ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
close(fd);
return -1;
}
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index 4ae7aa7..4978182 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -57,6 +57,8 @@
static void setIdleTimeout(const uint32_t& timeout);
static void setMaxPipesPerMixer(const uint32_t value);
static int setPartialUpdatePref(hwc_context_t *ctx, bool enable);
+ static bool getPartialUpdatePref(hwc_context_t *ctx);
+ void setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list);
protected:
enum ePipeType {
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 286ae22..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
@@ -479,11 +479,6 @@
return (hnd && (private_handle_t::PRIV_FLAGS_TILE_RENDERED & hnd->flags));
}
-//Return true if buffer is marked locked
-static inline bool isBufferLocked(const private_handle_t* hnd) {
- return (hnd && (private_handle_t::PRIV_FLAGS_HWC_LOCK & hnd->flags));
-}
-
//Return true if the buffer is intended for Secure Display
static inline bool isSecureDisplayBuffer(const private_handle_t* hnd) {
return (hnd && (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY));
@@ -644,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 f28293d..ef47475 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -58,6 +58,7 @@
/* Enable/Disable/Set refresh rate dynamically */
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);
}