Merge "Revert "hwc: Perform MDP downscaling for WFD/HDMI Scenario""
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 50528c7..89ac919 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -75,9 +75,10 @@
static bool useUncached(int usage)
{
- if (usage & GRALLOC_USAGE_PRIVATE_UNCACHED ||
- usage & GRALLOC_USAGE_SW_WRITE_RARELY ||
- usage & GRALLOC_USAGE_SW_READ_RARELY)
+ if (usage & GRALLOC_USAGE_PRIVATE_UNCACHED)
+ return true;
+ if(((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY)
+ ||((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_RARELY))
return true;
return false;
}
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index f90420f..6c7f26d 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -134,6 +134,13 @@
ctx->layerProp[dpy] = new LayerProp[numAppLayers];
}
+static void handleGeomChange(hwc_context_t *ctx, int dpy,
+ hwc_display_contents_1_t *list) {
+ if(list->flags & HWC_GEOMETRY_CHANGED) {
+ ctx->mOverlay->forceSet(dpy);
+ }
+}
+
static int display_commit(hwc_context_t *ctx, int dpy) {
struct mdp_display_commit commit_info;
memset(&commit_info, 0, sizeof(struct mdp_display_commit));
@@ -153,6 +160,7 @@
if (LIKELY(list && list->numHwLayers > 1) &&
ctx->dpyAttr[dpy].isActive) {
reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
+ handleGeomChange(ctx, dpy, list);
uint32_t last = list->numHwLayers - 1;
hwc_layer_1_t *fbLayer = &list->hwLayers[last];
if(fbLayer->handle) {
@@ -179,6 +187,7 @@
ctx->dpyAttr[dpy].isActive &&
ctx->dpyAttr[dpy].connected) {
reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
+ handleGeomChange(ctx, dpy, list);
uint32_t last = list->numHwLayers - 1;
hwc_layer_1_t *fbLayer = &list->hwLayers[last];
if(!ctx->dpyAttr[dpy].isPause) {
@@ -220,6 +229,7 @@
ctx->dpyAttr[dpy].isActive &&
ctx->dpyAttr[dpy].connected) {
reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
+ handleGeomChange(ctx, dpy, list);
uint32_t last = list->numHwLayers - 1;
hwc_layer_1_t *fbLayer = &list->hwLayers[last];
if(!ctx->dpyAttr[dpy].isPause) {
@@ -257,10 +267,8 @@
{
int ret = 0;
hwc_context_t* ctx = (hwc_context_t*)(dev);
- ctx->mBlankLock.lock();
//Will be unlocked at the end of set
- ctx->mExtLock.lock();
- ctx->mSecureLock.lock();
+ ctx->mDrawLock.lock();
reset(ctx, numDisplays, displays);
ctx->mOverlay->configBegin();
@@ -312,7 +320,7 @@
#ifdef QCOM_BSP
case HWC_EVENT_ORIENTATION:
if(dpy == HWC_DISPLAY_PRIMARY) {
- Locker::Autolock _l(ctx->mBlankLock);
+ Locker::Autolock _l(ctx->mDrawLock);
// store the primary display orientation
// will be used in hwc_video::configure to disable
// rotation animation on external display
@@ -331,7 +339,7 @@
ATRACE_CALL();
hwc_context_t* ctx = (hwc_context_t*)(dev);
- Locker::Autolock _l(ctx->mBlankLock);
+ Locker::Autolock _l(ctx->mDrawLock);
int ret = 0, value = 0;
ALOGD_IF(BLANK_DEBUG, "%s: %s display: %d", __FUNCTION__,
blank==1 ? "Blanking":"Unblanking", dpy);
@@ -615,9 +623,7 @@
MDPComp::resetIdleFallBack();
ctx->mVideoTransFlag = false;
//Was locked at the beginning of prepare
- ctx->mSecureLock.unlock();
- ctx->mExtLock.unlock();
- ctx->mBlankLock.unlock();
+ ctx->mDrawLock.unlock();
return ret;
}
@@ -707,6 +713,7 @@
void hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len)
{
hwc_context_t* ctx = (hwc_context_t*)(dev);
+ Locker::Autolock _l(ctx->mDrawLock);
android::String8 aBuf("");
dumpsys_log(aBuf, "Qualcomm HWC state:\n");
dumpsys_log(aBuf, " MDPVersion=%d\n", ctx->mMDP.version);
@@ -751,7 +758,7 @@
//Setup HWC methods
dev->device.common.tag = HARDWARE_DEVICE_TAG;
- dev->device.common.version = HWC_DEVICE_API_VERSION_1_1;
+ dev->device.common.version = HWC_DEVICE_API_VERSION_1_2;
dev->device.common.module = const_cast<hw_module_t*>(module);
dev->device.common.close = hwc_device_close;
dev->device.prepare = hwc_prepare;
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index b5ac2b8..ac2650c 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -158,7 +158,10 @@
orient = ovutils::OVERLAY_TRANSFORM_0;
transform = 0;
ovutils::PipeArgs parg(mdpFlags, info, zOrder, isFg,
- static_cast<ovutils::eRotFlags>(rotFlags));
+ static_cast<ovutils::eRotFlags>(rotFlags),
+ ovutils::DEFAULT_PLANE_ALPHA,
+ (ovutils::eBlending)
+ getBlending(layer->blending));
ret = true;
if(configMdp(ctx->mOverlay, parg, orient, sourceCrop, displayFrame,
NULL, mDest) < 0) {
@@ -255,11 +258,16 @@
ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
+ //XXX: FB layer plane alpha is currently sent as zero from
+ //surfaceflinger
ovutils::PipeArgs pargL(mdpFlagsL,
info,
zOrder,
ovutils::IS_FG_OFF,
- ovutils::ROT_FLAGS_NONE);
+ ovutils::ROT_FLAGS_NONE,
+ ovutils::DEFAULT_PLANE_ALPHA,
+ (ovutils::eBlending)
+ getBlending(layer->blending));
ov.setSource(pargL, destL);
ovutils::eMdpFlags mdpFlagsR = mdpFlagsL;
@@ -268,7 +276,10 @@
info,
zOrder,
ovutils::IS_FG_OFF,
- ovutils::ROT_FLAGS_NONE);
+ ovutils::ROT_FLAGS_NONE,
+ ovutils::DEFAULT_PLANE_ALPHA,
+ (ovutils::eBlending)
+ getBlending(layer->blending));
ov.setSource(pargR, destR);
hwc_rect_t sourceCrop = layer->sourceCrop;
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index e97d769..81ccfed 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -55,7 +55,6 @@
void MDPComp::dump(android::String8& buf)
{
- Locker::Autolock _l(mMdpCompLock);
dumpsys_log(buf,"HWC Map for Dpy: %s \n",
(mDpy == 0) ? "\"PRIMARY\"" :
(mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
@@ -569,6 +568,13 @@
return false;
}
+ if(layer->planeAlpha < 0xFF) {
+ ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
+ in video only mode",
+ __FUNCTION__);
+ return false;
+ }
+
return true;
}
@@ -738,92 +744,88 @@
int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
const int numLayers = ctx->listStats[mDpy].numAppLayers;
- { //LOCK SCOPE BEGIN
- Locker::Autolock _l(mMdpCompLock);
+ //reset old data
+ mCurrentFrame.reset(numLayers);
- //reset old data
- mCurrentFrame.reset(numLayers);
-
- //number of app layers exceeds MAX_NUM_APP_LAYERS fall back to GPU
- //do not cache the information for next draw cycle.
- if(numLayers > MAX_NUM_APP_LAYERS) {
- mCachedFrame.updateCounts(mCurrentFrame);
- ALOGD_IF(isDebug(), "%s: Number of App layers exceeded the limit ",
- __FUNCTION__);
- return -1;
- }
-
- //Hard conditions, if not met, cannot do MDP comp
- if(!isFrameDoable(ctx)) {
- ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
- __FUNCTION__);
- reset(numLayers, list);
- return -1;
- }
-
- //Check whether layers marked for MDP Composition is actually doable.
- if(isFullFrameDoable(ctx, list)){
- mCurrentFrame.map();
- //Configure framebuffer first if applicable
- if(mCurrentFrame.fbZ >= 0) {
- if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list,
- mCurrentFrame.fbZ)) {
- ALOGE("%s configure framebuffer failed", __func__);
- reset(numLayers, list);
- return -1;
- }
- }
- //Acquire and Program MDP pipes
- if(!programMDP(ctx, list)) {
- reset(numLayers, list);
- return -1;
- } else { //Success
- //Any change in composition types needs an FB refresh
- mCurrentFrame.needsRedraw = false;
- if(mCurrentFrame.fbCount &&
- ((mCurrentFrame.mdpCount != mCachedFrame.mdpCount) ||
- (mCurrentFrame.fbCount != mCachedFrame.cacheCount) ||
- (mCurrentFrame.fbZ != mCachedFrame.fbZ) ||
- (!mCurrentFrame.mdpCount) ||
- (list->flags & HWC_GEOMETRY_CHANGED) ||
- isSkipPresent(ctx, mDpy) ||
- (mDpy > HWC_DISPLAY_PRIMARY))) {
- mCurrentFrame.needsRedraw = true;
- }
- }
- } else if(isOnlyVideoDoable(ctx, list)) {
- //All layers marked for MDP comp cannot be bypassed.
- //Try to compose atleast YUV layers through MDP comp and let
- //all the RGB layers compose in FB
- //Destination over
- mCurrentFrame.fbZ = -1;
- if(mCurrentFrame.fbCount)
- mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
-
- mCurrentFrame.map();
-
- //Configure framebuffer first if applicable
- if(mCurrentFrame.fbZ >= 0) {
- if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, mCurrentFrame.fbZ)) {
- ALOGE("%s configure framebuffer failed", __func__);
- reset(numLayers, list);
- return -1;
- }
- }
- if(!programYUV(ctx, list)) {
- reset(numLayers, list);
- return -1;
- }
- } else {
- reset(numLayers, list);
- return -1;
- }
-
- //UpdateLayerFlags
- setMDPCompLayerFlags(ctx, list);
+ //number of app layers exceeds MAX_NUM_APP_LAYERS fall back to GPU
+ //do not cache the information for next draw cycle.
+ if(numLayers > MAX_NUM_APP_LAYERS) {
mCachedFrame.updateCounts(mCurrentFrame);
+ ALOGD_IF(isDebug(), "%s: Number of App layers exceeded the limit ",
+ __FUNCTION__);
+ return -1;
+ }
- } //LOCK SCOPE END. dump also need this lock.
+ //Hard conditions, if not met, cannot do MDP comp
+ if(!isFrameDoable(ctx)) {
+ ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
+ __FUNCTION__);
+ reset(numLayers, list);
+ return -1;
+ }
+
+ //Check whether layers marked for MDP Composition is actually doable.
+ if(isFullFrameDoable(ctx, list)) {
+ mCurrentFrame.map();
+ //Configure framebuffer first if applicable
+ if(mCurrentFrame.fbZ >= 0) {
+ if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list,
+ mCurrentFrame.fbZ)) {
+ ALOGE("%s configure framebuffer failed", __func__);
+ reset(numLayers, list);
+ return -1;
+ }
+ }
+ //Acquire and Program MDP pipes
+ if(!programMDP(ctx, list)) {
+ reset(numLayers, list);
+ return -1;
+ } else { //Success
+ //Any change in composition types needs an FB refresh
+ mCurrentFrame.needsRedraw = false;
+ if(mCurrentFrame.fbCount &&
+ ((mCurrentFrame.mdpCount != mCachedFrame.mdpCount) ||
+ (mCurrentFrame.fbCount != mCachedFrame.cacheCount) ||
+ (mCurrentFrame.fbZ != mCachedFrame.fbZ) ||
+ (!mCurrentFrame.mdpCount) ||
+ (list->flags & HWC_GEOMETRY_CHANGED) ||
+ isSkipPresent(ctx, mDpy) ||
+ (mDpy > HWC_DISPLAY_PRIMARY))) {
+ mCurrentFrame.needsRedraw = true;
+ }
+ }
+ } else if(isOnlyVideoDoable(ctx, list)) {
+ //All layers marked for MDP comp cannot be bypassed.
+ //Try to compose atleast YUV layers through MDP comp and let
+ //all the RGB layers compose in FB
+ //Destination over
+ mCurrentFrame.fbZ = -1;
+ if(mCurrentFrame.fbCount)
+ mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
+
+ mCurrentFrame.map();
+
+ //Configure framebuffer first if applicable
+ if(mCurrentFrame.fbZ >= 0) {
+ if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, mCurrentFrame.fbZ)) {
+ ALOGE("%s configure framebuffer failed", __func__);
+ reset(numLayers, list);
+ return -1;
+ }
+ }
+ if(!programYUV(ctx, list)) {
+ reset(numLayers, list);
+ return -1;
+ }
+ } else {
+ reset(numLayers, list);
+ return -1;
+ }
+
+ //UpdateLayerFlags
+ setMDPCompLayerFlags(ctx, list);
+ mCachedFrame.updateCounts(mCurrentFrame);
+
// unlock it before calling dump function to avoid deadlock
if(isDebug()) {
ALOGD("GEOMETRY change: %d", (list->flags & HWC_GEOMETRY_CHANGED));
@@ -925,8 +927,6 @@
return true;
}
- Locker::Autolock _l(mMdpCompLock);
-
/* reset Invalidator */
if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount)
idleInvalidator->markForSleep();
@@ -1132,8 +1132,6 @@
return true;
}
- Locker::Autolock _l(mMdpCompLock);
-
/* reset Invalidator */
if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount)
idleInvalidator->markForSleep();
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index 1385fbb..2f1670b 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -170,7 +170,6 @@
static IdleInvalidator *idleInvalidator;
struct FrameInfo mCurrentFrame;
struct LayerCache mCachedFrame;
- mutable Locker mMdpCompLock;
};
class MDPCompLowRes : public MDPComp {
diff --git a/libhwcomposer/hwc_qclient.cpp b/libhwcomposer/hwc_qclient.cpp
index c20f5c1..45c82fd 100644
--- a/libhwcomposer/hwc_qclient.cpp
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -71,7 +71,7 @@
}
void QClient::securing(uint32_t startEnd) {
- Locker::Autolock _sl(mHwcContext->mSecureLock);
+ Locker::Autolock _sl(mHwcContext->mDrawLock);
//The only way to make this class in this process subscribe to media
//player's death.
IMediaDeathNotifier::getMediaPlayerService();
@@ -85,7 +85,7 @@
}
void QClient::unsecuring(uint32_t startEnd) {
- Locker::Autolock _sl(mHwcContext->mSecureLock);
+ Locker::Autolock _sl(mHwcContext->mDrawLock);
mHwcContext->mSecuring = startEnd;
//We're done unsecuring
if(startEnd == IQService::END)
@@ -95,7 +95,7 @@
}
void QClient::MPDeathNotifier::died() {
- Locker::Autolock _sl(mHwcContext->mSecureLock);
+ Locker::Autolock _sl(mHwcContext->mDrawLock);
ALOGD_IF(QCLIENT_DEBUG, "Media Player died");
mHwcContext->mSecuring = false;
mHwcContext->mSecureMode = false;
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index 1d127f0..916b346 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -125,7 +125,7 @@
break;
}
- Locker::Autolock _l(ctx->mExtLock);
+ Locker::Autolock _l(ctx->mDrawLock);
clear(ctx, dpy);
ctx->dpyAttr[dpy].connected = false;
ctx->dpyAttr[dpy].isActive = false;
@@ -164,7 +164,7 @@
//fail, since Layer Mixer#0 is still connected to WriteBack.
//This block will force composition to close fb2 in above
//example.
- Locker::Autolock _l(ctx->mExtLock);
+ Locker::Autolock _l(ctx->mDrawLock);
ctx->dpyAttr[dpy].isConfiguring = true;
ctx->proc->invalidate(ctx->proc);
}
@@ -177,7 +177,7 @@
ALOGD_IF(UEVENT_DEBUG,"Received HDMI connection request"
"when WFD is active");
{
- Locker::Autolock _l(ctx->mExtLock);
+ Locker::Autolock _l(ctx->mDrawLock);
clear(ctx, HWC_DISPLAY_VIRTUAL);
ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected = false;
ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive = false;
@@ -193,7 +193,7 @@
ctx->proc->hotplug(ctx->proc, HWC_DISPLAY_EXTERNAL,
EXTERNAL_OFFLINE);
{
- Locker::Autolock _l(ctx->mExtLock);
+ Locker::Autolock _l(ctx->mDrawLock);
ctx->mVirtualonExtActive = false;
}
}
@@ -205,7 +205,7 @@
ctx->mExtDisplay->configure();
} else {
{
- Locker::Autolock _l(ctx->mExtLock);
+ Locker::Autolock _l(ctx->mDrawLock);
/* TRUE only when we are on proprietary WFD session */
ctx->mVirtualonExtActive = true;
char property[PROPERTY_VALUE_MAX];
@@ -220,7 +220,7 @@
ctx->mVirtualDisplay->configure();
}
- Locker::Autolock _l(ctx->mExtLock);
+ Locker::Autolock _l(ctx->mDrawLock);
setup(ctx, dpy);
ctx->dpyAttr[dpy].isPause = false;
ctx->dpyAttr[dpy].connected = true;
@@ -255,7 +255,7 @@
//Since external didnt have any pipes, force primary to give up
//its pipes; we don't allow inter-mixer pipe transfers.
{
- Locker::Autolock _l(ctx->mExtLock);
+ Locker::Autolock _l(ctx->mDrawLock);
ctx->dpyAttr[dpy].isConfiguring = true;
ctx->dpyAttr[dpy].isActive = true;
ctx->proc->invalidate(ctx->proc);
@@ -264,7 +264,7 @@
* 2 / 1000);
{
//At this point external has all the pipes it would need.
- Locker::Autolock _l(ctx->mExtLock);
+ Locker::Autolock _l(ctx->mDrawLock);
ctx->dpyAttr[dpy].isPause = false;
ctx->proc->invalidate(ctx->proc);
}
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 91cf337..34ed842 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -641,6 +641,18 @@
return false;
}
+int getBlending(int blending) {
+ switch(blending) {
+ case HWC_BLENDING_NONE:
+ return overlay::utils::OVERLAY_BLENDING_OPAQUE;
+ case HWC_BLENDING_PREMULT:
+ return overlay::utils::OVERLAY_BLENDING_PREMULT;
+ case HWC_BLENDING_COVERAGE :
+ default:
+ return overlay::utils::OVERLAY_BLENDING_COVERAGE;
+ }
+}
+
//Crops source buffer against destination and FB boundaries
void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,
const hwc_rect_t& scissor, int orient) {
@@ -1123,7 +1135,10 @@
//For the mdp, since either we are pre-rotating or MDP does flips
orient = OVERLAY_TRANSFORM_0;
transform = 0;
- PipeArgs parg(mdpFlags, whf, z, isFg, static_cast<eRotFlags>(rotFlags));
+ PipeArgs parg(mdpFlags, whf, z, isFg,
+ static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
+ (ovutils::eBlending) getBlending(layer->blending));
+
if(configMdp(ctx->mOverlay, parg, orient, crop, dst, metadata, dest) < 0) {
ALOGE("%s: commit failed for low res panel", __FUNCTION__);
return -1;
@@ -1252,7 +1267,9 @@
//configure left mixer
if(lDest != OV_INVALID) {
PipeArgs pargL(mdpFlagsL, whf, z, isFg,
- static_cast<eRotFlags>(rotFlags));
+ static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
+ (ovutils::eBlending) getBlending(layer->blending));
+
if(configMdp(ctx->mOverlay, pargL, orient,
tmp_cropL, tmp_dstL, metadata, lDest) < 0) {
ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
@@ -1263,7 +1280,9 @@
//configure right mixer
if(rDest != OV_INVALID) {
PipeArgs pargR(mdpFlagsR, whf, z, isFg,
- static_cast<eRotFlags>(rotFlags));
+ static_cast<eRotFlags>(rotFlags),
+ layer->planeAlpha,
+ (ovutils::eBlending) getBlending(layer->blending));
tmp_dstR.right = tmp_dstR.right - lSplit;
tmp_dstR.left = tmp_dstR.left - lSplit;
if(configMdp(ctx->mOverlay, pargR, orient,
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 251b3cb..50c6a7a 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -170,6 +170,7 @@
bool needsScaling(hwc_context_t* ctx, hwc_layer_1_t const* layer, const int& dpy);
bool isAlphaPresent(hwc_layer_1_t const* layer);
int hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable);
+int getBlending(int blending);
//Helper function to dump logs
void dumpsys_log(android::String8& buf, const char* fmt, ...);
@@ -281,8 +282,7 @@
void init_vsync_thread(hwc_context_t* ctx);
inline void getLayerResolution(const hwc_layer_1_t* layer,
- int& width, int& height)
-{
+ int& width, int& height) {
hwc_rect_t displayFrame = layer->displayFrame;
width = displayFrame.right - displayFrame.left;
height = displayFrame.bottom - displayFrame.top;
@@ -348,17 +348,8 @@
bool mVirtualonExtActive;
//Display in secure mode indicator
bool mSecureMode;
- //Lock to prevent set from being called while blanking
- mutable Locker mBlankLock;
- //Lock to protect prepare & set when detaching external disp
- mutable Locker mExtLock;
- /*Lock to set both mSecureMode and mSecuring as part
- of binder thread without context switch to composition
- thread. This lock is needed only for A-family targets
- since the state of mSecureMode and mSecuring variables
- are not checked in B-family targets.
- */
- mutable Locker mSecureLock;
+ //Lock to protect drawing data structures
+ mutable Locker mDrawLock;
//Drawing round when we use GPU
bool isPaddingRound;
// External Orientation
diff --git a/liblight/lights.c b/liblight/lights.c
index eb71b74..ccfbe10 100644
--- a/liblight/lights.c
+++ b/liblight/lights.c
@@ -51,6 +51,9 @@
char const*const LCD_FILE
= "/sys/class/leds/lcd-backlight/brightness";
+char const*const BUTTON_FILE
+ = "/sys/class/leds/button-backlight/brightness";
+
char const*const RED_BLINK_FILE
= "/sys/class/leds/red/blink";
@@ -209,6 +212,16 @@
return 0;
}
+static int
+set_light_buttons(struct light_device_t* dev,
+ struct light_state_t const* state)
+{
+ int err = 0;
+ pthread_mutex_lock(&g_lock);
+ err = write_int(BUTTON_FILE, state->color & 0xFF);
+ pthread_mutex_unlock(&g_lock);
+ return err;
+}
/** Close the lights device */
static int
@@ -238,6 +251,8 @@
set_light = set_light_backlight;
else if (0 == strcmp(LIGHT_ID_NOTIFICATIONS, name))
set_light = set_light_notifications;
+ else if (0 == strcmp(LIGHT_ID_BUTTONS, name))
+ set_light = set_light_buttons;
else if (0 == strcmp(LIGHT_ID_ATTENTION, name))
set_light = set_light_attention;
else
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index ecd66a6..ea25358 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -58,6 +58,7 @@
PipeBook::resetUse(i);
PipeBook::resetAllocation(i);
}
+ sForceSetBitmap = 0;
mDumpStr[0] = '\0';
}
@@ -142,6 +143,9 @@
if(mPipeBook[index].mPipe->commit()) {
ret = true;
PipeBook::setUse((int)dest);
+ if(sForceSetBitmap & (1 << mPipeBook[index].mDisplay)) {
+ mPipeBook[index].mPipe->forceSet();
+ }
} else {
int dpy = mPipeBook[index].mDisplay;
for(int i = 0; i < PipeBook::NUM_PIPES; i++)
@@ -387,6 +391,7 @@
Overlay* Overlay::sInstance = 0;
int Overlay::sDpyFbMap[DPY_MAX] = {0, -1, -1};
int Overlay::sDMAMode = DMA_LINE_MODE;
+int Overlay::sForceSetBitmap = 0;
int Overlay::PipeBook::NUM_PIPES = 0;
int Overlay::PipeBook::sPipeUsageBitmap = 0;
int Overlay::PipeBook::sLastUsageBitmap = 0;
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index fea50b3..280223c 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -82,10 +82,6 @@
bool commit(utils::eDest dest);
bool queueBuffer(int fd, uint32_t offset, utils::eDest dest);
- /* Closes open pipes, called during startup */
- static int initOverlay();
- /* Returns the singleton instance of overlay */
- static Overlay* getInstance();
/* Returns available ("unallocated") pipes for a display's mixer */
int availablePipes(int dpy, int mixer);
/* Returns if any of the requested pipe type is attached to any of the
@@ -98,6 +94,13 @@
void getDump(char *buf, size_t len);
/* Reset usage and allocation bits on all pipes for given display */
void clear(int dpy);
+ /* Marks the display, whose pipes need to be forcibaly configured */
+ void forceSet(const int& dpy);
+
+ /* Closes open pipes, called during startup */
+ static int initOverlay();
+ /* Returns the singleton instance of overlay */
+ static Overlay* getInstance();
static void setDMAMode(const int& mode);
static int getDMAMode();
/* Returns the framebuffer node backing up the display */
@@ -168,6 +171,7 @@
static Overlay *sInstance;
static int sDpyFbMap[DPY_MAX];
static int sDMAMode;
+ static int sForceSetBitmap;
};
inline void Overlay::validate(int index) {
@@ -208,6 +212,10 @@
return sDpyFbMap[dpy];
}
+inline void Overlay::forceSet(const int& dpy) {
+ sForceSetBitmap |= (1 << dpy);
+}
+
inline bool Overlay::PipeBook::valid() {
return (mPipe != NULL);
}
diff --git a/liboverlay/overlayMdp.cpp b/liboverlay/overlayMdp.cpp
index 2d88376..674e62d 100644
--- a/liboverlay/overlayMdp.cpp
+++ b/liboverlay/overlayMdp.cpp
@@ -94,13 +94,14 @@
setSrcWhf(args.whf);
//TODO These are hardcoded. Can be moved out of setSource.
- mOVInfo.alpha = 0xff;
mOVInfo.transp_mask = 0xffffffff;
//TODO These calls should ideally be a part of setPipeParams API
setFlags(args.mdpFlags);
setZ(args.zorder);
setIsFg(args.isFg);
+ setPlaneAlpha(args.planeAlpha);
+ setBlending(args.blending);
}
void MdpCtrl::setCrop(const utils::Dim& d) {
diff --git a/liboverlay/overlayMdp.h b/liboverlay/overlayMdp.h
index 056d982..5bfec6b 100644
--- a/liboverlay/overlayMdp.h
+++ b/liboverlay/overlayMdp.h
@@ -99,8 +99,13 @@
void setZ(utils::eZorder z);
/* set isFg flag */
void setIsFg(utils::eIsFg isFg);
- /* return a copy of src whf*/
+ /* return a copy of src whf*/
utils::Whf getSrcWhf() const;
+ /* set plane alpha */
+ void setPlaneAlpha(int planeAlpha);
+ /* set blending method */
+ void setBlending(overlay::utils::eBlending blending);
+
/* set src whf */
void setSrcWhf(const utils::Whf& whf);
/* set src/dst rect dim */
@@ -241,6 +246,24 @@
mDownscale = dscale;
}
+inline void MdpCtrl::setPlaneAlpha(int planeAlpha) {
+ mOVInfo.alpha = planeAlpha;
+}
+
+inline void MdpCtrl::setBlending(overlay::utils::eBlending blending) {
+ switch((int) blending) {
+ case utils::OVERLAY_BLENDING_OPAQUE:
+ mOVInfo.blend_op = BLEND_OP_OPAQUE;
+ break;
+ case utils::OVERLAY_BLENDING_PREMULT:
+ mOVInfo.blend_op = BLEND_OP_PREMULTIPLIED;
+ break;
+ case utils::OVERLAY_BLENDING_COVERAGE:
+ default:
+ mOVInfo.blend_op = BLEND_OP_COVERAGE;
+ }
+}
+
inline bool MdpCtrl::ovChanged() const {
#ifdef USES_POST_PROCESSING
// Some pp params are stored as pointer address,
diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h
index b543018..e49a50c 100644
--- a/liboverlay/overlayUtils.h
+++ b/liboverlay/overlayUtils.h
@@ -212,6 +212,8 @@
enum { MAX_PATH_LEN = 256 };
+enum { DEFAULT_PLANE_ALPHA = 0xFF };
+
/**
* Rotator flags: not to be confused with orientation flags.
* Usually, you want to open the rotator to make sure it is
@@ -329,21 +331,36 @@
OVERLAY_TRANSFORM_INV = 0x80
};
+enum eBlending {
+ OVERLAY_BLENDING_UNDEFINED = 0x0,
+ /* No blending */
+ OVERLAY_BLENDING_OPAQUE,
+ /* src.rgb + dst.rgb*(1-src_alpha) */
+ OVERLAY_BLENDING_PREMULT,
+ /* src.rgb * src_alpha + dst.rgb (1 - src_alpha) */
+ OVERLAY_BLENDING_COVERAGE,
+};
+
// Used to consolidate pipe params
struct PipeArgs {
PipeArgs() : mdpFlags(OV_MDP_FLAGS_NONE),
zorder(Z_SYSTEM_ALLOC),
isFg(IS_FG_OFF),
- rotFlags(ROT_FLAGS_NONE){
+ rotFlags(ROT_FLAGS_NONE),
+ planeAlpha(DEFAULT_PLANE_ALPHA),
+ blending(OVERLAY_BLENDING_COVERAGE){
}
PipeArgs(eMdpFlags f, Whf _whf,
- eZorder z, eIsFg fg, eRotFlags r) :
+ eZorder z, eIsFg fg, eRotFlags r,
+ int pA = DEFAULT_PLANE_ALPHA, eBlending b = OVERLAY_BLENDING_COVERAGE) :
mdpFlags(f),
whf(_whf),
zorder(z),
isFg(fg),
- rotFlags(r) {
+ rotFlags(r),
+ planeAlpha(pA),
+ blending(b){
}
eMdpFlags mdpFlags; // for mdp_overlay flags
@@ -351,6 +368,8 @@
eZorder zorder; // stage number
eIsFg isFg; // control alpha & transp
eRotFlags rotFlags;
+ int planeAlpha;
+ eBlending blending;
};
// Cannot use HW_OVERLAY_MAGNIFICATION_LIMIT, since at the time