1 /*
2  * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
3  * Not a Contribution, Apache license notifications and license are retained
4  * for attribution purposes only.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #include <math.h>
20 #include "hwc_mdpcomp.h"
21 #include <sys/ioctl.h>
22 #include "external.h"
23 #include "virtual.h"
24 #include "qdMetaData.h"
25 #include "mdp_version.h"
26 #include "hwc_fbupdate.h"
27 #include "hwc_ad.h"
28 #include <overlayRotator.h>
29 #include "hwc_copybit.h"
30 
31 using namespace overlay;
32 using namespace qdutils;
33 using namespace overlay::utils;
34 namespace ovutils = overlay::utils;
35 
36 namespace qhwc {
37 
38 //==============MDPComp========================================================
39 
40 IdleInvalidator *MDPComp::idleInvalidator = NULL;
41 bool MDPComp::sIdleFallBack = false;
42 bool MDPComp::sHandleTimeout = false;
43 bool MDPComp::sDebugLogs = false;
44 bool MDPComp::sEnabled = false;
45 bool MDPComp::sEnableMixedMode = true;
46 int MDPComp::sSimulationFlags = 0;
47 int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
48 bool MDPComp::sEnable4k2kYUVSplit = false;
49 bool MDPComp::sSrcSplitEnabled = false;
getObject(hwc_context_t * ctx,const int & dpy)50 MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
51     if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
52         sSrcSplitEnabled = true;
53         return new MDPCompSrcSplit(dpy);
54     } else if(isDisplaySplit(ctx, dpy)) {
55         return new MDPCompSplit(dpy);
56     }
57     return new MDPCompNonSplit(dpy);
58 }
59 
MDPComp(int dpy)60 MDPComp::MDPComp(int dpy):mDpy(dpy){};
61 
dump(android::String8 & buf,hwc_context_t * ctx)62 void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
63 {
64     if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
65         return;
66 
67     dumpsys_log(buf,"HWC Map for Dpy: %s \n",
68                 (mDpy == 0) ? "\"PRIMARY\"" :
69                 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
70     dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
71                 "fbCount:%2d \n", mCurrentFrame.layerCount,
72                 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
73     dumpsys_log(buf,"needsFBRedraw:%3s  pipesUsed:%2d  MaxPipesPerMixer: %d \n",
74                 (mCurrentFrame.needsRedraw? "YES" : "NO"),
75                 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
76     if(isDisplaySplit(ctx, mDpy)) {
77         dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
78                 "Right: [%d, %d, %d, %d] \n",
79                 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
80                 ctx->listStats[mDpy].lRoi.right,
81                 ctx->listStats[mDpy].lRoi.bottom,
82                 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
83                 ctx->listStats[mDpy].rRoi.right,
84                 ctx->listStats[mDpy].rRoi.bottom);
85     } else {
86         dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
87                 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
88                 ctx->listStats[mDpy].lRoi.right,
89                 ctx->listStats[mDpy].lRoi.bottom);
90     }
91     dumpsys_log(buf," ---------------------------------------------  \n");
92     dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype  |  Z  \n");
93     dumpsys_log(buf," ---------------------------------------------  \n");
94     for(int index = 0; index < mCurrentFrame.layerCount; index++ )
95         dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
96                     index,
97                     (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
98                      mCurrentFrame.layerToMDP[index],
99                     (mCurrentFrame.isFBComposed[index] ?
100                     (mCurrentFrame.drop[index] ? "DROP" :
101                     (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
102                     (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
103     mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
104     dumpsys_log(buf,"\n");
105 }
106 
init(hwc_context_t * ctx)107 bool MDPComp::init(hwc_context_t *ctx) {
108 
109     if(!ctx) {
110         ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
111         return false;
112     }
113 
114     char property[PROPERTY_VALUE_MAX];
115 
116     sEnabled = false;
117     if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
118        (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
119         (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
120         sEnabled = true;
121     }
122 
123 #ifdef DELTA_PANEL
124     if((property_get("ro.hwc.is_delta_panel", property, NULL) > 0) &&
125        (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
126         (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
127         sEnabled = false;
128     }
129 #endif
130 
131     sEnableMixedMode = true;
132     if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
133        (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
134         (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
135         sEnableMixedMode = false;
136     }
137 
138     sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
139     if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
140         int val = atoi(property);
141         if(val >= 0)
142             sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
143     }
144 
145     if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
146         // Idle invalidation is not necessary on command mode panels
147         long idle_timeout = DEFAULT_IDLE_TIME;
148         if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
149             if(atoi(property) != 0)
150                 idle_timeout = atoi(property);
151         }
152 
153         //create Idle Invalidator only when not disabled through property
154         if(idle_timeout != -1)
155             idleInvalidator = IdleInvalidator::getInstance();
156 
157         if(idleInvalidator == NULL) {
158             ALOGE("%s: failed to instantiate idleInvalidator object",
159                   __FUNCTION__);
160         } else {
161             idleInvalidator->init(timeout_handler, ctx,
162                                   (unsigned int)idle_timeout);
163         }
164     }
165 
166     if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
167             property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
168             (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
169             !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
170         sEnable4k2kYUVSplit = true;
171     }
172 
173     if ((property_get("persist.hwc.ptor.enable", property, NULL) > 0) &&
174             ((!strncasecmp(property, "true", PROPERTY_VALUE_MAX )) ||
175              (!strncmp(property, "1", PROPERTY_VALUE_MAX )))) {
176         ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
177                                                     HWC_DISPLAY_PRIMARY);
178     }
179 
180     return true;
181 }
182 
reset(hwc_context_t * ctx)183 void MDPComp::reset(hwc_context_t *ctx) {
184     const int numLayers = ctx->listStats[mDpy].numAppLayers;
185     mCurrentFrame.reset(numLayers);
186     ctx->mOverlay->clear(mDpy);
187     ctx->mLayerRotMap[mDpy]->clear();
188 }
189 
reset()190 void MDPComp::reset() {
191     sHandleTimeout = false;
192     mModeOn = false;
193 }
194 
timeout_handler(void * udata)195 void MDPComp::timeout_handler(void *udata) {
196     struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
197 
198     if(!ctx) {
199         ALOGE("%s: received empty data in timer callback", __FUNCTION__);
200         return;
201     }
202     Locker::Autolock _l(ctx->mDrawLock);
203     // Handle timeout event only if the previous composition is MDP or MIXED.
204     if(!sHandleTimeout) {
205         ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
206         return;
207     }
208     if(!ctx->proc) {
209         ALOGE("%s: HWC proc not registered", __FUNCTION__);
210         return;
211     }
212     sIdleFallBack = true;
213     /* Trigger SF to redraw the current frame */
214     ctx->proc->invalidate(ctx->proc);
215 }
216 
setMDPCompLayerFlags(hwc_context_t * ctx,hwc_display_contents_1_t * list)217 void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
218                                    hwc_display_contents_1_t* list) {
219     LayerProp *layerProp = ctx->layerProp[mDpy];
220 
221     for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
222         hwc_layer_1_t* layer = &(list->hwLayers[index]);
223         if(!mCurrentFrame.isFBComposed[index]) {
224             layerProp[index].mFlags |= HWC_MDPCOMP;
225             layer->compositionType = HWC_OVERLAY;
226             layer->hints |= HWC_HINT_CLEAR_FB;
227         } else {
228             /* Drop the layer when its already present in FB OR when it lies
229              * outside frame's ROI */
230             if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
231                 layer->compositionType = HWC_OVERLAY;
232             }
233         }
234     }
235 }
236 
setRedraw(hwc_context_t * ctx,hwc_display_contents_1_t * list)237 void MDPComp::setRedraw(hwc_context_t *ctx,
238         hwc_display_contents_1_t* list) {
239     mCurrentFrame.needsRedraw = false;
240     if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
241             (list->flags & HWC_GEOMETRY_CHANGED) ||
242             isSkipPresent(ctx, mDpy)) {
243         mCurrentFrame.needsRedraw = true;
244     }
245 }
246 
FrameInfo()247 MDPComp::FrameInfo::FrameInfo() {
248     memset(&mdpToLayer, 0, sizeof(mdpToLayer));
249     reset(0);
250 }
251 
reset(const int & numLayers)252 void MDPComp::FrameInfo::reset(const int& numLayers) {
253     for(int i = 0 ; i < MAX_PIPES_PER_MIXER; i++ ) {
254         if(mdpToLayer[i].pipeInfo) {
255             delete mdpToLayer[i].pipeInfo;
256             mdpToLayer[i].pipeInfo = NULL;
257             //We dont own the rotator
258             mdpToLayer[i].rot = NULL;
259         }
260     }
261 
262     memset(&mdpToLayer, 0, sizeof(mdpToLayer));
263     memset(&layerToMDP, -1, sizeof(layerToMDP));
264     memset(&isFBComposed, 1, sizeof(isFBComposed));
265 
266     layerCount = numLayers;
267     fbCount = numLayers;
268     mdpCount = 0;
269     needsRedraw = true;
270     fbZ = -1;
271 }
272 
map()273 void MDPComp::FrameInfo::map() {
274     // populate layer and MDP maps
275     int mdpIdx = 0;
276     for(int idx = 0; idx < layerCount; idx++) {
277         if(!isFBComposed[idx]) {
278             mdpToLayer[mdpIdx].listIndex = idx;
279             layerToMDP[idx] = mdpIdx++;
280         }
281     }
282 }
283 
LayerCache()284 MDPComp::LayerCache::LayerCache() {
285     reset();
286 }
287 
reset()288 void MDPComp::LayerCache::reset() {
289     memset(&hnd, 0, sizeof(hnd));
290     memset(&isFBComposed, true, sizeof(isFBComposed));
291     memset(&drop, false, sizeof(drop));
292     layerCount = 0;
293 }
294 
cacheAll(hwc_display_contents_1_t * list)295 void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
296     const int numAppLayers = (int)list->numHwLayers - 1;
297     for(int i = 0; i < numAppLayers; i++) {
298         hnd[i] = list->hwLayers[i].handle;
299     }
300 }
301 
updateCounts(const FrameInfo & curFrame)302 void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
303     layerCount = curFrame.layerCount;
304     memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
305     memcpy(&drop, &curFrame.drop, sizeof(drop));
306 }
307 
isSameFrame(const FrameInfo & curFrame,hwc_display_contents_1_t * list)308 bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
309                                       hwc_display_contents_1_t* list) {
310     if(layerCount != curFrame.layerCount)
311         return false;
312     for(int i = 0; i < curFrame.layerCount; i++) {
313         if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
314                 (curFrame.drop[i] != drop[i])) {
315             return false;
316         }
317         if(curFrame.isFBComposed[i] &&
318            (hnd[i] != list->hwLayers[i].handle)){
319             return false;
320         }
321     }
322     return true;
323 }
324 
isSupportedForMDPComp(hwc_context_t * ctx,hwc_layer_1_t * layer)325 bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
326     private_handle_t *hnd = (private_handle_t *)layer->handle;
327     if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
328         (not isValidDimension(ctx,layer))
329         //More conditions here, SKIP, sRGB+Blend etc
330         ) {
331         return false;
332     }
333     return true;
334 }
335 
isValidDimension(hwc_context_t * ctx,hwc_layer_1_t * layer)336 bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
337     private_handle_t *hnd = (private_handle_t *)layer->handle;
338 
339     if(!hnd) {
340         if (layer->flags & HWC_COLOR_FILL) {
341             // Color layer
342             return true;
343         }
344         ALOGE("%s: layer handle is NULL", __FUNCTION__);
345         return false;
346     }
347 
348     //XXX: Investigate doing this with pixel phase on MDSS
349     if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
350         return false;
351 
352     hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
353     hwc_rect_t dst = layer->displayFrame;
354     bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
355     int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
356     int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
357     int dst_w = dst.right - dst.left;
358     int dst_h = dst.bottom - dst.top;
359     float w_scale = ((float)crop_w / (float)dst_w);
360     float h_scale = ((float)crop_h / (float)dst_h);
361 
362     /* Workaround for MDP HW limitation in DSI command mode panels where
363      * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
364      * less than 5 pixels
365      * There also is a HW limilation in MDP, minimum block size is 2x2
366      * Fallback to GPU if height is less than 2.
367      */
368     if((crop_w < 5)||(crop_h < 5))
369         return false;
370 
371     if((w_scale > 1.0f) || (h_scale > 1.0f)) {
372         const uint32_t maxMDPDownscale =
373             qdutils::MDPVersion::getInstance().getMaxMDPDownscale();
374         const float w_dscale = w_scale;
375         const float h_dscale = h_scale;
376 
377         if(ctx->mMDP.version >= qdutils::MDSS_V5) {
378 
379             if(!qdutils::MDPVersion::getInstance().supportsDecimation()) {
380                 /* On targets that doesnt support Decimation (eg.,8x26)
381                  * maximum downscale support is overlay pipe downscale.
382                  */
383                 if(crop_w > MAX_DISPLAY_DIM || w_dscale > maxMDPDownscale ||
384                         h_dscale > maxMDPDownscale)
385                     return false;
386             } else {
387                 // Decimation on macrotile format layers is not supported.
388                 if(isTileRendered(hnd)) {
389                     /* MDP can read maximum MAX_DISPLAY_DIM width.
390                      * Bail out if
391                      *      1. Src crop > MAX_DISPLAY_DIM on nonsplit MDPComp
392                      *      2. exceeds maximum downscale limit
393                      */
394                     if(((crop_w > MAX_DISPLAY_DIM) && !sSrcSplitEnabled) ||
395                             w_dscale > maxMDPDownscale ||
396                             h_dscale > maxMDPDownscale) {
397                         return false;
398                     }
399                 } else if(w_dscale > 64 || h_dscale > 64)
400                     return false;
401             }
402         } else { //A-family
403             if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
404                 return false;
405         }
406     }
407 
408     if((w_scale < 1.0f) || (h_scale < 1.0f)) {
409         const uint32_t upscale =
410             qdutils::MDPVersion::getInstance().getMaxMDPUpscale();
411         const float w_uscale = 1.0f / w_scale;
412         const float h_uscale = 1.0f / h_scale;
413 
414         if(w_uscale > upscale || h_uscale > upscale)
415             return false;
416     }
417 
418     return true;
419 }
420 
isFrameDoable(hwc_context_t * ctx)421 bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
422     bool ret = true;
423 
424     if(!isEnabled()) {
425         ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
426         ret = false;
427     } else if((qdutils::MDPVersion::getInstance().is8x26() ||
428                qdutils::MDPVersion::getInstance().is8x16() ||
429                qdutils::MDPVersion::getInstance().is8x39()) &&
430             ctx->mVideoTransFlag &&
431             isSecondaryConnected(ctx)) {
432         //1 Padding round to shift pipes across mixers
433         ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
434                 __FUNCTION__);
435         ret = false;
436     } else if(isSecondaryConfiguring(ctx)) {
437         ALOGD_IF( isDebug(),"%s: External Display connection is pending",
438                   __FUNCTION__);
439         ret = false;
440     } else if(ctx->isPaddingRound) {
441         ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
442                  __FUNCTION__,mDpy);
443         ret = false;
444     }
445     return ret;
446 }
447 
trimAgainstROI(hwc_context_t * ctx,hwc_rect_t & fbRect)448 void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
449     hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
450     fbRect = getIntersection(fbRect, roi);
451 }
452 
453 /* 1) Identify layers that are not visible or lying outside the updating ROI and
454  *    drop them from composition.
455  * 2) If we have a scaling layer which needs cropping against generated
456  *    ROI, reset ROI to full resolution. */
validateAndApplyROI(hwc_context_t * ctx,hwc_display_contents_1_t * list)457 bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
458         hwc_display_contents_1_t* list) {
459     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
460     hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
461 
462     for(int i = numAppLayers - 1; i >= 0; i--){
463         if(!isValidRect(visibleRect)) {
464             mCurrentFrame.drop[i] = true;
465             mCurrentFrame.dropCount++;
466             continue;
467         }
468 
469         const hwc_layer_1_t* layer =  &list->hwLayers[i];
470         hwc_rect_t dstRect = layer->displayFrame;
471         hwc_rect_t res  = getIntersection(visibleRect, dstRect);
472 
473         if(!isValidRect(res)) {
474             mCurrentFrame.drop[i] = true;
475             mCurrentFrame.dropCount++;
476         } else {
477             /* Reset frame ROI when any layer which needs scaling also needs ROI
478              * cropping */
479             if(!isSameRect(res, dstRect) && needsScaling (layer)) {
480                 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
481                 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
482                 mCurrentFrame.dropCount = 0;
483                 return false;
484             }
485 
486             /* deduct any opaque region from visibleRect */
487             if (layer->blending == HWC_BLENDING_NONE)
488                 visibleRect = deductRect(visibleRect, res);
489         }
490     }
491     return true;
492 }
493 
494 /* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
495  * are updating. If DirtyRegion is applicable, calculate it by accounting all
496  * the changing layer's dirtyRegion. */
generateROI(hwc_context_t * ctx,hwc_display_contents_1_t * list)497 void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
498         hwc_display_contents_1_t* list) {
499     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
500     if(!canPartialUpdate(ctx, list))
501         return;
502 
503     struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
504     hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
505         (int)ctx->dpyAttr[mDpy].yres};
506 
507     for(int index = 0; index < numAppLayers; index++ ) {
508         hwc_layer_1_t* layer = &list->hwLayers[index];
509         if ((mCachedFrame.hnd[index] != layer->handle) ||
510                 isYuvBuffer((private_handle_t *)layer->handle)) {
511             hwc_rect_t dst = layer->displayFrame;
512             hwc_rect_t updatingRect = dst;
513 
514 #ifdef QCOM_BSP
515             if(!needsScaling(layer) && !layer->transform)
516             {
517                 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
518                 int x_off = dst.left - src.left;
519                 int y_off = dst.top - src.top;
520                 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
521             }
522 #endif
523 
524             roi = getUnion(roi, updatingRect);
525         }
526     }
527 
528     /* No layer is updating. Still SF wants a refresh.*/
529     if(!isValidRect(roi))
530         return;
531 
532     // Align ROI coordinates to panel restrictions
533     roi = getSanitizeROI(roi, fullFrame);
534 
535     ctx->listStats[mDpy].lRoi = roi;
536     if(!validateAndApplyROI(ctx, list))
537         resetROI(ctx, mDpy);
538 
539     ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
540             ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
541             ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
542 }
543 
trimAgainstROI(hwc_context_t * ctx,hwc_rect_t & fbRect)544 void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
545     hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
546     hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
547 
548     hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
549     hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
550     fbRect = getUnion(l_fbRect, r_fbRect);
551 }
552 /* 1) Identify layers that are not visible or lying outside BOTH the updating
553  *    ROI's and drop them from composition. If a layer is spanning across both
554  *    the halves of the screen but needed by only ROI, the non-contributing
555  *    half will not be programmed for MDP.
556  * 2) If we have a scaling layer which needs cropping against generated
557  *    ROI, reset ROI to full resolution. */
validateAndApplyROI(hwc_context_t * ctx,hwc_display_contents_1_t * list)558 bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
559         hwc_display_contents_1_t* list) {
560 
561     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
562 
563     hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
564     hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
565 
566     for(int i = numAppLayers - 1; i >= 0; i--){
567         if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
568         {
569             mCurrentFrame.drop[i] = true;
570             mCurrentFrame.dropCount++;
571             continue;
572         }
573 
574         const hwc_layer_1_t* layer =  &list->hwLayers[i];
575         hwc_rect_t dstRect = layer->displayFrame;
576 
577         hwc_rect_t l_res  = getIntersection(visibleRectL, dstRect);
578         hwc_rect_t r_res  = getIntersection(visibleRectR, dstRect);
579         hwc_rect_t res = getUnion(l_res, r_res);
580 
581         if(!isValidRect(l_res) && !isValidRect(r_res)) {
582             mCurrentFrame.drop[i] = true;
583             mCurrentFrame.dropCount++;
584         } else {
585             /* Reset frame ROI when any layer which needs scaling also needs ROI
586              * cropping */
587             if(!isSameRect(res, dstRect) && needsScaling (layer)) {
588                 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
589                 mCurrentFrame.dropCount = 0;
590                 return false;
591             }
592 
593             if (layer->blending == HWC_BLENDING_NONE) {
594                 visibleRectL = deductRect(visibleRectL, l_res);
595                 visibleRectR = deductRect(visibleRectR, r_res);
596             }
597         }
598     }
599     return true;
600 }
601 /* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
602  * are updating. If DirtyRegion is applicable, calculate it by accounting all
603  * the changing layer's dirtyRegion. */
generateROI(hwc_context_t * ctx,hwc_display_contents_1_t * list)604 void MDPCompSplit::generateROI(hwc_context_t *ctx,
605         hwc_display_contents_1_t* list) {
606     if(!canPartialUpdate(ctx, list))
607         return;
608 
609     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
610     int lSplit = getLeftSplit(ctx, mDpy);
611 
612     int hw_h = (int)ctx->dpyAttr[mDpy].yres;
613     int hw_w = (int)ctx->dpyAttr[mDpy].xres;
614 
615     struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
616     struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
617 
618     struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
619     struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
620 
621     for(int index = 0; index < numAppLayers; index++ ) {
622         hwc_layer_1_t* layer = &list->hwLayers[index];
623         private_handle_t *hnd = (private_handle_t *)layer->handle;
624         if ((mCachedFrame.hnd[index] != layer->handle) ||
625                 isYuvBuffer(hnd)) {
626             hwc_rect_t dst = layer->displayFrame;
627             hwc_rect_t updatingRect = dst;
628 
629 #ifdef QCOM_BSP
630             if(!needsScaling(layer) && !layer->transform)
631             {
632                 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
633                 int x_off = dst.left - src.left;
634                 int y_off = dst.top - src.top;
635                 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
636             }
637 #endif
638 
639             hwc_rect_t l_dst  = getIntersection(l_frame, updatingRect);
640             if(isValidRect(l_dst))
641                 l_roi = getUnion(l_roi, l_dst);
642 
643             hwc_rect_t r_dst  = getIntersection(r_frame, updatingRect);
644             if(isValidRect(r_dst))
645                 r_roi = getUnion(r_roi, r_dst);
646         }
647     }
648 
649     /* For panels that cannot accept commands in both the interfaces, we cannot
650      * send two ROI's (for each half). We merge them into single ROI and split
651      * them across lSplit for MDP mixer use. The ROI's will be merged again
652      * finally before udpating the panel in the driver. */
653     if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
654         hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
655         l_roi = getIntersection(temp_roi, l_frame);
656         r_roi = getIntersection(temp_roi, r_frame);
657     }
658 
659     /* No layer is updating. Still SF wants a refresh. */
660     if(!isValidRect(l_roi) && !isValidRect(r_roi))
661         return;
662 
663     l_roi = getSanitizeROI(l_roi, l_frame);
664     r_roi = getSanitizeROI(r_roi, r_frame);
665 
666     ctx->listStats[mDpy].lRoi = l_roi;
667     ctx->listStats[mDpy].rRoi = r_roi;
668 
669     if(!validateAndApplyROI(ctx, list))
670         resetROI(ctx, mDpy);
671 
672     ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
673             "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
674             ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
675             ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
676             ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
677             ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
678 }
679 
680 /* Checks for conditions where all the layers marked for MDP comp cannot be
681  * bypassed. On such conditions we try to bypass atleast YUV layers */
tryFullFrame(hwc_context_t * ctx,hwc_display_contents_1_t * list)682 bool MDPComp::tryFullFrame(hwc_context_t *ctx,
683                                 hwc_display_contents_1_t* list){
684 
685     const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
686     int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
687 
688     if(sIdleFallBack && !ctx->listStats[mDpy].secureUI) {
689         ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
690         return false;
691     }
692 
693     if(isSkipPresent(ctx, mDpy)) {
694         ALOGD_IF(isDebug(),"%s: SKIP present: %d",
695                 __FUNCTION__,
696                 isSkipPresent(ctx, mDpy));
697         return false;
698     }
699 
700     if(mDpy > HWC_DISPLAY_PRIMARY && (priDispW > MAX_DISPLAY_DIM) &&
701                               (ctx->dpyAttr[mDpy].xres < MAX_DISPLAY_DIM)) {
702         // Disable MDP comp on Secondary when the primary is highres panel and
703         // the secondary is a normal 1080p, because, MDP comp on secondary under
704         // in such usecase, decimation gets used for downscale and there will be
705         // a quality mismatch when there will be a fallback to GPU comp
706         ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
707               __FUNCTION__);
708         return false;
709     }
710 
711     // check for action safe flag and downscale mode which requires scaling.
712     if(ctx->dpyAttr[mDpy].mActionSafePresent
713             || ctx->dpyAttr[mDpy].mDownScaleMode) {
714         ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
715         return false;
716     }
717 
718     for(int i = 0; i < numAppLayers; ++i) {
719         hwc_layer_1_t* layer = &list->hwLayers[i];
720         private_handle_t *hnd = (private_handle_t *)layer->handle;
721 
722         if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
723             if(!canUseRotator(ctx, mDpy)) {
724                 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
725                         __FUNCTION__, mDpy);
726                 return false;
727             }
728         }
729 
730         //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
731         // may not need it if Gfx pre-rotation can handle all flips & rotations
732         if(qdutils::MDPVersion::getInstance().is8x26() &&
733                                 (ctx->dpyAttr[mDpy].xres > 1024) &&
734                                 (layer->transform & HWC_TRANSFORM_FLIP_H) &&
735                                 (!isYuvBuffer(hnd)))
736                    return false;
737     }
738 
739     if(ctx->mAD->isDoable()) {
740         return false;
741     }
742 
743     //If all above hard conditions are met we can do full or partial MDP comp.
744     bool ret = false;
745     if(fullMDPComp(ctx, list)) {
746         ret = true;
747     } else if(fullMDPCompWithPTOR(ctx, list)) {
748         ret = true;
749     } else if(partialMDPComp(ctx, list)) {
750         ret = true;
751     }
752 
753     return ret;
754 }
755 
fullMDPComp(hwc_context_t * ctx,hwc_display_contents_1_t * list)756 bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
757 
758     if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
759         return false;
760 
761     //Will benefit presentation / secondary-only layer.
762     if((mDpy > HWC_DISPLAY_PRIMARY) &&
763             (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
764         ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
765         return false;
766     }
767 
768     const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
769     for(int i = 0; i < numAppLayers; i++) {
770         hwc_layer_1_t* layer = &list->hwLayers[i];
771         if(not mCurrentFrame.drop[i] and
772            not isSupportedForMDPComp(ctx, layer)) {
773             ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
774             return false;
775         }
776     }
777 
778     mCurrentFrame.fbCount = 0;
779     memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
780            sizeof(mCurrentFrame.isFBComposed));
781     mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
782         mCurrentFrame.dropCount;
783 
784     if(sEnable4k2kYUVSplit){
785         adjustForSourceSplit(ctx, list);
786     }
787 
788     if(!postHeuristicsHandling(ctx, list)) {
789         ALOGD_IF(isDebug(), "post heuristic handling failed");
790         reset(ctx);
791         return false;
792     }
793     ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
794              __FUNCTION__);
795     return true;
796 }
797 
798 /* Full MDP Composition with Peripheral Tiny Overlap Removal.
799  * MDP bandwidth limitations can be avoided, if the overlap region
800  * covered by the smallest layer at a higher z-order, gets composed
801  * by Copybit on a render buffer, which can be queued to MDP.
802  */
fullMDPCompWithPTOR(hwc_context_t * ctx,hwc_display_contents_1_t * list)803 bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
804     hwc_display_contents_1_t* list) {
805 
806     const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
807     const int stagesForMDP = min(sMaxPipesPerMixer,
808             ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
809 
810     // Hard checks where we cannot use this mode
811     if (mDpy || !ctx->mCopyBit[mDpy] || isDisplaySplit(ctx, mDpy)) {
812         ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
813         return false;
814     }
815 
816     // Frame level checks
817     if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
818         isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
819         isSecurePresent(ctx, mDpy)) {
820         ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
821         return false;
822     }
823     // MDP comp checks
824     for(int i = 0; i < numAppLayers; i++) {
825         hwc_layer_1_t* layer = &list->hwLayers[i];
826         if(not isSupportedForMDPComp(ctx, layer)) {
827             ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
828             return false;
829         }
830     }
831 
832     /* We cannot use this composition mode, if:
833      1. A below layer needs scaling.
834      2. Overlap is not peripheral to display.
835      3. Overlap or a below layer has 90 degree transform.
836      4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
837      */
838 
839     int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
840     hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
841     memset(overlapRect, 0, sizeof(overlapRect));
842     int layerPixelCount, minPixelCount = 0;
843     int numPTORLayersFound = 0;
844     for (int i = numAppLayers-1; (i >= 0 &&
845                                   numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
846         hwc_layer_1_t* layer = &list->hwLayers[i];
847         hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
848         hwc_rect_t dispFrame = layer->displayFrame;
849         layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
850         // PTOR layer should be peripheral and cannot have transform
851         if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
852                                 has90Transform(layer)) {
853             continue;
854         }
855         if((3 * (layerPixelCount + minPixelCount)) >
856                 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
857             // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
858             continue;
859         }
860         // Found the PTOR layer
861         bool found = true;
862         for (int j = i-1; j >= 0; j--) {
863             // Check if the layers below this layer qualifies for PTOR comp
864             hwc_layer_1_t* layer = &list->hwLayers[j];
865             hwc_rect_t disFrame = layer->displayFrame;
866             //layer below PTOR is intersecting and has 90 degree transform or
867             // needs scaling cannot be supported.
868             if ((isValidRect(getIntersection(dispFrame, disFrame)))
869                             && (has90Transform(layer) || needsScaling(layer))) {
870                 found = false;
871                 break;
872             }
873         }
874         // Store the minLayer Index
875         if(found) {
876             minLayerIndex[numPTORLayersFound] = i;
877             overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
878             minPixelCount += layerPixelCount;
879             numPTORLayersFound++;
880         }
881     }
882 
883     if(isValidRect(getIntersection(overlapRect[0], overlapRect[1]))) {
884         ALOGD_IF(isDebug(), "%s: Ignore Rect2 its intersects with Rect1",
885                  __FUNCTION__);
886         // reset second minLayerIndex[1];
887         minLayerIndex[1] = -1;
888         numPTORLayersFound--;
889     }
890 
891     // No overlap layers
892     if (!numPTORLayersFound)
893         return false;
894 
895     ctx->mPtorInfo.count = numPTORLayersFound;
896     for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
897         ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
898     }
899 
900     if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
901         // reset PTOR
902         ctx->mPtorInfo.count = 0;
903         return false;
904     }
905     // Store the displayFrame and the sourceCrops of the layers
906     hwc_rect_t displayFrame[numAppLayers];
907     hwc_rect_t sourceCrop[numAppLayers];
908     for(int i = 0; i < numAppLayers; i++) {
909         hwc_layer_1_t* layer = &list->hwLayers[i];
910         displayFrame[i] = layer->displayFrame;
911         sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
912     }
913 
914     for(int j = 0; j < numPTORLayersFound; j++) {
915         int index =  ctx->mPtorInfo.layerIndex[j];
916         // Remove overlap from crop & displayFrame of below layers
917         for (int i = 0; i < index && index !=-1; i++) {
918             hwc_layer_1_t* layer = &list->hwLayers[i];
919             if(!isValidRect(getIntersection(layer->displayFrame,
920                                             overlapRect[j])))  {
921                 continue;
922             }
923             // Update layer attributes
924             hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
925             hwc_rect_t destRect = deductRect(layer->displayFrame,
926                                              overlapRect[j]);
927             qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
928                                        layer->transform);
929             layer->sourceCropf.left = (float)srcCrop.left;
930             layer->sourceCropf.top = (float)srcCrop.top;
931             layer->sourceCropf.right = (float)srcCrop.right;
932             layer->sourceCropf.bottom = (float)srcCrop.bottom;
933         }
934     }
935 
936     mCurrentFrame.mdpCount = numAppLayers;
937     mCurrentFrame.fbCount = 0;
938     mCurrentFrame.fbZ = -1;
939 
940     for (int j = 0; j < numAppLayers; j++)
941         mCurrentFrame.isFBComposed[j] = false;
942 
943     bool result = postHeuristicsHandling(ctx, list);
944 
945     // Restore layer attributes
946     for(int i = 0; i < numAppLayers; i++) {
947         hwc_layer_1_t* layer = &list->hwLayers[i];
948         layer->displayFrame = displayFrame[i];
949         layer->sourceCropf.left = (float)sourceCrop[i].left;
950         layer->sourceCropf.top = (float)sourceCrop[i].top;
951         layer->sourceCropf.right = (float)sourceCrop[i].right;
952         layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
953     }
954 
955     if (!result) {
956         // reset PTOR
957         ctx->mPtorInfo.count = 0;
958         reset(ctx);
959     } else {
960         ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
961                  ctx->mPtorInfo.layerIndex[0],  ctx->mPtorInfo.layerIndex[1]);
962     }
963 
964     ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
965              (result ? "successful" : "failed"));
966     return result;
967 }
968 
partialMDPComp(hwc_context_t * ctx,hwc_display_contents_1_t * list)969 bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
970 {
971     if(!sEnableMixedMode) {
972         //Mixed mode is disabled. No need to even try caching.
973         return false;
974     }
975 
976     bool ret = false;
977     if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
978         ret =   loadBasedComp(ctx, list) or
979                 cacheBasedComp(ctx, list);
980     } else {
981         ret =   cacheBasedComp(ctx, list) or
982                 loadBasedComp(ctx, list);
983     }
984 
985     return ret;
986 }
987 
cacheBasedComp(hwc_context_t * ctx,hwc_display_contents_1_t * list)988 bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
989         hwc_display_contents_1_t* list) {
990     if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
991         return false;
992 
993     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
994     mCurrentFrame.reset(numAppLayers);
995     updateLayerCache(ctx, list);
996 
997     //If an MDP marked layer is unsupported cannot do partial MDP Comp
998     for(int i = 0; i < numAppLayers; i++) {
999         if(!mCurrentFrame.isFBComposed[i]) {
1000             hwc_layer_1_t* layer = &list->hwLayers[i];
1001             if(not isSupportedForMDPComp(ctx, layer)) {
1002                 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1003                         __FUNCTION__);
1004                 reset(ctx);
1005                 return false;
1006             }
1007         }
1008     }
1009 
1010     updateYUV(ctx, list, false /*secure only*/);
1011     bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1012     if(!ret) {
1013         ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1014         reset(ctx);
1015         return false;
1016     }
1017 
1018     int mdpCount = mCurrentFrame.mdpCount;
1019 
1020     if(sEnable4k2kYUVSplit){
1021         adjustForSourceSplit(ctx, list);
1022     }
1023 
1024     //Will benefit cases where a video has non-updating background.
1025     if((mDpy > HWC_DISPLAY_PRIMARY) and
1026             (mdpCount > MAX_SEC_LAYERS)) {
1027         ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1028         reset(ctx);
1029         return false;
1030     }
1031 
1032     if(!postHeuristicsHandling(ctx, list)) {
1033         ALOGD_IF(isDebug(), "post heuristic handling failed");
1034         reset(ctx);
1035         return false;
1036     }
1037     ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1038              __FUNCTION__);
1039 
1040     return true;
1041 }
1042 
loadBasedComp(hwc_context_t * ctx,hwc_display_contents_1_t * list)1043 bool MDPComp::loadBasedComp(hwc_context_t *ctx,
1044         hwc_display_contents_1_t* list) {
1045     if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1046         return false;
1047 
1048     if(not isLoadBasedCompDoable(ctx)) {
1049         return false;
1050     }
1051 
1052     const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1053     const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1054     const int stagesForMDP = min(sMaxPipesPerMixer,
1055             ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
1056 
1057     int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1058     int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1059     int lastMDPSupportedIndex = numAppLayers;
1060     int dropCount = 0;
1061 
1062     //Find the minimum MDP batch size
1063     for(int i = 0; i < numAppLayers;i++) {
1064         if(mCurrentFrame.drop[i]) {
1065             dropCount++;
1066             continue;
1067         }
1068         hwc_layer_1_t* layer = &list->hwLayers[i];
1069         if(not isSupportedForMDPComp(ctx, layer)) {
1070             lastMDPSupportedIndex = i;
1071             mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1072             fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1073             break;
1074         }
1075     }
1076 
1077     ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1078             "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1079             mCurrentFrame.dropCount);
1080 
1081     //Start at a point where the fb batch should at least have 2 layers, for
1082     //this mode to be justified.
1083     while(fbBatchSize < 2) {
1084         ++fbBatchSize;
1085         --mdpBatchSize;
1086     }
1087 
1088     //If there are no layers for MDP, this mode doesnt make sense.
1089     if(mdpBatchSize < 1) {
1090         ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1091                 __FUNCTION__);
1092         return false;
1093     }
1094 
1095     mCurrentFrame.reset(numAppLayers);
1096 
1097     //Try with successively smaller mdp batch sizes until we succeed or reach 1
1098     while(mdpBatchSize > 0) {
1099         //Mark layers for MDP comp
1100         int mdpBatchLeft = mdpBatchSize;
1101         for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1102             if(mCurrentFrame.drop[i]) {
1103                 continue;
1104             }
1105             mCurrentFrame.isFBComposed[i] = false;
1106             --mdpBatchLeft;
1107         }
1108 
1109         mCurrentFrame.fbZ = mdpBatchSize;
1110         mCurrentFrame.fbCount = fbBatchSize;
1111         mCurrentFrame.mdpCount = mdpBatchSize;
1112 
1113         ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1114                 __FUNCTION__, mdpBatchSize, fbBatchSize,
1115                 mCurrentFrame.dropCount);
1116 
1117         if(postHeuristicsHandling(ctx, list)) {
1118             ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
1119                      __FUNCTION__);
1120             ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1121                      __FUNCTION__);
1122             return true;
1123         }
1124 
1125         reset(ctx);
1126         --mdpBatchSize;
1127         ++fbBatchSize;
1128     }
1129 
1130     return false;
1131 }
1132 
isLoadBasedCompDoable(hwc_context_t * ctx)1133 bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
1134     if(mDpy or isSecurePresent(ctx, mDpy) or
1135             isYuvPresent(ctx, mDpy)) {
1136         return false;
1137     }
1138     return true;
1139 }
1140 
canPartialUpdate(hwc_context_t * ctx,hwc_display_contents_1_t * list)1141 bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1142         hwc_display_contents_1_t* list){
1143     if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1144             isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1145             mDpy ) {
1146         return false;
1147     }
1148     if(ctx->listStats[mDpy].secureUI)
1149         return false;
1150     return true;
1151 }
1152 
tryVideoOnly(hwc_context_t * ctx,hwc_display_contents_1_t * list)1153 bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1154         hwc_display_contents_1_t* list) {
1155     const bool secureOnly = true;
1156     return videoOnlyComp(ctx, list, not secureOnly) or
1157             videoOnlyComp(ctx, list, secureOnly);
1158 }
1159 
videoOnlyComp(hwc_context_t * ctx,hwc_display_contents_1_t * list,bool secureOnly)1160 bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
1161         hwc_display_contents_1_t* list, bool secureOnly) {
1162     if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1163         return false;
1164     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1165 
1166     mCurrentFrame.reset(numAppLayers);
1167     mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1168     updateYUV(ctx, list, secureOnly);
1169     int mdpCount = mCurrentFrame.mdpCount;
1170 
1171     if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1172         reset(ctx);
1173         return false;
1174     }
1175 
1176     /* Bail out if we are processing only secured video layers
1177      * and we dont have any */
1178     if(!isSecurePresent(ctx, mDpy) && secureOnly){
1179         reset(ctx);
1180         return false;
1181     }
1182 
1183     if(mCurrentFrame.fbCount)
1184         mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
1185 
1186     if(sEnable4k2kYUVSplit){
1187         adjustForSourceSplit(ctx, list);
1188     }
1189 
1190     if(!postHeuristicsHandling(ctx, list)) {
1191         ALOGD_IF(isDebug(), "post heuristic handling failed");
1192         reset(ctx);
1193         return false;
1194     }
1195 
1196     ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1197              __FUNCTION__);
1198     return true;
1199 }
1200 
1201 /* Checks for conditions where YUV layers cannot be bypassed */
isYUVDoable(hwc_context_t * ctx,hwc_layer_1_t * layer)1202 bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1203     if(isSkipLayer(layer)) {
1204         ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
1205         return false;
1206     }
1207 
1208     if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
1209         ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1210         return false;
1211     }
1212 
1213     if(isSecuring(ctx, layer)) {
1214         ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1215         return false;
1216     }
1217 
1218     if(!isValidDimension(ctx, layer)) {
1219         ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1220             __FUNCTION__);
1221         return false;
1222     }
1223 
1224     if(layer->planeAlpha < 0xFF) {
1225         ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1226                  in video only mode",
1227                  __FUNCTION__);
1228         return false;
1229     }
1230 
1231     return true;
1232 }
1233 
1234 /* starts at fromIndex and check for each layer to find
1235  * if it it has overlapping with any Updating layer above it in zorder
1236  * till the end of the batch. returns true if it finds any intersection */
canPushBatchToTop(const hwc_display_contents_1_t * list,int fromIndex,int toIndex)1237 bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1238         int fromIndex, int toIndex) {
1239     for(int i = fromIndex; i < toIndex; i++) {
1240         if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1241             if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1242                 return false;
1243             }
1244         }
1245     }
1246     return true;
1247 }
1248 
1249 /* Checks if given layer at targetLayerIndex has any
1250  * intersection with all the updating layers in beween
1251  * fromIndex and toIndex. Returns true if it finds intersectiion */
intersectingUpdatingLayers(const hwc_display_contents_1_t * list,int fromIndex,int toIndex,int targetLayerIndex)1252 bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1253         int fromIndex, int toIndex, int targetLayerIndex) {
1254     for(int i = fromIndex; i <= toIndex; i++) {
1255         if(!mCurrentFrame.isFBComposed[i]) {
1256             if(areLayersIntersecting(&list->hwLayers[i],
1257                         &list->hwLayers[targetLayerIndex]))  {
1258                 return true;
1259             }
1260         }
1261     }
1262     return false;
1263 }
1264 
getBatch(hwc_display_contents_1_t * list,int & maxBatchStart,int & maxBatchEnd,int & maxBatchCount)1265 int MDPComp::getBatch(hwc_display_contents_1_t* list,
1266         int& maxBatchStart, int& maxBatchEnd,
1267         int& maxBatchCount) {
1268     int i = 0;
1269     int fbZOrder =-1;
1270     int droppedLayerCt = 0;
1271     while (i < mCurrentFrame.layerCount) {
1272         int batchCount = 0;
1273         int batchStart = i;
1274         int batchEnd = i;
1275         /* Adjust batch Z order with the dropped layers so far */
1276         int fbZ = batchStart - droppedLayerCt;
1277         int firstZReverseIndex = -1;
1278         int updatingLayersAbove = 0;//Updating layer count in middle of batch
1279         while(i < mCurrentFrame.layerCount) {
1280             if(!mCurrentFrame.isFBComposed[i]) {
1281                 if(!batchCount) {
1282                     i++;
1283                     break;
1284                 }
1285                 updatingLayersAbove++;
1286                 i++;
1287                 continue;
1288             } else {
1289                 if(mCurrentFrame.drop[i]) {
1290                     i++;
1291                     droppedLayerCt++;
1292                     continue;
1293                 } else if(updatingLayersAbove <= 0) {
1294                     batchCount++;
1295                     batchEnd = i;
1296                     i++;
1297                     continue;
1298                 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1299 
1300                     // We have a valid updating layer already. If layer-i not
1301                     // have overlapping with all updating layers in between
1302                     // batch-start and i, then we can add layer i to batch.
1303                     if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1304                         batchCount++;
1305                         batchEnd = i;
1306                         i++;
1307                         continue;
1308                     } else if(canPushBatchToTop(list, batchStart, i)) {
1309                         //If All the non-updating layers with in this batch
1310                         //does not have intersection with the updating layers
1311                         //above in z-order, then we can safely move the batch to
1312                         //higher z-order. Increment fbZ as it is moving up.
1313                         if( firstZReverseIndex < 0) {
1314                             firstZReverseIndex = i;
1315                         }
1316                         batchCount++;
1317                         batchEnd = i;
1318                         fbZ += updatingLayersAbove;
1319                         i++;
1320                         updatingLayersAbove = 0;
1321                         continue;
1322                     } else {
1323                         //both failed.start the loop again from here.
1324                         if(firstZReverseIndex >= 0) {
1325                             i = firstZReverseIndex;
1326                         }
1327                         break;
1328                     }
1329                 }
1330             }
1331         }
1332         if(batchCount > maxBatchCount) {
1333             maxBatchCount = batchCount;
1334             maxBatchStart = batchStart;
1335             maxBatchEnd = batchEnd;
1336             fbZOrder = fbZ;
1337         }
1338     }
1339     return fbZOrder;
1340 }
1341 
markLayersForCaching(hwc_context_t * ctx,hwc_display_contents_1_t * list)1342 bool  MDPComp::markLayersForCaching(hwc_context_t* ctx,
1343         hwc_display_contents_1_t* list) {
1344     /* Idea is to keep as many non-updating(cached) layers in FB and
1345      * send rest of them through MDP. This is done in 2 steps.
1346      *   1. Find the maximum contiguous batch of non-updating layers.
1347      *   2. See if we can improve this batch size for caching by adding
1348      *      opaque layers around the batch, if they don't have
1349      *      any overlapping with the updating layers in between.
1350      * NEVER mark an updating layer for caching.
1351      * But cached ones can be marked for MDP */
1352 
1353     int maxBatchStart = -1;
1354     int maxBatchEnd = -1;
1355     int maxBatchCount = 0;
1356     int fbZ = -1;
1357 
1358     /* Nothing is cached. No batching needed */
1359     if(mCurrentFrame.fbCount == 0) {
1360         return true;
1361     }
1362 
1363     /* No MDP comp layers, try to use other comp modes */
1364     if(mCurrentFrame.mdpCount == 0) {
1365         return false;
1366     }
1367 
1368     fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
1369 
1370     /* reset rest of the layers lying inside ROI for MDP comp */
1371     for(int i = 0; i < mCurrentFrame.layerCount; i++) {
1372         hwc_layer_1_t* layer = &list->hwLayers[i];
1373         if((i < maxBatchStart || i > maxBatchEnd) &&
1374                 mCurrentFrame.isFBComposed[i]){
1375             if(!mCurrentFrame.drop[i]){
1376                 //If an unsupported layer is being attempted to
1377                 //be pulled out we should fail
1378                 if(not isSupportedForMDPComp(ctx, layer)) {
1379                     return false;
1380                 }
1381                 mCurrentFrame.isFBComposed[i] = false;
1382             }
1383         }
1384     }
1385 
1386     // update the frame data
1387     mCurrentFrame.fbZ = fbZ;
1388     mCurrentFrame.fbCount = maxBatchCount;
1389     mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1390             mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1391 
1392     ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
1393             mCurrentFrame.fbCount);
1394 
1395     return true;
1396 }
1397 
updateLayerCache(hwc_context_t * ctx,hwc_display_contents_1_t * list)1398 void MDPComp::updateLayerCache(hwc_context_t* ctx,
1399         hwc_display_contents_1_t* list) {
1400     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1401     int fbCount = 0;
1402 
1403     for(int i = 0; i < numAppLayers; i++) {
1404         if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
1405             if(!mCurrentFrame.drop[i])
1406                 fbCount++;
1407             mCurrentFrame.isFBComposed[i] = true;
1408         } else {
1409             mCurrentFrame.isFBComposed[i] = false;
1410         }
1411     }
1412 
1413     mCurrentFrame.fbCount = fbCount;
1414     mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
1415                                                     - mCurrentFrame.dropCount;
1416 
1417     ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d"
1418              ,__FUNCTION__, mCurrentFrame.mdpCount, mCurrentFrame.fbCount,
1419             mCurrentFrame.dropCount);
1420 }
1421 
updateYUV(hwc_context_t * ctx,hwc_display_contents_1_t * list,bool secureOnly)1422 void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
1423         bool secureOnly) {
1424     int nYuvCount = ctx->listStats[mDpy].yuvCount;
1425     for(int index = 0;index < nYuvCount; index++){
1426         int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1427         hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1428 
1429         if(!isYUVDoable(ctx, layer)) {
1430             if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
1431                 mCurrentFrame.isFBComposed[nYuvIndex] = true;
1432                 mCurrentFrame.fbCount++;
1433             }
1434         } else {
1435             if(mCurrentFrame.isFBComposed[nYuvIndex]) {
1436                 private_handle_t *hnd = (private_handle_t *)layer->handle;
1437                 if(!secureOnly || isSecureBuffer(hnd)) {
1438                     mCurrentFrame.isFBComposed[nYuvIndex] = false;
1439                     mCurrentFrame.fbCount--;
1440                 }
1441             }
1442         }
1443     }
1444 
1445     mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1446             mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1447     ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1448              mCurrentFrame.fbCount);
1449 }
1450 
getUpdatingFBRect(hwc_context_t * ctx,hwc_display_contents_1_t * list)1451 hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1452         hwc_display_contents_1_t* list){
1453     hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
1454 
1455     /* Update only the region of FB needed for composition */
1456     for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1457         if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1458             hwc_layer_1_t* layer = &list->hwLayers[i];
1459             hwc_rect_t dst = layer->displayFrame;
1460             fbRect = getUnion(fbRect, dst);
1461         }
1462     }
1463     trimAgainstROI(ctx, fbRect);
1464     return fbRect;
1465 }
1466 
postHeuristicsHandling(hwc_context_t * ctx,hwc_display_contents_1_t * list)1467 bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1468         hwc_display_contents_1_t* list) {
1469 
1470     //Capability checks
1471     if(!resourceCheck(ctx, list)) {
1472         ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1473         return false;
1474     }
1475 
1476     //Limitations checks
1477     if(!hwLimitationsCheck(ctx, list)) {
1478         ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1479         return false;
1480     }
1481 
1482     //Configure framebuffer first if applicable
1483     if(mCurrentFrame.fbZ >= 0) {
1484         hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
1485         if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1486         {
1487             ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1488                     __FUNCTION__);
1489             return false;
1490         }
1491     }
1492 
1493     mCurrentFrame.map();
1494 
1495     if(!allocLayerPipes(ctx, list)) {
1496         ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
1497         return false;
1498     }
1499 
1500     for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1501             index++) {
1502         if(!mCurrentFrame.isFBComposed[index]) {
1503             int mdpIndex = mCurrentFrame.layerToMDP[index];
1504             hwc_layer_1_t* layer = &list->hwLayers[index];
1505 
1506             //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1507             if(mdpNextZOrder == mCurrentFrame.fbZ) {
1508                 mdpNextZOrder++;
1509             }
1510             MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1511             cur_pipe->zOrder = mdpNextZOrder++;
1512 
1513             private_handle_t *hnd = (private_handle_t *)layer->handle;
1514             if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
1515                 if(configure4k2kYuv(ctx, layer,
1516                             mCurrentFrame.mdpToLayer[mdpIndex])
1517                         != 0 ){
1518                     ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1519                             for layer %d",__FUNCTION__, index);
1520                     return false;
1521                 }
1522                 else{
1523                     mdpNextZOrder++;
1524                 }
1525                 continue;
1526             }
1527             if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1528                 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
1529                         layer %d",__FUNCTION__, index);
1530                 return false;
1531             }
1532         }
1533     }
1534 
1535     if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1536         ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1537                 ,__FUNCTION__, mDpy);
1538         return false;
1539     }
1540 
1541     setRedraw(ctx, list);
1542     return true;
1543 }
1544 
resourceCheck(hwc_context_t * ctx,hwc_display_contents_1_t * list)1545 bool MDPComp::resourceCheck(hwc_context_t* ctx,
1546         hwc_display_contents_1_t* list) {
1547     const bool fbUsed = mCurrentFrame.fbCount;
1548     if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1549         ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1550         return false;
1551     }
1552     // Init rotCount to number of rotate sessions used by other displays
1553     int rotCount = ctx->mRotMgr->getNumActiveSessions();
1554     // Count the number of rotator sessions required for current display
1555     for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1556         if(!mCurrentFrame.isFBComposed[index]) {
1557             hwc_layer_1_t* layer = &list->hwLayers[index];
1558             private_handle_t *hnd = (private_handle_t *)layer->handle;
1559             if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1560                 rotCount++;
1561             }
1562         }
1563     }
1564     // if number of layers to rotate exceeds max rotator sessions, bail out.
1565     if(rotCount > RotMgr::MAX_ROT_SESS) {
1566         ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions  %d",
1567                                     __FUNCTION__, mDpy);
1568         return false;
1569     }
1570     return true;
1571 }
1572 
hwLimitationsCheck(hwc_context_t * ctx,hwc_display_contents_1_t * list)1573 bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1574         hwc_display_contents_1_t* list) {
1575 
1576     //A-family hw limitation:
1577     //If a layer need alpha scaling, MDP can not support.
1578     if(ctx->mMDP.version < qdutils::MDSS_V5) {
1579         for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1580             if(!mCurrentFrame.isFBComposed[i] &&
1581                     isAlphaScaled( &list->hwLayers[i])) {
1582                 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1583                 return false;
1584             }
1585         }
1586     }
1587 
1588     // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1589     //If multiple layers requires downscaling and also they are overlapping
1590     //fall back to GPU since MDSS can not handle it.
1591     if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1592             qdutils::MDPVersion::getInstance().is8x26()) {
1593         for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1594             hwc_layer_1_t* botLayer = &list->hwLayers[i];
1595             if(!mCurrentFrame.isFBComposed[i] &&
1596                     isDownscaleRequired(botLayer)) {
1597                 //if layer-i is marked for MDP and needs downscaling
1598                 //check if any MDP layer on top of i & overlaps with layer-i
1599                 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1600                     hwc_layer_1_t* topLayer = &list->hwLayers[j];
1601                     if(!mCurrentFrame.isFBComposed[j] &&
1602                             isDownscaleRequired(topLayer)) {
1603                         hwc_rect_t r = getIntersection(botLayer->displayFrame,
1604                                 topLayer->displayFrame);
1605                         if(isValidRect(r))
1606                             return false;
1607                     }
1608                 }
1609             }
1610         }
1611     }
1612     return true;
1613 }
1614 
prepare(hwc_context_t * ctx,hwc_display_contents_1_t * list)1615 int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1616     int ret = 0;
1617     char property[PROPERTY_VALUE_MAX];
1618 
1619     if(!ctx || !list) {
1620         ALOGE("%s: Invalid context or list",__FUNCTION__);
1621         mCachedFrame.reset();
1622         return -1;
1623     }
1624 
1625     const int numLayers = ctx->listStats[mDpy].numAppLayers;
1626 
1627     if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1628         int currentFlags = atoi(property);
1629         if(currentFlags != sSimulationFlags) {
1630             sSimulationFlags = currentFlags;
1631             ALOGE("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1632                     sSimulationFlags, sSimulationFlags);
1633         }
1634     }
1635     // reset PTOR
1636     if(!mDpy)
1637         memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
1638 
1639     //Do not cache the information for next draw cycle.
1640     if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1641         ALOGI("%s: Unsupported layer count for mdp composition",
1642                 __FUNCTION__);
1643         mCachedFrame.reset();
1644         return -1;
1645     }
1646 
1647     //reset old data
1648     mCurrentFrame.reset(numLayers);
1649     memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1650     mCurrentFrame.dropCount = 0;
1651 
1652     // Detect the start of animation and fall back to GPU only once to cache
1653     // all the layers in FB and display FB content untill animation completes.
1654     if(ctx->listStats[mDpy].isDisplayAnimating) {
1655         mCurrentFrame.needsRedraw = false;
1656         if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1657             mCurrentFrame.needsRedraw = true;
1658             ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1659         }
1660         setMDPCompLayerFlags(ctx, list);
1661         mCachedFrame.updateCounts(mCurrentFrame);
1662         ret = -1;
1663         return ret;
1664     } else {
1665         ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1666     }
1667 
1668     //Hard conditions, if not met, cannot do MDP comp
1669     if(isFrameDoable(ctx)) {
1670         generateROI(ctx, list);
1671 
1672         mModeOn = tryFullFrame(ctx, list) || tryVideoOnly(ctx, list);
1673         if(mModeOn) {
1674             setMDPCompLayerFlags(ctx, list);
1675         } else {
1676             resetROI(ctx, mDpy);
1677             reset(ctx);
1678             memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1679             mCurrentFrame.dropCount = 0;
1680             ret = -1;
1681         }
1682     } else {
1683         ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1684                 __FUNCTION__);
1685         ret = -1;
1686     }
1687 
1688     if(isDebug()) {
1689         ALOGD("GEOMETRY change: %d",
1690                 (list->flags & HWC_GEOMETRY_CHANGED));
1691         android::String8 sDump("");
1692         dump(sDump, ctx);
1693         ALOGD("%s",sDump.string());
1694     }
1695 
1696     mCachedFrame.cacheAll(list);
1697     mCachedFrame.updateCounts(mCurrentFrame);
1698     return ret;
1699 }
1700 
allocSplitVGPipesfor4k2k(hwc_context_t * ctx,int index)1701 bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
1702 
1703     bool bRet = true;
1704     int mdpIndex = mCurrentFrame.layerToMDP[index];
1705     PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1706     info.pipeInfo = new MdpYUVPipeInfo;
1707     info.rot = NULL;
1708     MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
1709 
1710     pipe_info.lIndex = ovutils::OV_INVALID;
1711     pipe_info.rIndex = ovutils::OV_INVALID;
1712 
1713     Overlay::PipeSpecs pipeSpecs;
1714     pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1715     pipeSpecs.needsScaling = true;
1716     pipeSpecs.dpy = mDpy;
1717     pipeSpecs.fb = false;
1718 
1719     pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
1720     if(pipe_info.lIndex == ovutils::OV_INVALID){
1721         bRet = false;
1722         ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1723                 __FUNCTION__);
1724     }
1725     pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
1726     if(pipe_info.rIndex == ovutils::OV_INVALID){
1727         bRet = false;
1728         ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1729                 __FUNCTION__);
1730     }
1731     return bRet;
1732 }
1733 
drawOverlap(hwc_context_t * ctx,hwc_display_contents_1_t * list)1734 int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1735     int fd = -1;
1736     if (ctx->mPtorInfo.isActive()) {
1737         fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
1738         if (fd < 0) {
1739             ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
1740         }
1741     }
1742     return fd;
1743 }
1744 //=============MDPCompNonSplit==================================================
1745 
adjustForSourceSplit(hwc_context_t * ctx,hwc_display_contents_1_t * list)1746 void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
1747         hwc_display_contents_1_t* list) {
1748     //If 4k2k Yuv layer split is possible,  and if
1749     //fbz is above 4k2k layer, increment fb zorder by 1
1750     //as we split 4k2k layer and increment zorder for right half
1751     //of the layer
1752     if(!ctx)
1753         return;
1754     if(mCurrentFrame.fbZ >= 0) {
1755         for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1756                 index++) {
1757             if(!mCurrentFrame.isFBComposed[index]) {
1758                 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1759                     mdpNextZOrder++;
1760                 }
1761                 mdpNextZOrder++;
1762                 hwc_layer_1_t* layer = &list->hwLayers[index];
1763                 private_handle_t *hnd = (private_handle_t *)layer->handle;
1764                 if(is4kx2kYuvBuffer(hnd)) {
1765                     if(mdpNextZOrder <= mCurrentFrame.fbZ)
1766                         mCurrentFrame.fbZ += 1;
1767                     mdpNextZOrder++;
1768                     //As we split 4kx2k yuv layer and program to 2 VG pipes
1769                     //(if available) increase mdpcount by 1.
1770                     mCurrentFrame.mdpCount++;
1771                 }
1772             }
1773         }
1774     }
1775 }
1776 
1777 /*
1778  * Configures pipe(s) for MDP composition
1779  */
configure(hwc_context_t * ctx,hwc_layer_1_t * layer,PipeLayerPair & PipeLayerPair)1780 int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
1781                              PipeLayerPair& PipeLayerPair) {
1782     MdpPipeInfoNonSplit& mdp_info =
1783         *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
1784     eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1785     eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1786     eIsFg isFg = IS_FG_OFF;
1787     eDest dest = mdp_info.index;
1788 
1789     ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1790              __FUNCTION__, layer, zOrder, dest);
1791 
1792     return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
1793                            &PipeLayerPair.rot);
1794 }
1795 
allocLayerPipes(hwc_context_t * ctx,hwc_display_contents_1_t * list)1796 bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
1797         hwc_display_contents_1_t* list) {
1798     for(int index = 0; index < mCurrentFrame.layerCount; index++) {
1799 
1800         if(mCurrentFrame.isFBComposed[index]) continue;
1801 
1802         hwc_layer_1_t* layer = &list->hwLayers[index];
1803         private_handle_t *hnd = (private_handle_t *)layer->handle;
1804         if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
1805             if(allocSplitVGPipesfor4k2k(ctx, index)){
1806                 continue;
1807             }
1808         }
1809 
1810         int mdpIndex = mCurrentFrame.layerToMDP[index];
1811         PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1812         info.pipeInfo = new MdpPipeInfoNonSplit;
1813         info.rot = NULL;
1814         MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
1815 
1816         Overlay::PipeSpecs pipeSpecs;
1817         pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1818                 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1819         pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
1820                 (qdutils::MDPVersion::getInstance().is8x26() and
1821                 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
1822         pipeSpecs.dpy = mDpy;
1823         pipeSpecs.fb = false;
1824         pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
1825 
1826         pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
1827 
1828         if(pipe_info.index == ovutils::OV_INVALID) {
1829             ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
1830             return false;
1831         }
1832     }
1833     return true;
1834 }
1835 
configure4k2kYuv(hwc_context_t * ctx,hwc_layer_1_t * layer,PipeLayerPair & PipeLayerPair)1836 int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1837         PipeLayerPair& PipeLayerPair) {
1838     MdpYUVPipeInfo& mdp_info =
1839             *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
1840     eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1841     eIsFg isFg = IS_FG_OFF;
1842     eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1843     eDest lDest = mdp_info.lIndex;
1844     eDest rDest = mdp_info.rIndex;
1845 
1846     return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
1847             lDest, rDest, &PipeLayerPair.rot);
1848 }
1849 
draw(hwc_context_t * ctx,hwc_display_contents_1_t * list)1850 bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1851 
1852     if(!isEnabled() or !mModeOn) {
1853         ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
1854         return true;
1855     }
1856 
1857     // Set the Handle timeout to true for MDP or MIXED composition.
1858     if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
1859         sHandleTimeout = true;
1860     }
1861 
1862     overlay::Overlay& ov = *ctx->mOverlay;
1863     LayerProp *layerProp = ctx->layerProp[mDpy];
1864 
1865     int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1866     for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
1867     {
1868         if(mCurrentFrame.isFBComposed[i]) continue;
1869 
1870         hwc_layer_1_t *layer = &list->hwLayers[i];
1871         private_handle_t *hnd = (private_handle_t *)layer->handle;
1872         if(!hnd) {
1873             if (!(layer->flags & HWC_COLOR_FILL)) {
1874                 ALOGE("%s handle null", __FUNCTION__);
1875                 return false;
1876             }
1877             // No PLAY for Color layer
1878             layerProp[i].mFlags &= ~HWC_MDPCOMP;
1879             continue;
1880         }
1881 
1882         int mdpIndex = mCurrentFrame.layerToMDP[i];
1883 
1884         if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
1885         {
1886             MdpYUVPipeInfo& pipe_info =
1887                 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1888             Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1889             ovutils::eDest indexL = pipe_info.lIndex;
1890             ovutils::eDest indexR = pipe_info.rIndex;
1891             int fd = hnd->fd;
1892             uint32_t offset = (uint32_t)hnd->offset;
1893             if(rot) {
1894                 rot->queueBuffer(fd, offset);
1895                 fd = rot->getDstMemId();
1896                 offset = rot->getDstOffset();
1897             }
1898             if(indexL != ovutils::OV_INVALID) {
1899                 ovutils::eDest destL = (ovutils::eDest)indexL;
1900                 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1901                         using  pipe: %d", __FUNCTION__, layer, hnd, indexL );
1902                 if (!ov.queueBuffer(fd, offset, destL)) {
1903                     ALOGE("%s: queueBuffer failed for display:%d",
1904                             __FUNCTION__, mDpy);
1905                     return false;
1906                 }
1907             }
1908 
1909             if(indexR != ovutils::OV_INVALID) {
1910                 ovutils::eDest destR = (ovutils::eDest)indexR;
1911                 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1912                         using  pipe: %d", __FUNCTION__, layer, hnd, indexR );
1913                 if (!ov.queueBuffer(fd, offset, destR)) {
1914                     ALOGE("%s: queueBuffer failed for display:%d",
1915                             __FUNCTION__, mDpy);
1916                     return false;
1917                 }
1918             }
1919         }
1920         else{
1921             MdpPipeInfoNonSplit& pipe_info =
1922             *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1923             ovutils::eDest dest = pipe_info.index;
1924             if(dest == ovutils::OV_INVALID) {
1925                 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
1926                 return false;
1927             }
1928 
1929             if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1930                 continue;
1931             }
1932 
1933             int fd = hnd->fd;
1934             uint32_t offset = (uint32_t)hnd->offset;
1935             int index = ctx->mPtorInfo.getPTORArrayIndex(i);
1936             if (!mDpy && (index != -1)) {
1937                 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1938                 fd = hnd->fd;
1939                 // Use the offset of the RenderBuffer
1940                 offset = ctx->mPtorInfo.mRenderBuffOffset[index];
1941             }
1942 
1943             ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1944                     using  pipe: %d", __FUNCTION__, layer,
1945                     hnd, dest );
1946 
1947             Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1948             if(rot) {
1949                 if(!rot->queueBuffer(fd, offset))
1950                     return false;
1951                 fd = rot->getDstMemId();
1952                 offset = rot->getDstOffset();
1953             }
1954 
1955             if (!ov.queueBuffer(fd, offset, dest)) {
1956                 ALOGE("%s: queueBuffer failed for display:%d ",
1957                         __FUNCTION__, mDpy);
1958                 return false;
1959             }
1960         }
1961 
1962         layerProp[i].mFlags &= ~HWC_MDPCOMP;
1963     }
1964     return true;
1965 }
1966 
1967 //=============MDPCompSplit===================================================
1968 
adjustForSourceSplit(hwc_context_t * ctx,hwc_display_contents_1_t * list)1969 void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
1970          hwc_display_contents_1_t* list){
1971     //if 4kx2k yuv layer is totally present in either in left half
1972     //or right half then try splitting the yuv layer to avoid decimation
1973     const int lSplit = getLeftSplit(ctx, mDpy);
1974     if(mCurrentFrame.fbZ >= 0) {
1975         for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1976                 index++) {
1977             if(!mCurrentFrame.isFBComposed[index]) {
1978                 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1979                     mdpNextZOrder++;
1980                 }
1981                 mdpNextZOrder++;
1982                 hwc_layer_1_t* layer = &list->hwLayers[index];
1983                 private_handle_t *hnd = (private_handle_t *)layer->handle;
1984                 if(is4kx2kYuvBuffer(hnd)) {
1985                     hwc_rect_t dst = layer->displayFrame;
1986                     if((dst.left > lSplit) || (dst.right < lSplit)) {
1987                         mCurrentFrame.mdpCount += 1;
1988                     }
1989                     if(mdpNextZOrder <= mCurrentFrame.fbZ)
1990                         mCurrentFrame.fbZ += 1;
1991                     mdpNextZOrder++;
1992                 }
1993             }
1994         }
1995     }
1996 }
1997 
acquireMDPPipes(hwc_context_t * ctx,hwc_layer_1_t * layer,MdpPipeInfoSplit & pipe_info)1998 bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
1999         MdpPipeInfoSplit& pipe_info) {
2000 
2001     const int lSplit = getLeftSplit(ctx, mDpy);
2002     private_handle_t *hnd = (private_handle_t *)layer->handle;
2003     hwc_rect_t dst = layer->displayFrame;
2004     pipe_info.lIndex = ovutils::OV_INVALID;
2005     pipe_info.rIndex = ovutils::OV_INVALID;
2006 
2007     Overlay::PipeSpecs pipeSpecs;
2008     pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2009             Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2010     pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2011     pipeSpecs.dpy = mDpy;
2012     pipeSpecs.mixer = Overlay::MIXER_LEFT;
2013     pipeSpecs.fb = false;
2014 
2015     // Acquire pipe only for the updating half
2016     hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2017     hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2018 
2019     if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
2020         pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
2021         if(pipe_info.lIndex == ovutils::OV_INVALID)
2022             return false;
2023     }
2024 
2025     if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
2026         pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2027         pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
2028         if(pipe_info.rIndex == ovutils::OV_INVALID)
2029             return false;
2030     }
2031 
2032     return true;
2033 }
2034 
allocLayerPipes(hwc_context_t * ctx,hwc_display_contents_1_t * list)2035 bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
2036         hwc_display_contents_1_t* list) {
2037     for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
2038 
2039         if(mCurrentFrame.isFBComposed[index]) continue;
2040 
2041         hwc_layer_1_t* layer = &list->hwLayers[index];
2042         private_handle_t *hnd = (private_handle_t *)layer->handle;
2043         hwc_rect_t dst = layer->displayFrame;
2044         const int lSplit = getLeftSplit(ctx, mDpy);
2045         if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
2046             if((dst.left > lSplit)||(dst.right < lSplit)){
2047                 if(allocSplitVGPipesfor4k2k(ctx, index)){
2048                     continue;
2049                 }
2050             }
2051         }
2052         int mdpIndex = mCurrentFrame.layerToMDP[index];
2053         PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2054         info.pipeInfo = new MdpPipeInfoSplit;
2055         info.rot = NULL;
2056         MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
2057 
2058         if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2059             ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2060                     __FUNCTION__);
2061             return false;
2062         }
2063     }
2064     return true;
2065 }
2066 
configure4k2kYuv(hwc_context_t * ctx,hwc_layer_1_t * layer,PipeLayerPair & PipeLayerPair)2067 int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2068         PipeLayerPair& PipeLayerPair) {
2069     const int lSplit = getLeftSplit(ctx, mDpy);
2070     hwc_rect_t dst = layer->displayFrame;
2071     if((dst.left > lSplit)||(dst.right < lSplit)){
2072         MdpYUVPipeInfo& mdp_info =
2073                 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2074         eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2075         eIsFg isFg = IS_FG_OFF;
2076         eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2077         eDest lDest = mdp_info.lIndex;
2078         eDest rDest = mdp_info.rIndex;
2079 
2080         return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
2081                 lDest, rDest, &PipeLayerPair.rot);
2082     }
2083     else{
2084         return configure(ctx, layer, PipeLayerPair);
2085     }
2086 }
2087 
2088 /*
2089  * Configures pipe(s) for MDP composition
2090  */
configure(hwc_context_t * ctx,hwc_layer_1_t * layer,PipeLayerPair & PipeLayerPair)2091 int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2092         PipeLayerPair& PipeLayerPair) {
2093     MdpPipeInfoSplit& mdp_info =
2094         *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2095     eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2096     eIsFg isFg = IS_FG_OFF;
2097     eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2098     eDest lDest = mdp_info.lIndex;
2099     eDest rDest = mdp_info.rIndex;
2100 
2101     ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2102              "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2103 
2104     return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
2105                             rDest, &PipeLayerPair.rot);
2106 }
2107 
draw(hwc_context_t * ctx,hwc_display_contents_1_t * list)2108 bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2109 
2110     if(!isEnabled() or !mModeOn) {
2111         ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
2112         return true;
2113     }
2114 
2115     // Set the Handle timeout to true for MDP or MIXED composition.
2116     if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2117         sHandleTimeout = true;
2118     }
2119 
2120     overlay::Overlay& ov = *ctx->mOverlay;
2121     LayerProp *layerProp = ctx->layerProp[mDpy];
2122 
2123     int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2124     for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
2125     {
2126         if(mCurrentFrame.isFBComposed[i]) continue;
2127 
2128         hwc_layer_1_t *layer = &list->hwLayers[i];
2129         private_handle_t *hnd = (private_handle_t *)layer->handle;
2130         if(!hnd) {
2131             ALOGE("%s handle null", __FUNCTION__);
2132             return false;
2133         }
2134 
2135         if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2136             continue;
2137         }
2138 
2139         int mdpIndex = mCurrentFrame.layerToMDP[i];
2140 
2141         if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
2142         {
2143             MdpYUVPipeInfo& pipe_info =
2144                 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2145             Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2146             ovutils::eDest indexL = pipe_info.lIndex;
2147             ovutils::eDest indexR = pipe_info.rIndex;
2148             int fd = hnd->fd;
2149             uint32_t offset = (uint32_t)hnd->offset;
2150             if(rot) {
2151                 rot->queueBuffer(fd, offset);
2152                 fd = rot->getDstMemId();
2153                 offset = rot->getDstOffset();
2154             }
2155             if(indexL != ovutils::OV_INVALID) {
2156                 ovutils::eDest destL = (ovutils::eDest)indexL;
2157                 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2158                         using  pipe: %d", __FUNCTION__, layer, hnd, indexL );
2159                 if (!ov.queueBuffer(fd, offset, destL)) {
2160                     ALOGE("%s: queueBuffer failed for display:%d",
2161                             __FUNCTION__, mDpy);
2162                     return false;
2163                 }
2164             }
2165 
2166             if(indexR != ovutils::OV_INVALID) {
2167                 ovutils::eDest destR = (ovutils::eDest)indexR;
2168                 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2169                         using  pipe: %d", __FUNCTION__, layer, hnd, indexR );
2170                 if (!ov.queueBuffer(fd, offset, destR)) {
2171                     ALOGE("%s: queueBuffer failed for display:%d",
2172                             __FUNCTION__, mDpy);
2173                     return false;
2174                 }
2175             }
2176         }
2177         else{
2178             MdpPipeInfoSplit& pipe_info =
2179                 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2180             Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2181 
2182             ovutils::eDest indexL = pipe_info.lIndex;
2183             ovutils::eDest indexR = pipe_info.rIndex;
2184 
2185             int fd = hnd->fd;
2186             uint32_t offset = (uint32_t)hnd->offset;
2187             int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2188             if (!mDpy && (index != -1)) {
2189                 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2190                 fd = hnd->fd;
2191                 offset = ctx->mPtorInfo.mRenderBuffOffset[index];
2192             }
2193 
2194             if(ctx->mAD->draw(ctx, fd, offset)) {
2195                 fd = ctx->mAD->getDstFd();
2196                 offset = ctx->mAD->getDstOffset();
2197             }
2198 
2199             if(rot) {
2200                 rot->queueBuffer(fd, offset);
2201                 fd = rot->getDstMemId();
2202                 offset = rot->getDstOffset();
2203             }
2204 
2205             //************* play left mixer **********
2206             if(indexL != ovutils::OV_INVALID) {
2207                 ovutils::eDest destL = (ovutils::eDest)indexL;
2208                 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2209                         using  pipe: %d", __FUNCTION__, layer, hnd, indexL );
2210                 if (!ov.queueBuffer(fd, offset, destL)) {
2211                     ALOGE("%s: queueBuffer failed for left mixer",
2212                             __FUNCTION__);
2213                     return false;
2214                 }
2215             }
2216 
2217             //************* play right mixer **********
2218             if(indexR != ovutils::OV_INVALID) {
2219                 ovutils::eDest destR = (ovutils::eDest)indexR;
2220                 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2221                         using  pipe: %d", __FUNCTION__, layer, hnd, indexR );
2222                 if (!ov.queueBuffer(fd, offset, destR)) {
2223                     ALOGE("%s: queueBuffer failed for right mixer",
2224                             __FUNCTION__);
2225                     return false;
2226                 }
2227             }
2228         }
2229 
2230         layerProp[i].mFlags &= ~HWC_MDPCOMP;
2231     }
2232 
2233     return true;
2234 }
2235 
2236 //================MDPCompSrcSplit==============================================
acquireMDPPipes(hwc_context_t * ctx,hwc_layer_1_t * layer,MdpPipeInfoSplit & pipe_info)2237 bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
2238         MdpPipeInfoSplit& pipe_info) {
2239     private_handle_t *hnd = (private_handle_t *)layer->handle;
2240     hwc_rect_t dst = layer->displayFrame;
2241     hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2242     pipe_info.lIndex = ovutils::OV_INVALID;
2243     pipe_info.rIndex = ovutils::OV_INVALID;
2244 
2245     //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2246     //should have a higher priority than the right one. Pipe priorities are
2247     //starting with VG0, VG1 ... , RGB0 ..., DMA1
2248 
2249     Overlay::PipeSpecs pipeSpecs;
2250     pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2251             Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2252     pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2253     pipeSpecs.dpy = mDpy;
2254     pipeSpecs.fb = false;
2255 
2256     //1 pipe by default for a layer
2257     pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
2258     if(pipe_info.lIndex == ovutils::OV_INVALID) {
2259         return false;
2260     }
2261 
2262     /* Use 2 pipes IF
2263         a) Layer's crop width is > 2048 or
2264         b) Layer's dest width > 2048 or
2265         c) On primary, driver has indicated with caps to split always. This is
2266            based on an empirically derived value of panel height. Applied only
2267            if the layer's width is > mixer's width
2268     */
2269 
2270     bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
2271             qdutils::MDPVersion::getInstance().isSrcSplitAlways();
2272     int lSplit = getLeftSplit(ctx, mDpy);
2273     int dstWidth = dst.right - dst.left;
2274     int cropWidth = crop.right - crop.left;
2275 
2276     if(dstWidth > qdutils::MAX_DISPLAY_DIM or
2277             cropWidth > qdutils::MAX_DISPLAY_DIM or
2278             (primarySplitAlways and (cropWidth > lSplit))) {
2279         pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
2280         if(pipe_info.rIndex == ovutils::OV_INVALID) {
2281             return false;
2282         }
2283 
2284         // Return values
2285         // 1  Left pipe is higher priority, do nothing.
2286         // 0  Pipes of same priority.
2287         //-1  Right pipe is of higher priority, needs swap.
2288         if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2289                 pipe_info.rIndex) == -1) {
2290             qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
2291         }
2292     }
2293 
2294     return true;
2295 }
2296 
configure(hwc_context_t * ctx,hwc_layer_1_t * layer,PipeLayerPair & PipeLayerPair)2297 int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2298         PipeLayerPair& PipeLayerPair) {
2299     private_handle_t *hnd = (private_handle_t *)layer->handle;
2300     if(!hnd) {
2301         ALOGE("%s: layer handle is NULL", __FUNCTION__);
2302         return -1;
2303     }
2304     MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2305     MdpPipeInfoSplit& mdp_info =
2306         *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2307     Rotator **rot = &PipeLayerPair.rot;
2308     eZorder z = static_cast<eZorder>(mdp_info.zOrder);
2309     eIsFg isFg = IS_FG_OFF;
2310     eDest lDest = mdp_info.lIndex;
2311     eDest rDest = mdp_info.rIndex;
2312     hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2313     hwc_rect_t dst = layer->displayFrame;
2314     int transform = layer->transform;
2315     eTransform orient = static_cast<eTransform>(transform);
2316     const int downscale = 0;
2317     int rotFlags = ROT_FLAGS_NONE;
2318     uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2319     Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2320 
2321     ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2322              "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2323 
2324     // Handle R/B swap
2325     if (layer->flags & HWC_FORMAT_RB_SWAP) {
2326         if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2327             whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2328         else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2329             whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2330     }
2331 
2332     eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
2333     setMdpFlags(ctx, layer, mdpFlags, 0, transform);
2334 
2335     if(lDest != OV_INVALID && rDest != OV_INVALID) {
2336         //Enable overfetch
2337         setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
2338     }
2339 
2340     if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
2341         (*rot) = ctx->mRotMgr->getNext();
2342         if((*rot) == NULL) return -1;
2343         ctx->mLayerRotMap[mDpy]->add(layer, *rot);
2344         //If the video is using a single pipe, enable BWC
2345         if(rDest == OV_INVALID) {
2346             BwcPM::setBwc(crop, dst, transform, mdpFlags);
2347         }
2348         //Configure rotator for pre-rotation
2349         if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
2350             ALOGE("%s: configRotator failed!", __FUNCTION__);
2351             return -1;
2352         }
2353         updateSource(orient, whf, crop, *rot);
2354         rotFlags |= ROT_PREROTATED;
2355     }
2356 
2357     //If 2 pipes being used, divide layer into half, crop and dst
2358     hwc_rect_t cropL = crop;
2359     hwc_rect_t cropR = crop;
2360     hwc_rect_t dstL = dst;
2361     hwc_rect_t dstR = dst;
2362     if(lDest != OV_INVALID && rDest != OV_INVALID) {
2363         cropL.right = (crop.right + crop.left) / 2;
2364         cropR.left = cropL.right;
2365         sanitizeSourceCrop(cropL, cropR, hnd);
2366 
2367         //Swap crops on H flip since 2 pipes are being used
2368         if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2369             hwc_rect_t tmp = cropL;
2370             cropL = cropR;
2371             cropR = tmp;
2372         }
2373 
2374         dstL.right = (dst.right + dst.left) / 2;
2375         dstR.left = dstL.right;
2376     }
2377 
2378     //For the mdp, since either we are pre-rotating or MDP does flips
2379     orient = OVERLAY_TRANSFORM_0;
2380     transform = 0;
2381 
2382     //configure left pipe
2383     if(lDest != OV_INVALID) {
2384         PipeArgs pargL(mdpFlags, whf, z, isFg,
2385                 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2386                 (ovutils::eBlending) getBlending(layer->blending));
2387 
2388         if(configMdp(ctx->mOverlay, pargL, orient,
2389                     cropL, dstL, metadata, lDest) < 0) {
2390             ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2391             return -1;
2392         }
2393     }
2394 
2395     //configure right pipe
2396     if(rDest != OV_INVALID) {
2397         PipeArgs pargR(mdpFlags, whf, z, isFg,
2398                 static_cast<eRotFlags>(rotFlags),
2399                 layer->planeAlpha,
2400                 (ovutils::eBlending) getBlending(layer->blending));
2401         if(configMdp(ctx->mOverlay, pargR, orient,
2402                     cropR, dstR, metadata, rDest) < 0) {
2403             ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2404             return -1;
2405         }
2406     }
2407 
2408     return 0;
2409 }
2410 
2411 }; //namespace
2412 
2413