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 
28 namespace overlay {
29 class Rotator;
30 };
31 
32 namespace qhwc {
33 namespace ovutils = overlay::utils;
34 
35 class MDPComp {
36 public:
37     explicit MDPComp(int);
~MDPComp()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);
isGLESOnlyComp()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);
resetIdleFallBack()54     static void resetIdleFallBack() { sIdleFallBack = false; }
isIdleFallback()55     static bool isIdleFallback() { return sIdleFallBack; }
dynamicDebug(bool enable)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);
setSingleFullScreenUpdate()62     static void setSingleFullScreenUpdate() { sIsSingleFullScreenUpdate = true; }
63 
64 protected:
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;
~MdpPipeInfoMdpPipeInfo84         virtual ~MdpPipeInfo(){};
85     };
86 
87     struct MdpYUVPipeInfo : public MdpPipeInfo{
88         ovutils::eDest lIndex;
89         ovutils::eDest rIndex;
~MdpYUVPipeInfoMdpYUVPipeInfo90         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 */
isDebug()208     static bool isDebug() { return sDebugLogs ? true : false; };
209     /* Is feature enabled */
isEnabled()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 
287 class MDPCompNonSplit : public MDPComp {
288 public:
MDPCompNonSplit(int dpy)289     explicit MDPCompNonSplit(int dpy):MDPComp(dpy){};
~MDPCompNonSplit()290     virtual ~MDPCompNonSplit(){};
291     virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
292 
293 private:
294     struct MdpPipeInfoNonSplit : public MdpPipeInfo {
295         ovutils::eDest index;
~MdpPipeInfoNonSplitMdpPipeInfoNonSplit296         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 
326 class MDPCompSplit : public MDPComp {
327 public:
MDPCompSplit(int dpy)328     explicit MDPCompSplit(int dpy):MDPComp(dpy){};
~MDPCompSplit()329     virtual ~MDPCompSplit(){};
330     virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
331 
332 protected:
333     struct MdpPipeInfoSplit : public MdpPipeInfo {
334         ovutils::eDest lIndex;
335         ovutils::eDest rIndex;
~MdpPipeInfoSplitMdpPipeInfoSplit336         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);
352 private:
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 
369 class MDPCompSrcSplit : public MDPCompSplit {
370 public:
MDPCompSrcSplit(int dpy)371     explicit MDPCompSrcSplit(int dpy) : MDPCompSplit(dpy){};
~MDPCompSrcSplit()372     virtual ~MDPCompSrcSplit(){};
373 private:
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