hwc: Fix locking.
Remove the unnecessary blank lock, mdp comp lock, secure lock.
Rename the ext lock to a more appropriate draw lock.
The mdp comp lock is at an incorrect place and causes unwanted
objects to show up in dumpsys, since configDone hasnt cleaned
them up yet.
dump(), blank(), draw() should all acquire a common lock.
draw() includes prepare() and set().
Change-Id: I595547dd5a393a8af6cd8c9297d50793b715e658
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index f90420f..8a16f08 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -257,10 +257,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 +310,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 +329,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 +613,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 +703,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);
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index e97d769..1d75a9c 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\"");
@@ -738,92 +737,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 +920,6 @@
return true;
}
- Locker::Autolock _l(mMdpCompLock);
-
/* reset Invalidator */
if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount)
idleInvalidator->markForSleep();
@@ -1132,8 +1125,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 5d7d4d3..12a9f32 100644
--- a/libhwcomposer/hwc_qclient.cpp
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -74,7 +74,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();
@@ -88,7 +88,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)
@@ -98,7 +98,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.h b/libhwcomposer/hwc_utils.h
index 71b51ab..d9f96a5 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -357,17 +357,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