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