hwc: Implement mixed mode composition.
With this change we are moving MDP composition from all-or-nothing
implementation to mixed mode implementation where layers can
partially be composited through MDP and while rest of the layers are
composed / cached in framebuffer.
- Mixed mode design is based on layer caching
- Mixed mode path is configured only when non-bypassing
layers are cached.
- Never allow mixed mode when FB needs to be udpated.
- If we cannot bypass all MDP comp marked layers, bail
out completely.
Change-Id: Ie08f39db07e032b537f042d0d2bfe772ebfed049
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index d847f56..7970cd3 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -29,7 +29,7 @@
#define MAX_PIPES_PER_MIXER 4
namespace overlay {
- class Rotator;
+class Rotator;
};
namespace qhwc {
@@ -37,74 +37,104 @@
class MDPComp {
public:
+ explicit MDPComp(int);
virtual ~MDPComp(){};
/*sets up mdp comp for the current frame */
- bool prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list);
+ int prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list);
/* draw */
virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list) = 0;
-
+ /* dumpsys */
void dump(android::String8& buf);
- bool isUsed() { return (mState == MDPCOMP_ON); };
- static MDPComp* getObject(const int& width);
+ static MDPComp* getObject(const int& width, const int dpy);
/* Handler to invoke frame redraw on Idle Timer expiry */
static void timeout_handler(void *udata);
+ /* Initialize MDP comp*/
static bool init(hwc_context_t *ctx);
protected:
- enum eState {
- MDPCOMP_ON = 0,
- MDPCOMP_OFF,
- };
-
enum ePipeType {
MDPCOMP_OV_RGB = ovutils::OV_MDP_PIPE_RGB,
MDPCOMP_OV_VG = ovutils::OV_MDP_PIPE_VG,
MDPCOMP_OV_DMA = ovutils::OV_MDP_PIPE_DMA,
MDPCOMP_OV_ANY,
};
+
+ /* mdp pipe data */
struct MdpPipeInfo {
int zOrder;
virtual ~MdpPipeInfo(){};
};
+
+ /* per layer data */
struct PipeLayerPair {
MdpPipeInfo *pipeInfo;
- native_handle_t* handle;
overlay::Rotator* rot;
+ int listIndex;
};
- /* introduced for mixed mode implementation */
+ /* per frame data */
struct FrameInfo {
- int count;
- struct PipeLayerPair* pipeLayer;
+ /* maps layer list to mdp list */
+ int layerCount;
+ int layerToMDP[MAX_NUM_LAYERS];
+
+ /* maps mdp list to layer list */
+ int mdpCount;
+ struct PipeLayerPair mdpToLayer[MAX_PIPES_PER_MIXER];
+
+ /* layer composing on FB? */
+ int fbCount;
+ bool isFBComposed[MAX_NUM_LAYERS];
+
+ bool needsRedraw;
+ int fbZ;
+
+ /* c'tor */
+ FrameInfo();
+ /* clear old frame data */
+ void reset();
};
+ /* cached data */
+ struct LayerCache {
+ int layerCount;
+ int mdpCount;
+ int cacheCount;
+ buffer_handle_t hnd[MAX_NUM_LAYERS];
+
+ /* c'tor */
+ LayerCache();
+ /* clear caching info*/
+ void reset();
+ };
+
+ /* No of pipes needed for Framebuffer */
+ virtual int pipesForFB() = 0;
/* calculates pipes needed for the panel */
virtual int pipesNeeded(hwc_context_t *ctx,
hwc_display_contents_1_t* list) = 0;
/* allocates pipe from pipe book */
virtual bool allocLayerPipes(hwc_context_t *ctx,
- hwc_display_contents_1_t* list,FrameInfo& current_frame) = 0;
+ hwc_display_contents_1_t* list) = 0;
/* configures MPD pipes */
virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
- PipeLayerPair& pipeLayerPair) = 0;
+ PipeLayerPair& pipeLayerPair) = 0;
/* set/reset flags for MDPComp */
void setMDPCompLayerFlags(hwc_context_t *ctx,
- hwc_display_contents_1_t* list);
- void unsetMDPCompLayerFlags(hwc_context_t* ctx,
- hwc_display_contents_1_t* list);
- /* get/set states */
- eState getState() { return mState; };
- /* reset state */
- void reset( hwc_context_t *ctx, hwc_display_contents_1_t* list );
+ hwc_display_contents_1_t* list);
/* allocate MDP pipes from overlay */
ovutils::eDest getMdpPipe(hwc_context_t *ctx, ePipeType type);
+
/* checks for conditions where mdpcomp is not possible */
- bool isDoable(hwc_context_t *ctx, hwc_display_contents_1_t* list);
- /* sets up MDP comp for current frame */
- bool setup(hwc_context_t* ctx, hwc_display_contents_1_t* list);
+ bool isFrameDoable(hwc_context_t *ctx);
+ /* checks for conditions where RGB layers cannot be bypassed */
+ bool isFullFrameDoable(hwc_context_t *ctx, hwc_display_contents_1_t* list);
+ /* checks for conditions where YUV layers cannot be bypassed */
+ bool isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer);
+
/* set up Border fill as Base pipe */
static bool setupBasePipe(hwc_context_t*);
/* Is debug enabled */
@@ -113,20 +143,34 @@
static bool isEnabled() { return sEnabled; };
/* checks for mdp comp width limitation */
bool isWidthValid(hwc_context_t *ctx, hwc_layer_1_t *layer);
+ /* tracks non updating layers*/
+ void updateLayerCache(hwc_context_t* ctx, hwc_display_contents_1_t* list);
+ /* resets cache for complete fallback */
+ void resetFrameForFB(hwc_context_t* ctx, hwc_display_contents_1_t* list);
+ /* optimize layers for mdp comp*/
+ void batchLayers();
+ /* gets available pipes for mdp comp */
+ int getAvailablePipes(hwc_context_t* ctx);
+ /* updates cache map with YUV info */
+ void updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list);
+ int programMDP(hwc_context_t *ctx, hwc_display_contents_1_t* list);
- eState mState;
+ int mDpy;
static bool sEnabled;
static bool sDebugLogs;
static bool sIdleFallBack;
+ static int sMaxPipesPerMixer;
static IdleInvalidator *idleInvalidator;
struct FrameInfo mCurrentFrame;
+ struct LayerCache mCachedFrame;
};
class MDPCompLowRes : public MDPComp {
public:
- virtual ~MDPCompLowRes(){};
- virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
+ explicit MDPCompLowRes(int dpy):MDPComp(dpy){};
+ virtual ~MDPCompLowRes(){};
+ virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
private:
struct MdpPipeInfoLowRes : public MdpPipeInfo {
@@ -134,21 +178,21 @@
virtual ~MdpPipeInfoLowRes() {};
};
+ virtual int pipesForFB() { return 1; };
/* configure's overlay pipes for the frame */
virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
- PipeLayerPair& pipeLayerPair);
+ PipeLayerPair& pipeLayerPair);
/* allocates pipes to selected candidates */
virtual bool allocLayerPipes(hwc_context_t *ctx,
- hwc_display_contents_1_t* list,
- FrameInfo& current_frame);
+ hwc_display_contents_1_t* list);
- virtual int pipesNeeded(hwc_context_t *ctx,
- hwc_display_contents_1_t* list);
+ virtual int pipesNeeded(hwc_context_t *ctx, hwc_display_contents_1_t* list);
};
class MDPCompHighRes : public MDPComp {
public:
+ explicit MDPCompHighRes(int dpy):MDPComp(dpy){};
virtual ~MDPCompHighRes(){};
virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
private:
@@ -159,16 +203,16 @@
};
bool acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
- MdpPipeInfoHighRes& pipe_info, ePipeType type);
+ MdpPipeInfoHighRes& pipe_info, ePipeType type);
+ virtual int pipesForFB() { return 2; };
/* configure's overlay pipes for the frame */
virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
- PipeLayerPair& pipeLayerPair);
+ PipeLayerPair& pipeLayerPair);
/* allocates pipes to selected candidates */
virtual bool allocLayerPipes(hwc_context_t *ctx,
- hwc_display_contents_1_t* list,
- FrameInfo& current_frame);
+ hwc_display_contents_1_t* list);
virtual int pipesNeeded(hwc_context_t *ctx, hwc_display_contents_1_t* list);
};