hwc/overlay: Implement rotator caching
* A non-updating layer requiring rotation, can make use of
the older rotator buffer written when the layer got first
updated, rather than invoking a new rotator cycle.
* A rotator play is avoided in cases where incoming layer
buffer fd, offset, whf, src-rect, dst-rect, etc are similar
to that of the previous input layer to the rotator.
* For ex: In a usecase where video layer updates happen at
30fps and all other asynchrous UI updates happen at 60fps,
instead of the traditional 60 calls of rotator play per sec,
we now do only 30 thereby saving rotator bandwidth.
* Property "debug.rotcache.disable" can be used to disable
this feature.
Change-Id: I1d1c352c63007b7e0b4fee40882086ccd2f5a4aa
diff --git a/liboverlay/overlayMdssRot.cpp b/liboverlay/overlayMdssRot.cpp
index 8e55362..87e134a 100644
--- a/liboverlay/overlayMdssRot.cpp
+++ b/liboverlay/overlayMdssRot.cpp
@@ -51,10 +51,18 @@
void MdssRot::setRotations(uint32_t flags) { mRotInfo.flags |= flags; }
+int MdssRot::getSrcMemId() const {
+ return mRotData.data.memory_id;
+}
+
int MdssRot::getDstMemId() const {
return mRotData.dst_data.memory_id;
}
+uint32_t MdssRot::getSrcOffset() const {
+ return mRotData.data.offset;
+}
+
uint32_t MdssRot::getDstOffset() const {
return mRotData.dst_data.offset;
}
@@ -81,6 +89,19 @@
uint32_t MdssRot::getSessId() const { return mRotInfo.id; }
+void MdssRot::save() {
+ mLSRotInfo = mRotInfo;
+}
+
+bool MdssRot::rotConfChanged() const {
+ // 0 means same
+ if(0 == ::memcmp(&mRotInfo, &mLSRotInfo,
+ sizeof (mdp_overlay))) {
+ return false;
+ }
+ return true;
+}
+
bool MdssRot::init() {
if(!utils::openDev(mFd, 0, Res::fbPath, O_RDWR)) {
ALOGE("MdssRot failed to init fb0");
@@ -164,7 +185,10 @@
}
bool MdssRot::queueBuffer(int fd, uint32_t offset) {
- if(enabled()) {
+ if(enabled() and (not isRotCached(fd,offset))) {
+ int prev_fd = getSrcMemId();
+ uint32_t prev_offset = getSrcOffset();
+
mRotData.data.memory_id = fd;
mRotData.data.offset = offset;
@@ -175,14 +199,17 @@
mRotData.dst_data.offset =
mMem.mRotOffset[mMem.mCurrIndex];
- mMem.mCurrIndex =
- (mMem.mCurrIndex + 1) % mMem.mem.numBufs();
if(!overlay::mdp_wrapper::play(mFd.getFD(), mRotData)) {
ALOGE("MdssRot play failed!");
dump();
+ mRotData.data.memory_id = prev_fd;
+ mRotData.data.offset = prev_offset;
return false;
}
+ save();
+ mMem.mCurrIndex =
+ (mMem.mCurrIndex + 1) % mMem.mem.numBufs();
}
return true;
}
@@ -260,6 +287,7 @@
void MdssRot::reset() {
ovutils::memset0(mRotInfo);
+ ovutils::memset0(mLSRotInfo);
ovutils::memset0(mRotData);
mRotData.data.memory_id = -1;
mRotInfo.id = MSMFB_NEW_REQUEST;