blob: 4c4dcd2d5f87d53057ec62db79845d6e5bde0d13 [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002 * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003 * 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
Saurabh Shah4fdde762013-04-30 18:47:33 -070019#include <math.h>
Naseer Ahmed7c958d42012-07-31 18:57:03 -070020#include "hwc_mdpcomp.h"
Naseer Ahmed54821fe2012-11-28 18:44:38 -050021#include <sys/ioctl.h>
Saurabh Shah56f610d2012-08-07 15:27:06 -070022#include "external.h"
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070023#include "virtual.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080024#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080025#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070026#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070027#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080028#include <overlayRotator.h>
Sushil Chauhandefd3522014-05-13 18:17:12 -070029#include "hwc_copybit.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080030
Saurabh Shah85234ec2013-04-12 17:09:00 -070031using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070032using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080033using namespace overlay::utils;
34namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070035
Naseer Ahmed7c958d42012-07-31 18:57:03 -070036namespace qhwc {
37
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080038//==============MDPComp========================================================
39
Naseer Ahmed7c958d42012-07-31 18:57:03 -070040IdleInvalidator *MDPComp::idleInvalidator = NULL;
41bool MDPComp::sIdleFallBack = false;
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -080042bool MDPComp::sHandleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070043bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050044bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070045bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -070046int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080047int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Raj Kamal389d6e32014-08-04 14:43:24 +053048bool MDPComp::sEnableYUVsplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070049bool MDPComp::sSrcSplitEnabled = false;
Saurabh Shah88e4d272013-09-03 13:31:29 -070050MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070051 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
52 sSrcSplitEnabled = true;
53 return new MDPCompSrcSplit(dpy);
54 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070055 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080056 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070057 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080058}
59
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080060MDPComp::MDPComp(int dpy):mDpy(dpy){};
61
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070062void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080063{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070064 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
65 return;
66
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080067 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070068 (mDpy == 0) ? "\"PRIMARY\"" :
69 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070070 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
71 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080072 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
73 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
74 (mCurrentFrame.needsRedraw? "YES" : "NO"),
75 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070076 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 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080091 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"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070098 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080099 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700100 (mCurrentFrame.drop[index] ? "DROP" :
101 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800102 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
103 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
104 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800105}
106
107bool MDPComp::init(hwc_context_t *ctx) {
108
109 if(!ctx) {
110 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
111 return false;
112 }
113
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800114 char property[PROPERTY_VALUE_MAX];
115
116 sEnabled = false;
117 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800118 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
119 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800120 sEnabled = true;
121 }
122
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700123 sEnableMixedMode = true;
124 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
125 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
126 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
127 sEnableMixedMode = false;
128 }
129
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800130 sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Saurabh Shah85234ec2013-04-12 17:09:00 -0700131 if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
132 int val = atoi(property);
133 if(val >= 0)
134 sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800135 }
136
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400137 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
138 // Idle invalidation is not necessary on command mode panels
139 long idle_timeout = DEFAULT_IDLE_TIME;
140 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
141 if(atoi(property) != 0)
142 idle_timeout = atoi(property);
143 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800144
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400145 //create Idle Invalidator only when not disabled through property
146 if(idle_timeout != -1)
147 idleInvalidator = IdleInvalidator::getInstance();
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800148
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400149 if(idleInvalidator == NULL) {
150 ALOGE("%s: failed to instantiate idleInvalidator object",
151 __FUNCTION__);
152 } else {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530153 idleInvalidator->init(timeout_handler, ctx,
154 (unsigned int)idle_timeout);
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400155 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800156 }
radhakrishnac9a67412013-09-25 17:40:42 +0530157
Saurabh Shah7c727642014-06-02 15:47:14 -0700158 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700159 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700160 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
161 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
162 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530163 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530164 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700165
166 if ((property_get("persist.hwc.ptor.enable", property, NULL) > 0) &&
167 ((!strncasecmp(property, "true", PROPERTY_VALUE_MAX )) ||
168 (!strncmp(property, "1", PROPERTY_VALUE_MAX )))) {
169 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
170 HWC_DISPLAY_PRIMARY);
171 }
172
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700173 return true;
174}
175
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800176void MDPComp::reset(hwc_context_t *ctx) {
177 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700178 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800179 ctx->mOverlay->clear(mDpy);
180 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700181}
182
Raj Kamal4393eaa2014-06-06 13:45:20 +0530183void MDPComp::reset() {
184 sHandleTimeout = false;
185 mModeOn = false;
186}
187
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700188void MDPComp::timeout_handler(void *udata) {
189 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
190
191 if(!ctx) {
192 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
193 return;
194 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800195 Locker::Autolock _l(ctx->mDrawLock);
196 // Handle timeout event only if the previous composition is MDP or MIXED.
197 if(!sHandleTimeout) {
198 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
199 return;
200 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700201 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700202 ALOGE("%s: HWC proc not registered", __FUNCTION__);
203 return;
204 }
205 sIdleFallBack = true;
206 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700207 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700208}
209
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800210void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800211 hwc_display_contents_1_t* list) {
212 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800213
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800214 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800215 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800216 if(!mCurrentFrame.isFBComposed[index]) {
217 layerProp[index].mFlags |= HWC_MDPCOMP;
218 layer->compositionType = HWC_OVERLAY;
219 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800220 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700221 /* Drop the layer when its already present in FB OR when it lies
222 * outside frame's ROI */
223 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800224 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700225 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800226 }
227 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700228}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500229
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800230void MDPComp::setRedraw(hwc_context_t *ctx,
231 hwc_display_contents_1_t* list) {
232 mCurrentFrame.needsRedraw = false;
233 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
234 (list->flags & HWC_GEOMETRY_CHANGED) ||
235 isSkipPresent(ctx, mDpy)) {
236 mCurrentFrame.needsRedraw = true;
237 }
238}
239
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800240MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700241 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700242 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800243}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800244
Saurabh Shahaa236822013-04-24 18:07:26 -0700245void MDPComp::FrameInfo::reset(const int& numLayers) {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700246 for(int i = 0; i < MAX_PIPES_PER_MIXER; i++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800247 if(mdpToLayer[i].pipeInfo) {
248 delete mdpToLayer[i].pipeInfo;
249 mdpToLayer[i].pipeInfo = NULL;
250 //We dont own the rotator
251 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800252 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800253 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800254
255 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
256 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700257 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800258
Saurabh Shahaa236822013-04-24 18:07:26 -0700259 layerCount = numLayers;
260 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800261 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700262 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800263 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800264}
265
Saurabh Shahaa236822013-04-24 18:07:26 -0700266void MDPComp::FrameInfo::map() {
267 // populate layer and MDP maps
268 int mdpIdx = 0;
269 for(int idx = 0; idx < layerCount; idx++) {
270 if(!isFBComposed[idx]) {
271 mdpToLayer[mdpIdx].listIndex = idx;
272 layerToMDP[idx] = mdpIdx++;
273 }
274 }
275}
276
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800277MDPComp::LayerCache::LayerCache() {
278 reset();
279}
280
281void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700282 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530283 memset(&isFBComposed, true, sizeof(isFBComposed));
284 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800285 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700286}
287
288void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530289 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700290 for(int i = 0; i < numAppLayers; i++) {
291 hnd[i] = list->hwLayers[i].handle;
292 }
293}
294
295void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700296 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530297 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
298 memcpy(&drop, &curFrame.drop, sizeof(drop));
299}
300
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800301bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
302 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530303 if(layerCount != curFrame.layerCount)
304 return false;
305 for(int i = 0; i < curFrame.layerCount; i++) {
306 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
307 (curFrame.drop[i] != drop[i])) {
308 return false;
309 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800310 if(curFrame.isFBComposed[i] &&
311 (hnd[i] != list->hwLayers[i].handle)){
312 return false;
313 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530314 }
315 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800316}
317
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700318bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
319 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800320 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700321 (not isValidDimension(ctx,layer))
322 //More conditions here, SKIP, sRGB+Blend etc
323 ) {
324 return false;
325 }
326 return true;
327}
328
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530329bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800330 private_handle_t *hnd = (private_handle_t *)layer->handle;
331
332 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700333 if (layer->flags & HWC_COLOR_FILL) {
334 // Color layer
335 return true;
336 }
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800337 ALOGE("%s: layer handle is NULL", __FUNCTION__);
338 return false;
339 }
340
Naseer Ahmede850a802013-09-06 13:12:52 -0400341 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400342 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400343 return false;
344
Saurabh Shah62e1d732013-09-17 10:44:05 -0700345 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700346 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700347 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700348 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
349 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700350 int dst_w = dst.right - dst.left;
351 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800352 float w_scale = ((float)crop_w / (float)dst_w);
353 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530354 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700355
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800356 /* Workaround for MDP HW limitation in DSI command mode panels where
357 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
358 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530359 * There also is a HW limilation in MDP, minimum block size is 2x2
360 * Fallback to GPU if height is less than 2.
361 */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800362 if((crop_w < 5)||(crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800363 return false;
364
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800365 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530366 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800367 const float w_dscale = w_scale;
368 const float h_dscale = h_scale;
369
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800370 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700371
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530372 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700373 /* On targets that doesnt support Decimation (eg.,8x26)
374 * maximum downscale support is overlay pipe downscale.
375 */
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530376 if(crop_w > mdpHw.getMaxMixerWidth() ||
377 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700378 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800379 return false;
380 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700381 // Decimation on macrotile format layers is not supported.
382 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530383 /* Bail out if
384 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700385 * 2. exceeds maximum downscale limit
386 */
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530387 if(((crop_w > mdpHw.getMaxMixerWidth()) &&
388 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700389 w_dscale > maxMDPDownscale ||
390 h_dscale > maxMDPDownscale) {
391 return false;
392 }
393 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800394 return false;
395 }
396 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700397 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700398 return false;
399 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700400 }
401
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800402 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530403 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800404 const float w_uscale = 1.0f / w_scale;
405 const float h_uscale = 1.0f / h_scale;
406
407 if(w_uscale > upscale || h_uscale > upscale)
408 return false;
409 }
410
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800411 return true;
412}
413
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800414bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700415 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800416
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800417 if(!isEnabled()) {
418 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700419 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530420 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530421 qdutils::MDPVersion::getInstance().is8x16() ||
422 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800423 ctx->mVideoTransFlag &&
424 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700425 //1 Padding round to shift pipes across mixers
426 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
427 __FUNCTION__);
428 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700429 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
430 /* TODO: freeing up all the resources only for the targets having total
431 number of pipes < 8. Need to analyze number of VIG pipes used
432 for primary in previous draw cycle and accordingly decide
433 whether to fall back to full GPU comp or video only comp
434 */
435 if(isSecondaryConfiguring(ctx)) {
436 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
437 __FUNCTION__);
438 ret = false;
439 } else if(ctx->isPaddingRound) {
440 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
441 __FUNCTION__,mDpy);
442 ret = false;
443 }
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700444 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700445 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800446}
447
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800448void 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. */
457bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
458 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700459 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800460 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800461
462 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800463 if(!isValidRect(visibleRect)) {
464 mCurrentFrame.drop[i] = true;
465 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800466 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800467 }
468
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700469 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700470 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800471 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700472
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700473 if(!isValidRect(res)) {
474 mCurrentFrame.drop[i] = true;
475 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800476 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700477 /* Reset frame ROI when any layer which needs scaling also needs ROI
478 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800479 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800480 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700481 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
482 mCurrentFrame.dropCount = 0;
483 return false;
484 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800485
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800486 /* deduct any opaque region from visibleRect */
487 if (layer->blending == HWC_BLENDING_NONE)
488 visibleRect = deductRect(visibleRect, res);
489 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700490 }
491 return true;
492}
493
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800494/* 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. */
497void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
498 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700499 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800500 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700501 return;
502
503 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800504 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
505 (int)ctx->dpyAttr[mDpy].yres};
506
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700507 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800508 hwc_layer_1_t* layer = &list->hwLayers[index];
509 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800510 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700511 hwc_rect_t dst = layer->displayFrame;
512 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800513
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800514#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800515 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700516 {
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 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800522#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800523
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800524 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700525 }
526 }
527
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800528 /* No layer is updating. Still SF wants a refresh.*/
529 if(!isValidRect(roi))
530 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800531
532 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800533 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800534
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800535 ctx->listStats[mDpy].lRoi = roi;
536 if(!validateAndApplyROI(ctx, list))
537 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700538
539 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800540 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
541 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
542}
543
544void 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. */
558bool 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. */
604void 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];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800623 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800624 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800625 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700626 hwc_rect_t dst = layer->displayFrame;
627 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800628
629#ifdef QCOM_BSP
630 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700631 {
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 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800637#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
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700649 /* 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
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800659 /* 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);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700678}
679
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800680/* 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 */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800682bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800683 hwc_display_contents_1_t* list){
684
Saurabh Shahaa236822013-04-24 18:07:26 -0700685 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800686 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800687
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -0700688 // No Idle fall back, if secure display or secure RGB layers are present
689 if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
690 !ctx->listStats[mDpy].secureRGBCount)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700691 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
692 return false;
693 }
694
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800695 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700696 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
697 __FUNCTION__,
698 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800699 return false;
700 }
701
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700702 // if secondary is configuring or Padding round, fall back to video only
703 // composition and release all assigned non VIG pipes from primary.
704 if(isSecondaryConfiguring(ctx)) {
705 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
706 __FUNCTION__);
707 return false;
708 } else if(ctx->isPaddingRound) {
709 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
710 __FUNCTION__,mDpy);
711 return false;
712 }
713
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530714 MDPVersion& mdpHw = MDPVersion::getInstance();
715 if(mDpy > HWC_DISPLAY_PRIMARY &&
716 (priDispW > mdpHw.getMaxMixerWidth()) &&
717 (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800718 // Disable MDP comp on Secondary when the primary is highres panel and
719 // the secondary is a normal 1080p, because, MDP comp on secondary under
720 // in such usecase, decimation gets used for downscale and there will be
721 // a quality mismatch when there will be a fallback to GPU comp
722 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
723 __FUNCTION__);
724 return false;
725 }
726
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800727 // check for action safe flag and downscale mode which requires scaling.
728 if(ctx->dpyAttr[mDpy].mActionSafePresent
729 || ctx->dpyAttr[mDpy].mDownScaleMode) {
730 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
731 return false;
732 }
733
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800734 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800735 hwc_layer_1_t* layer = &list->hwLayers[i];
736 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800737
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800738 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700739 if(!canUseRotator(ctx, mDpy)) {
740 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
741 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700742 return false;
743 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800744 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530745
746 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
747 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700748 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530749 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
750 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
751 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800752 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700753
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700754 if(ctx->mAD->isDoable()) {
755 return false;
756 }
757
Saurabh Shahaa236822013-04-24 18:07:26 -0700758 //If all above hard conditions are met we can do full or partial MDP comp.
759 bool ret = false;
760 if(fullMDPComp(ctx, list)) {
761 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700762 } else if(fullMDPCompWithPTOR(ctx, list)) {
763 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700764 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700765 ret = true;
766 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530767
Saurabh Shahaa236822013-04-24 18:07:26 -0700768 return ret;
769}
770
771bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700772
773 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
774 return false;
775
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700776 //Will benefit presentation / secondary-only layer.
777 if((mDpy > HWC_DISPLAY_PRIMARY) &&
778 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
779 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
780 return false;
781 }
782
783 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
784 for(int i = 0; i < numAppLayers; i++) {
785 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700786 if(not mCurrentFrame.drop[i] and
787 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700788 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
789 return false;
790 }
791 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800792
Saurabh Shahaa236822013-04-24 18:07:26 -0700793 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700794 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
795 sizeof(mCurrentFrame.isFBComposed));
796 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
797 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700798
Raj Kamal389d6e32014-08-04 14:43:24 +0530799 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800800 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530801 }
802
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800803 if(!postHeuristicsHandling(ctx, list)) {
804 ALOGD_IF(isDebug(), "post heuristic handling failed");
805 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700806 return false;
807 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700808 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
809 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700810 return true;
811}
812
Sushil Chauhandefd3522014-05-13 18:17:12 -0700813/* Full MDP Composition with Peripheral Tiny Overlap Removal.
814 * MDP bandwidth limitations can be avoided, if the overlap region
815 * covered by the smallest layer at a higher z-order, gets composed
816 * by Copybit on a render buffer, which can be queued to MDP.
817 */
818bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
819 hwc_display_contents_1_t* list) {
820
821 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
822 const int stagesForMDP = min(sMaxPipesPerMixer,
823 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
824
825 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700826 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700827 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
828 return false;
829 }
830
831 // Frame level checks
832 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
833 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
834 isSecurePresent(ctx, mDpy)) {
835 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
836 return false;
837 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700838 // MDP comp checks
839 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700840 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700841 if(not isSupportedForMDPComp(ctx, layer)) {
842 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
843 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700844 }
845 }
846
Sushil Chauhandefd3522014-05-13 18:17:12 -0700847 /* We cannot use this composition mode, if:
848 1. A below layer needs scaling.
849 2. Overlap is not peripheral to display.
850 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700851 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700852 */
853
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700854 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
855 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
856 memset(overlapRect, 0, sizeof(overlapRect));
857 int layerPixelCount, minPixelCount = 0;
858 int numPTORLayersFound = 0;
859 for (int i = numAppLayers-1; (i >= 0 &&
860 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700861 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700862 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700863 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700864 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
865 // PTOR layer should be peripheral and cannot have transform
866 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
867 has90Transform(layer)) {
868 continue;
869 }
870 if((3 * (layerPixelCount + minPixelCount)) >
871 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
872 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
873 continue;
874 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700875 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700876 for (int j = i-1; j >= 0; j--) {
877 // Check if the layers below this layer qualifies for PTOR comp
878 hwc_layer_1_t* layer = &list->hwLayers[j];
879 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700880 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700881 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700882 if (isValidRect(getIntersection(dispFrame, disFrame))) {
883 if (has90Transform(layer) || needsScaling(layer)) {
884 found = false;
885 break;
886 }
887 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700888 }
889 }
890 // Store the minLayer Index
891 if(found) {
892 minLayerIndex[numPTORLayersFound] = i;
893 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
894 minPixelCount += layerPixelCount;
895 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700896 }
897 }
898
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700899 if(isValidRect(getIntersection(overlapRect[0], overlapRect[1]))) {
900 ALOGD_IF(isDebug(), "%s: Ignore Rect2 its intersects with Rect1",
901 __FUNCTION__);
902 // reset second minLayerIndex[1];
903 minLayerIndex[1] = -1;
904 numPTORLayersFound--;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700905 }
906
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700907 // No overlap layers
908 if (!numPTORLayersFound)
909 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700910
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700911 ctx->mPtorInfo.count = numPTORLayersFound;
912 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
913 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
914 }
915
916 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
917 // reset PTOR
918 ctx->mPtorInfo.count = 0;
919 return false;
920 }
921 // Store the displayFrame and the sourceCrops of the layers
922 hwc_rect_t displayFrame[numAppLayers];
923 hwc_rect_t sourceCrop[numAppLayers];
924 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700925 hwc_layer_1_t* layer = &list->hwLayers[i];
926 displayFrame[i] = layer->displayFrame;
927 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700928 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700929
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700930 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
931 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
932
Xu Yangcda012c2014-07-30 21:57:21 +0800933 // Store the blending mode, planeAlpha, and transform of PTOR layers
934 int32_t blending[numPTORLayersFound];
935 uint8_t planeAlpha[numPTORLayersFound];
936 uint32_t transform[numPTORLayersFound];
937
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700938 for(int j = 0; j < numPTORLayersFound; j++) {
939 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700940
941 // Update src crop of PTOR layer
942 hwc_layer_1_t* layer = &list->hwLayers[index];
943 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
944 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
945 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
946 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
947
948 // Store & update w, h, format of PTOR layer
949 private_handle_t *hnd = (private_handle_t *)layer->handle;
950 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
951 layerWhf[j] = whf;
952 hnd->width = renderBuf->width;
953 hnd->height = renderBuf->height;
954 hnd->format = renderBuf->format;
955
Xu Yangcda012c2014-07-30 21:57:21 +0800956 // Store & update blending mode, planeAlpha and transform of PTOR layer
957 blending[j] = layer->blending;
958 planeAlpha[j] = layer->planeAlpha;
959 transform[j] = layer->transform;
960 layer->blending = HWC_BLENDING_NONE;
961 layer->planeAlpha = 0xFF;
962 layer->transform = 0;
963
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700964 // Remove overlap from crop & displayFrame of below layers
965 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700966 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700967 if(!isValidRect(getIntersection(layer->displayFrame,
968 overlapRect[j]))) {
969 continue;
970 }
971 // Update layer attributes
972 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
973 hwc_rect_t destRect = deductRect(layer->displayFrame,
974 overlapRect[j]);
975 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
976 layer->transform);
977 layer->sourceCropf.left = (float)srcCrop.left;
978 layer->sourceCropf.top = (float)srcCrop.top;
979 layer->sourceCropf.right = (float)srcCrop.right;
980 layer->sourceCropf.bottom = (float)srcCrop.bottom;
981 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700982 }
983
984 mCurrentFrame.mdpCount = numAppLayers;
985 mCurrentFrame.fbCount = 0;
986 mCurrentFrame.fbZ = -1;
987
988 for (int j = 0; j < numAppLayers; j++)
989 mCurrentFrame.isFBComposed[j] = false;
990
991 bool result = postHeuristicsHandling(ctx, list);
992
993 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700994 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700995 hwc_layer_1_t* layer = &list->hwLayers[i];
996 layer->displayFrame = displayFrame[i];
997 layer->sourceCropf.left = (float)sourceCrop[i].left;
998 layer->sourceCropf.top = (float)sourceCrop[i].top;
999 layer->sourceCropf.right = (float)sourceCrop[i].right;
1000 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1001 }
1002
Xu Yangcda012c2014-07-30 21:57:21 +08001003 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001004 for (int i = 0; i < numPTORLayersFound; i++) {
1005 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001006 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001007 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1008 hnd->width = layerWhf[i].w;
1009 hnd->height = layerWhf[i].h;
1010 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001011 layer->blending = blending[i];
1012 layer->planeAlpha = planeAlpha[i];
1013 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001014 }
1015
Sushil Chauhandefd3522014-05-13 18:17:12 -07001016 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001017 // reset PTOR
1018 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001019 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001020 } else {
1021 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1022 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001023 }
1024
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001025 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1026 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001027 return result;
1028}
1029
Saurabh Shahaa236822013-04-24 18:07:26 -07001030bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1031{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001032 if(!sEnableMixedMode) {
1033 //Mixed mode is disabled. No need to even try caching.
1034 return false;
1035 }
1036
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001037 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001038 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001039 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001040 cacheBasedComp(ctx, list);
1041 } else {
1042 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001043 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001044 }
1045
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001046 return ret;
1047}
1048
1049bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1050 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001051 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1052 return false;
1053
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001054 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001055 mCurrentFrame.reset(numAppLayers);
1056 updateLayerCache(ctx, list);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001057
1058 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1059 for(int i = 0; i < numAppLayers; i++) {
1060 if(!mCurrentFrame.isFBComposed[i]) {
1061 hwc_layer_1_t* layer = &list->hwLayers[i];
1062 if(not isSupportedForMDPComp(ctx, layer)) {
1063 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1064 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001065 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001066 return false;
1067 }
1068 }
1069 }
1070
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001071 updateYUV(ctx, list, false /*secure only*/);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001072 /* mark secure RGB layers for MDP comp */
1073 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301074 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001075 if(!ret) {
1076 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001077 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001078 return false;
1079 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001080
1081 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001082
Raj Kamal389d6e32014-08-04 14:43:24 +05301083 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001084 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301085 }
1086
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001087 //Will benefit cases where a video has non-updating background.
1088 if((mDpy > HWC_DISPLAY_PRIMARY) and
1089 (mdpCount > MAX_SEC_LAYERS)) {
1090 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001091 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001092 return false;
1093 }
1094
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001095 if(!postHeuristicsHandling(ctx, list)) {
1096 ALOGD_IF(isDebug(), "post heuristic handling failed");
1097 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001098 return false;
1099 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001100 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1101 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001102
Saurabh Shahaa236822013-04-24 18:07:26 -07001103 return true;
1104}
1105
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001106bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001107 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001108 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1109 return false;
1110
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001111 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001112 return false;
1113 }
1114
Saurabh Shahb772ae32013-11-18 15:40:02 -08001115 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001116 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1117 const int stagesForMDP = min(sMaxPipesPerMixer,
1118 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001119
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001120 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1121 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1122 int lastMDPSupportedIndex = numAppLayers;
1123 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001124
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001125 //Find the minimum MDP batch size
1126 for(int i = 0; i < numAppLayers;i++) {
1127 if(mCurrentFrame.drop[i]) {
1128 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001129 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001130 }
1131 hwc_layer_1_t* layer = &list->hwLayers[i];
1132 if(not isSupportedForMDPComp(ctx, layer)) {
1133 lastMDPSupportedIndex = i;
1134 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1135 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001136 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001137 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001138 }
1139
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001140 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1141 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1142 mCurrentFrame.dropCount);
1143
1144 //Start at a point where the fb batch should at least have 2 layers, for
1145 //this mode to be justified.
1146 while(fbBatchSize < 2) {
1147 ++fbBatchSize;
1148 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001149 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001150
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001151 //If there are no layers for MDP, this mode doesnt make sense.
1152 if(mdpBatchSize < 1) {
1153 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1154 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001155 return false;
1156 }
1157
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001158 mCurrentFrame.reset(numAppLayers);
1159
1160 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1161 while(mdpBatchSize > 0) {
1162 //Mark layers for MDP comp
1163 int mdpBatchLeft = mdpBatchSize;
1164 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1165 if(mCurrentFrame.drop[i]) {
1166 continue;
1167 }
1168 mCurrentFrame.isFBComposed[i] = false;
1169 --mdpBatchLeft;
1170 }
1171
1172 mCurrentFrame.fbZ = mdpBatchSize;
1173 mCurrentFrame.fbCount = fbBatchSize;
1174 mCurrentFrame.mdpCount = mdpBatchSize;
1175
1176 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1177 __FUNCTION__, mdpBatchSize, fbBatchSize,
1178 mCurrentFrame.dropCount);
1179
1180 if(postHeuristicsHandling(ctx, list)) {
1181 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001182 __FUNCTION__);
1183 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1184 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001185 return true;
1186 }
1187
1188 reset(ctx);
1189 --mdpBatchSize;
1190 ++fbBatchSize;
1191 }
1192
1193 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001194}
1195
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001196bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301197 if(mDpy or isSecurePresent(ctx, mDpy) or
1198 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001199 return false;
1200 }
1201 return true;
1202}
1203
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001204bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1205 hwc_display_contents_1_t* list){
1206 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1207 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1208 mDpy ) {
1209 return false;
1210 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001211 if(ctx->listStats[mDpy].secureUI)
1212 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001213 return true;
1214}
1215
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001216bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1217 hwc_display_contents_1_t* list) {
1218 const bool secureOnly = true;
1219 return videoOnlyComp(ctx, list, not secureOnly) or
1220 videoOnlyComp(ctx, list, secureOnly);
1221}
1222
1223bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001224 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001225 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1226 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001227 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001228
Saurabh Shahaa236822013-04-24 18:07:26 -07001229 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001230 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001231 updateYUV(ctx, list, secureOnly);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001232 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001233
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001234 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1235 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001236 return false;
1237 }
1238
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001239 /* Bail out if we are processing only secured video layers
1240 * and we dont have any */
1241 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001242 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001243 return false;
1244 }
1245
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001246 if(mCurrentFrame.fbCount)
1247 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001248
Raj Kamal389d6e32014-08-04 14:43:24 +05301249 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001250 adjustForSourceSplit(ctx, list);
1251 }
1252
1253 if(!postHeuristicsHandling(ctx, list)) {
1254 ALOGD_IF(isDebug(), "post heuristic handling failed");
1255 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001256 return false;
1257 }
1258
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001259 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1260 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001261 return true;
1262}
1263
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001264/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1265bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1266 hwc_display_contents_1_t* list) {
1267 const bool secureOnly = true;
1268 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1269 mdpOnlyLayersComp(ctx, list, secureOnly);
1270
1271}
1272
1273bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1274 hwc_display_contents_1_t* list, bool secureOnly) {
1275
1276 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1277 return false;
1278
1279 /* Bail out if we are processing only secured video layers
1280 * and we dont have any */
1281 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1282 reset(ctx);
1283 return false;
1284 }
1285
1286 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1287 mCurrentFrame.reset(numAppLayers);
1288 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1289
1290 updateYUV(ctx, list, secureOnly);
1291 /* mark secure RGB layers for MDP comp */
1292 updateSecureRGB(ctx, list);
1293
1294 if(mCurrentFrame.mdpCount == 0) {
1295 reset(ctx);
1296 return false;
1297 }
1298
1299 /* find the maximum batch of layers to be marked for framebuffer */
1300 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1301 if(!ret) {
1302 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1303 reset(ctx);
1304 return false;
1305 }
1306
1307 if(sEnableYUVsplit){
1308 adjustForSourceSplit(ctx, list);
1309 }
1310
1311 if(!postHeuristicsHandling(ctx, list)) {
1312 ALOGD_IF(isDebug(), "post heuristic handling failed");
1313 reset(ctx);
1314 return false;
1315 }
1316
1317 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1318 __FUNCTION__);
1319 return true;
1320}
1321
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001322/* Checks for conditions where YUV layers cannot be bypassed */
1323bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001324 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001325 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001326 return false;
1327 }
1328
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001329 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001330 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1331 return false;
1332 }
1333
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001334 if(isSecuring(ctx, layer)) {
1335 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1336 return false;
1337 }
1338
Saurabh Shah4fdde762013-04-30 18:47:33 -07001339 if(!isValidDimension(ctx, layer)) {
1340 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1341 __FUNCTION__);
1342 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001343 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001344
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001345 if(layer->planeAlpha < 0xFF) {
1346 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1347 in video only mode",
1348 __FUNCTION__);
1349 return false;
1350 }
1351
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001352 return true;
1353}
1354
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001355/* Checks for conditions where Secure RGB layers cannot be bypassed */
1356bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1357 if(isSkipLayer(layer)) {
1358 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1359 __FUNCTION__, mDpy);
1360 return false;
1361 }
1362
1363 if(isSecuring(ctx, layer)) {
1364 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1365 return false;
1366 }
1367
1368 if(not isSupportedForMDPComp(ctx, layer)) {
1369 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1370 __FUNCTION__);
1371 return false;
1372 }
1373 return true;
1374}
1375
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301376/* starts at fromIndex and check for each layer to find
1377 * if it it has overlapping with any Updating layer above it in zorder
1378 * till the end of the batch. returns true if it finds any intersection */
1379bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1380 int fromIndex, int toIndex) {
1381 for(int i = fromIndex; i < toIndex; i++) {
1382 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1383 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1384 return false;
1385 }
1386 }
1387 }
1388 return true;
1389}
1390
1391/* Checks if given layer at targetLayerIndex has any
1392 * intersection with all the updating layers in beween
1393 * fromIndex and toIndex. Returns true if it finds intersectiion */
1394bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1395 int fromIndex, int toIndex, int targetLayerIndex) {
1396 for(int i = fromIndex; i <= toIndex; i++) {
1397 if(!mCurrentFrame.isFBComposed[i]) {
1398 if(areLayersIntersecting(&list->hwLayers[i],
1399 &list->hwLayers[targetLayerIndex])) {
1400 return true;
1401 }
1402 }
1403 }
1404 return false;
1405}
1406
1407int MDPComp::getBatch(hwc_display_contents_1_t* list,
1408 int& maxBatchStart, int& maxBatchEnd,
1409 int& maxBatchCount) {
1410 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301411 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001412 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301413 while (i < mCurrentFrame.layerCount) {
1414 int batchCount = 0;
1415 int batchStart = i;
1416 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001417 /* Adjust batch Z order with the dropped layers so far */
1418 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301419 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301420 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301421 while(i < mCurrentFrame.layerCount) {
1422 if(!mCurrentFrame.isFBComposed[i]) {
1423 if(!batchCount) {
1424 i++;
1425 break;
1426 }
1427 updatingLayersAbove++;
1428 i++;
1429 continue;
1430 } else {
1431 if(mCurrentFrame.drop[i]) {
1432 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001433 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301434 continue;
1435 } else if(updatingLayersAbove <= 0) {
1436 batchCount++;
1437 batchEnd = i;
1438 i++;
1439 continue;
1440 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1441
1442 // We have a valid updating layer already. If layer-i not
1443 // have overlapping with all updating layers in between
1444 // batch-start and i, then we can add layer i to batch.
1445 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1446 batchCount++;
1447 batchEnd = i;
1448 i++;
1449 continue;
1450 } else if(canPushBatchToTop(list, batchStart, i)) {
1451 //If All the non-updating layers with in this batch
1452 //does not have intersection with the updating layers
1453 //above in z-order, then we can safely move the batch to
1454 //higher z-order. Increment fbZ as it is moving up.
1455 if( firstZReverseIndex < 0) {
1456 firstZReverseIndex = i;
1457 }
1458 batchCount++;
1459 batchEnd = i;
1460 fbZ += updatingLayersAbove;
1461 i++;
1462 updatingLayersAbove = 0;
1463 continue;
1464 } else {
1465 //both failed.start the loop again from here.
1466 if(firstZReverseIndex >= 0) {
1467 i = firstZReverseIndex;
1468 }
1469 break;
1470 }
1471 }
1472 }
1473 }
1474 if(batchCount > maxBatchCount) {
1475 maxBatchCount = batchCount;
1476 maxBatchStart = batchStart;
1477 maxBatchEnd = batchEnd;
1478 fbZOrder = fbZ;
1479 }
1480 }
1481 return fbZOrder;
1482}
1483
1484bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1485 hwc_display_contents_1_t* list) {
1486 /* Idea is to keep as many non-updating(cached) layers in FB and
1487 * send rest of them through MDP. This is done in 2 steps.
1488 * 1. Find the maximum contiguous batch of non-updating layers.
1489 * 2. See if we can improve this batch size for caching by adding
1490 * opaque layers around the batch, if they don't have
1491 * any overlapping with the updating layers in between.
1492 * NEVER mark an updating layer for caching.
1493 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001494
1495 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001496 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001497 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301498 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001499
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001500 /* Nothing is cached. No batching needed */
1501 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001502 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001503 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001504
1505 /* No MDP comp layers, try to use other comp modes */
1506 if(mCurrentFrame.mdpCount == 0) {
1507 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001508 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001509
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301510 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001511
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301512 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001513 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001514 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001515 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301516 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001517 if(!mCurrentFrame.drop[i]){
1518 //If an unsupported layer is being attempted to
1519 //be pulled out we should fail
1520 if(not isSupportedForMDPComp(ctx, layer)) {
1521 return false;
1522 }
1523 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001524 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001525 }
1526 }
1527
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301528 // update the frame data
1529 mCurrentFrame.fbZ = fbZ;
1530 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001531 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001532 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001533
1534 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301535 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001536
1537 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001538}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001539
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001540void MDPComp::updateLayerCache(hwc_context_t* ctx,
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001541 hwc_display_contents_1_t* list) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001542 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001543 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001544
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001545 for(int i = 0; i < numAppLayers; i++) {
1546 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001547 if(!mCurrentFrame.drop[i])
1548 fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001549 mCurrentFrame.isFBComposed[i] = true;
1550 } else {
Saurabh Shahaa236822013-04-24 18:07:26 -07001551 mCurrentFrame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001552 }
1553 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001554
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001555 mCurrentFrame.fbCount = fbCount;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001556 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
1557 - mCurrentFrame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001558
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001559 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d"
1560 ,__FUNCTION__, mCurrentFrame.mdpCount, mCurrentFrame.fbCount,
1561 mCurrentFrame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001562}
1563
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001564void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
1565 bool secureOnly) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001566 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1567 for(int index = 0;index < nYuvCount; index++){
1568 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1569 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1570
1571 if(!isYUVDoable(ctx, layer)) {
1572 if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
1573 mCurrentFrame.isFBComposed[nYuvIndex] = true;
1574 mCurrentFrame.fbCount++;
1575 }
1576 } else {
1577 if(mCurrentFrame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001578 private_handle_t *hnd = (private_handle_t *)layer->handle;
1579 if(!secureOnly || isSecureBuffer(hnd)) {
1580 mCurrentFrame.isFBComposed[nYuvIndex] = false;
1581 mCurrentFrame.fbCount--;
1582 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001583 }
1584 }
1585 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001586
1587 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001588 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1589 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001590 mCurrentFrame.fbCount);
1591}
1592
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001593void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1594 hwc_display_contents_1_t* list) {
1595 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1596 for(int index = 0;index < nSecureRGBCount; index++){
1597 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1598 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1599
1600 if(!isSecureRGBDoable(ctx, layer)) {
1601 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1602 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1603 mCurrentFrame.fbCount++;
1604 }
1605 } else {
1606 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1607 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1608 mCurrentFrame.fbCount--;
1609 }
1610 }
1611 }
1612
1613 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1614 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1615 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1616 mCurrentFrame.fbCount);
1617}
1618
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001619hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1620 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001621 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001622
1623 /* Update only the region of FB needed for composition */
1624 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1625 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1626 hwc_layer_1_t* layer = &list->hwLayers[i];
1627 hwc_rect_t dst = layer->displayFrame;
1628 fbRect = getUnion(fbRect, dst);
1629 }
1630 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001631 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001632 return fbRect;
1633}
1634
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001635bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1636 hwc_display_contents_1_t* list) {
1637
1638 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001639 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001640 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1641 return false;
1642 }
1643
1644 //Limitations checks
1645 if(!hwLimitationsCheck(ctx, list)) {
1646 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1647 return false;
1648 }
1649
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001650 //Configure framebuffer first if applicable
1651 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001652 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001653 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1654 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001655 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1656 __FUNCTION__);
1657 return false;
1658 }
1659 }
1660
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001661 mCurrentFrame.map();
1662
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001663 if(!allocLayerPipes(ctx, list)) {
1664 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001665 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001666 }
1667
1668 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001669 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001670 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001671 int mdpIndex = mCurrentFrame.layerToMDP[index];
1672 hwc_layer_1_t* layer = &list->hwLayers[index];
1673
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301674 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1675 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1676 mdpNextZOrder++;
1677 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001678 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1679 cur_pipe->zOrder = mdpNextZOrder++;
1680
radhakrishnac9a67412013-09-25 17:40:42 +05301681 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301682 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301683 if(configure4k2kYuv(ctx, layer,
1684 mCurrentFrame.mdpToLayer[mdpIndex])
1685 != 0 ){
1686 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1687 for layer %d",__FUNCTION__, index);
1688 return false;
1689 }
1690 else{
1691 mdpNextZOrder++;
1692 }
1693 continue;
1694 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001695 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1696 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301697 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001698 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001699 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001700 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001701 }
1702
Saurabh Shaha36be922013-12-16 18:18:39 -08001703 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1704 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1705 ,__FUNCTION__, mDpy);
1706 return false;
1707 }
1708
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001709 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001710 return true;
1711}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001712
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001713bool MDPComp::resourceCheck(hwc_context_t* ctx,
1714 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001715 const bool fbUsed = mCurrentFrame.fbCount;
1716 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1717 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1718 return false;
1719 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001720 // Init rotCount to number of rotate sessions used by other displays
1721 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1722 // Count the number of rotator sessions required for current display
1723 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1724 if(!mCurrentFrame.isFBComposed[index]) {
1725 hwc_layer_1_t* layer = &list->hwLayers[index];
1726 private_handle_t *hnd = (private_handle_t *)layer->handle;
1727 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1728 rotCount++;
1729 }
1730 }
1731 }
1732 // if number of layers to rotate exceeds max rotator sessions, bail out.
1733 if(rotCount > RotMgr::MAX_ROT_SESS) {
1734 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1735 __FUNCTION__, mDpy);
1736 return false;
1737 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001738 return true;
1739}
1740
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301741bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1742 hwc_display_contents_1_t* list) {
1743
1744 //A-family hw limitation:
1745 //If a layer need alpha scaling, MDP can not support.
1746 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1747 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1748 if(!mCurrentFrame.isFBComposed[i] &&
1749 isAlphaScaled( &list->hwLayers[i])) {
1750 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1751 return false;
1752 }
1753 }
1754 }
1755
1756 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1757 //If multiple layers requires downscaling and also they are overlapping
1758 //fall back to GPU since MDSS can not handle it.
1759 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1760 qdutils::MDPVersion::getInstance().is8x26()) {
1761 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1762 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1763 if(!mCurrentFrame.isFBComposed[i] &&
1764 isDownscaleRequired(botLayer)) {
1765 //if layer-i is marked for MDP and needs downscaling
1766 //check if any MDP layer on top of i & overlaps with layer-i
1767 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1768 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1769 if(!mCurrentFrame.isFBComposed[j] &&
1770 isDownscaleRequired(topLayer)) {
1771 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1772 topLayer->displayFrame);
1773 if(isValidRect(r))
1774 return false;
1775 }
1776 }
1777 }
1778 }
1779 }
1780 return true;
1781}
1782
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001783int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001784 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001785 char property[PROPERTY_VALUE_MAX];
1786
Raj Kamal4393eaa2014-06-06 13:45:20 +05301787 if(!ctx || !list) {
1788 ALOGE("%s: Invalid context or list",__FUNCTION__);
1789 mCachedFrame.reset();
1790 return -1;
1791 }
1792
1793 const int numLayers = ctx->listStats[mDpy].numAppLayers;
1794
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001795 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1796 int currentFlags = atoi(property);
1797 if(currentFlags != sSimulationFlags) {
1798 sSimulationFlags = currentFlags;
1799 ALOGE("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1800 sSimulationFlags, sSimulationFlags);
1801 }
1802 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001803 // reset PTOR
1804 if(!mDpy)
1805 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001806
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301807 //Do not cache the information for next draw cycle.
1808 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1809 ALOGI("%s: Unsupported layer count for mdp composition",
1810 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001811 mCachedFrame.reset();
1812 return -1;
1813 }
1814
Saurabh Shahb39f8152013-08-22 10:21:44 -07001815 //reset old data
1816 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001817 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1818 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301819
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001820 // Detect the start of animation and fall back to GPU only once to cache
1821 // all the layers in FB and display FB content untill animation completes.
1822 if(ctx->listStats[mDpy].isDisplayAnimating) {
1823 mCurrentFrame.needsRedraw = false;
1824 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1825 mCurrentFrame.needsRedraw = true;
1826 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1827 }
1828 setMDPCompLayerFlags(ctx, list);
1829 mCachedFrame.updateCounts(mCurrentFrame);
1830 ret = -1;
1831 return ret;
1832 } else {
1833 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1834 }
1835
Saurabh Shahb39f8152013-08-22 10:21:44 -07001836 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001837 if(isFrameDoable(ctx)) {
1838 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001839
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001840 // if tryFullFrame fails, try to push all video and secure RGB layers
1841 // to MDP for composition.
1842 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
1843 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301844 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001845 setMDPCompLayerFlags(ctx, list);
1846 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001847 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001848 reset(ctx);
1849 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1850 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001851 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001852 }
1853 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001854 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1855 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001856 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001857 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001858
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001859 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001860 ALOGD("GEOMETRY change: %d",
1861 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001862 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001863 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001864 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001865 }
1866
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001867 mCachedFrame.cacheAll(list);
1868 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001869 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001870}
1871
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001872bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301873
1874 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301875 int mdpIndex = mCurrentFrame.layerToMDP[index];
1876 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1877 info.pipeInfo = new MdpYUVPipeInfo;
1878 info.rot = NULL;
1879 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301880
1881 pipe_info.lIndex = ovutils::OV_INVALID;
1882 pipe_info.rIndex = ovutils::OV_INVALID;
1883
Saurabh Shahc62f3982014-03-05 14:28:26 -08001884 Overlay::PipeSpecs pipeSpecs;
1885 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1886 pipeSpecs.needsScaling = true;
1887 pipeSpecs.dpy = mDpy;
1888 pipeSpecs.fb = false;
1889
1890 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301891 if(pipe_info.lIndex == ovutils::OV_INVALID){
1892 bRet = false;
1893 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1894 __FUNCTION__);
1895 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001896 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301897 if(pipe_info.rIndex == ovutils::OV_INVALID){
1898 bRet = false;
1899 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1900 __FUNCTION__);
1901 }
1902 return bRet;
1903}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001904
1905int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1906 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001907 if (ctx->mPtorInfo.isActive()) {
1908 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001909 if (fd < 0) {
1910 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001911 }
1912 }
1913 return fd;
1914}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001915//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001916
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001917void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301918 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001919 //If 4k2k Yuv layer split is possible, and if
1920 //fbz is above 4k2k layer, increment fb zorder by 1
1921 //as we split 4k2k layer and increment zorder for right half
1922 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07001923 if(!ctx)
1924 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001925 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301926 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1927 index++) {
1928 if(!mCurrentFrame.isFBComposed[index]) {
1929 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1930 mdpNextZOrder++;
1931 }
1932 mdpNextZOrder++;
1933 hwc_layer_1_t* layer = &list->hwLayers[index];
1934 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301935 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301936 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1937 mCurrentFrame.fbZ += 1;
1938 mdpNextZOrder++;
1939 //As we split 4kx2k yuv layer and program to 2 VG pipes
1940 //(if available) increase mdpcount by 1.
1941 mCurrentFrame.mdpCount++;
1942 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001943 }
1944 }
1945 }
radhakrishnac9a67412013-09-25 17:40:42 +05301946}
1947
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001948/*
1949 * Configures pipe(s) for MDP composition
1950 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001951int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001952 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001953 MdpPipeInfoNonSplit& mdp_info =
1954 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001955 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1956 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08001957 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001958
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001959 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1960 __FUNCTION__, layer, zOrder, dest);
1961
Saurabh Shah2c8ad052014-08-15 13:27:46 -07001962 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001963 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001964}
1965
Saurabh Shah88e4d272013-09-03 13:31:29 -07001966bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001967 hwc_display_contents_1_t* list) {
1968 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001969
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001970 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001971
Jeykumar Sankarancf537002013-01-21 21:19:15 -08001972 hwc_layer_1_t* layer = &list->hwLayers[index];
1973 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301974 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001975 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301976 continue;
1977 }
1978 }
1979
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001980 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001981 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001982 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08001983 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001984 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001985
Saurabh Shahc62f3982014-03-05 14:28:26 -08001986 Overlay::PipeSpecs pipeSpecs;
1987 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1988 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1989 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
1990 (qdutils::MDPVersion::getInstance().is8x26() and
1991 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
1992 pipeSpecs.dpy = mDpy;
1993 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08001994 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001995
Saurabh Shahc62f3982014-03-05 14:28:26 -08001996 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
1997
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001998 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001999 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002000 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002001 }
2002 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002003 return true;
2004}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002005
radhakrishnac9a67412013-09-25 17:40:42 +05302006int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2007 PipeLayerPair& PipeLayerPair) {
2008 MdpYUVPipeInfo& mdp_info =
2009 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2010 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302011 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2012 eDest lDest = mdp_info.lIndex;
2013 eDest rDest = mdp_info.rIndex;
2014
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002015 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302016 lDest, rDest, &PipeLayerPair.rot);
2017}
2018
Saurabh Shah88e4d272013-09-03 13:31:29 -07002019bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002020
Raj Kamal4393eaa2014-06-06 13:45:20 +05302021 if(!isEnabled() or !mModeOn) {
2022 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302023 return true;
2024 }
2025
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002026 // Set the Handle timeout to true for MDP or MIXED composition.
2027 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2028 sHandleTimeout = true;
2029 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002030
2031 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002032 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002033
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002034 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2035 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002036 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002037 if(mCurrentFrame.isFBComposed[i]) continue;
2038
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002039 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002040 private_handle_t *hnd = (private_handle_t *)layer->handle;
2041 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002042 if (!(layer->flags & HWC_COLOR_FILL)) {
2043 ALOGE("%s handle null", __FUNCTION__);
2044 return false;
2045 }
2046 // No PLAY for Color layer
2047 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2048 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002049 }
2050
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002051 int mdpIndex = mCurrentFrame.layerToMDP[i];
2052
Raj Kamal389d6e32014-08-04 14:43:24 +05302053 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302054 {
2055 MdpYUVPipeInfo& pipe_info =
2056 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2057 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2058 ovutils::eDest indexL = pipe_info.lIndex;
2059 ovutils::eDest indexR = pipe_info.rIndex;
2060 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302061 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302062 if(rot) {
2063 rot->queueBuffer(fd, offset);
2064 fd = rot->getDstMemId();
2065 offset = rot->getDstOffset();
2066 }
2067 if(indexL != ovutils::OV_INVALID) {
2068 ovutils::eDest destL = (ovutils::eDest)indexL;
2069 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2070 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2071 if (!ov.queueBuffer(fd, offset, destL)) {
2072 ALOGE("%s: queueBuffer failed for display:%d",
2073 __FUNCTION__, mDpy);
2074 return false;
2075 }
2076 }
2077
2078 if(indexR != ovutils::OV_INVALID) {
2079 ovutils::eDest destR = (ovutils::eDest)indexR;
2080 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2081 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2082 if (!ov.queueBuffer(fd, offset, destR)) {
2083 ALOGE("%s: queueBuffer failed for display:%d",
2084 __FUNCTION__, mDpy);
2085 return false;
2086 }
2087 }
2088 }
2089 else{
2090 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002091 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302092 ovutils::eDest dest = pipe_info.index;
2093 if(dest == ovutils::OV_INVALID) {
2094 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002095 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302096 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002097
radhakrishnac9a67412013-09-25 17:40:42 +05302098 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2099 continue;
2100 }
2101
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002102 int fd = hnd->fd;
2103 uint32_t offset = (uint32_t)hnd->offset;
2104 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2105 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002106 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002107 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002108 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002109 }
2110
radhakrishnac9a67412013-09-25 17:40:42 +05302111 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2112 using pipe: %d", __FUNCTION__, layer,
2113 hnd, dest );
2114
radhakrishnac9a67412013-09-25 17:40:42 +05302115 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2116 if(rot) {
2117 if(!rot->queueBuffer(fd, offset))
2118 return false;
2119 fd = rot->getDstMemId();
2120 offset = rot->getDstOffset();
2121 }
2122
2123 if (!ov.queueBuffer(fd, offset, dest)) {
2124 ALOGE("%s: queueBuffer failed for display:%d ",
2125 __FUNCTION__, mDpy);
2126 return false;
2127 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002128 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002129
2130 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002131 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002132 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002133}
2134
Saurabh Shah88e4d272013-09-03 13:31:29 -07002135//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002136
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002137void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302138 hwc_display_contents_1_t* list){
2139 //if 4kx2k yuv layer is totally present in either in left half
2140 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302141 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302142 if(mCurrentFrame.fbZ >= 0) {
2143 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2144 index++) {
2145 if(!mCurrentFrame.isFBComposed[index]) {
2146 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2147 mdpNextZOrder++;
2148 }
2149 mdpNextZOrder++;
2150 hwc_layer_1_t* layer = &list->hwLayers[index];
2151 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302152 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302153 hwc_rect_t dst = layer->displayFrame;
2154 if((dst.left > lSplit) || (dst.right < lSplit)) {
2155 mCurrentFrame.mdpCount += 1;
2156 }
2157 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2158 mCurrentFrame.fbZ += 1;
2159 mdpNextZOrder++;
2160 }
2161 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002162 }
radhakrishnac9a67412013-09-25 17:40:42 +05302163 }
2164}
2165
Saurabh Shah88e4d272013-09-03 13:31:29 -07002166bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002167 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002168
Saurabh Shahc62f3982014-03-05 14:28:26 -08002169 const int lSplit = getLeftSplit(ctx, mDpy);
2170 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002171 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002172 pipe_info.lIndex = ovutils::OV_INVALID;
2173 pipe_info.rIndex = ovutils::OV_INVALID;
2174
Saurabh Shahc62f3982014-03-05 14:28:26 -08002175 Overlay::PipeSpecs pipeSpecs;
2176 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2177 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2178 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2179 pipeSpecs.dpy = mDpy;
2180 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2181 pipeSpecs.fb = false;
2182
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002183 // Acquire pipe only for the updating half
2184 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2185 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2186
2187 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002188 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002189 if(pipe_info.lIndex == ovutils::OV_INVALID)
2190 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002191 }
2192
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002193 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002194 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2195 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002196 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002197 return false;
2198 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002199
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002200 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002201}
2202
Saurabh Shah88e4d272013-09-03 13:31:29 -07002203bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002204 hwc_display_contents_1_t* list) {
2205 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002206
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002207 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002208
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002209 hwc_layer_1_t* layer = &list->hwLayers[index];
2210 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302211 hwc_rect_t dst = layer->displayFrame;
2212 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302213 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302214 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002215 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302216 continue;
2217 }
2218 }
2219 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002220 int mdpIndex = mCurrentFrame.layerToMDP[index];
2221 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002222 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002223 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002224 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002225
Saurabh Shahc62f3982014-03-05 14:28:26 -08002226 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2227 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2228 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002229 return false;
2230 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002231 }
2232 return true;
2233}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002234
radhakrishnac9a67412013-09-25 17:40:42 +05302235int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2236 PipeLayerPair& PipeLayerPair) {
2237 const int lSplit = getLeftSplit(ctx, mDpy);
2238 hwc_rect_t dst = layer->displayFrame;
2239 if((dst.left > lSplit)||(dst.right < lSplit)){
2240 MdpYUVPipeInfo& mdp_info =
2241 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2242 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302243 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2244 eDest lDest = mdp_info.lIndex;
2245 eDest rDest = mdp_info.rIndex;
2246
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002247 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302248 lDest, rDest, &PipeLayerPair.rot);
2249 }
2250 else{
2251 return configure(ctx, layer, PipeLayerPair);
2252 }
2253}
2254
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002255/*
2256 * Configures pipe(s) for MDP composition
2257 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002258int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002259 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002260 MdpPipeInfoSplit& mdp_info =
2261 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002262 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002263 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2264 eDest lDest = mdp_info.lIndex;
2265 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002266
2267 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2268 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2269
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002270 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002271 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002272}
2273
Saurabh Shah88e4d272013-09-03 13:31:29 -07002274bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002275
Raj Kamal4393eaa2014-06-06 13:45:20 +05302276 if(!isEnabled() or !mModeOn) {
2277 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302278 return true;
2279 }
2280
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002281 // Set the Handle timeout to true for MDP or MIXED composition.
2282 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2283 sHandleTimeout = true;
2284 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002285
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002286 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002287 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002288
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002289 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2290 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002291 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002292 if(mCurrentFrame.isFBComposed[i]) continue;
2293
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002294 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002295 private_handle_t *hnd = (private_handle_t *)layer->handle;
2296 if(!hnd) {
2297 ALOGE("%s handle null", __FUNCTION__);
2298 return false;
2299 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002300
2301 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2302 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002303 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002304
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002305 int mdpIndex = mCurrentFrame.layerToMDP[i];
2306
Raj Kamal389d6e32014-08-04 14:43:24 +05302307 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302308 {
2309 MdpYUVPipeInfo& pipe_info =
2310 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2311 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2312 ovutils::eDest indexL = pipe_info.lIndex;
2313 ovutils::eDest indexR = pipe_info.rIndex;
2314 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302315 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302316 if(rot) {
2317 rot->queueBuffer(fd, offset);
2318 fd = rot->getDstMemId();
2319 offset = rot->getDstOffset();
2320 }
2321 if(indexL != ovutils::OV_INVALID) {
2322 ovutils::eDest destL = (ovutils::eDest)indexL;
2323 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2324 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2325 if (!ov.queueBuffer(fd, offset, destL)) {
2326 ALOGE("%s: queueBuffer failed for display:%d",
2327 __FUNCTION__, mDpy);
2328 return false;
2329 }
2330 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002331
radhakrishnac9a67412013-09-25 17:40:42 +05302332 if(indexR != ovutils::OV_INVALID) {
2333 ovutils::eDest destR = (ovutils::eDest)indexR;
2334 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2335 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2336 if (!ov.queueBuffer(fd, offset, destR)) {
2337 ALOGE("%s: queueBuffer failed for display:%d",
2338 __FUNCTION__, mDpy);
2339 return false;
2340 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002341 }
2342 }
radhakrishnac9a67412013-09-25 17:40:42 +05302343 else{
2344 MdpPipeInfoSplit& pipe_info =
2345 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2346 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002347
radhakrishnac9a67412013-09-25 17:40:42 +05302348 ovutils::eDest indexL = pipe_info.lIndex;
2349 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002350
radhakrishnac9a67412013-09-25 17:40:42 +05302351 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002352 uint32_t offset = (uint32_t)hnd->offset;
2353 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2354 if (!mDpy && (index != -1)) {
2355 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2356 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002357 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002358 }
radhakrishnac9a67412013-09-25 17:40:42 +05302359
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002360 if(ctx->mAD->draw(ctx, fd, offset)) {
2361 fd = ctx->mAD->getDstFd();
2362 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002363 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002364
radhakrishnac9a67412013-09-25 17:40:42 +05302365 if(rot) {
2366 rot->queueBuffer(fd, offset);
2367 fd = rot->getDstMemId();
2368 offset = rot->getDstOffset();
2369 }
2370
2371 //************* play left mixer **********
2372 if(indexL != ovutils::OV_INVALID) {
2373 ovutils::eDest destL = (ovutils::eDest)indexL;
2374 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2375 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2376 if (!ov.queueBuffer(fd, offset, destL)) {
2377 ALOGE("%s: queueBuffer failed for left mixer",
2378 __FUNCTION__);
2379 return false;
2380 }
2381 }
2382
2383 //************* play right mixer **********
2384 if(indexR != ovutils::OV_INVALID) {
2385 ovutils::eDest destR = (ovutils::eDest)indexR;
2386 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2387 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2388 if (!ov.queueBuffer(fd, offset, destR)) {
2389 ALOGE("%s: queueBuffer failed for right mixer",
2390 __FUNCTION__);
2391 return false;
2392 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002393 }
2394 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002395
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002396 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2397 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002398
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002399 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002400}
Saurabh Shahab47c692014-02-12 18:45:57 -08002401
2402//================MDPCompSrcSplit==============================================
2403bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002404 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002405 private_handle_t *hnd = (private_handle_t *)layer->handle;
2406 hwc_rect_t dst = layer->displayFrame;
2407 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2408 pipe_info.lIndex = ovutils::OV_INVALID;
2409 pipe_info.rIndex = ovutils::OV_INVALID;
2410
2411 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2412 //should have a higher priority than the right one. Pipe priorities are
2413 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002414
Saurabh Shahc62f3982014-03-05 14:28:26 -08002415 Overlay::PipeSpecs pipeSpecs;
2416 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2417 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2418 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2419 pipeSpecs.dpy = mDpy;
2420 pipeSpecs.fb = false;
2421
Saurabh Shahab47c692014-02-12 18:45:57 -08002422 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002423 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002424 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002425 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002426 }
2427
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002428 /* Use 2 pipes IF
2429 a) Layer's crop width is > 2048 or
2430 b) Layer's dest width > 2048 or
2431 c) On primary, driver has indicated with caps to split always. This is
2432 based on an empirically derived value of panel height. Applied only
2433 if the layer's width is > mixer's width
2434 */
2435
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302436 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002437 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302438 mdpHw.isSrcSplitAlways();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002439 int lSplit = getLeftSplit(ctx, mDpy);
2440 int dstWidth = dst.right - dst.left;
2441 int cropWidth = crop.right - crop.left;
2442
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002443 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2444 //pipe line length, we are still using 2 pipes. This is fine just because
2445 //this is source split where destination doesn't matter. Evaluate later to
2446 //see if going through all the calcs to save a pipe is worth it
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302447 if(dstWidth > mdpHw.getMaxMixerWidth() or
2448 cropWidth > mdpHw.getMaxMixerWidth() or
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002449 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002450 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002451 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002452 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002453 }
2454
2455 // Return values
2456 // 1 Left pipe is higher priority, do nothing.
2457 // 0 Pipes of same priority.
2458 //-1 Right pipe is of higher priority, needs swap.
2459 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2460 pipe_info.rIndex) == -1) {
2461 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002462 }
2463 }
2464
2465 return true;
2466}
2467
Saurabh Shahab47c692014-02-12 18:45:57 -08002468int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2469 PipeLayerPair& PipeLayerPair) {
2470 private_handle_t *hnd = (private_handle_t *)layer->handle;
2471 if(!hnd) {
2472 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2473 return -1;
2474 }
2475 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2476 MdpPipeInfoSplit& mdp_info =
2477 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2478 Rotator **rot = &PipeLayerPair.rot;
2479 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002480 eDest lDest = mdp_info.lIndex;
2481 eDest rDest = mdp_info.rIndex;
2482 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2483 hwc_rect_t dst = layer->displayFrame;
2484 int transform = layer->transform;
2485 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002486 int rotFlags = ROT_FLAGS_NONE;
2487 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2488 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2489
2490 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2491 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2492
2493 // Handle R/B swap
2494 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2495 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2496 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2497 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2498 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2499 }
2500
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002501 int downscale = getRotDownscale(ctx, layer);
Saurabh Shah97e2d802014-04-14 18:03:54 -07002502 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002503 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002504
2505 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2506 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002507 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002508 }
2509
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002510 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002511 (*rot) = ctx->mRotMgr->getNext();
2512 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002513 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002514 //If the video is using a single pipe, enable BWC
2515 if(rDest == OV_INVALID) {
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002516 BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002517 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002518 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002519 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002520 ALOGE("%s: configRotator failed!", __FUNCTION__);
2521 return -1;
2522 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002523 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002524 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002525 }
2526
2527 //If 2 pipes being used, divide layer into half, crop and dst
2528 hwc_rect_t cropL = crop;
2529 hwc_rect_t cropR = crop;
2530 hwc_rect_t dstL = dst;
2531 hwc_rect_t dstR = dst;
2532 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2533 cropL.right = (crop.right + crop.left) / 2;
2534 cropR.left = cropL.right;
2535 sanitizeSourceCrop(cropL, cropR, hnd);
2536
Saurabh Shahb729b192014-08-15 18:04:24 -07002537 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002538 //Swap crops on H flip since 2 pipes are being used
2539 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2540 hwc_rect_t tmp = cropL;
2541 cropL = cropR;
2542 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002543 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002544 }
2545
Saurabh Shahb729b192014-08-15 18:04:24 -07002546 //cropSwap trick: If the src and dst widths are both odd, let us say
2547 //2507, then splitting both into half would cause left width to be 1253
2548 //and right 1254. If crop is swapped because of H flip, this will cause
2549 //left crop width to be 1254, whereas left dst width remains 1253, thus
2550 //inducing a scaling that is unaccounted for. To overcome that we add 1
2551 //to the dst width if there is a cropSwap. So if the original width was
2552 //2507, the left dst width will be 1254. Even if the original width was
2553 //even for ex: 2508, the left dst width will still remain 1254.
2554 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002555 dstR.left = dstL.right;
2556 }
2557
2558 //For the mdp, since either we are pre-rotating or MDP does flips
2559 orient = OVERLAY_TRANSFORM_0;
2560 transform = 0;
2561
2562 //configure left pipe
2563 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002564 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002565 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2566 (ovutils::eBlending) getBlending(layer->blending));
2567
2568 if(configMdp(ctx->mOverlay, pargL, orient,
2569 cropL, dstL, metadata, lDest) < 0) {
2570 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2571 return -1;
2572 }
2573 }
2574
2575 //configure right pipe
2576 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002577 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002578 static_cast<eRotFlags>(rotFlags),
2579 layer->planeAlpha,
2580 (ovutils::eBlending) getBlending(layer->blending));
2581 if(configMdp(ctx->mOverlay, pargR, orient,
2582 cropR, dstR, metadata, rDest) < 0) {
2583 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2584 return -1;
2585 }
2586 }
2587
2588 return 0;
2589}
2590
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002591}; //namespace
2592