overlay: Support for returning pipe based on capability
Add support for returning pipes based on capabilities.
getPipe() API takes in pipe specifications like format class,
scaling, display, mixer, fb and decides what pipe to return.
The nextPipe() API is now just a private helper.
Change-Id: I0ab809662c0ad6297e19a44f39264ee929944d13
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index 7e7f275..c1757ad 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -42,7 +42,7 @@
namespace overlay {
using namespace utils;
-
+using namespace qdutils;
Overlay::Overlay() {
int numPipes = qdutils::MDPVersion::getInstance().getTotalPipes();
@@ -158,6 +158,103 @@
return dest;
}
+utils::eDest Overlay::getPipe(const PipeSpecs& pipeSpecs) {
+ if(MDPVersion::getInstance().is8x26()) {
+ return getPipe_8x26(pipeSpecs);
+ } else if(MDPVersion::getInstance().is8x16()) {
+ return getPipe_8x16(pipeSpecs);
+ }
+
+ eDest dest = OV_INVALID;
+
+ //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);
+ } else if(pipeSpecs.fb == false) { //RGB App layers
+ if(not pipeSpecs.needsScaling) {
+ dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs.dpy, pipeSpecs.mixer);
+ }
+ if(dest == OV_INVALID) {
+ dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs.dpy, pipeSpecs.mixer);
+ }
+ if(dest == OV_INVALID) {
+ dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
+ }
+ } else { //FB layer
+ dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs.dpy, pipeSpecs.mixer);
+ if(dest == OV_INVALID) {
+ dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
+ }
+ //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);
+ }
+ }
+ return dest;
+}
+
+utils::eDest Overlay::getPipe_8x26(const PipeSpecs& pipeSpecs) {
+ //Use this to hide all the 8x26 requirements that cannot be humanly
+ //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);
+ } else if(pipeSpecs.fb == false) { //RGB app layers
+ if(not pipeSpecs.needsScaling) {
+ dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs.dpy, pipeSpecs.mixer);
+ }
+ if(dest == OV_INVALID) {
+ dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs.dpy, pipeSpecs.mixer);
+ }
+ if(dest == OV_INVALID) {
+ dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
+ }
+ } 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);
+ if(dest == OV_INVALID) {
+ dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
+ }
+ }
+ if(dest == OV_INVALID and (not pipeSpecs.needsScaling)) {
+ dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs.dpy, pipeSpecs.mixer);
+ }
+ }
+ return dest;
+}
+
+utils::eDest Overlay::getPipe_8x16(const PipeSpecs& pipeSpecs) {
+ //Having such functions help keeping the interface generic but code specific
+ //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);
+ } else if(pipeSpecs.fb == false) { //RGB app layers
+ //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);
+ if(dest == OV_INVALID) {
+ dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs.dpy, pipeSpecs.mixer);
+ }
+ } else {
+ //For 8x16 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);
+ if(dest == OV_INVALID) {
+ dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
+ }
+ }
+ if(dest == OV_INVALID) {
+ dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs.dpy, pipeSpecs.mixer);
+ }
+ }
+ return dest;
+}
+
void Overlay::endAllSessions() {
for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
if(mPipeBook[i].valid() && mPipeBook[i].mSession==PipeBook::START)
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index 44193be..fa19dc3 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -53,6 +53,17 @@
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 };
+
+ struct PipeSpecs {
+ PipeSpecs() : formatClass(FORMAT_RGB), needsScaling(false), fb(false),
+ dpy(DPY_PRIMARY), mixer(MIXER_DEFAULT) {}
+ int formatClass;
+ bool needsScaling;
+ bool fb;
+ int dpy;
+ int mixer;
+ };
/* dtor close */
~Overlay();
@@ -69,14 +80,10 @@
*/
void configDone();
- /* Returns an available pipe based on the type of pipe requested. When ANY
- * 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. 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);
+ /* Get a pipe that supported the specified format class (yuv, rgb) and has
+ * scaling capabilities.
+ */
+ utils::eDest getPipe(const PipeSpecs& pipeSpecs);
/* Returns the eDest corresponding to an already allocated pipeid.
* Useful for the reservation case, when libvpu reserves the pipe at its
* end, and expect the overlay to allocate a given pipe for a layer.
@@ -147,6 +154,18 @@
void validate(int index);
static void setDMAMultiplexingSupported();
void dump() const;
+ /* Returns an available pipe based on the type of pipe requested. When ANY
+ * 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. 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);
+ /* Helpers that enfore target specific policies while returning pipes */
+ utils::eDest getPipe_8x26(const PipeSpecs& pipeSpecs);
+ utils::eDest getPipe_8x16(const PipeSpecs& pipeSpecs);
+
/* Returns the scalar object */
static scale::Scale *getScalar();
/* Creates a scalar object using libscale.so */