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