1/*
2 * Copyright (C) 2012-2015, 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
28namespace overlay {
29class Rotator;
30};
31
32namespace qhwc {
33namespace ovutils = overlay::utils;
34
35class MDPComp {
36public:
37    explicit MDPComp(int);
38    virtual ~MDPComp(){};
39    /*sets up mdp comp for the current frame */
40    int prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list);
41    /* draw */
42    virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list) = 0;
43    //Reset values
44    void reset();
45    /* dumpsys */
46    void dump(android::String8& buf, hwc_context_t *ctx);
47    bool isGLESOnlyComp() { return (mCurrentFrame.mdpCount == 0); }
48    int drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list);
49    static MDPComp* getObject(hwc_context_t *ctx, const int& dpy);
50    /* Handler to invoke frame redraw on Idle Timer expiry */
51    static void timeout_handler(void *udata);
52    /* Initialize MDP comp*/
53    static bool init(hwc_context_t *ctx);
54    static void resetIdleFallBack() { sIdleFallBack = false; }
55    static bool isIdleFallback() { return sIdleFallBack; }
56    static void dynamicDebug(bool enable){ sDebugLogs = enable; }
57    static void setIdleTimeout(const uint32_t& timeout);
58    static void setMaxPipesPerMixer(const uint32_t value);
59    static int setPartialUpdatePref(hwc_context_t *ctx, bool enable);
60    static bool getPartialUpdatePref(hwc_context_t *ctx);
61    void setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list);
62    static void setSingleFullScreenUpdate() { sIsSingleFullScreenUpdate = true; }
63
64protected:
65    enum ePipeType {
66        MDPCOMP_OV_RGB = ovutils::OV_MDP_PIPE_RGB,
67        MDPCOMP_OV_VG = ovutils::OV_MDP_PIPE_VG,
68        MDPCOMP_OV_DMA = ovutils::OV_MDP_PIPE_DMA,
69        MDPCOMP_OV_ANY,
70    };
71
72    //Simulation flags
73    enum {
74        MDPCOMP_AVOID_FULL_MDP = 0x001,
75        MDPCOMP_AVOID_CACHE_MDP = 0x002,
76        MDPCOMP_AVOID_LOAD_MDP = 0x004,
77        MDPCOMP_AVOID_VIDEO_ONLY = 0x008,
78        MDPCOMP_AVOID_MDP_ONLY_LAYERS = 0x010,
79    };
80
81    /* mdp pipe data */
82    struct MdpPipeInfo {
83        int zOrder;
84        virtual ~MdpPipeInfo(){};
85    };
86
87    struct MdpYUVPipeInfo : public MdpPipeInfo{
88        ovutils::eDest lIndex;
89        ovutils::eDest rIndex;
90        virtual ~MdpYUVPipeInfo(){};
91    };
92
93    /* per layer data */
94    struct PipeLayerPair {
95        MdpPipeInfo *pipeInfo;
96        overlay::Rotator* rot;
97        int listIndex;
98    };
99
100    /* per frame data */
101    struct FrameInfo {
102        /* maps layer list to mdp list */
103        int layerCount;
104        int layerToMDP[MAX_NUM_APP_LAYERS];
105
106        /* maps mdp list to layer list */
107        int mdpCount;
108        struct PipeLayerPair mdpToLayer[MAX_NUM_BLEND_STAGES];
109
110        /* layer composing on FB? */
111        int fbCount;
112        bool isFBComposed[MAX_NUM_APP_LAYERS];
113        /* layers lying outside ROI. Will
114         * be dropped off from the composition */
115        int dropCount;
116        bool drop[MAX_NUM_APP_LAYERS];
117
118        bool needsRedraw;
119        int fbZ;
120
121        /* c'tor */
122        FrameInfo();
123        /* clear old frame data */
124        void reset(const int& numLayers);
125        void map();
126    };
127
128    /* cached data */
129    struct LayerCache {
130        int layerCount;
131        bool isFBComposed[MAX_NUM_APP_LAYERS];
132        bool drop[MAX_NUM_APP_LAYERS];
133
134        /* c'tor */
135        LayerCache();
136        /* clear caching info*/
137        void reset();
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    /* Calculates the dirtyRegion for the given layer */
160    hwc_rect_t calculateDirtyRect(const hwc_layer_1_t* layer,
161                                hwc_rect_t& scissor);
162    /* validates the ROI generated for fallback conditions */
163    virtual bool validateAndApplyROI(hwc_context_t *ctx,
164            hwc_display_contents_1_t* list) = 0;
165    /* Trims layer coordinates against ROI generated */
166    virtual void trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& crop,
167            hwc_rect& dst) = 0;
168    /* set/reset flags for MDPComp */
169    void setMDPCompLayerFlags(hwc_context_t *ctx,
170                              hwc_display_contents_1_t* list);
171    void setRedraw(hwc_context_t *ctx,
172            hwc_display_contents_1_t* list);
173    /* checks for conditions where mdpcomp is not possible */
174    bool isFrameDoable(hwc_context_t *ctx);
175    /* checks for conditions where RGB layers cannot be bypassed */
176    bool tryFullFrame(hwc_context_t *ctx, hwc_display_contents_1_t* list);
177    /* checks if full MDP comp can be done */
178    bool fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
179    /* Full MDP Composition with Peripheral Tiny Overlap Removal */
180    bool fullMDPCompWithPTOR(hwc_context_t *ctx,hwc_display_contents_1_t* list);
181    /* check if we can use layer cache to do at least partial MDP comp */
182    bool partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
183    /* Partial MDP comp that uses caching to save power as primary goal */
184    bool cacheBasedComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
185    /* Partial MDP comp that balances the load between MDP and GPU such that
186     * MDP is loaded to the max of its capacity. The lower z order layers are
187     * fed to MDP, whereas the upper ones to GPU, because the upper ones have
188     * lower number of pixels and can reduce GPU processing time */
189    bool loadBasedComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
190    /* Checks if its worth doing load based partial comp */
191    bool isLoadBasedCompDoable(hwc_context_t *ctx);
192    /* checks for conditions where only video can be bypassed */
193    bool tryVideoOnly(hwc_context_t *ctx, hwc_display_contents_1_t* list);
194    bool videoOnlyComp(hwc_context_t *ctx, hwc_display_contents_1_t* list,
195            bool secureOnly);
196    /* checks for conditions where only secure RGB and video can be bypassed */
197    bool tryMDPOnlyLayers(hwc_context_t *ctx, hwc_display_contents_1_t* list);
198    bool mdpOnlyLayersComp(hwc_context_t *ctx, hwc_display_contents_1_t* list,
199            bool secureOnly);
200    /* checks for conditions where YUV layers cannot be bypassed */
201    bool isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer);
202    /* checks for conditions where Secure RGB layers cannot be bypassed */
203    bool isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer);
204    /* checks if MDP/MDSS can process current list w.r.to HW limitations
205     * All peculiar HW limitations should go here */
206    bool hwLimitationsCheck(hwc_context_t* ctx, hwc_display_contents_1_t* list);
207    /* Is debug enabled */
208    static bool isDebug() { return sDebugLogs ? true : false; };
209    /* Is feature enabled */
210    static bool isEnabled() { return sEnabled; };
211    /* checks for mdp comp dimension limitation */
212    bool isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer);
213    /* tracks non updating layers*/
214    void updateLayerCache(hwc_context_t* ctx, hwc_display_contents_1_t* list,
215                          FrameInfo& frame);
216    /* optimize layers for mdp comp*/
217    bool markLayersForCaching(hwc_context_t* ctx,
218            hwc_display_contents_1_t* list);
219    int getBatch(hwc_display_contents_1_t* list,
220            int& maxBatchStart, int& maxBatchEnd,
221            int& maxBatchCount);
222    bool canPushBatchToTop(const hwc_display_contents_1_t* list,
223            int fromIndex, int toIndex);
224    bool intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
225            int fromIndex, int toIndex, int targetLayerIndex);
226
227    /* drop other non-AIV layers from external display list.*/
228    void dropNonAIVLayers(hwc_context_t* ctx, hwc_display_contents_1_t* list);
229
230        /* updates cache map with YUV info */
231    void updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
232            bool secureOnly, FrameInfo& frame);
233    /* updates cache map with secure RGB info */
234    void updateSecureRGB(hwc_context_t* ctx,
235            hwc_display_contents_1_t* list);
236    /* Validates if the GPU/MDP layer split chosen by a strategy is supported
237     * by MDP.
238     * Sets up MDP comp data structures to reflect covnversion from layers to
239     * overlay pipes.
240     * Configures overlay.
241     * Configures if GPU should redraw.
242     */
243    bool postHeuristicsHandling(hwc_context_t *ctx,
244            hwc_display_contents_1_t* list);
245    void reset(hwc_context_t *ctx);
246    bool isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer);
247    bool resourceCheck(hwc_context_t* ctx, hwc_display_contents_1_t* list);
248    hwc_rect_t getUpdatingFBRect(hwc_context_t *ctx,
249            hwc_display_contents_1_t* list);
250    /* checks for conditions to enable partial udpate */
251    bool canPartialUpdate(hwc_context_t *ctx, hwc_display_contents_1_t* list);
252    // Checks if only videocontent is updating
253    bool onlyVideosUpdating(hwc_context_t *ctx, hwc_display_contents_1_t* list);
254    static bool loadPerfLib();
255    void setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list);
256
257    int mDpy;
258    static bool sEnabled;
259    static bool sEnableMixedMode;
260    static int sSimulationFlags;
261    static bool sDebugLogs;
262    static bool sIdleFallBack;
263    /* Handles the timeout event from kernel, if the value is set to true */
264    static bool sHandleTimeout;
265    static int sMaxPipesPerMixer;
266    static bool sSrcSplitEnabled;
267    static IdleInvalidator *sIdleInvalidator;
268    static bool sIsSingleFullScreenUpdate;
269    static int sMaxSecLayers;
270    static bool sIsPartialUpdateActive;
271    struct FrameInfo mCurrentFrame;
272    struct LayerCache mCachedFrame;
273    //Enable 4kx2k yuv layer split
274    static bool sEnableYUVsplit;
275    bool mModeOn; // if prepare happened
276    bool allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index);
277    //Enable Partial Update for MDP3 targets
278    static bool enablePartialUpdateForMDP3;
279    static void *sLibPerfHint;
280    static int sPerfLockHandle;
281    static int (*sPerfLockAcquire)(int, int, int*, int);
282    static int (*sPerfLockRelease)(int value);
283    static int sPerfHintWindow;
284
285};
286
287class MDPCompNonSplit : public MDPComp {
288public:
289    explicit MDPCompNonSplit(int dpy):MDPComp(dpy){};
290    virtual ~MDPCompNonSplit(){};
291    virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
292
293private:
294    struct MdpPipeInfoNonSplit : public MdpPipeInfo {
295        ovutils::eDest index;
296        virtual ~MdpPipeInfoNonSplit() {};
297    };
298
299    /* configure's overlay pipes for the frame */
300    virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
301                          PipeLayerPair& pipeLayerPair);
302
303    /* allocates pipes to selected candidates */
304    virtual bool allocLayerPipes(hwc_context_t *ctx,
305                                 hwc_display_contents_1_t* list);
306
307    /* Increments mdpCount if 4k2k yuv layer split is enabled.
308     * updates framebuffer z order if fb lies above source-split layer */
309    virtual void adjustForSourceSplit(hwc_context_t *ctx,
310            hwc_display_contents_1_t* list);
311
312    /* configures 4kx2k yuv layer to 2 VG pipes*/
313    virtual int configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
314            PipeLayerPair& PipeLayerPair);
315    /* generates ROI based on the modified area of the frame */
316    virtual void generateROI(hwc_context_t *ctx,
317            hwc_display_contents_1_t* list);
318    /* validates the ROI generated for fallback conditions */
319    virtual bool validateAndApplyROI(hwc_context_t *ctx,
320            hwc_display_contents_1_t* list);
321    /* Trims layer coordinates against ROI generated */
322    virtual void trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& crop,
323            hwc_rect& dst);
324};
325
326class MDPCompSplit : public MDPComp {
327public:
328    explicit MDPCompSplit(int dpy):MDPComp(dpy){};
329    virtual ~MDPCompSplit(){};
330    virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
331
332protected:
333    struct MdpPipeInfoSplit : public MdpPipeInfo {
334        ovutils::eDest lIndex;
335        ovutils::eDest rIndex;
336        virtual ~MdpPipeInfoSplit() {};
337    };
338
339    virtual bool acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
340                         MdpPipeInfoSplit& pipe_info);
341
342    /* configure's overlay pipes for the frame */
343    virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
344                          PipeLayerPair& pipeLayerPair);
345
346    /* allocates pipes to selected candidates */
347    virtual bool allocLayerPipes(hwc_context_t *ctx,
348                                 hwc_display_contents_1_t* list);
349    /* Trims layer coordinates against ROI generated */
350    virtual void trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& crop,
351            hwc_rect& dst);
352private:
353    /* Increments mdpCount if 4k2k yuv layer split is enabled.
354     * updates framebuffer z order if fb lies above source-split layer */
355    virtual void adjustForSourceSplit(hwc_context_t *ctx,
356            hwc_display_contents_1_t* list);
357
358    /* configures 4kx2k yuv layer*/
359    virtual int configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
360            PipeLayerPair& PipeLayerPair);
361    /* generates ROI based on the modified area of the frame */
362    virtual void generateROI(hwc_context_t *ctx,
363            hwc_display_contents_1_t* list);
364    /* validates the ROI generated for fallback conditions */
365    virtual bool validateAndApplyROI(hwc_context_t *ctx,
366            hwc_display_contents_1_t* list);
367};
368
369class MDPCompSrcSplit : public MDPCompSplit {
370public:
371    explicit MDPCompSrcSplit(int dpy) : MDPCompSplit(dpy){};
372    virtual ~MDPCompSrcSplit(){};
373private:
374    virtual bool acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
375            MdpPipeInfoSplit& pipe_info);
376
377    virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
378            PipeLayerPair& pipeLayerPair);
379    /* generates ROI based on the modified area of the frame */
380    virtual void generateROI(hwc_context_t *ctx,
381            hwc_display_contents_1_t* list);
382    /* validates the ROI generated for fallback conditions */
383    virtual bool validateAndApplyROI(hwc_context_t *ctx,
384            hwc_display_contents_1_t* list);
385};
386
387}; //namespace
388#endif
389