blob: 8546af0d85fa24a4a8255e3a66cf078650620e71 [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"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080023#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080024#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070025#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070026#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080027#include <overlayRotator.h>
Sushil Chauhandefd3522014-05-13 18:17:12 -070028#include "hwc_copybit.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080029
Saurabh Shah85234ec2013-04-12 17:09:00 -070030using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070031using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080032using namespace overlay::utils;
33namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070034
Naseer Ahmed7c958d42012-07-31 18:57:03 -070035namespace qhwc {
36
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080037//==============MDPComp========================================================
38
Naseer Ahmed7c958d42012-07-31 18:57:03 -070039IdleInvalidator *MDPComp::idleInvalidator = NULL;
40bool MDPComp::sIdleFallBack = false;
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -080041bool MDPComp::sHandleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070042bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050043bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070044bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -070045int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080046int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Raj Kamal389d6e32014-08-04 14:43:24 +053047bool MDPComp::sEnableYUVsplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070048bool MDPComp::sSrcSplitEnabled = false;
Saurabh Shah88e4d272013-09-03 13:31:29 -070049MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070050 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
51 sSrcSplitEnabled = true;
52 return new MDPCompSrcSplit(dpy);
53 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070054 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080055 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070056 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080057}
58
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080059MDPComp::MDPComp(int dpy):mDpy(dpy){};
60
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070061void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080062{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070063 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
64 return;
65
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080066 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070067 (mDpy == 0) ? "\"PRIMARY\"" :
68 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070069 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
70 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080071 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
72 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
73 (mCurrentFrame.needsRedraw? "YES" : "NO"),
74 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070075 if(isDisplaySplit(ctx, mDpy)) {
76 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
77 "Right: [%d, %d, %d, %d] \n",
78 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
79 ctx->listStats[mDpy].lRoi.right,
80 ctx->listStats[mDpy].lRoi.bottom,
81 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
82 ctx->listStats[mDpy].rRoi.right,
83 ctx->listStats[mDpy].rRoi.bottom);
84 } else {
85 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
86 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
87 ctx->listStats[mDpy].lRoi.right,
88 ctx->listStats[mDpy].lRoi.bottom);
89 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080090 dumpsys_log(buf," --------------------------------------------- \n");
91 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
92 dumpsys_log(buf," --------------------------------------------- \n");
93 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
94 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
95 index,
96 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070097 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080098 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070099 (mCurrentFrame.drop[index] ? "DROP" :
100 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800101 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
102 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
103 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800104}
105
106bool MDPComp::init(hwc_context_t *ctx) {
107
108 if(!ctx) {
109 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
110 return false;
111 }
112
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800113 char property[PROPERTY_VALUE_MAX];
114
115 sEnabled = false;
116 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800117 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
118 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800119 sEnabled = true;
120 }
121
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700122 sEnableMixedMode = true;
123 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
124 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
125 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
126 sEnableMixedMode = false;
127 }
128
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800129 sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Saurabh Shah85234ec2013-04-12 17:09:00 -0700130 if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
131 int val = atoi(property);
132 if(val >= 0)
133 sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800134 }
135
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400136 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
137 // Idle invalidation is not necessary on command mode panels
138 long idle_timeout = DEFAULT_IDLE_TIME;
139 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
140 if(atoi(property) != 0)
141 idle_timeout = atoi(property);
142 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800143
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400144 //create Idle Invalidator only when not disabled through property
145 if(idle_timeout != -1)
146 idleInvalidator = IdleInvalidator::getInstance();
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800147
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400148 if(idleInvalidator == NULL) {
149 ALOGE("%s: failed to instantiate idleInvalidator object",
150 __FUNCTION__);
151 } else {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530152 idleInvalidator->init(timeout_handler, ctx,
153 (unsigned int)idle_timeout);
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400154 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800155 }
radhakrishnac9a67412013-09-25 17:40:42 +0530156
Saurabh Shah7c727642014-06-02 15:47:14 -0700157 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700158 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700159 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
160 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
161 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530162 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530163 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700164
165 if ((property_get("persist.hwc.ptor.enable", property, NULL) > 0) &&
166 ((!strncasecmp(property, "true", PROPERTY_VALUE_MAX )) ||
167 (!strncmp(property, "1", PROPERTY_VALUE_MAX )))) {
168 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
169 HWC_DISPLAY_PRIMARY);
170 }
171
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700172 return true;
173}
174
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800175void MDPComp::reset(hwc_context_t *ctx) {
176 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700177 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800178 ctx->mOverlay->clear(mDpy);
179 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700180}
181
Raj Kamal4393eaa2014-06-06 13:45:20 +0530182void MDPComp::reset() {
183 sHandleTimeout = false;
184 mModeOn = false;
185}
186
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700187void MDPComp::timeout_handler(void *udata) {
188 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
189
190 if(!ctx) {
191 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
192 return;
193 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800194 Locker::Autolock _l(ctx->mDrawLock);
195 // Handle timeout event only if the previous composition is MDP or MIXED.
196 if(!sHandleTimeout) {
197 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
198 return;
199 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700200 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700201 ALOGE("%s: HWC proc not registered", __FUNCTION__);
202 return;
203 }
204 sIdleFallBack = true;
205 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700206 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700207}
208
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800209void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800210 hwc_display_contents_1_t* list) {
211 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800212
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800213 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800214 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800215 if(!mCurrentFrame.isFBComposed[index]) {
216 layerProp[index].mFlags |= HWC_MDPCOMP;
217 layer->compositionType = HWC_OVERLAY;
218 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800219 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700220 /* Drop the layer when its already present in FB OR when it lies
221 * outside frame's ROI */
222 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800223 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700224 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800225 }
226 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700227}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500228
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800229void MDPComp::setRedraw(hwc_context_t *ctx,
230 hwc_display_contents_1_t* list) {
231 mCurrentFrame.needsRedraw = false;
232 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
233 (list->flags & HWC_GEOMETRY_CHANGED) ||
234 isSkipPresent(ctx, mDpy)) {
235 mCurrentFrame.needsRedraw = true;
236 }
237}
238
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800239MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700240 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700241 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800242}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800243
Saurabh Shahaa236822013-04-24 18:07:26 -0700244void MDPComp::FrameInfo::reset(const int& numLayers) {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700245 for(int i = 0; i < MAX_PIPES_PER_MIXER; i++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800246 if(mdpToLayer[i].pipeInfo) {
247 delete mdpToLayer[i].pipeInfo;
248 mdpToLayer[i].pipeInfo = NULL;
249 //We dont own the rotator
250 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800251 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800252 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800253
254 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
255 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700256 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800257
Saurabh Shahaa236822013-04-24 18:07:26 -0700258 layerCount = numLayers;
259 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800260 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700261 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800262 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800263}
264
Saurabh Shahaa236822013-04-24 18:07:26 -0700265void MDPComp::FrameInfo::map() {
266 // populate layer and MDP maps
267 int mdpIdx = 0;
268 for(int idx = 0; idx < layerCount; idx++) {
269 if(!isFBComposed[idx]) {
270 mdpToLayer[mdpIdx].listIndex = idx;
271 layerToMDP[idx] = mdpIdx++;
272 }
273 }
274}
275
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800276MDPComp::LayerCache::LayerCache() {
277 reset();
278}
279
280void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700281 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530282 memset(&isFBComposed, true, sizeof(isFBComposed));
283 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800284 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700285}
286
287void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530288 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700289 for(int i = 0; i < numAppLayers; i++) {
290 hnd[i] = list->hwLayers[i].handle;
291 }
292}
293
294void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700295 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530296 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
297 memcpy(&drop, &curFrame.drop, sizeof(drop));
298}
299
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800300bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
301 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530302 if(layerCount != curFrame.layerCount)
303 return false;
304 for(int i = 0; i < curFrame.layerCount; i++) {
305 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
306 (curFrame.drop[i] != drop[i])) {
307 return false;
308 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800309 if(curFrame.isFBComposed[i] &&
310 (hnd[i] != list->hwLayers[i].handle)){
311 return false;
312 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530313 }
314 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800315}
316
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700317bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
318 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800319 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700320 (not isValidDimension(ctx,layer))
321 //More conditions here, SKIP, sRGB+Blend etc
322 ) {
323 return false;
324 }
325 return true;
326}
327
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530328bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800329 private_handle_t *hnd = (private_handle_t *)layer->handle;
330
331 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700332 if (layer->flags & HWC_COLOR_FILL) {
333 // Color layer
334 return true;
335 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700336 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800337 return false;
338 }
339
Naseer Ahmede850a802013-09-06 13:12:52 -0400340 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400341 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400342 return false;
343
Saurabh Shah62e1d732013-09-17 10:44:05 -0700344 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700345 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700346 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700347 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
348 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700349 int dst_w = dst.right - dst.left;
350 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800351 float w_scale = ((float)crop_w / (float)dst_w);
352 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530353 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700354
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800355 /* Workaround for MDP HW limitation in DSI command mode panels where
356 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
357 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530358 * There also is a HW limilation in MDP, minimum block size is 2x2
359 * Fallback to GPU if height is less than 2.
360 */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800361 if((crop_w < 5)||(crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800362 return false;
363
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800364 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530365 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800366 const float w_dscale = w_scale;
367 const float h_dscale = h_scale;
368
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800369 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700370
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530371 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700372 /* On targets that doesnt support Decimation (eg.,8x26)
373 * maximum downscale support is overlay pipe downscale.
374 */
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530375 if(crop_w > mdpHw.getMaxMixerWidth() ||
376 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700377 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800378 return false;
379 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700380 // Decimation on macrotile format layers is not supported.
381 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530382 /* Bail out if
383 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700384 * 2. exceeds maximum downscale limit
385 */
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530386 if(((crop_w > mdpHw.getMaxMixerWidth()) &&
387 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700388 w_dscale > maxMDPDownscale ||
389 h_dscale > maxMDPDownscale) {
390 return false;
391 }
392 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800393 return false;
394 }
395 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700396 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700397 return false;
398 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700399 }
400
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800401 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530402 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800403 const float w_uscale = 1.0f / w_scale;
404 const float h_uscale = 1.0f / h_scale;
405
406 if(w_uscale > upscale || h_uscale > upscale)
407 return false;
408 }
409
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800410 return true;
411}
412
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800413bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700414 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800415
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800416 if(!isEnabled()) {
417 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700418 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530419 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530420 qdutils::MDPVersion::getInstance().is8x16() ||
421 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800422 ctx->mVideoTransFlag &&
423 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700424 //1 Padding round to shift pipes across mixers
425 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
426 __FUNCTION__);
427 ret = false;
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800428 } else if(isSecondaryConfiguring(ctx)) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800429 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800430 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700431 ret = false;
Saurabh Shahaa236822013-04-24 18:07:26 -0700432 } else if(ctx->isPaddingRound) {
Raj Kamal9ed3d6b2014-02-07 16:15:17 +0530433 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
434 __FUNCTION__,mDpy);
Saurabh Shahaa236822013-04-24 18:07:26 -0700435 ret = false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700436 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700437 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800438}
439
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800440void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
441 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
442 fbRect = getIntersection(fbRect, roi);
443}
444
445/* 1) Identify layers that are not visible or lying outside the updating ROI and
446 * drop them from composition.
447 * 2) If we have a scaling layer which needs cropping against generated
448 * ROI, reset ROI to full resolution. */
449bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
450 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700451 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800452 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800453
454 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800455 if(!isValidRect(visibleRect)) {
456 mCurrentFrame.drop[i] = true;
457 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800458 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800459 }
460
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700461 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700462 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800463 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700464
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700465 if(!isValidRect(res)) {
466 mCurrentFrame.drop[i] = true;
467 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800468 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700469 /* Reset frame ROI when any layer which needs scaling also needs ROI
470 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800471 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800472 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700473 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
474 mCurrentFrame.dropCount = 0;
475 return false;
476 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800477
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800478 /* deduct any opaque region from visibleRect */
479 if (layer->blending == HWC_BLENDING_NONE)
480 visibleRect = deductRect(visibleRect, res);
481 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700482 }
483 return true;
484}
485
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800486/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
487 * are updating. If DirtyRegion is applicable, calculate it by accounting all
488 * the changing layer's dirtyRegion. */
489void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
490 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700491 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800492 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700493 return;
494
495 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800496 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
497 (int)ctx->dpyAttr[mDpy].yres};
498
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700499 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800500 hwc_layer_1_t* layer = &list->hwLayers[index];
501 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800502 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700503 hwc_rect_t dst = layer->displayFrame;
504 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800505
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800506#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800507 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700508 {
509 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
510 int x_off = dst.left - src.left;
511 int y_off = dst.top - src.top;
512 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
513 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800514#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800515
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800516 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700517 }
518 }
519
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800520 /* No layer is updating. Still SF wants a refresh.*/
521 if(!isValidRect(roi))
522 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800523
524 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800525 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800526
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800527 ctx->listStats[mDpy].lRoi = roi;
528 if(!validateAndApplyROI(ctx, list))
529 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700530
531 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800532 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
533 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
534}
535
536void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
537 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
538 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
539
540 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
541 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
542 fbRect = getUnion(l_fbRect, r_fbRect);
543}
544/* 1) Identify layers that are not visible or lying outside BOTH the updating
545 * ROI's and drop them from composition. If a layer is spanning across both
546 * the halves of the screen but needed by only ROI, the non-contributing
547 * half will not be programmed for MDP.
548 * 2) If we have a scaling layer which needs cropping against generated
549 * ROI, reset ROI to full resolution. */
550bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
551 hwc_display_contents_1_t* list) {
552
553 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
554
555 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
556 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
557
558 for(int i = numAppLayers - 1; i >= 0; i--){
559 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
560 {
561 mCurrentFrame.drop[i] = true;
562 mCurrentFrame.dropCount++;
563 continue;
564 }
565
566 const hwc_layer_1_t* layer = &list->hwLayers[i];
567 hwc_rect_t dstRect = layer->displayFrame;
568
569 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
570 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
571 hwc_rect_t res = getUnion(l_res, r_res);
572
573 if(!isValidRect(l_res) && !isValidRect(r_res)) {
574 mCurrentFrame.drop[i] = true;
575 mCurrentFrame.dropCount++;
576 } else {
577 /* Reset frame ROI when any layer which needs scaling also needs ROI
578 * cropping */
579 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
580 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
581 mCurrentFrame.dropCount = 0;
582 return false;
583 }
584
585 if (layer->blending == HWC_BLENDING_NONE) {
586 visibleRectL = deductRect(visibleRectL, l_res);
587 visibleRectR = deductRect(visibleRectR, r_res);
588 }
589 }
590 }
591 return true;
592}
593/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
594 * are updating. If DirtyRegion is applicable, calculate it by accounting all
595 * the changing layer's dirtyRegion. */
596void MDPCompSplit::generateROI(hwc_context_t *ctx,
597 hwc_display_contents_1_t* list) {
598 if(!canPartialUpdate(ctx, list))
599 return;
600
601 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
602 int lSplit = getLeftSplit(ctx, mDpy);
603
604 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
605 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
606
607 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
608 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
609
610 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
611 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
612
613 for(int index = 0; index < numAppLayers; index++ ) {
614 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800615 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800616 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800617 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700618 hwc_rect_t dst = layer->displayFrame;
619 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800620
621#ifdef QCOM_BSP
622 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700623 {
624 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
625 int x_off = dst.left - src.left;
626 int y_off = dst.top - src.top;
627 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
628 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800629#endif
630
631 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
632 if(isValidRect(l_dst))
633 l_roi = getUnion(l_roi, l_dst);
634
635 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
636 if(isValidRect(r_dst))
637 r_roi = getUnion(r_roi, r_dst);
638 }
639 }
640
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700641 /* For panels that cannot accept commands in both the interfaces, we cannot
642 * send two ROI's (for each half). We merge them into single ROI and split
643 * them across lSplit for MDP mixer use. The ROI's will be merged again
644 * finally before udpating the panel in the driver. */
645 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
646 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
647 l_roi = getIntersection(temp_roi, l_frame);
648 r_roi = getIntersection(temp_roi, r_frame);
649 }
650
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800651 /* No layer is updating. Still SF wants a refresh. */
652 if(!isValidRect(l_roi) && !isValidRect(r_roi))
653 return;
654
655 l_roi = getSanitizeROI(l_roi, l_frame);
656 r_roi = getSanitizeROI(r_roi, r_frame);
657
658 ctx->listStats[mDpy].lRoi = l_roi;
659 ctx->listStats[mDpy].rRoi = r_roi;
660
661 if(!validateAndApplyROI(ctx, list))
662 resetROI(ctx, mDpy);
663
664 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
665 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
666 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
667 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
668 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
669 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700670}
671
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800672/* Checks for conditions where all the layers marked for MDP comp cannot be
673 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800674bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800675 hwc_display_contents_1_t* list){
676
Saurabh Shahaa236822013-04-24 18:07:26 -0700677 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800678 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800679
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -0700680 // No Idle fall back, if secure display or secure RGB layers are present
681 if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
682 !ctx->listStats[mDpy].secureRGBCount)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700683 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
684 return false;
685 }
686
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800687 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700688 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
689 __FUNCTION__,
690 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800691 return false;
692 }
693
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530694 MDPVersion& mdpHw = MDPVersion::getInstance();
695 if(mDpy > HWC_DISPLAY_PRIMARY &&
696 (priDispW > mdpHw.getMaxMixerWidth()) &&
697 (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800698 // Disable MDP comp on Secondary when the primary is highres panel and
699 // the secondary is a normal 1080p, because, MDP comp on secondary under
700 // in such usecase, decimation gets used for downscale and there will be
701 // a quality mismatch when there will be a fallback to GPU comp
702 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
703 __FUNCTION__);
704 return false;
705 }
706
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800707 // check for action safe flag and downscale mode which requires scaling.
708 if(ctx->dpyAttr[mDpy].mActionSafePresent
709 || ctx->dpyAttr[mDpy].mDownScaleMode) {
710 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
711 return false;
712 }
713
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800714 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800715 hwc_layer_1_t* layer = &list->hwLayers[i];
716 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800717
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800718 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700719 if(!canUseRotator(ctx, mDpy)) {
720 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
721 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700722 return false;
723 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800724 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530725
726 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
727 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700728 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530729 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
730 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
731 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800732 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700733
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700734 if(ctx->mAD->isDoable()) {
735 return false;
736 }
737
Saurabh Shahaa236822013-04-24 18:07:26 -0700738 //If all above hard conditions are met we can do full or partial MDP comp.
739 bool ret = false;
740 if(fullMDPComp(ctx, list)) {
741 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700742 } else if(fullMDPCompWithPTOR(ctx, list)) {
743 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700744 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700745 ret = true;
746 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530747
Saurabh Shahaa236822013-04-24 18:07:26 -0700748 return ret;
749}
750
751bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700752
753 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
754 return false;
755
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700756 //Will benefit presentation / secondary-only layer.
757 if((mDpy > HWC_DISPLAY_PRIMARY) &&
758 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
759 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
760 return false;
761 }
762
763 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
764 for(int i = 0; i < numAppLayers; i++) {
765 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700766 if(not mCurrentFrame.drop[i] and
767 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700768 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
769 return false;
770 }
771 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800772
Saurabh Shahaa236822013-04-24 18:07:26 -0700773 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700774 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
775 sizeof(mCurrentFrame.isFBComposed));
776 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
777 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700778
Raj Kamal389d6e32014-08-04 14:43:24 +0530779 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800780 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530781 }
782
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800783 if(!postHeuristicsHandling(ctx, list)) {
784 ALOGD_IF(isDebug(), "post heuristic handling failed");
785 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700786 return false;
787 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700788 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
789 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700790 return true;
791}
792
Sushil Chauhandefd3522014-05-13 18:17:12 -0700793/* Full MDP Composition with Peripheral Tiny Overlap Removal.
794 * MDP bandwidth limitations can be avoided, if the overlap region
795 * covered by the smallest layer at a higher z-order, gets composed
796 * by Copybit on a render buffer, which can be queued to MDP.
797 */
798bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
799 hwc_display_contents_1_t* list) {
800
801 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
802 const int stagesForMDP = min(sMaxPipesPerMixer,
803 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
804
805 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700806 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700807 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
808 return false;
809 }
810
811 // Frame level checks
812 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
813 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
814 isSecurePresent(ctx, mDpy)) {
815 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
816 return false;
817 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700818 // MDP comp checks
819 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700820 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700821 if(not isSupportedForMDPComp(ctx, layer)) {
822 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
823 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700824 }
825 }
826
Sushil Chauhandefd3522014-05-13 18:17:12 -0700827 /* We cannot use this composition mode, if:
828 1. A below layer needs scaling.
829 2. Overlap is not peripheral to display.
830 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700831 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700832 */
833
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700834 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
835 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
836 memset(overlapRect, 0, sizeof(overlapRect));
837 int layerPixelCount, minPixelCount = 0;
838 int numPTORLayersFound = 0;
839 for (int i = numAppLayers-1; (i >= 0 &&
840 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700841 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700842 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700843 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700844 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
845 // PTOR layer should be peripheral and cannot have transform
846 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
847 has90Transform(layer)) {
848 continue;
849 }
850 if((3 * (layerPixelCount + minPixelCount)) >
851 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
852 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
853 continue;
854 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700855 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700856 for (int j = i-1; j >= 0; j--) {
857 // Check if the layers below this layer qualifies for PTOR comp
858 hwc_layer_1_t* layer = &list->hwLayers[j];
859 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700860 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700861 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700862 if (isValidRect(getIntersection(dispFrame, disFrame))) {
863 if (has90Transform(layer) || needsScaling(layer)) {
864 found = false;
865 break;
866 }
867 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700868 }
869 }
870 // Store the minLayer Index
871 if(found) {
872 minLayerIndex[numPTORLayersFound] = i;
873 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
874 minPixelCount += layerPixelCount;
875 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700876 }
877 }
878
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700879 if(isValidRect(getIntersection(overlapRect[0], overlapRect[1]))) {
880 ALOGD_IF(isDebug(), "%s: Ignore Rect2 its intersects with Rect1",
881 __FUNCTION__);
882 // reset second minLayerIndex[1];
883 minLayerIndex[1] = -1;
884 numPTORLayersFound--;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700885 }
886
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700887 // No overlap layers
888 if (!numPTORLayersFound)
889 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700890
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700891 ctx->mPtorInfo.count = numPTORLayersFound;
892 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
893 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
894 }
895
896 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
897 // reset PTOR
898 ctx->mPtorInfo.count = 0;
899 return false;
900 }
901 // Store the displayFrame and the sourceCrops of the layers
902 hwc_rect_t displayFrame[numAppLayers];
903 hwc_rect_t sourceCrop[numAppLayers];
904 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700905 hwc_layer_1_t* layer = &list->hwLayers[i];
906 displayFrame[i] = layer->displayFrame;
907 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700908 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700909
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700910 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
911 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
912
Xu Yangcda012c2014-07-30 21:57:21 +0800913 // Store the blending mode, planeAlpha, and transform of PTOR layers
914 int32_t blending[numPTORLayersFound];
915 uint8_t planeAlpha[numPTORLayersFound];
916 uint32_t transform[numPTORLayersFound];
917
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700918 for(int j = 0; j < numPTORLayersFound; j++) {
919 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700920
921 // Update src crop of PTOR layer
922 hwc_layer_1_t* layer = &list->hwLayers[index];
923 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
924 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
925 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
926 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
927
928 // Store & update w, h, format of PTOR layer
929 private_handle_t *hnd = (private_handle_t *)layer->handle;
930 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
931 layerWhf[j] = whf;
932 hnd->width = renderBuf->width;
933 hnd->height = renderBuf->height;
934 hnd->format = renderBuf->format;
935
Xu Yangcda012c2014-07-30 21:57:21 +0800936 // Store & update blending mode, planeAlpha and transform of PTOR layer
937 blending[j] = layer->blending;
938 planeAlpha[j] = layer->planeAlpha;
939 transform[j] = layer->transform;
940 layer->blending = HWC_BLENDING_NONE;
941 layer->planeAlpha = 0xFF;
942 layer->transform = 0;
943
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700944 // Remove overlap from crop & displayFrame of below layers
945 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700946 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700947 if(!isValidRect(getIntersection(layer->displayFrame,
948 overlapRect[j]))) {
949 continue;
950 }
951 // Update layer attributes
952 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
953 hwc_rect_t destRect = deductRect(layer->displayFrame,
954 overlapRect[j]);
955 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
956 layer->transform);
957 layer->sourceCropf.left = (float)srcCrop.left;
958 layer->sourceCropf.top = (float)srcCrop.top;
959 layer->sourceCropf.right = (float)srcCrop.right;
960 layer->sourceCropf.bottom = (float)srcCrop.bottom;
961 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700962 }
963
964 mCurrentFrame.mdpCount = numAppLayers;
965 mCurrentFrame.fbCount = 0;
966 mCurrentFrame.fbZ = -1;
967
968 for (int j = 0; j < numAppLayers; j++)
969 mCurrentFrame.isFBComposed[j] = false;
970
971 bool result = postHeuristicsHandling(ctx, list);
972
973 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700974 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700975 hwc_layer_1_t* layer = &list->hwLayers[i];
976 layer->displayFrame = displayFrame[i];
977 layer->sourceCropf.left = (float)sourceCrop[i].left;
978 layer->sourceCropf.top = (float)sourceCrop[i].top;
979 layer->sourceCropf.right = (float)sourceCrop[i].right;
980 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
981 }
982
Xu Yangcda012c2014-07-30 21:57:21 +0800983 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700984 for (int i = 0; i < numPTORLayersFound; i++) {
985 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +0800986 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700987 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
988 hnd->width = layerWhf[i].w;
989 hnd->height = layerWhf[i].h;
990 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +0800991 layer->blending = blending[i];
992 layer->planeAlpha = planeAlpha[i];
993 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700994 }
995
Sushil Chauhandefd3522014-05-13 18:17:12 -0700996 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700997 // reset PTOR
998 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700999 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001000 } else {
1001 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1002 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001003 }
1004
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001005 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1006 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001007 return result;
1008}
1009
Saurabh Shahaa236822013-04-24 18:07:26 -07001010bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1011{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001012 if(!sEnableMixedMode) {
1013 //Mixed mode is disabled. No need to even try caching.
1014 return false;
1015 }
1016
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001017 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001018 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001019 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001020 cacheBasedComp(ctx, list);
1021 } else {
1022 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001023 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001024 }
1025
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001026 return ret;
1027}
1028
1029bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1030 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001031 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1032 return false;
1033
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001034 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001035 mCurrentFrame.reset(numAppLayers);
1036 updateLayerCache(ctx, list);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001037
1038 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1039 for(int i = 0; i < numAppLayers; i++) {
1040 if(!mCurrentFrame.isFBComposed[i]) {
1041 hwc_layer_1_t* layer = &list->hwLayers[i];
1042 if(not isSupportedForMDPComp(ctx, layer)) {
1043 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1044 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001045 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001046 return false;
1047 }
1048 }
1049 }
1050
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001051 updateYUV(ctx, list, false /*secure only*/);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001052 /* mark secure RGB layers for MDP comp */
1053 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301054 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001055 if(!ret) {
1056 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001057 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001058 return false;
1059 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001060
1061 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001062
Raj Kamal389d6e32014-08-04 14:43:24 +05301063 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001064 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301065 }
1066
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001067 //Will benefit cases where a video has non-updating background.
1068 if((mDpy > HWC_DISPLAY_PRIMARY) and
1069 (mdpCount > MAX_SEC_LAYERS)) {
1070 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001071 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001072 return false;
1073 }
1074
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001075 if(!postHeuristicsHandling(ctx, list)) {
1076 ALOGD_IF(isDebug(), "post heuristic handling failed");
1077 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001078 return false;
1079 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001080 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1081 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001082
Saurabh Shahaa236822013-04-24 18:07:26 -07001083 return true;
1084}
1085
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001086bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001087 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001088 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1089 return false;
1090
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001091 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001092 return false;
1093 }
1094
Saurabh Shahb772ae32013-11-18 15:40:02 -08001095 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001096 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1097 const int stagesForMDP = min(sMaxPipesPerMixer,
1098 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001099
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001100 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1101 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1102 int lastMDPSupportedIndex = numAppLayers;
1103 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001104
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001105 //Find the minimum MDP batch size
1106 for(int i = 0; i < numAppLayers;i++) {
1107 if(mCurrentFrame.drop[i]) {
1108 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001109 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001110 }
1111 hwc_layer_1_t* layer = &list->hwLayers[i];
1112 if(not isSupportedForMDPComp(ctx, layer)) {
1113 lastMDPSupportedIndex = i;
1114 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1115 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001116 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001117 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001118 }
1119
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001120 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1121 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1122 mCurrentFrame.dropCount);
1123
1124 //Start at a point where the fb batch should at least have 2 layers, for
1125 //this mode to be justified.
1126 while(fbBatchSize < 2) {
1127 ++fbBatchSize;
1128 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001129 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001130
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001131 //If there are no layers for MDP, this mode doesnt make sense.
1132 if(mdpBatchSize < 1) {
1133 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1134 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001135 return false;
1136 }
1137
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001138 mCurrentFrame.reset(numAppLayers);
1139
1140 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1141 while(mdpBatchSize > 0) {
1142 //Mark layers for MDP comp
1143 int mdpBatchLeft = mdpBatchSize;
1144 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1145 if(mCurrentFrame.drop[i]) {
1146 continue;
1147 }
1148 mCurrentFrame.isFBComposed[i] = false;
1149 --mdpBatchLeft;
1150 }
1151
1152 mCurrentFrame.fbZ = mdpBatchSize;
1153 mCurrentFrame.fbCount = fbBatchSize;
1154 mCurrentFrame.mdpCount = mdpBatchSize;
1155
1156 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1157 __FUNCTION__, mdpBatchSize, fbBatchSize,
1158 mCurrentFrame.dropCount);
1159
1160 if(postHeuristicsHandling(ctx, list)) {
1161 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001162 __FUNCTION__);
1163 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1164 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001165 return true;
1166 }
1167
1168 reset(ctx);
1169 --mdpBatchSize;
1170 ++fbBatchSize;
1171 }
1172
1173 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001174}
1175
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001176bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301177 if(mDpy or isSecurePresent(ctx, mDpy) or
1178 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001179 return false;
1180 }
1181 return true;
1182}
1183
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001184bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1185 hwc_display_contents_1_t* list){
1186 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1187 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1188 mDpy ) {
1189 return false;
1190 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001191 if(ctx->listStats[mDpy].secureUI)
1192 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001193 return true;
1194}
1195
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001196bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1197 hwc_display_contents_1_t* list) {
1198 const bool secureOnly = true;
1199 return videoOnlyComp(ctx, list, not secureOnly) or
1200 videoOnlyComp(ctx, list, secureOnly);
1201}
1202
1203bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001204 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001205 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1206 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001207 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001208
Saurabh Shahaa236822013-04-24 18:07:26 -07001209 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001210 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001211 updateYUV(ctx, list, secureOnly);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001212 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001213
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001214 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1215 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001216 return false;
1217 }
1218
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001219 /* Bail out if we are processing only secured video layers
1220 * and we dont have any */
1221 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001222 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001223 return false;
1224 }
1225
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001226 if(mCurrentFrame.fbCount)
1227 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001228
Raj Kamal389d6e32014-08-04 14:43:24 +05301229 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001230 adjustForSourceSplit(ctx, list);
1231 }
1232
1233 if(!postHeuristicsHandling(ctx, list)) {
1234 ALOGD_IF(isDebug(), "post heuristic handling failed");
1235 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001236 return false;
1237 }
1238
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001239 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1240 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001241 return true;
1242}
1243
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001244/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1245bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1246 hwc_display_contents_1_t* list) {
1247 const bool secureOnly = true;
1248 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1249 mdpOnlyLayersComp(ctx, list, secureOnly);
1250
1251}
1252
1253bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1254 hwc_display_contents_1_t* list, bool secureOnly) {
1255
1256 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1257 return false;
1258
1259 /* Bail out if we are processing only secured video layers
1260 * and we dont have any */
1261 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1262 reset(ctx);
1263 return false;
1264 }
1265
1266 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1267 mCurrentFrame.reset(numAppLayers);
1268 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1269
1270 updateYUV(ctx, list, secureOnly);
1271 /* mark secure RGB layers for MDP comp */
1272 updateSecureRGB(ctx, list);
1273
1274 if(mCurrentFrame.mdpCount == 0) {
1275 reset(ctx);
1276 return false;
1277 }
1278
1279 /* find the maximum batch of layers to be marked for framebuffer */
1280 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1281 if(!ret) {
1282 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1283 reset(ctx);
1284 return false;
1285 }
1286
1287 if(sEnableYUVsplit){
1288 adjustForSourceSplit(ctx, list);
1289 }
1290
1291 if(!postHeuristicsHandling(ctx, list)) {
1292 ALOGD_IF(isDebug(), "post heuristic handling failed");
1293 reset(ctx);
1294 return false;
1295 }
1296
1297 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1298 __FUNCTION__);
1299 return true;
1300}
1301
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001302/* Checks for conditions where YUV layers cannot be bypassed */
1303bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001304 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001305 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001306 return false;
1307 }
1308
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001309 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001310 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1311 return false;
1312 }
1313
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001314 if(isSecuring(ctx, layer)) {
1315 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1316 return false;
1317 }
1318
Saurabh Shah4fdde762013-04-30 18:47:33 -07001319 if(!isValidDimension(ctx, layer)) {
1320 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1321 __FUNCTION__);
1322 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001323 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001324
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001325 if(layer->planeAlpha < 0xFF) {
1326 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1327 in video only mode",
1328 __FUNCTION__);
1329 return false;
1330 }
1331
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001332 return true;
1333}
1334
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001335/* Checks for conditions where Secure RGB layers cannot be bypassed */
1336bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1337 if(isSkipLayer(layer)) {
1338 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1339 __FUNCTION__, mDpy);
1340 return false;
1341 }
1342
1343 if(isSecuring(ctx, layer)) {
1344 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1345 return false;
1346 }
1347
1348 if(not isSupportedForMDPComp(ctx, layer)) {
1349 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1350 __FUNCTION__);
1351 return false;
1352 }
1353 return true;
1354}
1355
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301356/* starts at fromIndex and check for each layer to find
1357 * if it it has overlapping with any Updating layer above it in zorder
1358 * till the end of the batch. returns true if it finds any intersection */
1359bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1360 int fromIndex, int toIndex) {
1361 for(int i = fromIndex; i < toIndex; i++) {
1362 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1363 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1364 return false;
1365 }
1366 }
1367 }
1368 return true;
1369}
1370
1371/* Checks if given layer at targetLayerIndex has any
1372 * intersection with all the updating layers in beween
1373 * fromIndex and toIndex. Returns true if it finds intersectiion */
1374bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1375 int fromIndex, int toIndex, int targetLayerIndex) {
1376 for(int i = fromIndex; i <= toIndex; i++) {
1377 if(!mCurrentFrame.isFBComposed[i]) {
1378 if(areLayersIntersecting(&list->hwLayers[i],
1379 &list->hwLayers[targetLayerIndex])) {
1380 return true;
1381 }
1382 }
1383 }
1384 return false;
1385}
1386
1387int MDPComp::getBatch(hwc_display_contents_1_t* list,
1388 int& maxBatchStart, int& maxBatchEnd,
1389 int& maxBatchCount) {
1390 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301391 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001392 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301393 while (i < mCurrentFrame.layerCount) {
1394 int batchCount = 0;
1395 int batchStart = i;
1396 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001397 /* Adjust batch Z order with the dropped layers so far */
1398 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301399 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301400 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301401 while(i < mCurrentFrame.layerCount) {
1402 if(!mCurrentFrame.isFBComposed[i]) {
1403 if(!batchCount) {
1404 i++;
1405 break;
1406 }
1407 updatingLayersAbove++;
1408 i++;
1409 continue;
1410 } else {
1411 if(mCurrentFrame.drop[i]) {
1412 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001413 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301414 continue;
1415 } else if(updatingLayersAbove <= 0) {
1416 batchCount++;
1417 batchEnd = i;
1418 i++;
1419 continue;
1420 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1421
1422 // We have a valid updating layer already. If layer-i not
1423 // have overlapping with all updating layers in between
1424 // batch-start and i, then we can add layer i to batch.
1425 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1426 batchCount++;
1427 batchEnd = i;
1428 i++;
1429 continue;
1430 } else if(canPushBatchToTop(list, batchStart, i)) {
1431 //If All the non-updating layers with in this batch
1432 //does not have intersection with the updating layers
1433 //above in z-order, then we can safely move the batch to
1434 //higher z-order. Increment fbZ as it is moving up.
1435 if( firstZReverseIndex < 0) {
1436 firstZReverseIndex = i;
1437 }
1438 batchCount++;
1439 batchEnd = i;
1440 fbZ += updatingLayersAbove;
1441 i++;
1442 updatingLayersAbove = 0;
1443 continue;
1444 } else {
1445 //both failed.start the loop again from here.
1446 if(firstZReverseIndex >= 0) {
1447 i = firstZReverseIndex;
1448 }
1449 break;
1450 }
1451 }
1452 }
1453 }
1454 if(batchCount > maxBatchCount) {
1455 maxBatchCount = batchCount;
1456 maxBatchStart = batchStart;
1457 maxBatchEnd = batchEnd;
1458 fbZOrder = fbZ;
1459 }
1460 }
1461 return fbZOrder;
1462}
1463
1464bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1465 hwc_display_contents_1_t* list) {
1466 /* Idea is to keep as many non-updating(cached) layers in FB and
1467 * send rest of them through MDP. This is done in 2 steps.
1468 * 1. Find the maximum contiguous batch of non-updating layers.
1469 * 2. See if we can improve this batch size for caching by adding
1470 * opaque layers around the batch, if they don't have
1471 * any overlapping with the updating layers in between.
1472 * NEVER mark an updating layer for caching.
1473 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001474
1475 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001476 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001477 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301478 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001479
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001480 /* Nothing is cached. No batching needed */
1481 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001482 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001483 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001484
1485 /* No MDP comp layers, try to use other comp modes */
1486 if(mCurrentFrame.mdpCount == 0) {
1487 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001488 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001489
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301490 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001491
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301492 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001493 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001494 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001495 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301496 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001497 if(!mCurrentFrame.drop[i]){
1498 //If an unsupported layer is being attempted to
1499 //be pulled out we should fail
1500 if(not isSupportedForMDPComp(ctx, layer)) {
1501 return false;
1502 }
1503 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001504 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001505 }
1506 }
1507
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301508 // update the frame data
1509 mCurrentFrame.fbZ = fbZ;
1510 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001511 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001512 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001513
1514 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301515 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001516
1517 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001518}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001519
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001520void MDPComp::updateLayerCache(hwc_context_t* ctx,
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001521 hwc_display_contents_1_t* list) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001522 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001523 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001524
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001525 for(int i = 0; i < numAppLayers; i++) {
1526 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001527 if(!mCurrentFrame.drop[i])
1528 fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001529 mCurrentFrame.isFBComposed[i] = true;
1530 } else {
Saurabh Shahaa236822013-04-24 18:07:26 -07001531 mCurrentFrame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001532 }
1533 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001534
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001535 mCurrentFrame.fbCount = fbCount;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001536 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
1537 - mCurrentFrame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001538
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001539 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d"
1540 ,__FUNCTION__, mCurrentFrame.mdpCount, mCurrentFrame.fbCount,
1541 mCurrentFrame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001542}
1543
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001544void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
1545 bool secureOnly) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001546 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1547 for(int index = 0;index < nYuvCount; index++){
1548 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1549 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1550
1551 if(!isYUVDoable(ctx, layer)) {
1552 if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
1553 mCurrentFrame.isFBComposed[nYuvIndex] = true;
1554 mCurrentFrame.fbCount++;
1555 }
1556 } else {
1557 if(mCurrentFrame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001558 private_handle_t *hnd = (private_handle_t *)layer->handle;
1559 if(!secureOnly || isSecureBuffer(hnd)) {
1560 mCurrentFrame.isFBComposed[nYuvIndex] = false;
1561 mCurrentFrame.fbCount--;
1562 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001563 }
1564 }
1565 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001566
1567 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001568 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1569 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001570 mCurrentFrame.fbCount);
1571}
1572
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001573void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1574 hwc_display_contents_1_t* list) {
1575 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1576 for(int index = 0;index < nSecureRGBCount; index++){
1577 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1578 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1579
1580 if(!isSecureRGBDoable(ctx, layer)) {
1581 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1582 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1583 mCurrentFrame.fbCount++;
1584 }
1585 } else {
1586 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1587 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1588 mCurrentFrame.fbCount--;
1589 }
1590 }
1591 }
1592
1593 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1594 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1595 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1596 mCurrentFrame.fbCount);
1597}
1598
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001599hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1600 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001601 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001602
1603 /* Update only the region of FB needed for composition */
1604 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1605 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1606 hwc_layer_1_t* layer = &list->hwLayers[i];
1607 hwc_rect_t dst = layer->displayFrame;
1608 fbRect = getUnion(fbRect, dst);
1609 }
1610 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001611 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001612 return fbRect;
1613}
1614
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001615bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1616 hwc_display_contents_1_t* list) {
1617
1618 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001619 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001620 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1621 return false;
1622 }
1623
1624 //Limitations checks
1625 if(!hwLimitationsCheck(ctx, list)) {
1626 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1627 return false;
1628 }
1629
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001630 //Configure framebuffer first if applicable
1631 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001632 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001633 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1634 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001635 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1636 __FUNCTION__);
1637 return false;
1638 }
1639 }
1640
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001641 mCurrentFrame.map();
1642
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001643 if(!allocLayerPipes(ctx, list)) {
1644 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001645 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001646 }
1647
1648 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001649 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001650 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001651 int mdpIndex = mCurrentFrame.layerToMDP[index];
1652 hwc_layer_1_t* layer = &list->hwLayers[index];
1653
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301654 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1655 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1656 mdpNextZOrder++;
1657 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001658 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1659 cur_pipe->zOrder = mdpNextZOrder++;
1660
radhakrishnac9a67412013-09-25 17:40:42 +05301661 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301662 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301663 if(configure4k2kYuv(ctx, layer,
1664 mCurrentFrame.mdpToLayer[mdpIndex])
1665 != 0 ){
1666 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1667 for layer %d",__FUNCTION__, index);
1668 return false;
1669 }
1670 else{
1671 mdpNextZOrder++;
1672 }
1673 continue;
1674 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001675 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1676 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301677 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001678 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001679 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001680 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001681 }
1682
Saurabh Shaha36be922013-12-16 18:18:39 -08001683 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1684 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1685 ,__FUNCTION__, mDpy);
1686 return false;
1687 }
1688
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001689 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001690 return true;
1691}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001692
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001693bool MDPComp::resourceCheck(hwc_context_t* ctx,
1694 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001695 const bool fbUsed = mCurrentFrame.fbCount;
1696 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1697 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1698 return false;
1699 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001700 // Init rotCount to number of rotate sessions used by other displays
1701 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1702 // Count the number of rotator sessions required for current display
1703 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1704 if(!mCurrentFrame.isFBComposed[index]) {
1705 hwc_layer_1_t* layer = &list->hwLayers[index];
1706 private_handle_t *hnd = (private_handle_t *)layer->handle;
1707 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1708 rotCount++;
1709 }
1710 }
1711 }
1712 // if number of layers to rotate exceeds max rotator sessions, bail out.
1713 if(rotCount > RotMgr::MAX_ROT_SESS) {
1714 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1715 __FUNCTION__, mDpy);
1716 return false;
1717 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001718 return true;
1719}
1720
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301721bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1722 hwc_display_contents_1_t* list) {
1723
1724 //A-family hw limitation:
1725 //If a layer need alpha scaling, MDP can not support.
1726 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1727 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1728 if(!mCurrentFrame.isFBComposed[i] &&
1729 isAlphaScaled( &list->hwLayers[i])) {
1730 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1731 return false;
1732 }
1733 }
1734 }
1735
1736 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1737 //If multiple layers requires downscaling and also they are overlapping
1738 //fall back to GPU since MDSS can not handle it.
1739 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1740 qdutils::MDPVersion::getInstance().is8x26()) {
1741 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1742 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1743 if(!mCurrentFrame.isFBComposed[i] &&
1744 isDownscaleRequired(botLayer)) {
1745 //if layer-i is marked for MDP and needs downscaling
1746 //check if any MDP layer on top of i & overlaps with layer-i
1747 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1748 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1749 if(!mCurrentFrame.isFBComposed[j] &&
1750 isDownscaleRequired(topLayer)) {
1751 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1752 topLayer->displayFrame);
1753 if(isValidRect(r))
1754 return false;
1755 }
1756 }
1757 }
1758 }
1759 }
1760 return true;
1761}
1762
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001763int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001764 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001765 char property[PROPERTY_VALUE_MAX];
1766
Raj Kamal4393eaa2014-06-06 13:45:20 +05301767 if(!ctx || !list) {
1768 ALOGE("%s: Invalid context or list",__FUNCTION__);
1769 mCachedFrame.reset();
1770 return -1;
1771 }
1772
1773 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001774 if(mDpy == HWC_DISPLAY_PRIMARY) {
1775 sSimulationFlags = 0;
1776 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1777 int currentFlags = atoi(property);
1778 if(currentFlags != sSimulationFlags) {
1779 sSimulationFlags = currentFlags;
1780 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1781 sSimulationFlags, sSimulationFlags);
1782 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001783 }
1784 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001785 // reset PTOR
1786 if(!mDpy)
1787 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001788
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301789 //Do not cache the information for next draw cycle.
1790 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1791 ALOGI("%s: Unsupported layer count for mdp composition",
1792 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001793 mCachedFrame.reset();
1794 return -1;
1795 }
1796
Saurabh Shahb39f8152013-08-22 10:21:44 -07001797 //reset old data
1798 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001799 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1800 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301801
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001802 // Detect the start of animation and fall back to GPU only once to cache
1803 // all the layers in FB and display FB content untill animation completes.
1804 if(ctx->listStats[mDpy].isDisplayAnimating) {
1805 mCurrentFrame.needsRedraw = false;
1806 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1807 mCurrentFrame.needsRedraw = true;
1808 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1809 }
1810 setMDPCompLayerFlags(ctx, list);
1811 mCachedFrame.updateCounts(mCurrentFrame);
1812 ret = -1;
1813 return ret;
1814 } else {
1815 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1816 }
1817
Saurabh Shahb39f8152013-08-22 10:21:44 -07001818 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001819 if(isFrameDoable(ctx)) {
1820 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001821
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001822 // if tryFullFrame fails, try to push all video and secure RGB layers
1823 // to MDP for composition.
1824 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
1825 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301826 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001827 setMDPCompLayerFlags(ctx, list);
1828 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001829 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001830 reset(ctx);
1831 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1832 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001833 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001834 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1835 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001836 }
1837 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001838 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1839 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001840 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001841 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001842
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001843 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001844 ALOGD("GEOMETRY change: %d",
1845 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001846 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001847 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001848 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001849 }
1850
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001851 mCachedFrame.cacheAll(list);
1852 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001853 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001854}
1855
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001856bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301857
1858 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301859 int mdpIndex = mCurrentFrame.layerToMDP[index];
1860 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1861 info.pipeInfo = new MdpYUVPipeInfo;
1862 info.rot = NULL;
1863 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301864
1865 pipe_info.lIndex = ovutils::OV_INVALID;
1866 pipe_info.rIndex = ovutils::OV_INVALID;
1867
Saurabh Shahc62f3982014-03-05 14:28:26 -08001868 Overlay::PipeSpecs pipeSpecs;
1869 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1870 pipeSpecs.needsScaling = true;
1871 pipeSpecs.dpy = mDpy;
1872 pipeSpecs.fb = false;
1873
1874 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301875 if(pipe_info.lIndex == ovutils::OV_INVALID){
1876 bRet = false;
1877 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1878 __FUNCTION__);
1879 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001880 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301881 if(pipe_info.rIndex == ovutils::OV_INVALID){
1882 bRet = false;
1883 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1884 __FUNCTION__);
1885 }
1886 return bRet;
1887}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001888
1889int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1890 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001891 if (ctx->mPtorInfo.isActive()) {
1892 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001893 if (fd < 0) {
1894 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001895 }
1896 }
1897 return fd;
1898}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001899//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001900
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001901void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301902 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001903 //If 4k2k Yuv layer split is possible, and if
1904 //fbz is above 4k2k layer, increment fb zorder by 1
1905 //as we split 4k2k layer and increment zorder for right half
1906 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07001907 if(!ctx)
1908 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001909 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301910 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1911 index++) {
1912 if(!mCurrentFrame.isFBComposed[index]) {
1913 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1914 mdpNextZOrder++;
1915 }
1916 mdpNextZOrder++;
1917 hwc_layer_1_t* layer = &list->hwLayers[index];
1918 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301919 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301920 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1921 mCurrentFrame.fbZ += 1;
1922 mdpNextZOrder++;
1923 //As we split 4kx2k yuv layer and program to 2 VG pipes
1924 //(if available) increase mdpcount by 1.
1925 mCurrentFrame.mdpCount++;
1926 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001927 }
1928 }
1929 }
radhakrishnac9a67412013-09-25 17:40:42 +05301930}
1931
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001932/*
1933 * Configures pipe(s) for MDP composition
1934 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001935int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001936 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001937 MdpPipeInfoNonSplit& mdp_info =
1938 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001939 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1940 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08001941 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001942
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001943 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1944 __FUNCTION__, layer, zOrder, dest);
1945
Saurabh Shah2c8ad052014-08-15 13:27:46 -07001946 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001947 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001948}
1949
Saurabh Shah88e4d272013-09-03 13:31:29 -07001950bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001951 hwc_display_contents_1_t* list) {
1952 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001953
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001954 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001955
Jeykumar Sankarancf537002013-01-21 21:19:15 -08001956 hwc_layer_1_t* layer = &list->hwLayers[index];
1957 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301958 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001959 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301960 continue;
1961 }
1962 }
1963
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001964 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001965 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001966 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08001967 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001968 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001969
Saurabh Shahc62f3982014-03-05 14:28:26 -08001970 Overlay::PipeSpecs pipeSpecs;
1971 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1972 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1973 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
1974 (qdutils::MDPVersion::getInstance().is8x26() and
1975 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
1976 pipeSpecs.dpy = mDpy;
1977 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08001978 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001979
Saurabh Shahc62f3982014-03-05 14:28:26 -08001980 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
1981
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001982 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001983 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001984 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001985 }
1986 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001987 return true;
1988}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001989
radhakrishnac9a67412013-09-25 17:40:42 +05301990int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1991 PipeLayerPair& PipeLayerPair) {
1992 MdpYUVPipeInfo& mdp_info =
1993 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
1994 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05301995 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1996 eDest lDest = mdp_info.lIndex;
1997 eDest rDest = mdp_info.rIndex;
1998
Saurabh Shah2c8ad052014-08-15 13:27:46 -07001999 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302000 lDest, rDest, &PipeLayerPair.rot);
2001}
2002
Saurabh Shah88e4d272013-09-03 13:31:29 -07002003bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002004
Raj Kamal4393eaa2014-06-06 13:45:20 +05302005 if(!isEnabled() or !mModeOn) {
2006 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302007 return true;
2008 }
2009
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002010 // Set the Handle timeout to true for MDP or MIXED composition.
2011 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2012 sHandleTimeout = true;
2013 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002014
2015 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002016 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002017
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002018 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2019 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002020 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002021 if(mCurrentFrame.isFBComposed[i]) continue;
2022
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002023 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002024 private_handle_t *hnd = (private_handle_t *)layer->handle;
2025 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002026 if (!(layer->flags & HWC_COLOR_FILL)) {
2027 ALOGE("%s handle null", __FUNCTION__);
2028 return false;
2029 }
2030 // No PLAY for Color layer
2031 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2032 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002033 }
2034
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002035 int mdpIndex = mCurrentFrame.layerToMDP[i];
2036
Raj Kamal389d6e32014-08-04 14:43:24 +05302037 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302038 {
2039 MdpYUVPipeInfo& pipe_info =
2040 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2041 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2042 ovutils::eDest indexL = pipe_info.lIndex;
2043 ovutils::eDest indexR = pipe_info.rIndex;
2044 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302045 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302046 if(rot) {
2047 rot->queueBuffer(fd, offset);
2048 fd = rot->getDstMemId();
2049 offset = rot->getDstOffset();
2050 }
2051 if(indexL != ovutils::OV_INVALID) {
2052 ovutils::eDest destL = (ovutils::eDest)indexL;
2053 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2054 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2055 if (!ov.queueBuffer(fd, offset, destL)) {
2056 ALOGE("%s: queueBuffer failed for display:%d",
2057 __FUNCTION__, mDpy);
2058 return false;
2059 }
2060 }
2061
2062 if(indexR != ovutils::OV_INVALID) {
2063 ovutils::eDest destR = (ovutils::eDest)indexR;
2064 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2065 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2066 if (!ov.queueBuffer(fd, offset, destR)) {
2067 ALOGE("%s: queueBuffer failed for display:%d",
2068 __FUNCTION__, mDpy);
2069 return false;
2070 }
2071 }
2072 }
2073 else{
2074 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002075 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302076 ovutils::eDest dest = pipe_info.index;
2077 if(dest == ovutils::OV_INVALID) {
2078 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002079 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302080 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002081
radhakrishnac9a67412013-09-25 17:40:42 +05302082 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2083 continue;
2084 }
2085
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002086 int fd = hnd->fd;
2087 uint32_t offset = (uint32_t)hnd->offset;
2088 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2089 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002090 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002091 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002092 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002093 }
2094
radhakrishnac9a67412013-09-25 17:40:42 +05302095 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2096 using pipe: %d", __FUNCTION__, layer,
2097 hnd, dest );
2098
radhakrishnac9a67412013-09-25 17:40:42 +05302099 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2100 if(rot) {
2101 if(!rot->queueBuffer(fd, offset))
2102 return false;
2103 fd = rot->getDstMemId();
2104 offset = rot->getDstOffset();
2105 }
2106
2107 if (!ov.queueBuffer(fd, offset, dest)) {
2108 ALOGE("%s: queueBuffer failed for display:%d ",
2109 __FUNCTION__, mDpy);
2110 return false;
2111 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002112 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002113
2114 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002115 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002116 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002117}
2118
Saurabh Shah88e4d272013-09-03 13:31:29 -07002119//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002120
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002121void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302122 hwc_display_contents_1_t* list){
2123 //if 4kx2k yuv layer is totally present in either in left half
2124 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302125 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302126 if(mCurrentFrame.fbZ >= 0) {
2127 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2128 index++) {
2129 if(!mCurrentFrame.isFBComposed[index]) {
2130 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2131 mdpNextZOrder++;
2132 }
2133 mdpNextZOrder++;
2134 hwc_layer_1_t* layer = &list->hwLayers[index];
2135 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302136 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302137 hwc_rect_t dst = layer->displayFrame;
2138 if((dst.left > lSplit) || (dst.right < lSplit)) {
2139 mCurrentFrame.mdpCount += 1;
2140 }
2141 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2142 mCurrentFrame.fbZ += 1;
2143 mdpNextZOrder++;
2144 }
2145 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002146 }
radhakrishnac9a67412013-09-25 17:40:42 +05302147 }
2148}
2149
Saurabh Shah88e4d272013-09-03 13:31:29 -07002150bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002151 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002152
Saurabh Shahc62f3982014-03-05 14:28:26 -08002153 const int lSplit = getLeftSplit(ctx, mDpy);
2154 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002155 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002156 pipe_info.lIndex = ovutils::OV_INVALID;
2157 pipe_info.rIndex = ovutils::OV_INVALID;
2158
Saurabh Shahc62f3982014-03-05 14:28:26 -08002159 Overlay::PipeSpecs pipeSpecs;
2160 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2161 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2162 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2163 pipeSpecs.dpy = mDpy;
2164 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2165 pipeSpecs.fb = false;
2166
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002167 // Acquire pipe only for the updating half
2168 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2169 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2170
2171 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002172 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002173 if(pipe_info.lIndex == ovutils::OV_INVALID)
2174 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002175 }
2176
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002177 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002178 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2179 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002180 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002181 return false;
2182 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002183
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002184 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002185}
2186
Saurabh Shah88e4d272013-09-03 13:31:29 -07002187bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002188 hwc_display_contents_1_t* list) {
2189 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002190
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002191 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002192
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002193 hwc_layer_1_t* layer = &list->hwLayers[index];
2194 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302195 hwc_rect_t dst = layer->displayFrame;
2196 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302197 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302198 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002199 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302200 continue;
2201 }
2202 }
2203 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002204 int mdpIndex = mCurrentFrame.layerToMDP[index];
2205 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002206 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002207 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002208 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002209
Saurabh Shahc62f3982014-03-05 14:28:26 -08002210 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2211 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2212 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002213 return false;
2214 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002215 }
2216 return true;
2217}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002218
radhakrishnac9a67412013-09-25 17:40:42 +05302219int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2220 PipeLayerPair& PipeLayerPair) {
2221 const int lSplit = getLeftSplit(ctx, mDpy);
2222 hwc_rect_t dst = layer->displayFrame;
2223 if((dst.left > lSplit)||(dst.right < lSplit)){
2224 MdpYUVPipeInfo& mdp_info =
2225 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2226 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302227 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2228 eDest lDest = mdp_info.lIndex;
2229 eDest rDest = mdp_info.rIndex;
2230
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002231 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302232 lDest, rDest, &PipeLayerPair.rot);
2233 }
2234 else{
2235 return configure(ctx, layer, PipeLayerPair);
2236 }
2237}
2238
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002239/*
2240 * Configures pipe(s) for MDP composition
2241 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002242int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002243 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002244 MdpPipeInfoSplit& mdp_info =
2245 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002246 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002247 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2248 eDest lDest = mdp_info.lIndex;
2249 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002250
2251 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2252 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2253
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002254 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002255 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002256}
2257
Saurabh Shah88e4d272013-09-03 13:31:29 -07002258bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002259
Raj Kamal4393eaa2014-06-06 13:45:20 +05302260 if(!isEnabled() or !mModeOn) {
2261 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302262 return true;
2263 }
2264
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002265 // Set the Handle timeout to true for MDP or MIXED composition.
2266 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2267 sHandleTimeout = true;
2268 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002269
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002270 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002271 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002272
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002273 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2274 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002275 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002276 if(mCurrentFrame.isFBComposed[i]) continue;
2277
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002278 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002279 private_handle_t *hnd = (private_handle_t *)layer->handle;
2280 if(!hnd) {
2281 ALOGE("%s handle null", __FUNCTION__);
2282 return false;
2283 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002284
2285 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2286 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002287 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002288
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002289 int mdpIndex = mCurrentFrame.layerToMDP[i];
2290
Raj Kamal389d6e32014-08-04 14:43:24 +05302291 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302292 {
2293 MdpYUVPipeInfo& pipe_info =
2294 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2295 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2296 ovutils::eDest indexL = pipe_info.lIndex;
2297 ovutils::eDest indexR = pipe_info.rIndex;
2298 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302299 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302300 if(rot) {
2301 rot->queueBuffer(fd, offset);
2302 fd = rot->getDstMemId();
2303 offset = rot->getDstOffset();
2304 }
2305 if(indexL != ovutils::OV_INVALID) {
2306 ovutils::eDest destL = (ovutils::eDest)indexL;
2307 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2308 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2309 if (!ov.queueBuffer(fd, offset, destL)) {
2310 ALOGE("%s: queueBuffer failed for display:%d",
2311 __FUNCTION__, mDpy);
2312 return false;
2313 }
2314 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002315
radhakrishnac9a67412013-09-25 17:40:42 +05302316 if(indexR != ovutils::OV_INVALID) {
2317 ovutils::eDest destR = (ovutils::eDest)indexR;
2318 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2319 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2320 if (!ov.queueBuffer(fd, offset, destR)) {
2321 ALOGE("%s: queueBuffer failed for display:%d",
2322 __FUNCTION__, mDpy);
2323 return false;
2324 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002325 }
2326 }
radhakrishnac9a67412013-09-25 17:40:42 +05302327 else{
2328 MdpPipeInfoSplit& pipe_info =
2329 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2330 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002331
radhakrishnac9a67412013-09-25 17:40:42 +05302332 ovutils::eDest indexL = pipe_info.lIndex;
2333 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002334
radhakrishnac9a67412013-09-25 17:40:42 +05302335 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002336 uint32_t offset = (uint32_t)hnd->offset;
2337 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2338 if (!mDpy && (index != -1)) {
2339 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2340 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002341 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002342 }
radhakrishnac9a67412013-09-25 17:40:42 +05302343
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002344 if(ctx->mAD->draw(ctx, fd, offset)) {
2345 fd = ctx->mAD->getDstFd();
2346 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002347 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002348
radhakrishnac9a67412013-09-25 17:40:42 +05302349 if(rot) {
2350 rot->queueBuffer(fd, offset);
2351 fd = rot->getDstMemId();
2352 offset = rot->getDstOffset();
2353 }
2354
2355 //************* play left mixer **********
2356 if(indexL != ovutils::OV_INVALID) {
2357 ovutils::eDest destL = (ovutils::eDest)indexL;
2358 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2359 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2360 if (!ov.queueBuffer(fd, offset, destL)) {
2361 ALOGE("%s: queueBuffer failed for left mixer",
2362 __FUNCTION__);
2363 return false;
2364 }
2365 }
2366
2367 //************* play right mixer **********
2368 if(indexR != ovutils::OV_INVALID) {
2369 ovutils::eDest destR = (ovutils::eDest)indexR;
2370 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2371 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2372 if (!ov.queueBuffer(fd, offset, destR)) {
2373 ALOGE("%s: queueBuffer failed for right mixer",
2374 __FUNCTION__);
2375 return false;
2376 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002377 }
2378 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002379
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002380 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2381 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002382
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002383 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002384}
Saurabh Shahab47c692014-02-12 18:45:57 -08002385
2386//================MDPCompSrcSplit==============================================
2387bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002388 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002389 private_handle_t *hnd = (private_handle_t *)layer->handle;
2390 hwc_rect_t dst = layer->displayFrame;
2391 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2392 pipe_info.lIndex = ovutils::OV_INVALID;
2393 pipe_info.rIndex = ovutils::OV_INVALID;
2394
2395 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2396 //should have a higher priority than the right one. Pipe priorities are
2397 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002398
Saurabh Shahc62f3982014-03-05 14:28:26 -08002399 Overlay::PipeSpecs pipeSpecs;
2400 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2401 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2402 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2403 pipeSpecs.dpy = mDpy;
2404 pipeSpecs.fb = false;
2405
Saurabh Shahab47c692014-02-12 18:45:57 -08002406 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002407 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002408 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002409 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002410 }
2411
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002412 /* Use 2 pipes IF
2413 a) Layer's crop width is > 2048 or
2414 b) Layer's dest width > 2048 or
2415 c) On primary, driver has indicated with caps to split always. This is
2416 based on an empirically derived value of panel height. Applied only
2417 if the layer's width is > mixer's width
2418 */
2419
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302420 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002421 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302422 mdpHw.isSrcSplitAlways();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002423 int lSplit = getLeftSplit(ctx, mDpy);
2424 int dstWidth = dst.right - dst.left;
2425 int cropWidth = crop.right - crop.left;
2426
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002427 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2428 //pipe line length, we are still using 2 pipes. This is fine just because
2429 //this is source split where destination doesn't matter. Evaluate later to
2430 //see if going through all the calcs to save a pipe is worth it
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302431 if(dstWidth > mdpHw.getMaxMixerWidth() or
2432 cropWidth > mdpHw.getMaxMixerWidth() or
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002433 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002434 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002435 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002436 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002437 }
2438
2439 // Return values
2440 // 1 Left pipe is higher priority, do nothing.
2441 // 0 Pipes of same priority.
2442 //-1 Right pipe is of higher priority, needs swap.
2443 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2444 pipe_info.rIndex) == -1) {
2445 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002446 }
2447 }
2448
2449 return true;
2450}
2451
Saurabh Shahab47c692014-02-12 18:45:57 -08002452int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2453 PipeLayerPair& PipeLayerPair) {
2454 private_handle_t *hnd = (private_handle_t *)layer->handle;
2455 if(!hnd) {
2456 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2457 return -1;
2458 }
2459 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2460 MdpPipeInfoSplit& mdp_info =
2461 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2462 Rotator **rot = &PipeLayerPair.rot;
2463 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002464 eDest lDest = mdp_info.lIndex;
2465 eDest rDest = mdp_info.rIndex;
2466 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2467 hwc_rect_t dst = layer->displayFrame;
2468 int transform = layer->transform;
2469 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002470 int rotFlags = ROT_FLAGS_NONE;
2471 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2472 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2473
2474 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2475 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2476
2477 // Handle R/B swap
2478 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2479 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2480 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2481 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2482 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2483 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002484 /* Calculate the external display position based on MDP downscale,
2485 ActionSafe, and extorientation features. */
2486 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002487
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002488 int downscale = getRotDownscale(ctx, layer);
Saurabh Shah97e2d802014-04-14 18:03:54 -07002489 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002490 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002491
2492 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2493 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002494 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002495 }
2496
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002497 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002498 (*rot) = ctx->mRotMgr->getNext();
2499 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002500 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002501 //If the video is using a single pipe, enable BWC
2502 if(rDest == OV_INVALID) {
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002503 BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002504 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002505 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002506 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002507 ALOGE("%s: configRotator failed!", __FUNCTION__);
2508 return -1;
2509 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002510 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002511 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002512 }
2513
2514 //If 2 pipes being used, divide layer into half, crop and dst
2515 hwc_rect_t cropL = crop;
2516 hwc_rect_t cropR = crop;
2517 hwc_rect_t dstL = dst;
2518 hwc_rect_t dstR = dst;
2519 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2520 cropL.right = (crop.right + crop.left) / 2;
2521 cropR.left = cropL.right;
2522 sanitizeSourceCrop(cropL, cropR, hnd);
2523
Saurabh Shahb729b192014-08-15 18:04:24 -07002524 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002525 //Swap crops on H flip since 2 pipes are being used
2526 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2527 hwc_rect_t tmp = cropL;
2528 cropL = cropR;
2529 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002530 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002531 }
2532
Saurabh Shahb729b192014-08-15 18:04:24 -07002533 //cropSwap trick: If the src and dst widths are both odd, let us say
2534 //2507, then splitting both into half would cause left width to be 1253
2535 //and right 1254. If crop is swapped because of H flip, this will cause
2536 //left crop width to be 1254, whereas left dst width remains 1253, thus
2537 //inducing a scaling that is unaccounted for. To overcome that we add 1
2538 //to the dst width if there is a cropSwap. So if the original width was
2539 //2507, the left dst width will be 1254. Even if the original width was
2540 //even for ex: 2508, the left dst width will still remain 1254.
2541 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002542 dstR.left = dstL.right;
2543 }
2544
2545 //For the mdp, since either we are pre-rotating or MDP does flips
2546 orient = OVERLAY_TRANSFORM_0;
2547 transform = 0;
2548
2549 //configure left pipe
2550 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002551 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002552 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2553 (ovutils::eBlending) getBlending(layer->blending));
2554
2555 if(configMdp(ctx->mOverlay, pargL, orient,
2556 cropL, dstL, metadata, lDest) < 0) {
2557 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2558 return -1;
2559 }
2560 }
2561
2562 //configure right pipe
2563 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002564 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002565 static_cast<eRotFlags>(rotFlags),
2566 layer->planeAlpha,
2567 (ovutils::eBlending) getBlending(layer->blending));
2568 if(configMdp(ctx->mOverlay, pargR, orient,
2569 cropR, dstR, metadata, rDest) < 0) {
2570 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2571 return -1;
2572 }
2573 }
2574
2575 return 0;
2576}
2577
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002578}; //namespace
2579