Merge "hwc: Reset layer-to-rotator map and fences on configuration failure"
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 6077ae8..bb9adbf 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -178,6 +178,8 @@
sourceCrop, mdpFlags, rotFlags);
if(!ret) {
ALOGE("%s: preRotate for external Failed!", __FUNCTION__);
+ ctx->mOverlay->clear(mDpy);
+ ctx->mLayerRotMap[mDpy]->clear();
return false;
}
//For the mdp, since either we are pre-rotating or MDP does flips
@@ -192,6 +194,7 @@
if(configMdp(ctx->mOverlay, parg, orient, sourceCrop, displayFrame,
NULL, mDest) < 0) {
ALOGE("%s: configMdp failed for dpy %d", __FUNCTION__, mDpy);
+ ctx->mLayerRotMap[mDpy]->clear();
ret = false;
}
}
@@ -365,6 +368,9 @@
ALOGE("%s: commit fails for right", __FUNCTION__);
ret = false;
}
+ if(ret == false) {
+ ctx->mLayerRotMap[mDpy]->clear();
+ }
}
return ret;
}
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index baa2146..6f2cb9c 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -1518,6 +1518,7 @@
if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
ALOGE("%s: configRotator failed!", __FUNCTION__);
ctx->mOverlay->clear(dpy);
+ ctx->mLayerRotMap[dpy]->clear();
return -1;
}
ctx->mLayerRotMap[dpy]->add(layer, *rot);
@@ -1535,6 +1536,7 @@
if(configMdp(ctx->mOverlay, parg, orient, crop, dst, metadata, dest) < 0) {
ALOGE("%s: commit failed for low res panel", __FUNCTION__);
+ ctx->mLayerRotMap[dpy]->clear();
return -1;
}
return 0;
@@ -1644,6 +1646,7 @@
if(configRotator(*rot, whf, crop, mdpFlagsL, orient, downscale) < 0) {
ALOGE("%s: configRotator failed!", __FUNCTION__);
ctx->mOverlay->clear(dpy);
+ ctx->mLayerRotMap[dpy]->clear();
return -1;
}
ctx->mLayerRotMap[dpy]->add(layer, *rot);
@@ -1709,6 +1712,7 @@
if(configMdp(ctx->mOverlay, pargL, orient,
tmp_cropL, tmp_dstL, metadata, lDest) < 0) {
ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
+ ctx->mLayerRotMap[dpy]->clear();
return -1;
}
}
@@ -1724,6 +1728,7 @@
if(configMdp(ctx->mOverlay, pargR, orient,
tmp_cropR, tmp_dstR, metadata, rDest) < 0) {
ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
+ ctx->mLayerRotMap[dpy]->clear();
return -1;
}
}
@@ -1948,6 +1953,21 @@
mCount = 0;
}
+void LayerRotMap::clear() {
+ for (uint32_t i = 0; i < mCount; i++) {
+ //mCount represents rotator objects for just this display.
+ //We could have popped mCount topmost objects from mRotMgr, but if each
+ //round has the same failure, typical of stability runs, it would lead
+ //to unnecessary memory allocation, deallocation each time. So we let
+ //the rotator objects be around, but just knock off the fences they
+ //hold. Ultimately the rotator objects will be GCed when not required.
+ //Also resetting fences is required if at least one rotation round has
+ //succeeded before. It'll be a NOP otherwise.
+ mRot[i]->resetReleaseFd();
+ }
+ reset();
+}
+
void LayerRotMap::setReleaseFd(const int& fence) {
for(uint32_t i = 0; i < mCount; i++) {
mRot[i]->setReleaseFd(dup(fence));
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 29b38fc..2503e43 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -142,7 +142,11 @@
LayerRotMap() { reset(); }
enum { MAX_SESS = 3 };
void add(hwc_layer_1_t* layer, overlay::Rotator *rot);
+ //Resets the mapping of layer to rotator
void reset();
+ //Clears mappings and existing rotator fences
+ //Intended to be used during errors
+ void clear();
uint32_t getCount() const;
hwc_layer_1_t* getLayer(uint32_t index) const;
overlay::Rotator* getRot(uint32_t index) const;
diff --git a/liboverlay/overlayRotator.cpp b/liboverlay/overlayRotator.cpp
index 7b3dda1..4b6a8bc 100644
--- a/liboverlay/overlayRotator.cpp
+++ b/liboverlay/overlayRotator.cpp
@@ -107,6 +107,12 @@
mRelFence[mCurrOffset] = fence;
}
+void RotMem::Mem::resetReleaseFd() {
+ //Will wait for previous offline rotation to finish, close fence fd
+ //and reset
+ setReleaseFd(-1);
+}
+
//============RotMgr=========================
RotMgr::RotMgr() {
diff --git a/liboverlay/overlayRotator.h b/liboverlay/overlayRotator.h
index 7c1095f..6bb94a6 100644
--- a/liboverlay/overlayRotator.h
+++ b/liboverlay/overlayRotator.h
@@ -56,6 +56,7 @@
bool close() { return m.close(); }
uint32_t size() const { return m.bufSz(); }
void setReleaseFd(const int& fence);
+ void resetReleaseFd();
// Max rotator buffers
enum { ROT_NUM_BUFS = 2 };
// rotator data info dst offset
@@ -72,6 +73,7 @@
Mem& prev() { return m[(_curr+1) % MAX_ROT_MEM]; }
RotMem& operator++() { ++_curr; return *this; }
void setReleaseFd(const int& fence) { curr().setReleaseFd(fence); }
+ void resetReleaseFd() { curr().resetReleaseFd(); }
bool close();
uint32_t _curr;
Mem m[MAX_ROT_MEM];
@@ -96,6 +98,7 @@
virtual void dump() const = 0;
virtual void getDump(char *buf, size_t len) const = 0;
void setReleaseFd(const int& fence) { mMem.setReleaseFd(fence); }
+ void resetReleaseFd() { mMem.resetReleaseFd(); }
static Rotator *getRotator();
protected: