hwc: Avoid changing VG pipe color format dynamically
VG pipe can be allocated for both YUV as well as RGB layer.
Switching this color format dynamically can cause overlay set
failure due to smp allocation change. Avoid this condition by
storing the color format it is allocated for.
Change-Id: I84df03883bd050c80d49e2ab63a37905535fb670
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index 3a96b71..6088a86 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -97,9 +97,11 @@
return dest;
}
-eDest Overlay::nextPipe(eMdpPipeType type, int dpy, int mixer) {
+eDest Overlay::nextPipe(eMdpPipeType type, const PipeSpecs& pipeSpecs) {
eDest dest = OV_INVALID;
-
+ int dpy = pipeSpecs.dpy;
+ int mixer = pipeSpecs.mixer;
+ int formatType = pipeSpecs.formatClass;
for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
if( (type == OV_MDP_PIPE_ANY || //Pipe type match
type == PipeBook::getPipeType((eDest)i)) &&
@@ -107,6 +109,8 @@
mPipeBook[i].mDisplay == dpy) &&
(mPipeBook[i].mMixer == MIXER_UNUSED || //Free or same mixer
mPipeBook[i].mMixer == mixer) &&
+ (mPipeBook[i].mFormatType == FORMAT_NONE || //Free or same format
+ mPipeBook[i].mFormatType == formatType) &&
PipeBook::isNotAllocated(i) && //Free pipe
( (sDMAMultiplexingSupported && dpy) ||
!(sDMAMode == DMA_BLOCK_MODE && //DMA pipe in Line mode
@@ -122,6 +126,7 @@
int index = (int)dest;
mPipeBook[index].mDisplay = dpy;
mPipeBook[index].mMixer = mixer;
+ mPipeBook[index].mFormatType = formatType;
if(not mPipeBook[index].valid()) {
mPipeBook[index].mPipe = new GenericPipe(dpy);
mPipeBook[index].mSession = PipeBook::NONE;
@@ -146,28 +151,28 @@
//The default behavior is to assume RGB and VG pipes have scalars
if(pipeSpecs.formatClass == FORMAT_YUV) {
- return nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
+ return nextPipe(OV_MDP_PIPE_VG, pipeSpecs);
} else if(pipeSpecs.fb == false) { //RGB App layers
if(not pipeSpecs.needsScaling) {
- dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs.dpy, pipeSpecs.mixer);
+ dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs);
}
if(dest == OV_INVALID) {
- dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs.dpy, pipeSpecs.mixer);
+ dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs);
}
if(dest == OV_INVALID) {
- dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
+ dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs);
}
} else { //FB layer
- dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs.dpy, pipeSpecs.mixer);
+ dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs);
if(dest == OV_INVALID) {
- dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
+ dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs);
}
//Some features can cause FB to have scaling as well.
//If we ever come to this block with FB needing scaling,
//the screen will be black for a frame, since the FB won't get a pipe
//but atleast this will prevent a hang
if(dest == OV_INVALID and (not pipeSpecs.needsScaling)) {
- dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs.dpy, pipeSpecs.mixer);
+ dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs);
}
}
return dest;
@@ -178,31 +183,31 @@
//described in a generic way
eDest dest = OV_INVALID;
if(pipeSpecs.formatClass == FORMAT_YUV) { //video
- return nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
+ return nextPipe(OV_MDP_PIPE_VG, pipeSpecs);
} else if(pipeSpecs.fb == false) { //RGB app layers
if((not pipeSpecs.needsScaling) and
(not (pipeSpecs.numActiveDisplays > 1 &&
pipeSpecs.dpy == DPY_PRIMARY))) {
- dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs.dpy, pipeSpecs.mixer);
+ dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs);
}
if(dest == OV_INVALID) {
- dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs.dpy, pipeSpecs.mixer);
+ dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs);
}
if(dest == OV_INVALID) {
- dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
+ dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs);
}
} else { //FB layer
//For 8x26 Secondary we use DMA always for FB for inline rotation
if(pipeSpecs.dpy == DPY_PRIMARY) {
- dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs.dpy, pipeSpecs.mixer);
+ dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs);
if(dest == OV_INVALID) {
- dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
+ dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs);
}
}
if(dest == OV_INVALID and (not pipeSpecs.needsScaling) and
(not (pipeSpecs.numActiveDisplays > 1 &&
pipeSpecs.dpy == DPY_PRIMARY))) {
- dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs.dpy, pipeSpecs.mixer);
+ dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs);
}
}
return dest;
@@ -213,16 +218,16 @@
//and rife with assumptions
eDest dest = OV_INVALID;
if(pipeSpecs.formatClass == FORMAT_YUV or pipeSpecs.needsScaling) {
- return nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
+ return nextPipe(OV_MDP_PIPE_VG, pipeSpecs);
} else {
//Since this is a specific func, we can assume stuff like RGB pipe not
//having scalar blocks
- dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs.dpy, pipeSpecs.mixer);
+ dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs);
if(dest == OV_INVALID) {
- dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs.dpy, pipeSpecs.mixer);
+ dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs);
}
if(dest == OV_INVALID) {
- dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
+ dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs);
}
}
return dest;
@@ -241,14 +246,14 @@
//unused
eDest dest = OV_INVALID;
if(pipeSpecs.formatClass == FORMAT_YUV) {
- return nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
+ return nextPipe(OV_MDP_PIPE_VG, pipeSpecs);
} else {
- dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs.dpy, pipeSpecs.mixer);
+ dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs);
if(dest == OV_INVALID) {
- dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
+ dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs);
}
if(dest == OV_INVALID and not pipeSpecs.needsScaling) {
- dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs.dpy, pipeSpecs.mixer);
+ dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs);
}
}
return dest;
@@ -570,6 +575,7 @@
mPipe = NULL;
mDisplay = DPY_UNUSED;
mMixer = MIXER_UNUSED;
+ mFormatType = FORMAT_NONE;
}
void Overlay::PipeBook::destroy() {
@@ -579,6 +585,7 @@
}
mDisplay = DPY_UNUSED;
mMixer = MIXER_UNUSED;
+ mFormatType = FORMAT_NONE;
mSession = NONE;
}
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index e8369ca..665e23f 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -50,7 +50,7 @@
enum { MIXER_LEFT, MIXER_RIGHT, MIXER_UNUSED };
enum { MIXER_DEFAULT = MIXER_LEFT, MIXER_MAX = MIXER_UNUSED };
enum { MAX_FB_DEVICES = DPY_MAX };
- enum { FORMAT_YUV, FORMAT_RGB };
+ enum { FORMAT_YUV, FORMAT_RGB , FORMAT_NONE };
struct PipeSpecs {
PipeSpecs() : formatClass(FORMAT_RGB), needsScaling(false), fb(false),
@@ -170,7 +170,7 @@
* 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);
+ utils::eDest nextPipe(utils::eMdpPipeType, const PipeSpecs& pipeSpecs);
/* Helpers that enfore target specific policies while returning pipes */
utils::eDest getPipe_8x26(const PipeSpecs& pipeSpecs);
utils::eDest getPipe_8x16(const PipeSpecs& pipeSpecs);
@@ -199,6 +199,8 @@
int mDisplay;
/* Mixer within a split display this pipe is attached to */
int mMixer;
+ /* Format for which this pipe is attached to the mixer*/
+ int mFormatType;
/* operations on bitmap */
static bool pipeUsageUnchanged();