hwc/overlay: Prevent pipes from switching mixers
For split displays, earlier we allowed pipes to switch mixers in
subsequent rounds. This change prevents that and makes sure there
is one composition round where a pipe being transferred to another
mixer of the same display is UNSET
Change-Id: I3c679cc4256363eeb70c5cf8bcaf5047b8a064c2
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index 5115a5b..fac0c49 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -70,8 +70,9 @@
//fds
if(mPipeBook[i].valid()) {
char str[32];
- sprintf(str, "Unset=%s dpy=%d; ",
- PipeBook::getDestStr((eDest)i), mPipeBook[i].mDisplay);
+ sprintf(str, "Unset=%s dpy=%d mix=%d; ",
+ PipeBook::getDestStr((eDest)i),
+ mPipeBook[i].mDisplay, mPipeBook[i].mMixer);
#if PIPE_DEBUG
strncat(mDumpStr, str, strlen(str));
#endif
@@ -83,46 +84,41 @@
PipeBook::save();
}
-eDest Overlay::nextPipe(eMdpPipeType type, int dpy) {
+eDest Overlay::nextPipe(eMdpPipeType type, int dpy, int mixer) {
eDest dest = OV_INVALID;
for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
- //Match requested pipe type
- if(type == OV_MDP_PIPE_ANY || type == PipeBook::getPipeType((eDest)i)) {
- //If the pipe is not allocated to any display or used by the
- //requesting display already in previous round.
- if((mPipeBook[i].mDisplay == DPY_UNUSED ||
- mPipeBook[i].mDisplay == dpy) &&
- PipeBook::isNotAllocated(i)) {
- //In block mode we don't allow line operations
- if(sDMAMode == DMA_BLOCK_MODE &&
- PipeBook::getPipeType((eDest)i) == OV_MDP_PIPE_DMA)
- continue;
-
- dest = (eDest)i;
- PipeBook::setAllocation(i);
- break;
- }
+ if( (type == OV_MDP_PIPE_ANY || //Pipe type match
+ type == PipeBook::getPipeType((eDest)i)) &&
+ (mPipeBook[i].mDisplay == DPY_UNUSED || //Free or same display
+ mPipeBook[i].mDisplay == dpy) &&
+ (mPipeBook[i].mMixer == MIXER_UNUSED || //Free or same mixer
+ mPipeBook[i].mMixer == mixer) &&
+ PipeBook::isNotAllocated(i) && //Free pipe
+ !(sDMAMode == DMA_BLOCK_MODE && //DMA pipe in Line mode
+ PipeBook::getPipeType((eDest)i) == OV_MDP_PIPE_DMA)) {
+ dest = (eDest)i;
+ PipeBook::setAllocation(i);
+ break;
}
}
if(dest != OV_INVALID) {
int index = (int)dest;
- //If the pipe is not registered with any display OR if the pipe is
- //requested again by the same display using it, then go ahead.
mPipeBook[index].mDisplay = dpy;
+ mPipeBook[index].mMixer = mixer;
if(not mPipeBook[index].valid()) {
mPipeBook[index].mPipe = new GenericPipe(dpy);
char str[32];
- snprintf(str, 32, "Set=%s dpy=%d; ",
- PipeBook::getDestStr(dest), dpy);
+ snprintf(str, 32, "Set=%s dpy=%d mix=%d; ",
+ PipeBook::getDestStr(dest), dpy, mixer);
#if PIPE_DEBUG
strncat(mDumpStr, str, strlen(str));
#endif
}
} else {
- ALOGD_IF(PIPE_DEBUG, "Pipe unavailable type=%d display=%d",
- (int)type, dpy);
+ ALOGD_IF(PIPE_DEBUG, "Pipe unavailable type=%d display=%d mixer=%d",
+ (int)type, dpy, mixer);
}
return dest;
@@ -376,6 +372,7 @@
void Overlay::PipeBook::init() {
mPipe = NULL;
mDisplay = DPY_UNUSED;
+ mMixer = MIXER_UNUSED;
}
void Overlay::PipeBook::destroy() {
@@ -384,6 +381,7 @@
mPipe = NULL;
}
mDisplay = DPY_UNUSED;
+ mMixer = MIXER_UNUSED;
}
Overlay* Overlay::sInstance = 0;
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index 10ae10d..63f5bf1 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -46,6 +46,8 @@
//High res panels can be backed by 2 layer mixers and a single fb node.
enum { DPY_PRIMARY, DPY_EXTERNAL, DPY_WRITEBACK, DPY_UNUSED };
enum { DPY_MAX = DPY_UNUSED };
+ enum { MIXER_LEFT, MIXER_RIGHT, MIXER_UNUSED };
+ enum { MIXER_DEFAULT = MIXER_LEFT, MIXER_MAX = MIXER_UNUSED };
enum { MAX_FB_DEVICES = DPY_MAX };
/* dtor close */
@@ -67,8 +69,10 @@
* is requested, the first available VG or RGB is returned. If no pipe is
* available for the display "dpy" then INV is returned. Note: If a pipe is
* assigned to a certain display, then it cannot be assigned to another
- * display without being garbage-collected once */
- utils::eDest nextPipe(utils::eMdpPipeType, int dpy);
+ * display without being garbage-collected once. To add if a pipe is
+ * asisgned to a mixer within a display it cannot be reused for another
+ * mixer without being UNSET once*/
+ utils::eDest nextPipe(utils::eMdpPipeType, int dpy, int mixer);
void setSource(const utils::PipeArgs args, utils::eDest dest);
void setCrop(const utils::Dim& d, utils::eDest dest);
@@ -82,8 +86,8 @@
static int initOverlay();
/* Returns the singleton instance of overlay */
static Overlay* getInstance();
- /* Returns available ("unallocated") pipes for a display */
- int availablePipes(int dpy);
+ /* 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
* displays
*/
@@ -123,6 +127,8 @@
GenericPipe *mPipe;
/* Display using this pipe. Refer to enums above */
int mDisplay;
+ /* Mixer within a split display this pipe is attached to */
+ int mMixer;
/* operations on bitmap */
static bool pipeUsageUnchanged();
@@ -178,12 +184,18 @@
PipeBook::getDestStr((utils::eDest)index));
}
-inline int Overlay::availablePipes(int dpy) {
- int avail = 0;
- for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
- if((mPipeBook[i].mDisplay == DPY_UNUSED ||
- mPipeBook[i].mDisplay == dpy) && PipeBook::isNotAllocated(i)) {
- avail++;
+inline int Overlay::availablePipes(int dpy, int mixer) {
+ int avail = 0;
+ for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
+ if( (mPipeBook[i].mDisplay == DPY_UNUSED ||
+ mPipeBook[i].mDisplay == dpy) &&
+ (mPipeBook[i].mMixer == MIXER_UNUSED ||
+ mPipeBook[i].mMixer == mixer) &&
+ PipeBook::isNotAllocated(i) &&
+ !(Overlay::getDMAMode() == Overlay::DMA_BLOCK_MODE &&
+ PipeBook::getPipeType((utils::eDest)i) ==
+ utils::OV_MDP_PIPE_DMA)) {
+ avail++;
}
}
return avail;