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 70
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    //Reset values
47    void reset();
48    /* dumpsys */
49    void dump(android::String8& buf, hwc_context_t *ctx);
50    bool isGLESOnlyComp() { return (mCurrentFrame.mdpCount == 0); }
51    int drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list);
52    static MDPComp* getObject(hwc_context_t *ctx, 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    static bool isIdleFallback() { return sIdleFallBack; }
59    static void dynamicDebug(bool enable){ sDebugLogs = enable; }
60
61protected:
62    enum { MAX_SEC_LAYERS = 1 }; //TODO add property support
63
64    enum ePipeType {
65        MDPCOMP_OV_RGB = ovutils::OV_MDP_PIPE_RGB,
66        MDPCOMP_OV_VG = ovutils::OV_MDP_PIPE_VG,
67        MDPCOMP_OV_DMA = ovutils::OV_MDP_PIPE_DMA,
68        MDPCOMP_OV_ANY,
69    };
70
71    //Simulation flags
72    enum {
73        MDPCOMP_AVOID_FULL_MDP = 0x001,
74        MDPCOMP_AVOID_CACHE_MDP = 0x002,
75        MDPCOMP_AVOID_LOAD_MDP = 0x004,
76        MDPCOMP_AVOID_VIDEO_ONLY = 0x008,
77    };
78
79    /* mdp pipe data */
80    struct MdpPipeInfo {
81        int zOrder;
82        virtual ~MdpPipeInfo(){};
83    };
84
85    struct MdpYUVPipeInfo : public MdpPipeInfo{
86        ovutils::eDest lIndex;
87        ovutils::eDest rIndex;
88        virtual ~MdpYUVPipeInfo(){};
89    };
90
91    /* per layer data */
92    struct PipeLayerPair {
93        MdpPipeInfo *pipeInfo;
94        overlay::Rotator* rot;
95        int listIndex;
96    };
97
98    /* per frame data */
99    struct FrameInfo {
100        /* maps layer list to mdp list */
101        int layerCount;
102        int layerToMDP[MAX_NUM_APP_LAYERS];
103
104        /* maps mdp list to layer list */
105        int mdpCount;
106        struct PipeLayerPair mdpToLayer[MAX_PIPES_PER_MIXER];
107
108        /* layer composing on FB? */
109        int fbCount;
110        bool isFBComposed[MAX_NUM_APP_LAYERS];
111        /* layers lying outside ROI. Will
112         * be dropped off from the composition */
113        int dropCount;
114        bool drop[MAX_NUM_APP_LAYERS];
115
116        bool needsRedraw;
117        int fbZ;
118
119        /* c'tor */
120        FrameInfo();
121        /* clear old frame data */
122        void reset(const int& numLayers);
123        void map();
124    };
125
126    /* cached data */
127    struct LayerCache {
128        int layerCount;
129        buffer_handle_t hnd[MAX_NUM_APP_LAYERS];
130        bool isFBComposed[MAX_NUM_APP_LAYERS];
131        bool drop[MAX_NUM_APP_LAYERS];
132
133        /* c'tor */
134        LayerCache();
135        /* clear caching info*/
136        void reset();
137        void cacheAll(hwc_display_contents_1_t* list);
138        void updateCounts(const FrameInfo&);
139        bool isSameFrame(const FrameInfo& curFrame,
140                         hwc_display_contents_1_t* list);
141    };
142
143    /* allocates pipe from pipe book */
144    virtual bool allocLayerPipes(hwc_context_t *ctx,
145                                 hwc_display_contents_1_t* list) = 0;
146    /* configures MPD pipes */
147    virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
148                          PipeLayerPair& pipeLayerPair) = 0;
149    /* Increments mdpCount if 4k2k yuv layer split is enabled.
150     * updates framebuffer z order if fb lies above source-split layer */
151    virtual void adjustForSourceSplit(hwc_context_t *ctx,
152            hwc_display_contents_1_t* list) = 0;
153    /* configures 4kx2k yuv layer*/
154    virtual int configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
155            PipeLayerPair& PipeLayerPair) = 0;
156    /* generates ROI based on the modified area of the frame */
157    virtual void generateROI(hwc_context_t *ctx,
158            hwc_display_contents_1_t* list) = 0;
159    /* validates the ROI generated for fallback conditions */
160    virtual bool validateAndApplyROI(hwc_context_t *ctx,
161            hwc_display_contents_1_t* list) = 0;
162    /* Trims fbRect calculated against ROI generated */
163    virtual void trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) = 0;
164
165    /* set/reset flags for MDPComp */
166    void setMDPCompLayerFlags(hwc_context_t *ctx,
167                              hwc_display_contents_1_t* list);
168    void setRedraw(hwc_context_t *ctx,
169            hwc_display_contents_1_t* list);
170    /* checks for conditions where mdpcomp is not possible */
171    bool isFrameDoable(hwc_context_t *ctx);
172    /* checks for conditions where RGB layers cannot be bypassed */
173    bool tryFullFrame(hwc_context_t *ctx, hwc_display_contents_1_t* list);
174    /* checks if full MDP comp can be done */
175    bool fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
176    /* Full MDP Composition with Peripheral Tiny Overlap Removal */
177    bool fullMDPCompWithPTOR(hwc_context_t *ctx,hwc_display_contents_1_t* list);
178    /* check if we can use layer cache to do at least partial MDP comp */
179    bool partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
180    /* Partial MDP comp that uses caching to save power as primary goal */
181    bool cacheBasedComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
182    /* Partial MDP comp that balances the load between MDP and GPU such that
183     * MDP is loaded to the max of its capacity. The lower z order layers are
184     * fed to MDP, whereas the upper ones to GPU, because the upper ones have
185     * lower number of pixels and can reduce GPU processing time */
186    bool loadBasedComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
187    /* Checks if its worth doing load based partial comp */
188    bool isLoadBasedCompDoable(hwc_context_t *ctx);
189    /* checks for conditions where only video can be bypassed */
190    bool tryVideoOnly(hwc_context_t *ctx, hwc_display_contents_1_t* list);
191    bool videoOnlyComp(hwc_context_t *ctx, hwc_display_contents_1_t* list,
192            bool secureOnly);
193    /* checks for conditions where YUV layers cannot be bypassed */
194    bool isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer);
195    /* checks if MDP/MDSS can process current list w.r.to HW limitations
196     * All peculiar HW limitations should go here */
197    bool hwLimitationsCheck(hwc_context_t* ctx, hwc_display_contents_1_t* list);
198    /* Is debug enabled */
199    static bool isDebug() { return sDebugLogs ? true : false; };
200    /* Is feature enabled */
201    static bool isEnabled() { return sEnabled; };
202    /* checks for mdp comp dimension limitation */
203    bool isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer);
204    /* tracks non updating layers*/
205    void updateLayerCache(hwc_context_t* ctx, hwc_display_contents_1_t* list);
206    /* optimize layers for mdp comp*/
207    bool markLayersForCaching(hwc_context_t* ctx,
208            hwc_display_contents_1_t* list);
209    int getBatch(hwc_display_contents_1_t* list,
210            int& maxBatchStart, int& maxBatchEnd,
211            int& maxBatchCount);
212    bool canPushBatchToTop(const hwc_display_contents_1_t* list,
213            int fromIndex, int toIndex);
214    bool intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
215            int fromIndex, int toIndex, int targetLayerIndex);
216
217        /* updates cache map with YUV info */
218    void updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
219            bool secureOnly);
220    /* Validates if the GPU/MDP layer split chosen by a strategy is supported
221     * by MDP.
222     * Sets up MDP comp data structures to reflect covnversion from layers to
223     * overlay pipes.
224     * Configures overlay.
225     * Configures if GPU should redraw.
226     */
227    bool postHeuristicsHandling(hwc_context_t *ctx,
228            hwc_display_contents_1_t* list);
229    void reset(hwc_context_t *ctx);
230    bool isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer);
231    bool resourceCheck(hwc_context_t* ctx, hwc_display_contents_1_t* list);
232    hwc_rect_t getUpdatingFBRect(hwc_context_t *ctx,
233            hwc_display_contents_1_t* list);
234    /* checks for conditions to enable partial udpate */
235    bool canPartialUpdate(hwc_context_t *ctx, hwc_display_contents_1_t* list);
236
237    int mDpy;
238    static bool sEnabled;
239    static bool sEnableMixedMode;
240    static int sSimulationFlags;
241    static bool sDebugLogs;
242    static bool sIdleFallBack;
243    /* Handles the timeout event from kernel, if the value is set to true */
244    static bool sHandleTimeout;
245    static int sMaxPipesPerMixer;
246    static bool sSrcSplitEnabled;
247    static IdleInvalidator *idleInvalidator;
248    struct FrameInfo mCurrentFrame;
249    struct LayerCache mCachedFrame;
250    //Enable 4kx2k yuv layer split
251    static bool sEnable4k2kYUVSplit;
252    bool mModeOn; // if prepare happened
253    bool allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index);
254};
255
256class MDPCompNonSplit : public MDPComp {
257public:
258    explicit MDPCompNonSplit(int dpy):MDPComp(dpy){};
259    virtual ~MDPCompNonSplit(){};
260    virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
261
262private:
263    struct MdpPipeInfoNonSplit : public MdpPipeInfo {
264        ovutils::eDest index;
265        virtual ~MdpPipeInfoNonSplit() {};
266    };
267
268    /* configure's overlay pipes for the frame */
269    virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
270                          PipeLayerPair& pipeLayerPair);
271
272    /* allocates pipes to selected candidates */
273    virtual bool allocLayerPipes(hwc_context_t *ctx,
274                                 hwc_display_contents_1_t* list);
275
276    /* Increments mdpCount if 4k2k yuv layer split is enabled.
277     * updates framebuffer z order if fb lies above source-split layer */
278    virtual void adjustForSourceSplit(hwc_context_t *ctx,
279            hwc_display_contents_1_t* list);
280
281    /* configures 4kx2k yuv layer to 2 VG pipes*/
282    virtual int configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
283            PipeLayerPair& PipeLayerPair);
284    /* generates ROI based on the modified area of the frame */
285    virtual void generateROI(hwc_context_t *ctx,
286            hwc_display_contents_1_t* list);
287    /* validates the ROI generated for fallback conditions */
288    virtual bool validateAndApplyROI(hwc_context_t *ctx,
289            hwc_display_contents_1_t* list);
290    /* Trims fbRect calculated against ROI generated */
291    virtual void trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect);
292};
293
294class MDPCompSplit : public MDPComp {
295public:
296    explicit MDPCompSplit(int dpy):MDPComp(dpy){};
297    virtual ~MDPCompSplit(){};
298    virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
299
300protected:
301    struct MdpPipeInfoSplit : public MdpPipeInfo {
302        ovutils::eDest lIndex;
303        ovutils::eDest rIndex;
304        virtual ~MdpPipeInfoSplit() {};
305    };
306
307    virtual bool acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
308                         MdpPipeInfoSplit& pipe_info);
309
310    /* configure's overlay pipes for the frame */
311    virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
312                          PipeLayerPair& pipeLayerPair);
313
314    /* allocates pipes to selected candidates */
315    virtual bool allocLayerPipes(hwc_context_t *ctx,
316                                 hwc_display_contents_1_t* list);
317private:
318    /* Increments mdpCount if 4k2k yuv layer split is enabled.
319     * updates framebuffer z order if fb lies above source-split layer */
320    virtual void adjustForSourceSplit(hwc_context_t *ctx,
321            hwc_display_contents_1_t* list);
322
323    /* configures 4kx2k yuv layer*/
324    virtual int configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
325            PipeLayerPair& PipeLayerPair);
326    /* generates ROI based on the modified area of the frame */
327    virtual void generateROI(hwc_context_t *ctx,
328            hwc_display_contents_1_t* list);
329    /* validates the ROI generated for fallback conditions */
330    virtual bool validateAndApplyROI(hwc_context_t *ctx,
331            hwc_display_contents_1_t* list);
332    /* Trims fbRect calculated against ROI generated */
333    virtual void trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect);
334};
335
336class MDPCompSrcSplit : public MDPCompSplit {
337public:
338    explicit MDPCompSrcSplit(int dpy) : MDPCompSplit(dpy){};
339    virtual ~MDPCompSrcSplit(){};
340private:
341    virtual bool acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
342            MdpPipeInfoSplit& pipe_info);
343
344    virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
345            PipeLayerPair& pipeLayerPair);
346};
347
348}; //namespace
349#endif
350