Merge "hwc: Use correct z-order in video overlay"
diff --git a/common.mk b/common.mk
index 360032b..f2ae8b2 100644
--- a/common.mk
+++ b/common.mk
@@ -12,10 +12,13 @@
common_includes += $(TARGET_OUT_HEADERS)/pp/inc
endif
-
#Common libraries external to display HAL
common_libs := liblog libutils libcutils libhardware
+ifeq ($(TARGET_USES_POST_PROCESSING),true)
+ common_libs += libmm-abl
+endif
+
#Common C flags
common_flags := -DDEBUG_CALC_FPS -Wno-missing-field-initializers
common_flags += -Werror
diff --git a/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp
index fa63b4c..5c58dd3 100644
--- a/libcopybit/copybit_c2d.cpp
+++ b/libcopybit/copybit_c2d.cpp
@@ -1259,10 +1259,11 @@
return status;
}
- // Flush the cache
+ // Clean the cache
IMemAlloc* memalloc = sAlloc->getAllocator(src_hnd->flags);
if (memalloc->clean_buffer((void *)(src_hnd->base), src_hnd->size,
- src_hnd->offset, src_hnd->fd)) {
+ src_hnd->offset, src_hnd->fd,
+ gralloc::CACHE_CLEAN)) {
ALOGE("%s: clean_buffer failed", __FUNCTION__);
delete_handle(dst_hnd);
delete_handle(src_hnd);
@@ -1297,12 +1298,6 @@
unmap_gpuaddr(ctx, mapped_src_idx);
return COPYBIT_FAILURE;
}
- } else {
- int c2d_format = get_format(src->format);
- if(is_alpha(c2d_format))
- src_surface.config_mask &= ~C2D_ALPHA_BLEND_NONE;
- else
- src_surface.config_mask |= C2D_ALPHA_BLEND_NONE;
}
} else {
src_surface.config_mask |= C2D_ALPHA_BLEND_NONE;
@@ -1349,10 +1344,11 @@
unmap_gpuaddr(ctx, mapped_src_idx);
return status;
}
- // Invalidate the cache.
+ // Clean the cache.
IMemAlloc* memalloc = sAlloc->getAllocator(dst_hnd->flags);
memalloc->clean_buffer((void *)(dst_hnd->base), dst_hnd->size,
- dst_hnd->offset, dst_hnd->fd);
+ dst_hnd->offset, dst_hnd->fd,
+ gralloc::CACHE_CLEAN);
}
delete_handle(dst_hnd);
delete_handle(src_hnd);
diff --git a/libexternal/external.cpp b/libexternal/external.cpp
index 3f13906..cf84a39 100644
--- a/libexternal/external.cpp
+++ b/libexternal/external.cpp
@@ -99,6 +99,8 @@
setResolution(mode);
setDpyHdmiAttr();
setExternalDisplay(true, mHdmiFbNum);
+ // set system property
+ property_set("hw.hdmiON", "1");
return 0;
}
@@ -128,6 +130,8 @@
closeFrameBuffer();
resetInfo();
setExternalDisplay(false);
+ // unset system property
+ property_set("hw.hdmiON", "0");
}
return 0;
}
@@ -142,29 +146,17 @@
return 0;
}
-void ExternalDisplay::processUEventOnline(const char *str) {
+int ExternalDisplay::ignoreRequest(const char *str) {
const char *s1 = str + strlen("change@/devices/virtual/switch/");
- if(!strncmp(s1,"hdmi",strlen(s1))) {
- // hdmi online event..!
- configureHDMIDisplay();
- // set system property
- property_set("hw.hdmiON", "1");
- }else if(!strncmp(s1,"wfd",strlen(s1))) {
- // wfd online event..!
- configureWFDDisplay();
+ if(!strncmp(s1,"wfd",strlen(s1))) {
+ if(mConnectedFbNum == mHdmiFbNum) {
+ ALOGE("Ignore wfd event when HDMI is active");
+ return true;
+ }
}
+ return false;
}
-void ExternalDisplay::processUEventOffline(const char *str) {
- const char *s1 = str + strlen("change@/devices/virtual/switch/");
- if(!strncmp(s1,"hdmi",strlen(s1))) {
- teardownHDMIDisplay();
- // unset system property
- property_set("hw.hdmiON", "0");
- }else if(!strncmp(s1,"wfd",strlen(s1))) {
- teardownWFDDisplay();
- }
-}
ExternalDisplay::ExternalDisplay(hwc_context_t* ctx):mFd(-1),
mCurrentMode(-1), mConnected(0), mConnectedFbNum(0), mModeCount(0),
@@ -174,6 +166,10 @@
memset(&mVInfo, 0, sizeof(mVInfo));
//Determine the fb index for external display devices.
updateExtDispDevFbIndex();
+ // disable HPD at start, it will be enabled later
+ // when the display powers on
+ // This helps for framework reboot or adb shell stop/start
+ writeHPDOption(0);
}
diff --git a/libexternal/external.h b/libexternal/external.h
index d46eec1..847b25c 100644
--- a/libexternal/external.h
+++ b/libexternal/external.h
@@ -47,11 +47,16 @@
void setExternalDisplay(bool connected, int extFbNum = 0);
bool isExternalConnected() { return mConnected;};
void setExtDpyNum(int extDpyNum) { mExtDpyNum = extDpyNum;};
+ int getExternalType() {return mConnectedFbNum;};
+ bool isWFDActive() {return (mConnectedFbNum == mWfdFbNum);};
void setHPD(uint32_t startEnd);
void setEDIDMode(int resMode);
void setActionSafeDimension(int w, int h);
- void processUEventOnline(const char *str);
- void processUEventOffline(const char *str);
+ int ignoreRequest(const char *str);
+ int configureHDMIDisplay();
+ int configureWFDDisplay();
+ int teardownHDMIDisplay();
+ int teardownWFDDisplay();
private:
void readCEUnderscanInfo();
@@ -72,10 +77,6 @@
void setDpyWfdAttr();
void getAttrForMode(int& width, int& height, int& fps);
void updateExtDispDevFbIndex();
- int configureHDMIDisplay();
- int configureWFDDisplay();
- int teardownHDMIDisplay();
- int teardownWFDDisplay();
int getExtFbNum(int &fbNum);
mutable android::Mutex mExtDispLock;
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 8ef5611..c697cf8 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -283,8 +283,6 @@
size += ALIGN( alignedw * ALIGN(height/2, 32), 8192);
break;
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
- case HAL_PIXEL_FORMAT_YCbCr_420_SP:
- case HAL_PIXEL_FORMAT_YCrCb_420_SP:
case HAL_PIXEL_FORMAT_YV12:
if ((format == HAL_PIXEL_FORMAT_YV12) && ((width&1) || (height&1))) {
ALOGE("w or h is odd for the YV12 format");
@@ -301,6 +299,11 @@
}
size = ALIGN(size, 4096);
break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ alignedh = height;
+ size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2, 4096);
+ break;
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
case HAL_PIXEL_FORMAT_YCrCb_422_SP:
if(width & 1) {
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index 8b9a6c5..628494b 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -174,7 +174,7 @@
if ((ssize_t)size <= 0)
return -EINVAL;
- size = (bufferSize != 0)? bufferSize : size;
+ size = (bufferSize >= size)? bufferSize : size;
// All buffers marked as protected or for external
// display need to go to overlay
diff --git a/libgralloc/ionalloc.cpp b/libgralloc/ionalloc.cpp
index 8480f98..83e62e7 100644
--- a/libgralloc/ionalloc.cpp
+++ b/libgralloc/ionalloc.cpp
@@ -145,7 +145,8 @@
}
memset(base, 0, ionAllocData.len);
// Clean cache after memset
- clean_buffer(base, data.size, data.offset, fd_data.fd);
+ clean_buffer(base, data.size, data.offset, fd_data.fd,
+ CACHE_CLEAN_AND_INVALIDATE);
}
data.base = base;
@@ -209,7 +210,7 @@
return err;
}
-int IonAlloc::clean_buffer(void *base, size_t size, int offset, int fd)
+int IonAlloc::clean_buffer(void *base, size_t size, int offset, int fd, int op)
{
struct ion_flush_data flush_data;
struct ion_fd_data fd_data;
@@ -237,7 +238,18 @@
#ifdef NEW_ION_API
struct ion_custom_data d;
- d.cmd = ION_IOC_CLEAN_INV_CACHES;
+ switch(op) {
+ case CACHE_CLEAN:
+ d.cmd = ION_IOC_CLEAN_CACHES;
+ break;
+ case CACHE_INVALIDATE:
+ d.cmd = ION_IOC_INV_CACHES;
+ break;
+ case CACHE_CLEAN_AND_INVALIDATE:
+ default:
+ d.cmd = ION_IOC_CLEAN_INV_CACHES;
+ }
+
d.arg = (unsigned long int)&flush_data;
if(ioctl(mIonFd, ION_IOC_CUSTOM, &d)) {
diff --git a/libgralloc/ionalloc.h b/libgralloc/ionalloc.h
index 7a11a34..174f44b 100644
--- a/libgralloc/ionalloc.h
+++ b/libgralloc/ionalloc.h
@@ -51,7 +51,7 @@
int offset);
virtual int clean_buffer(void*base, size_t size,
- int offset, int fd);
+ int offset, int fd, int op);
IonAlloc() { mIonFd = FD_INIT; }
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index 9c97aae..5a32975 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -222,12 +222,19 @@
pthread_mutex_unlock(lock);
}
*vaddr = (void*)hnd->base;
-
+ //Invalidate if reading in software. No need to do this for the metadata
+ //buffer as it is only read/written in software.
+ IMemAlloc* memalloc = getAllocator(hnd->flags) ;
+ err = memalloc->clean_buffer((void*)hnd->base,
+ hnd->size, hnd->offset, hnd->fd,
+ CACHE_INVALIDATE);
if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) &&
!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
// Mark the buffer to be flushed after cpu read/write
hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
}
+ } else {
+ hnd->flags |= private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH;
}
return err;
}
@@ -237,26 +244,26 @@
{
if (private_handle_t::validate(handle) < 0)
return -EINVAL;
-
+ int err = 0;
private_handle_t* hnd = (private_handle_t*)handle;
+ IMemAlloc* memalloc = getAllocator(hnd->flags);
if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
- int err;
- IMemAlloc* memalloc = getAllocator(hnd->flags) ;
err = memalloc->clean_buffer((void*)hnd->base,
- hnd->size, hnd->offset, hnd->fd);
- ALOGE_IF(err < 0, "cannot flush handle %p (offs=%x len=%x, flags = 0x%x) err=%s\n",
- hnd, hnd->offset, hnd->size, hnd->flags, strerror(errno));
- unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
- err = memalloc->clean_buffer((void*)hnd->base_metadata, size,
- hnd->offset_metadata, hnd->fd_metadata);
- ALOGE_IF(err < 0, "cannot flush handle %p (offs=%x len=%lu, "
- "flags = 0x%x) err=%s\n", hnd, hnd->offset_metadata, size,
- hnd->flags, strerror(errno));
+ hnd->size, hnd->offset, hnd->fd,
+ CACHE_CLEAN_AND_INVALIDATE);
hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
+ } else if(hnd->flags & private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH) {
+ hnd->flags &= ~private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH;
+ } else {
+ //Probably a round about way to do this, but this avoids adding new
+ //flags
+ err = memalloc->clean_buffer((void*)hnd->base,
+ hnd->size, hnd->offset, hnd->fd,
+ CACHE_INVALIDATE);
}
- return 0;
+ return err;
}
/*****************************************************************************/
diff --git a/libgralloc/memalloc.h b/libgralloc/memalloc.h
index 73ac652..664bfa2 100644
--- a/libgralloc/memalloc.h
+++ b/libgralloc/memalloc.h
@@ -34,6 +34,12 @@
namespace gralloc {
+enum {
+ CACHE_CLEAN = 0x1,
+ CACHE_INVALIDATE,
+ CACHE_CLEAN_AND_INVALIDATE,
+};
+
struct alloc_data {
void *base;
int fd;
@@ -68,7 +74,7 @@
// Clean and invalidate
virtual int clean_buffer(void *base, size_t size,
- int offset, int fd) = 0;
+ int offset, int fd, int op) = 0;
// Destructor
virtual ~IMemAlloc() {};
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index fccfcde..bc705ac 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -108,17 +108,12 @@
}
//clear prev layer prop flags and realloc for current frame
-static void reset_layer_prop(hwc_context_t* ctx, int dpy) {
- int layer_count = ctx->listStats[dpy].numAppLayers;
-
+static void reset_layer_prop(hwc_context_t* ctx, int dpy, int numAppLayers) {
if(ctx->layerProp[dpy]) {
delete[] ctx->layerProp[dpy];
ctx->layerProp[dpy] = NULL;
}
-
- if(layer_count) {
- ctx->layerProp[dpy] = new LayerProp[layer_count];
- }
+ ctx->layerProp[dpy] = new LayerProp[numAppLayers];
}
static int display_commit(hwc_context_t *ctx, int dpy) {
@@ -136,23 +131,27 @@
hwc_display_contents_1_t *list) {
hwc_context_t* ctx = (hwc_context_t*)(dev);
const int dpy = HWC_DISPLAY_PRIMARY;
- if (LIKELY(list && list->numHwLayers > 1 &&
- list->numHwLayers <= MAX_NUM_LAYERS) && ctx->dpyAttr[dpy].isActive) {
+ if (LIKELY(list && list->numHwLayers > 1) &&
+ ctx->dpyAttr[dpy].isActive) {
+ reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
uint32_t last = list->numHwLayers - 1;
hwc_layer_1_t *fbLayer = &list->hwLayers[last];
if(fbLayer->handle) {
+ if(list->numHwLayers > MAX_NUM_LAYERS) {
+ ctx->mFBUpdate[dpy]->prepare(ctx, list);
+ return 0;
+ }
setListStats(ctx, list, dpy);
- reset_layer_prop(ctx, dpy);
- int ret = ctx->mMDPComp->prepare(ctx, list);
+ bool ret = ctx->mMDPComp->prepare(ctx, list);
if(!ret) {
// IF MDPcomp fails use this route
ctx->mVidOv[dpy]->prepare(ctx, list);
ctx->mFBUpdate[dpy]->prepare(ctx, list);
+ // Use Copybit, when MDP comp fails
+ if(ctx->mCopyBit[dpy])
+ ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
+ ctx->mLayerCache[dpy]->updateLayerCache(list);
}
- ctx->mLayerCache[dpy]->updateLayerCache(list);
- // Use Copybit, when MDP comp fails
- if(!ret && ctx->mCopyBit[dpy])
- ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
}
}
return 0;
@@ -162,22 +161,25 @@
hwc_display_contents_1_t *list, int dpy) {
hwc_context_t* ctx = (hwc_context_t*)(dev);
- if (LIKELY(list && list->numHwLayers > 1 &&
- list->numHwLayers <= MAX_NUM_LAYERS) &&
- ctx->dpyAttr[dpy].isActive &&
- ctx->dpyAttr[dpy].connected) {
+ if (LIKELY(list && list->numHwLayers > 1) &&
+ ctx->dpyAttr[dpy].isActive &&
+ ctx->dpyAttr[dpy].connected) {
+ reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
uint32_t last = list->numHwLayers - 1;
+ hwc_layer_1_t *fbLayer = &list->hwLayers[last];
if(!ctx->dpyAttr[dpy].isPause) {
- hwc_layer_1_t *fbLayer = &list->hwLayers[last];
if(fbLayer->handle) {
+ ctx->mExtDispConfiguring = false;
+ if(list->numHwLayers > MAX_NUM_LAYERS) {
+ ctx->mFBUpdate[dpy]->prepare(ctx, list);
+ return 0;
+ }
setListStats(ctx, list, dpy);
- reset_layer_prop(ctx, dpy);
ctx->mVidOv[dpy]->prepare(ctx, list);
ctx->mFBUpdate[dpy]->prepare(ctx, list);
ctx->mLayerCache[dpy]->updateLayerCache(list);
if(ctx->mCopyBit[dpy])
ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
- ctx->mExtDispConfiguring = false;
}
} else {
// External Display is in Pause state.
@@ -362,19 +364,15 @@
//TODO We dont check for SKIP flag on this layer because we need PAN
//always. Last layer is always FB
- private_handle_t *hnd = NULL;
+ private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
if(copybitDone) {
hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
- } else {
- hnd = (private_handle_t *)fbLayer->handle;
}
- if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET && hnd) {
- if(!(fbLayer->flags & HWC_SKIP_LAYER) &&
- (list->numHwLayers > 1)) {
- if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
- ALOGE("%s: FBUpdate draw failed", __FUNCTION__);
- ret = -1;
- }
+
+ if(hnd) {
+ if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
+ ALOGE("%s: FBUpdate draw failed", __FUNCTION__);
+ ret = -1;
}
}
@@ -413,16 +411,12 @@
ret = -1;
}
- private_handle_t *hnd = NULL;
+ private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
if(copybitDone) {
hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
- } else {
- hnd = (private_handle_t *)fbLayer->handle;
}
- if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET &&
- !(fbLayer->flags & HWC_SKIP_LAYER) && hnd &&
- (list->numHwLayers > 1)) {
+ if(hnd) {
if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
ret = -1;
@@ -431,7 +425,7 @@
if (display_commit(ctx, dpy) < 0) {
ALOGE("%s: display commit fail!", __FUNCTION__);
- return -1;
+ ret = -1;
}
}
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index aa05aa9..3f40753 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -93,7 +93,7 @@
if (compositionType & qdutils::COMPOSITION_TYPE_DYN) {
// DYN Composition:
- // use copybit, if (TotalRGBRenderArea < 2 * FB Area)
+ // use copybit, if (TotalRGBRenderArea < threashold * FB Area)
// this is done based on perf inputs in ICS
// TODO: Above condition needs to be re-evaluated in JB
int fbWidth = ctx->dpyAttr[dpy].xres;
@@ -102,7 +102,7 @@
unsigned int renderArea = getRGBRenderingArea(list);
ALOGD_IF (DEBUG_COPYBIT, "%s:renderArea %u, fbArea %u",
__FUNCTION__, renderArea, fbArea);
- if (renderArea <= (2 * fbArea)) {
+ if (renderArea < (mDynThreshold * fbArea)) {
return true;
}
} else if ((compositionType & qdutils::COMPOSITION_TYPE_MDP)) {
@@ -554,6 +554,11 @@
mRenderBuffer[i] = NULL;
mRelFd[0] = -1;
mRelFd[1] = -1;
+
+ char value[PROPERTY_VALUE_MAX];
+ property_get("debug.hwc.dynThreshold", value, "2");
+ mDynThreshold = atof(value);
+
if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
if(copybit_open(module, &mEngine) < 0) {
ALOGE("FATAL ERROR: copybit open failed.");
diff --git a/libhwcomposer/hwc_copybit.h b/libhwcomposer/hwc_copybit.h
index bc3f263..a2d6405 100644
--- a/libhwcomposer/hwc_copybit.h
+++ b/libhwcomposer/hwc_copybit.h
@@ -80,6 +80,9 @@
//These are the the release FDs of the T-2 and T-1 round
//We wait on the T-2 fence
int mRelFd[2];
+
+ //Dynamic composition threshold for deciding copybit usage.
+ double mDynThreshold;
};
}; //namespace qhwc
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 5f524c7..e370ecb 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -67,10 +67,6 @@
if (LIKELY(ctx->mOverlay)) {
overlay::Overlay& ov = *(ctx->mOverlay);
private_handle_t *hnd = (private_handle_t *)layer->handle;
- if (!hnd) {
- ALOGE("%s:NULL private handle for layer!", __FUNCTION__);
- return false;
- }
ovutils::Whf info(hnd->width, hnd->height,
ovutils::getMdpFormat(hnd->format), hnd->size);
@@ -177,10 +173,6 @@
if (LIKELY(ctx->mOverlay)) {
overlay::Overlay& ov = *(ctx->mOverlay);
private_handle_t *hnd = (private_handle_t *)layer->handle;
- if (!hnd) {
- ALOGE("%s:NULL private handle for layer!", __FUNCTION__);
- return false;
- }
ovutils::Whf info(hnd->width, hnd->height,
ovutils::getMdpFormat(hnd->format), hnd->size);
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 56432db..e8559ac 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -631,6 +631,7 @@
hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
PipeLayerPair& info = currentFrame.pipeLayer[nYuvIndex];
info.pipeInfo = new MdpPipeInfoHighRes;
+ info.rot = NULL;
MdpPipeInfoHighRes& pipe_info = *(MdpPipeInfoHighRes*)info.pipeInfo;
if(!acquireMDPPipes(ctx, layer, pipe_info,MDPCOMP_OV_VG)) {
ALOGD_IF(isDebug(),"%s: Unable to get pipe for videos",
@@ -651,6 +652,7 @@
PipeLayerPair& info = currentFrame.pipeLayer[index];
info.pipeInfo = new MdpPipeInfoHighRes;
+ info.rot = NULL;
MdpPipeInfoHighRes& pipe_info = *(MdpPipeInfoHighRes*)info.pipeInfo;
ePipeType type = MDPCOMP_OV_ANY;
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index d27128e..b98db73 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -33,7 +33,7 @@
#include "external.h"
namespace qhwc {
-
+#define HWC_UEVENT_SWITCH_STR "change@/devices/virtual/switch/"
#define HWC_UEVENT_THREAD_NAME "hwcUeventThread"
/* External Display states */
@@ -51,6 +51,32 @@
return false;
}
+static void setup(hwc_context_t* ctx, int dpy, bool usecopybit)
+{
+ ctx->mFBUpdate[dpy] =
+ IFBUpdate::getObject(ctx->dpyAttr[dpy].xres, dpy);
+ if(usecopybit)
+ ctx->mCopyBit[dpy] = new CopyBit();
+ ctx->mVidOv[dpy] =
+ IVideoOverlay::getObject(ctx->dpyAttr[dpy].xres, dpy);
+}
+
+static void clear(hwc_context_t* ctx, int dpy)
+{
+ if(ctx->mFBUpdate[dpy]) {
+ delete ctx->mFBUpdate[dpy];
+ ctx->mFBUpdate[dpy] = NULL;
+ }
+ if(ctx->mCopyBit[dpy]){
+ delete ctx->mCopyBit[dpy];
+ ctx->mCopyBit[dpy] = NULL;
+ }
+ if(ctx->mVidOv[dpy]) {
+ delete ctx->mVidOv[dpy];
+ ctx->mVidOv[dpy] = NULL;
+ }
+}
+
static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
{
int vsync = 0;
@@ -65,7 +91,6 @@
qdutils::COMPOSITION_TYPE_C2D)) {
usecopybit = true;
}
-
if(!strcasestr("change@/devices/virtual/switch/hdmi", str) &&
!strcasestr("change@/devices/virtual/switch/wfd", str)) {
ALOGD_IF(UEVENT_DEBUG, "%s: Not Ext Disp Event ", __FUNCTION__);
@@ -84,9 +109,6 @@
int dpy = isHDMI(str) ? HWC_DISPLAY_EXTERNAL : extDpyNum;
- // update extDpyNum
- ctx->mExtDisplay->setExtDpyNum(dpy);
-
// parse HDMI/WFD switch state for connect/disconnect
// for HDMI:
// The event will be of the form:
@@ -106,30 +128,33 @@
if (str - udata >= len)
break;
}
+ ALOGD_IF(UEVENT_DEBUG, "Received str:%s",udata);
+ if(connected != EXTERNAL_ONLINE) {
+ if(ctx->mExtDisplay->ignoreRequest(udata)) {
+ ALOGD_IF(UEVENT_DEBUG,"No need to process this connection request"
+ "str:%s",udata);
+ ctx->dpyAttr[dpy].isActive = true;
+ return;
+ }
+ }
+
+ // update extDpyNum
+ ctx->mExtDisplay->setExtDpyNum(dpy);
switch(connected) {
case EXTERNAL_OFFLINE:
{ // disconnect event
- ctx->mExtDisplay->processUEventOffline(udata);
- if(ctx->mFBUpdate[dpy]) {
- Locker::Autolock _l(ctx->mExtSetLock);
- delete ctx->mFBUpdate[dpy];
- ctx->mFBUpdate[dpy] = NULL;
+ const char *s1 = udata + strlen(HWC_UEVENT_SWITCH_STR);
+ if(!strncmp(s1,"hdmi",strlen(s1))) {
+ ctx->mExtDisplay->teardownHDMIDisplay();
+ }else if(!strncmp(s1,"wfd",strlen(s1))) {
+ ctx->mExtDisplay->teardownWFDDisplay();
}
- if(ctx->mVidOv[dpy]) {
- Locker::Autolock _l(ctx->mExtSetLock);
- delete ctx->mVidOv[dpy];
- ctx->mVidOv[dpy] = NULL;
- }
- if(ctx->mCopyBit[dpy]){
- Locker::Autolock _l(ctx->mExtSetLock);
- delete ctx->mCopyBit[dpy];
- ctx->mCopyBit[dpy] = NULL;
- }
+ Locker::Autolock _l(ctx->mExtSetLock);
+ clear(ctx, dpy);
ALOGD("%s sending hotplug: connected = %d and dpy:%d",
__FUNCTION__, connected, dpy);
ctx->dpyAttr[dpy].connected = false;
- Locker::Autolock _l(ctx->mExtSetLock);
//hwc comp could be on
ctx->proc->hotplug(ctx->proc, dpy, connected);
break;
@@ -137,14 +162,38 @@
case EXTERNAL_ONLINE:
{ // connect case
ctx->mExtDispConfiguring = true;
- ctx->mExtDisplay->processUEventOnline(udata);
- ctx->mFBUpdate[dpy] =
- IFBUpdate::getObject(ctx->dpyAttr[dpy].xres, dpy);
- ctx->mVidOv[dpy] =
- IVideoOverlay::getObject(ctx->dpyAttr[dpy].xres, dpy);
+ const char *s1 = udata + strlen(HWC_UEVENT_SWITCH_STR);
+ if(!strncmp(s1,"hdmi",strlen(s1))) {
+ // hdmi online event..!
+ // check if WFD is configured
+ if(ctx->mExtDisplay->isWFDActive()) {
+ ALOGD_IF(UEVENT_DEBUG,"Received HDMI connection request"
+ "when WFD is active");
+ // teardown Active WFD Display
+ ctx->mExtDisplay->teardownWFDDisplay();
+ {
+ Locker::Autolock _l(ctx->mExtSetLock);
+ clear(ctx, dpy);
+ //send hotplug disconnect event
+ ALOGD_IF(UEVENT_DEBUG, "sending hotplug: disconnect"
+ "for WFD");
+ // hwc comp could be on
+ ctx->proc->hotplug(ctx->proc, dpy, EXTERNAL_OFFLINE);
+ }
+ //Invalidate
+ ctx->proc->invalidate(ctx->proc);
+ //wait for 1 second
+ ALOGE_IF(UEVENT_DEBUG, "wait for 1 second -- padding"
+ "round");
+ sleep(1);
+ }
+ ctx->mExtDisplay->configureHDMIDisplay();
+ } else if(!strncmp(s1,"wfd",strlen(s1))) {
+ // wfd online event..!
+ ctx->mExtDisplay->configureWFDDisplay();
+ }
ctx->dpyAttr[dpy].isPause = false;
- if(usecopybit)
- ctx->mCopyBit[dpy] = new CopyBit();
+ setup(ctx, dpy, usecopybit);
ALOGD("%s sending hotplug: connected = %d", __FUNCTION__,
connected);
ctx->dpyAttr[dpy].connected = true;
@@ -155,6 +204,9 @@
case EXTERNAL_PAUSE:
{ // pause case
ALOGD("%s Received Pause event",__FUNCTION__);
+ // This is required to ensure that composition
+ // fall back to FB, closing all MDP pipes.
+ ctx->mExtDispConfiguring = true;
ctx->dpyAttr[dpy].isActive = true;
ctx->dpyAttr[dpy].isPause = true;
break;
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 8764171..3245889 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -122,7 +122,6 @@
IVideoOverlay::getObject(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres,
HWC_DISPLAY_PRIMARY);
- char value[PROPERTY_VALUE_MAX];
// Check if the target supports copybit compostion (dyn/mdp/c2d) to
// decide if we need to open the copybit module.
int compositionType =
@@ -284,9 +283,23 @@
}
bool isAlphaScaled(hwc_layer_1_t const* layer) {
- if(needsScaling(layer)) {
- if(layer->blending != HWC_BLENDING_NONE)
+ if(needsScaling(layer) && isAlphaPresent(layer)) {
+ return true;
+ }
+ return false;
+}
+
+bool isAlphaPresent(hwc_layer_1_t const* layer) {
+ private_handle_t *hnd = (private_handle_t *)layer->handle;
+ if(hnd) {
+ int format = hnd->format;
+ switch(format) {
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ // In any more formats with Alpha go here..
return true;
+ default : return false;
+ }
}
return false;
}
@@ -597,6 +610,13 @@
ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_FLIP_V);
}
}
+
+ if(metadata &&
+ ((metadata->operation & PP_PARAM_HSIC)
+ || (metadata->operation & PP_PARAM_IGC)
+ || (metadata->operation & PP_PARAM_SHARP2))) {
+ ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_PP_EN);
+ }
}
static inline int configRotator(Rotator *rot, const Whf& whf,
@@ -612,7 +632,8 @@
static inline int configMdp(Overlay *ov, const PipeArgs& parg,
const eTransform& orient, const hwc_rect_t& crop,
- const hwc_rect_t& pos, const eDest& dest) {
+ const hwc_rect_t& pos, const MetaData_t *metadata,
+ const eDest& dest) {
ov->setSource(parg, dest);
ov->setTransform(orient, dest);
@@ -626,6 +647,9 @@
Dim position(pos.left, pos.top, posW, posH);
ov->setPosition(position, dest);
+ if (metadata)
+ ov->setVisualParams(*metadata, dest);
+
if (!ov->commit(dest)) {
return -1;
}
@@ -657,6 +681,8 @@
return -1;
}
+ MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+
hwc_rect_t crop = layer->sourceCrop;
hwc_rect_t dst = layer->displayFrame;
int transform = layer->transform;
@@ -698,7 +724,7 @@
transform = 0;
PipeArgs parg(mdpFlags, whf, z, isFg, static_cast<eRotFlags>(rotFlags));
- if(configMdp(ctx->mOverlay, parg, orient, crop, dst, dest) < 0) {
+ if(configMdp(ctx->mOverlay, parg, orient, crop, dst, metadata, dest) < 0) {
ALOGE("%s: commit failed for low res panel", __FUNCTION__);
return -1;
}
@@ -715,6 +741,8 @@
return -1;
}
+ MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+
int hw_w = ctx->dpyAttr[dpy].xres;
int hw_h = ctx->dpyAttr[dpy].yres;
hwc_rect_t crop = layer->sourceCrop;
@@ -790,7 +818,7 @@
PipeArgs pargL(mdpFlagsL, whf, z, isFg,
static_cast<eRotFlags>(rotFlags));
if(configMdp(ctx->mOverlay, pargL, orient,
- tmp_cropL, tmp_dstL, lDest) < 0) {
+ tmp_cropL, tmp_dstL, metadata, lDest) < 0) {
ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
return -1;
}
@@ -803,7 +831,7 @@
tmp_dstR.right = tmp_dstR.right - tmp_dstR.left;
tmp_dstR.left = 0;
if(configMdp(ctx->mOverlay, pargR, orient,
- tmp_cropR, tmp_dstR, rDest) < 0) {
+ tmp_cropR, tmp_dstR, metadata, rDest) < 0) {
ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
return -1;
}
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index bb602bc..e1f0995 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -33,9 +33,7 @@
#define ALIGN_TO(x, align) (((x) + ((align)-1)) & ~((align)-1))
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
-#define FINAL_TRANSFORM_MASK 0x000F
-#define MAX_NUM_DISPLAYS 4 //Yes, this is ambitious
-#define MAX_NUM_LAYERS 32
+#define MAX_NUM_LAYERS 32 //includes fb layer
#define MAX_DISPLAY_DIM 2048
// For support of virtual displays
@@ -144,6 +142,7 @@
bool isSecureModePolicy(int mdpVersion);
bool isExternalActive(hwc_context_t* ctx);
bool needsScaling(hwc_layer_1_t const* layer);
+bool isAlphaPresent(hwc_layer_1_t const* layer);
int hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable);
//Helper function to dump logs
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index d22aedb..1faeadf 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -30,6 +30,7 @@
#include "overlay.h"
#include "pipes/overlayGenPipe.h"
#include "mdp_version.h"
+#include "qdMetaData.h"
#define PIPE_DEBUG 0
@@ -194,6 +195,12 @@
mPipeBook[index].mPipe->setSource(newArgs);
}
+void Overlay::setVisualParams(const MetaData_t& metadata, utils::eDest dest) {
+ int index = (int)dest;
+ validate(index);
+ mPipeBook[index].mPipe->setVisualParams(metadata);
+}
+
Overlay* Overlay::getInstance() {
if(sInstance == NULL) {
sInstance = new Overlay();
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index aa12b76..fdeebc2 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -33,6 +33,8 @@
#include "overlayUtils.h"
#include "utils/threads.h"
+struct MetaData_t;
+
namespace overlay {
class GenericPipe;
@@ -64,6 +66,7 @@
void setCrop(const utils::Dim& d, utils::eDest dest);
void setTransform(const int orientation, utils::eDest dest);
void setPosition(const utils::Dim& dim, utils::eDest dest);
+ void setVisualParams(const MetaData_t& data, utils::eDest dest);
bool commit(utils::eDest dest);
bool queueBuffer(int fd, uint32_t offset, utils::eDest dest);
diff --git a/liboverlay/overlayCtrlData.h b/liboverlay/overlayCtrlData.h
index 5395834..513ebb9 100644
--- a/liboverlay/overlayCtrlData.h
+++ b/liboverlay/overlayCtrlData.h
@@ -65,6 +65,8 @@
void setTransform(const utils::eTransform& p);
/* set mdp position using dim */
void setPosition(const utils::Dim& dim);
+ /* set mdp visual params using metadata */
+ bool setVisualParams(const MetaData_t &metadata);
/* mdp set overlay/commit changes */
bool commit();
@@ -171,6 +173,15 @@
mMdp.setCrop(d);
}
+inline bool Ctrl::setVisualParams(const MetaData_t &metadata)
+{
+ if (!mMdp.setVisualParams(metadata)) {
+ ALOGE("Ctrl setVisualParams failed in MDP setVisualParams");
+ return false;
+ }
+ return true;
+}
+
inline void Ctrl::dump() const {
ALOGE("== Dump Ctrl start ==");
mMdp.dump();
diff --git a/liboverlay/overlayMdp.cpp b/liboverlay/overlayMdp.cpp
index d96066b..ee8bf51 100644
--- a/liboverlay/overlayMdp.cpp
+++ b/liboverlay/overlayMdp.cpp
@@ -18,6 +18,13 @@
#include <mdp_version.h>
#include "overlayUtils.h"
#include "overlayMdp.h"
+#include "mdp_version.h"
+
+#define HSIC_SETTINGS_DEBUG 0
+
+static inline bool isEqual(float f1, float f2) {
+ return ((int)(f1*100) == (int)(f2*100)) ? true : false;
+}
namespace ovutils = overlay::utils;
namespace overlay {
@@ -53,6 +60,15 @@
mLkgo.id = MSMFB_NEW_REQUEST;
mOrientation = utils::OVERLAY_TRANSFORM_0;
mDownscale = 0;
+#ifdef USES_POST_PROCESSING
+ mPPChanged = false;
+ memset(&mParams, 0, sizeof(struct compute_params));
+ mParams.params.conv_params.order = hsic_order_hsc_i;
+ mParams.params.conv_params.interface = interface_rec601;
+ mParams.params.conv_params.cc_matrix[0][0] = 1;
+ mParams.params.conv_params.cc_matrix[1][1] = 1;
+ mParams.params.conv_params.cc_matrix[2][2] = 1;
+#endif
}
bool MdpCtrl::close() {
@@ -63,7 +79,11 @@
result = false;
}
}
-
+#ifdef USES_POST_PROCESSING
+ /* free allocated memory in PP */
+ if (mOVInfo.overlay_pp_cfg.igc_cfg.c0_c1_data)
+ free(mOVInfo.overlay_pp_cfg.igc_cfg.c0_c1_data);
+#endif
reset();
if(!mFd.close()) {
@@ -191,4 +211,120 @@
ALOGE("== Dump MdpCtrl end ==");
}
+bool MdpCtrl::setVisualParams(const MetaData_t& data) {
+ bool needUpdate = false;
+#ifdef USES_POST_PROCESSING
+ /* calculate the data */
+ if (data.operation & PP_PARAM_HSIC) {
+ if (mParams.params.pa_params.hue != data.hsicData.hue) {
+ ALOGD_IF(HSIC_SETTINGS_DEBUG,
+ "Hue has changed from %d to %d",
+ mParams.params.pa_params.hue,data.hsicData.hue);
+ needUpdate = true;
+ }
+
+ if (!isEqual(mParams.params.pa_params.sat,
+ data.hsicData.saturation)) {
+ ALOGD_IF(HSIC_SETTINGS_DEBUG,
+ "Saturation has changed from %f to %f",
+ mParams.params.pa_params.sat,
+ data.hsicData.saturation);
+ needUpdate = true;
+ }
+
+ if (mParams.params.pa_params.intensity != data.hsicData.intensity) {
+ ALOGD_IF(HSIC_SETTINGS_DEBUG,
+ "Intensity has changed from %d to %d",
+ mParams.params.pa_params.intensity,
+ data.hsicData.intensity);
+ needUpdate = true;
+ }
+
+ if (!isEqual(mParams.params.pa_params.contrast,
+ data.hsicData.contrast)) {
+ ALOGD_IF(HSIC_SETTINGS_DEBUG,
+ "Contrast has changed from %f to %f",
+ mParams.params.pa_params.contrast,
+ data.hsicData.contrast);
+ needUpdate = true;
+ }
+
+ if (needUpdate) {
+ mParams.params.pa_params.hue = 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;
+ mParams.params.pa_params.ops = MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE;
+ mParams.operation |= PP_OP_PA;
+ }
+ }
+
+ if (data.operation & PP_PARAM_SHARP2) {
+ if (mParams.params.sharp_params.strength != data.Sharp2Data.strength) {
+ needUpdate = true;
+ }
+ if (mParams.params.sharp_params.edge_thr != data.Sharp2Data.edge_thr) {
+ needUpdate = true;
+ }
+ if (mParams.params.sharp_params.smooth_thr !=
+ data.Sharp2Data.smooth_thr) {
+ needUpdate = true;
+ }
+ if (mParams.params.sharp_params.noise_thr !=
+ data.Sharp2Data.noise_thr) {
+ needUpdate = true;
+ }
+
+ if (needUpdate) {
+ mParams.params.sharp_params.strength = data.Sharp2Data.strength;
+ mParams.params.sharp_params.edge_thr = data.Sharp2Data.edge_thr;
+ mParams.params.sharp_params.smooth_thr =
+ data.Sharp2Data.smooth_thr;
+ mParams.params.sharp_params.noise_thr = data.Sharp2Data.noise_thr;
+ mParams.params.sharp_params.ops =
+ MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE;
+ mParams.operation |= PP_OP_SHARP;
+ }
+ }
+
+ if (data.operation & PP_PARAM_IGC) {
+ if (mOVInfo.overlay_pp_cfg.igc_cfg.c0_c1_data == NULL){
+ uint32_t *igcData
+ = (uint32_t *)malloc(2 * MAX_IGC_LUT_ENTRIES * sizeof(uint32_t));
+ if (!igcData) {
+ ALOGE("IGC storage allocated failed");
+ return false;
+ }
+ mOVInfo.overlay_pp_cfg.igc_cfg.c0_c1_data = igcData;
+ mOVInfo.overlay_pp_cfg.igc_cfg.c2_data
+ = igcData + MAX_IGC_LUT_ENTRIES;
+ }
+
+ memcpy(mParams.params.igc_lut_params.c0,
+ data.igcData.c0, sizeof(uint16_t) * MAX_IGC_LUT_ENTRIES);
+ memcpy(mParams.params.igc_lut_params.c1,
+ data.igcData.c1, sizeof(uint16_t) * MAX_IGC_LUT_ENTRIES);
+ memcpy(mParams.params.igc_lut_params.c2,
+ data.igcData.c2, sizeof(uint16_t) * MAX_IGC_LUT_ENTRIES);
+
+ mParams.params.igc_lut_params.ops
+ = MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE;
+ mParams.operation |= PP_OP_IGC;
+ needUpdate = true;
+ }
+
+ if (data.operation & PP_PARAM_VID_INTFC) {
+ mParams.params.conv_params.interface =
+ (interface_type) data.video_interface;
+ needUpdate = true;
+ }
+
+ if (needUpdate) {
+ display_pp_compute_params(&mParams, &mOVInfo.overlay_pp_cfg);
+ mPPChanged = true;
+ }
+#endif
+ return true;
+}
+
} // overlay
diff --git a/liboverlay/overlayMdp.h b/liboverlay/overlayMdp.h
index 08d744f..f77ffae 100644
--- a/liboverlay/overlayMdp.h
+++ b/liboverlay/overlayMdp.h
@@ -22,6 +22,10 @@
#include "overlayUtils.h"
#include "mdpWrapper.h"
+#include "qdMetaData.h"
+#ifdef USES_POST_PROCESSING
+#include "lib-postproc.h"
+#endif
namespace overlay{
@@ -75,6 +79,8 @@
utils::Dim getDstRectDim() const;
/* returns a copy to src rect dim */
utils::Dim getSrcRectDim() const;
+ /* setVisualParam */
+ bool setVisualParams(const MetaData_t& data);
private:
/* Perform transformation calculations */
@@ -119,6 +125,12 @@
/* FD for the mdp fbnum */
OvFD mFd;
int mDownscale;
+#ifdef USES_POST_PROCESSING
+ /* PP Compute Params */
+ struct compute_params mParams;
+ /* indicate if PP params have been changed */
+ bool mPPChanged;
+#endif
};
@@ -227,6 +239,13 @@
}
inline bool MdpCtrl::ovChanged() const {
+#ifdef USES_POST_PROCESSING
+ // Some pp params are stored as pointer address,
+ // so can't compare their content directly.
+ if (mPPChanged) {
+ return true;
+ }
+#endif
// 0 means same
if(0 == ::memcmp(&mOVInfo, &mLkgo, sizeof (mdp_overlay))) {
return false;
diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp
index 8cc9cc0..898132f 100644
--- a/liboverlay/overlayUtils.cpp
+++ b/liboverlay/overlayUtils.cpp
@@ -28,6 +28,7 @@
*/
#include <stdlib.h>
+#include <math.h>
#include <utils/Log.h>
#include <linux/msm_mdp.h>
#include <cutils/properties.h>
@@ -189,7 +190,9 @@
// Use-case: Video playback [with downscaling and rotation].
if (dst_w && dst_h)
{
- uint32_t dscale = (src_w * src_h) / (dst_w * dst_h);
+ float fDscale = (float)(src_w * src_h) / (float)(dst_w * dst_h);
+ uint32_t dscale = (int)sqrtf(fDscale);
+
if(dscale < 2) {
// Down-scale to > 50% of orig.
dscale_factor = utils::ROT_DS_NONE;
diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h
index 3eabc1d..c189bb7 100644
--- a/liboverlay/overlayUtils.h
+++ b/liboverlay/overlayUtils.h
@@ -261,6 +261,7 @@
OV_MDP_FLIP_H = MDP_FLIP_LR,
OV_MDP_FLIP_V = MDP_FLIP_UD,
OV_MDSS_MDP_RIGHT_MIXER = MDSS_MDP_RIGHT_MIXER,
+ OV_MDP_PP_EN = MDP_OVERLAY_PP_CFG_EN,
};
enum eZorder {
diff --git a/liboverlay/pipes/overlayGenPipe.cpp b/liboverlay/pipes/overlayGenPipe.cpp
index 9108acd..90697a7 100644
--- a/liboverlay/pipes/overlayGenPipe.cpp
+++ b/liboverlay/pipes/overlayGenPipe.cpp
@@ -115,6 +115,11 @@
mCtrlData.ctrl.setPosition(d);
}
+bool GenericPipe::setVisualParams(const MetaData_t &metadata)
+{
+ return mCtrlData.ctrl.setVisualParams(metadata);
+}
+
bool GenericPipe::commit() {
bool ret = false;
int downscale_factor = utils::ROT_DS_NONE;
diff --git a/liboverlay/pipes/overlayGenPipe.h b/liboverlay/pipes/overlayGenPipe.h
index c71f8d2..63ffd32 100644
--- a/liboverlay/pipes/overlayGenPipe.h
+++ b/liboverlay/pipes/overlayGenPipe.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -36,7 +36,6 @@
namespace overlay {
-
class GenericPipe : utils::NoCopy {
public:
/* ctor */
@@ -54,6 +53,8 @@
void setTransform(const utils::eTransform& param);
/* set mdp posision using dim */
void setPosition(const utils::Dim& dim);
+ /* set visual param */
+ bool setVisualParams(const MetaData_t &metadata);
/* commit changes to the overlay "set"*/
bool commit();
/* Data APIs */
diff --git a/libqdutils/qdMetaData.cpp b/libqdutils/qdMetaData.cpp
index a53ba07..cc7e44a 100644
--- a/libqdutils/qdMetaData.cpp
+++ b/libqdutils/qdMetaData.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -43,6 +43,10 @@
ALOGE("%s: Bad fd for extra data!", __func__);
return -1;
}
+ if (!param) {
+ ALOGE("%s: input param is null!", __func__);
+ return -1;
+ }
unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
void *base = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED,
handle->fd_metadata, 0);
@@ -65,6 +69,12 @@
case PP_PARAM_INTERLACED:
data->interlaced = *((int32_t *)param);
break;
+ case PP_PARAM_IGC:
+ memcpy((void *)&data->igcData, param, sizeof(IGCData_t));
+ break;
+ case PP_PARAM_SHARP2:
+ memcpy((void *)&data->Sharp2Data, param, sizeof(Sharp2Data_t));
+ break;
default:
ALOGE("Unknown paramType %d", paramType);
break;
diff --git a/libqdutils/qdMetaData.h b/libqdutils/qdMetaData.h
index e60daed..bbca4b6 100644
--- a/libqdutils/qdMetaData.h
+++ b/libqdutils/qdMetaData.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -30,27 +30,45 @@
#ifndef _QDMETADATA_H
#define _QDMETADATA_H
+#define MAX_IGC_LUT_ENTRIES 256
-typedef struct {
+struct HSICData_t {
int32_t hue;
float saturation;
int32_t intensity;
float contrast;
-} HSICData_t;
+};
-typedef struct {
+struct Sharp2Data_t {
+ int32_t strength;
+ uint32_t edge_thr;
+ uint32_t smooth_thr;
+ uint32_t noise_thr;
+};
+
+struct IGCData_t{
+ uint16_t c0[MAX_IGC_LUT_ENTRIES];
+ uint16_t c1[MAX_IGC_LUT_ENTRIES];
+ uint16_t c2[MAX_IGC_LUT_ENTRIES];
+};
+
+struct MetaData_t {
int32_t operation;
int32_t interlaced;
HSICData_t hsicData;
int32_t sharpness;
int32_t video_interface;
-} MetaData_t;
+ IGCData_t igcData;
+ Sharp2Data_t Sharp2Data;
+};
typedef enum {
PP_PARAM_HSIC = 0x0001,
PP_PARAM_SHARPNESS = 0x0002,
PP_PARAM_INTERLACED = 0x0004,
- PP_PARAM_VID_INTFC = 0x0008
+ PP_PARAM_VID_INTFC = 0x0008,
+ PP_PARAM_IGC = 0x0010,
+ PP_PARAM_SHARP2 = 0x0020,
} DispParamType;
int setMetaData(private_handle_t *handle, DispParamType paramType, void *param);
diff --git a/libqservice/IQService.cpp b/libqservice/IQService.cpp
index 6c6f7b6..53b05e3 100644
--- a/libqservice/IQService.cpp
+++ b/libqservice/IQService.cpp
@@ -133,7 +133,7 @@
} break;
case SCREEN_REFRESH: {
CHECK_INTERFACE(IQService, data, reply);
- if(callerUid != AID_GRAPHICS) {
+ if(callerUid != AID_SYSTEM) {
ALOGE("display.qservice SCREEN_REFRESH access denied: \
pid=%d uid=%d process=%s",callerPid,
callerUid, callingProcName);