1/*
2 * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
3 *
4 * Not a Contribution, Apache license notifications and license are retained
5 * for attribution purposes only.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20#ifndef HWC_MDP_COMP
21#define HWC_MDP_COMP
22
23#include <hwc_utils.h>
24#include <idle_invalidator.h>
25#include <cutils/properties.h>
26#include <overlay.h>
27
28#define DEFAULT_IDLE_TIME 2000
29#define MAX_PIPES_PER_MIXER 4
30
31namespace overlay {
32class Rotator;
33};
34
35namespace qhwc {
36namespace ovutils = overlay::utils;
37
38class MDPComp {
39public:
40    explicit MDPComp(int);
41    virtual ~MDPComp(){};
42    /*sets up mdp comp for the current frame */
43    int prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list);
44    /* draw */
45    virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list) = 0;
46    /* dumpsys */
47    void dump(android::String8& buf);
48    void reset() { mCurrentFrame.reset(0); }
49    int getMDPCompCount() { return mCurrentFrame.mdpCount; }
50
51    static MDPComp* getObject(const int& width, const int& rightSplit,
52            const int& dpy);
53    /* Handler to invoke frame redraw on Idle Timer expiry */
54    static void timeout_handler(void *udata);
55    /* Initialize MDP comp*/
56    static bool init(hwc_context_t *ctx);
57    static void resetIdleFallBack() { sIdleFallBack = false; }
58
59protected:
60    enum { MAX_SEC_LAYERS = 1 }; //TODO add property support
61
62    enum ePipeType {
63        MDPCOMP_OV_RGB = ovutils::OV_MDP_PIPE_RGB,
64        MDPCOMP_OV_VG = ovutils::OV_MDP_PIPE_VG,
65        MDPCOMP_OV_DMA = ovutils::OV_MDP_PIPE_DMA,
66        MDPCOMP_OV_ANY,
67    };
68
69    /* mdp pipe data */
70    struct MdpPipeInfo {
71        int zOrder;
72        virtual ~MdpPipeInfo(){};
73    };
74
75    /* per layer data */
76    struct PipeLayerPair {
77        MdpPipeInfo *pipeInfo;
78        overlay::Rotator* rot;
79        int listIndex;
80    };
81
82    /* per frame data */
83    struct FrameInfo {
84        /* maps layer list to mdp list */
85        int layerCount;
86        int layerToMDP[MAX_NUM_APP_LAYERS];
87
88        /* maps mdp list to layer list */
89        int mdpCount;
90        struct PipeLayerPair mdpToLayer[MAX_PIPES_PER_MIXER];
91
92        /* layer composing on FB? */
93        int fbCount;
94        bool isFBComposed[MAX_NUM_APP_LAYERS];
95
96        bool needsRedraw;
97        int fbZ;
98
99        /* c'tor */
100        FrameInfo();
101        /* clear old frame data */
102        void reset(const int& numLayers);
103        void map();
104    };
105
106    /* cached data */
107    struct LayerCache {
108        int layerCount;
109        int mdpCount;
110        int fbCount;
111        int fbZ;
112        buffer_handle_t hnd[MAX_NUM_APP_LAYERS];
113
114        /* c'tor */
115        LayerCache();
116        /* clear caching info*/
117        void reset();
118        void cacheAll(hwc_display_contents_1_t* list);
119        void updateCounts(const FrameInfo&);
120    };
121
122    /* allocates pipe from pipe book */
123    virtual bool allocLayerPipes(hwc_context_t *ctx,
124                                 hwc_display_contents_1_t* list) = 0;
125    /* allocate MDP pipes from overlay */
126    ovutils::eDest getMdpPipe(hwc_context_t *ctx, ePipeType type, int mixer);
127    /* configures MPD pipes */
128    virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
129                          PipeLayerPair& pipeLayerPair) = 0;
130    /* Checks for pipes needed versus pipes available */
131    virtual bool arePipesAvailable(hwc_context_t *ctx,
132            hwc_display_contents_1_t* list) = 0;
133
134    /* set/reset flags for MDPComp */
135    void setMDPCompLayerFlags(hwc_context_t *ctx,
136                              hwc_display_contents_1_t* list);
137    /* checks for conditions where mdpcomp is not possible */
138    bool isFrameDoable(hwc_context_t *ctx);
139    /* checks for conditions where RGB layers cannot be bypassed */
140    bool isFullFrameDoable(hwc_context_t *ctx, hwc_display_contents_1_t* list);
141    /* checks if full MDP comp can be done */
142    bool fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
143    /* check if we can use layer cache to do at least partial MDP comp */
144    bool partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
145    /* Partial MDP comp that uses caching to save power as primary goal */
146    bool cacheBasedComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
147    /* Partial MDP comp that uses number of pixels to optimize perf goal */
148    bool loadBasedComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
149    /* Checks if its worth doing load based partial comp */
150    bool isLoadBasedCompDoable(hwc_context_t *ctx,
151            hwc_display_contents_1_t* list);
152    /* checks for conditions where only video can be bypassed */
153    bool isOnlyVideoDoable(hwc_context_t *ctx, hwc_display_contents_1_t* list);
154    /* checks for conditions where YUV layers cannot be bypassed */
155    bool isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer);
156
157    /* Is debug enabled */
158    static bool isDebug() { return sDebugLogs ? true : false; };
159    /* Is feature enabled */
160    static bool isEnabled() { return sEnabled; };
161    /* checks for mdp comp dimension limitation */
162    bool isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer);
163    /* tracks non updating layers*/
164    void updateLayerCache(hwc_context_t* ctx, hwc_display_contents_1_t* list);
165    /* optimize layers for mdp comp*/
166    bool batchLayers(hwc_context_t *ctx, hwc_display_contents_1_t* list);
167    /* updates cache map with YUV info */
168    void updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list);
169    bool programMDP(hwc_context_t *ctx, hwc_display_contents_1_t* list);
170    bool programYUV(hwc_context_t *ctx, hwc_display_contents_1_t* list);
171    void reset(const int& numAppLayers, hwc_display_contents_1_t* list);
172    bool isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer);
173
174    int mDpy;
175    static bool sEnabled;
176    static bool sEnableMixedMode;
177    static bool sDebugLogs;
178    static bool sIdleFallBack;
179    static int sMaxPipesPerMixer;
180    static IdleInvalidator *idleInvalidator;
181    struct FrameInfo mCurrentFrame;
182    struct LayerCache mCachedFrame;
183};
184
185class MDPCompLowRes : public MDPComp {
186public:
187    explicit MDPCompLowRes(int dpy):MDPComp(dpy){};
188    virtual ~MDPCompLowRes(){};
189    virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
190
191private:
192    struct MdpPipeInfoLowRes : public MdpPipeInfo {
193        ovutils::eDest index;
194        virtual ~MdpPipeInfoLowRes() {};
195    };
196
197    /* configure's overlay pipes for the frame */
198    virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
199                          PipeLayerPair& pipeLayerPair);
200
201    /* allocates pipes to selected candidates */
202    virtual bool allocLayerPipes(hwc_context_t *ctx,
203                                 hwc_display_contents_1_t* list);
204
205    /* Checks for pipes needed versus pipes available */
206    virtual bool arePipesAvailable(hwc_context_t *ctx,
207            hwc_display_contents_1_t* list);
208};
209
210class MDPCompHighRes : public MDPComp {
211public:
212    explicit MDPCompHighRes(int dpy):MDPComp(dpy){};
213    virtual ~MDPCompHighRes(){};
214    virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
215private:
216    struct MdpPipeInfoHighRes : public MdpPipeInfo {
217        ovutils::eDest lIndex;
218        ovutils::eDest rIndex;
219        virtual ~MdpPipeInfoHighRes() {};
220    };
221
222    bool acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
223                         MdpPipeInfoHighRes& pipe_info, ePipeType type);
224
225    /* configure's overlay pipes for the frame */
226    virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
227                          PipeLayerPair& pipeLayerPair);
228
229    /* allocates pipes to selected candidates */
230    virtual bool allocLayerPipes(hwc_context_t *ctx,
231                                 hwc_display_contents_1_t* list);
232
233    /* Checks for pipes needed versus pipes available */
234    virtual bool arePipesAvailable(hwc_context_t *ctx,
235            hwc_display_contents_1_t* list);
236
237    int pipesNeeded(hwc_context_t *ctx, hwc_display_contents_1_t* list,
238            int mixer);
239};
240
241}; //namespace
242#endif
243