blob: f2cff45a2a898759ffdee738549b9ac739b6b3f5 [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 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400375 if(crop_w > (int) mdpHw.getMaxMixerWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530376 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 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400386 if(((crop_w > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530387 !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 Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700428 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
429 /* TODO: freeing up all the resources only for the targets having total
430 number of pipes < 8. Need to analyze number of VIG pipes used
431 for primary in previous draw cycle and accordingly decide
432 whether to fall back to full GPU comp or video only comp
433 */
434 if(isSecondaryConfiguring(ctx)) {
435 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
436 __FUNCTION__);
437 ret = false;
438 } else if(ctx->isPaddingRound) {
439 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
440 __FUNCTION__,mDpy);
441 ret = false;
442 }
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700443 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700444 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800445}
446
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800447void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
448 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
449 fbRect = getIntersection(fbRect, roi);
450}
451
452/* 1) Identify layers that are not visible or lying outside the updating ROI and
453 * drop them from composition.
454 * 2) If we have a scaling layer which needs cropping against generated
455 * ROI, reset ROI to full resolution. */
456bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
457 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700458 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800459 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800460
461 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800462 if(!isValidRect(visibleRect)) {
463 mCurrentFrame.drop[i] = true;
464 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800465 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800466 }
467
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700468 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700469 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800470 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700471
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700472 if(!isValidRect(res)) {
473 mCurrentFrame.drop[i] = true;
474 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800475 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700476 /* Reset frame ROI when any layer which needs scaling also needs ROI
477 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800478 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800479 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700480 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
481 mCurrentFrame.dropCount = 0;
482 return false;
483 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800484
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800485 /* deduct any opaque region from visibleRect */
486 if (layer->blending == HWC_BLENDING_NONE)
487 visibleRect = deductRect(visibleRect, res);
488 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700489 }
490 return true;
491}
492
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800493/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
494 * are updating. If DirtyRegion is applicable, calculate it by accounting all
495 * the changing layer's dirtyRegion. */
496void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
497 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700498 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800499 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700500 return;
501
502 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800503 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
504 (int)ctx->dpyAttr[mDpy].yres};
505
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700506 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800507 hwc_layer_1_t* layer = &list->hwLayers[index];
508 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800509 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700510 hwc_rect_t dst = layer->displayFrame;
511 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800512
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800513#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800514 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700515 {
516 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
517 int x_off = dst.left - src.left;
518 int y_off = dst.top - src.top;
519 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
520 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800521#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800522
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800523 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700524 }
525 }
526
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800527 /* No layer is updating. Still SF wants a refresh.*/
528 if(!isValidRect(roi))
529 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800530
531 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800532 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800533
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800534 ctx->listStats[mDpy].lRoi = roi;
535 if(!validateAndApplyROI(ctx, list))
536 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700537
538 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800539 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
540 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
541}
542
543void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
544 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
545 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
546
547 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
548 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
549 fbRect = getUnion(l_fbRect, r_fbRect);
550}
551/* 1) Identify layers that are not visible or lying outside BOTH the updating
552 * ROI's and drop them from composition. If a layer is spanning across both
553 * the halves of the screen but needed by only ROI, the non-contributing
554 * half will not be programmed for MDP.
555 * 2) If we have a scaling layer which needs cropping against generated
556 * ROI, reset ROI to full resolution. */
557bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
558 hwc_display_contents_1_t* list) {
559
560 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
561
562 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
563 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
564
565 for(int i = numAppLayers - 1; i >= 0; i--){
566 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
567 {
568 mCurrentFrame.drop[i] = true;
569 mCurrentFrame.dropCount++;
570 continue;
571 }
572
573 const hwc_layer_1_t* layer = &list->hwLayers[i];
574 hwc_rect_t dstRect = layer->displayFrame;
575
576 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
577 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
578 hwc_rect_t res = getUnion(l_res, r_res);
579
580 if(!isValidRect(l_res) && !isValidRect(r_res)) {
581 mCurrentFrame.drop[i] = true;
582 mCurrentFrame.dropCount++;
583 } else {
584 /* Reset frame ROI when any layer which needs scaling also needs ROI
585 * cropping */
586 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
587 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
588 mCurrentFrame.dropCount = 0;
589 return false;
590 }
591
592 if (layer->blending == HWC_BLENDING_NONE) {
593 visibleRectL = deductRect(visibleRectL, l_res);
594 visibleRectR = deductRect(visibleRectR, r_res);
595 }
596 }
597 }
598 return true;
599}
600/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
601 * are updating. If DirtyRegion is applicable, calculate it by accounting all
602 * the changing layer's dirtyRegion. */
603void MDPCompSplit::generateROI(hwc_context_t *ctx,
604 hwc_display_contents_1_t* list) {
605 if(!canPartialUpdate(ctx, list))
606 return;
607
608 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
609 int lSplit = getLeftSplit(ctx, mDpy);
610
611 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
612 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
613
614 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
615 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
616
617 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
618 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
619
620 for(int index = 0; index < numAppLayers; index++ ) {
621 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800622 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800623 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800624 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700625 hwc_rect_t dst = layer->displayFrame;
626 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800627
628#ifdef QCOM_BSP
629 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700630 {
631 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
632 int x_off = dst.left - src.left;
633 int y_off = dst.top - src.top;
634 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
635 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800636#endif
637
638 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
639 if(isValidRect(l_dst))
640 l_roi = getUnion(l_roi, l_dst);
641
642 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
643 if(isValidRect(r_dst))
644 r_roi = getUnion(r_roi, r_dst);
645 }
646 }
647
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700648 /* For panels that cannot accept commands in both the interfaces, we cannot
649 * send two ROI's (for each half). We merge them into single ROI and split
650 * them across lSplit for MDP mixer use. The ROI's will be merged again
651 * finally before udpating the panel in the driver. */
652 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
653 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
654 l_roi = getIntersection(temp_roi, l_frame);
655 r_roi = getIntersection(temp_roi, r_frame);
656 }
657
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800658 /* No layer is updating. Still SF wants a refresh. */
659 if(!isValidRect(l_roi) && !isValidRect(r_roi))
660 return;
661
662 l_roi = getSanitizeROI(l_roi, l_frame);
663 r_roi = getSanitizeROI(r_roi, r_frame);
664
665 ctx->listStats[mDpy].lRoi = l_roi;
666 ctx->listStats[mDpy].rRoi = r_roi;
667
668 if(!validateAndApplyROI(ctx, list))
669 resetROI(ctx, mDpy);
670
671 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
672 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
673 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
674 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
675 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
676 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700677}
678
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800679/* Checks for conditions where all the layers marked for MDP comp cannot be
680 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800681bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800682 hwc_display_contents_1_t* list){
683
Saurabh Shahaa236822013-04-24 18:07:26 -0700684 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800685 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800686
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400687 // No Idle fall back, if secure display or secure RGB layers are present or
688 // if there's only a single layer being composed
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -0700689 if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400690 !ctx->listStats[mDpy].secureRGBCount) &&
691 (ctx->listStats[mDpy].numAppLayers != 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700692 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
693 return false;
694 }
695
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800696 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700697 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
698 __FUNCTION__,
699 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800700 return false;
701 }
702
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700703 // if secondary is configuring or Padding round, fall back to video only
704 // composition and release all assigned non VIG pipes from primary.
705 if(isSecondaryConfiguring(ctx)) {
706 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
707 __FUNCTION__);
708 return false;
709 } else if(ctx->isPaddingRound) {
710 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
711 __FUNCTION__,mDpy);
712 return false;
713 }
714
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530715 MDPVersion& mdpHw = MDPVersion::getInstance();
716 if(mDpy > HWC_DISPLAY_PRIMARY &&
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400717 (priDispW > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530718 (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800719 // Disable MDP comp on Secondary when the primary is highres panel and
720 // the secondary is a normal 1080p, because, MDP comp on secondary under
721 // in such usecase, decimation gets used for downscale and there will be
722 // a quality mismatch when there will be a fallback to GPU comp
723 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
724 __FUNCTION__);
725 return false;
726 }
727
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700728 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800729 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700730 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800731 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
732 return false;
733 }
734
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800735 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800736 hwc_layer_1_t* layer = &list->hwLayers[i];
737 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800738
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800739 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700740 if(!canUseRotator(ctx, mDpy)) {
741 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
742 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700743 return false;
744 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800745 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530746
747 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
748 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700749 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530750 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
751 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
752 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800753 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700754
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700755 if(ctx->mAD->isDoable()) {
756 return false;
757 }
758
Saurabh Shahaa236822013-04-24 18:07:26 -0700759 //If all above hard conditions are met we can do full or partial MDP comp.
760 bool ret = false;
761 if(fullMDPComp(ctx, list)) {
762 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700763 } else if(fullMDPCompWithPTOR(ctx, list)) {
764 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700765 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700766 ret = true;
767 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530768
Saurabh Shahaa236822013-04-24 18:07:26 -0700769 return ret;
770}
771
772bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700773
774 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
775 return false;
776
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700777 //Will benefit presentation / secondary-only layer.
778 if((mDpy > HWC_DISPLAY_PRIMARY) &&
779 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
780 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
781 return false;
782 }
783
784 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
785 for(int i = 0; i < numAppLayers; i++) {
786 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700787 if(not mCurrentFrame.drop[i] and
788 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700789 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
790 return false;
791 }
792 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800793
Saurabh Shahaa236822013-04-24 18:07:26 -0700794 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700795 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
796 sizeof(mCurrentFrame.isFBComposed));
797 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
798 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700799
Raj Kamal389d6e32014-08-04 14:43:24 +0530800 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800801 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530802 }
803
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800804 if(!postHeuristicsHandling(ctx, list)) {
805 ALOGD_IF(isDebug(), "post heuristic handling failed");
806 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700807 return false;
808 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700809 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
810 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700811 return true;
812}
813
Sushil Chauhandefd3522014-05-13 18:17:12 -0700814/* Full MDP Composition with Peripheral Tiny Overlap Removal.
815 * MDP bandwidth limitations can be avoided, if the overlap region
816 * covered by the smallest layer at a higher z-order, gets composed
817 * by Copybit on a render buffer, which can be queued to MDP.
818 */
819bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
820 hwc_display_contents_1_t* list) {
821
822 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
823 const int stagesForMDP = min(sMaxPipesPerMixer,
824 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
825
826 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700827 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700828 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
829 return false;
830 }
831
832 // Frame level checks
833 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
834 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
835 isSecurePresent(ctx, mDpy)) {
836 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
837 return false;
838 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700839 // MDP comp checks
840 for(int i = 0; i < numAppLayers; 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 if(not isSupportedForMDPComp(ctx, layer)) {
843 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
844 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700845 }
846 }
847
Sushil Chauhandefd3522014-05-13 18:17:12 -0700848 /* We cannot use this composition mode, if:
849 1. A below layer needs scaling.
850 2. Overlap is not peripheral to display.
851 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700852 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700853 */
854
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700855 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
856 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
857 memset(overlapRect, 0, sizeof(overlapRect));
858 int layerPixelCount, minPixelCount = 0;
859 int numPTORLayersFound = 0;
860 for (int i = numAppLayers-1; (i >= 0 &&
861 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700862 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700863 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700864 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700865 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
866 // PTOR layer should be peripheral and cannot have transform
867 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
868 has90Transform(layer)) {
869 continue;
870 }
871 if((3 * (layerPixelCount + minPixelCount)) >
872 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
873 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
874 continue;
875 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700876 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700877 for (int j = i-1; j >= 0; j--) {
878 // Check if the layers below this layer qualifies for PTOR comp
879 hwc_layer_1_t* layer = &list->hwLayers[j];
880 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700881 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700882 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700883 if (isValidRect(getIntersection(dispFrame, disFrame))) {
884 if (has90Transform(layer) || needsScaling(layer)) {
885 found = false;
886 break;
887 }
888 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700889 }
890 }
891 // Store the minLayer Index
892 if(found) {
893 minLayerIndex[numPTORLayersFound] = i;
894 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
895 minPixelCount += layerPixelCount;
896 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700897 }
898 }
899
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700900 // No overlap layers
901 if (!numPTORLayersFound)
902 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700903
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700904 // Store the displayFrame and the sourceCrops of the layers
905 hwc_rect_t displayFrame[numAppLayers];
906 hwc_rect_t sourceCrop[numAppLayers];
907 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700908 hwc_layer_1_t* layer = &list->hwLayers[i];
909 displayFrame[i] = layer->displayFrame;
910 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700911 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700912
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530913 /**
914 * It's possible that 2 PTOR layers might have overlapping.
915 * In such case, remove the intersection(again if peripheral)
916 * from the lower PTOR layer to avoid overlapping.
917 * If intersection is not on peripheral then compromise
918 * by reducing number of PTOR layers.
919 **/
920 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
921 if(isValidRect(commonRect)) {
922 overlapRect[1] = deductRect(overlapRect[1], commonRect);
923 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
924 }
925
926 ctx->mPtorInfo.count = numPTORLayersFound;
927 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
928 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
929 }
930
931 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
932 // reset PTOR
933 ctx->mPtorInfo.count = 0;
934 if(isValidRect(commonRect)) {
935 // If PTORs are intersecting restore displayframe of PTOR[1]
936 // before returning, as we have modified it above.
937 list->hwLayers[minLayerIndex[1]].displayFrame =
938 displayFrame[minLayerIndex[1]];
939 }
940 return false;
941 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700942 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
943 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
944
Xu Yangcda012c2014-07-30 21:57:21 +0800945 // Store the blending mode, planeAlpha, and transform of PTOR layers
946 int32_t blending[numPTORLayersFound];
947 uint8_t planeAlpha[numPTORLayersFound];
948 uint32_t transform[numPTORLayersFound];
949
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700950 for(int j = 0; j < numPTORLayersFound; j++) {
951 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700952
953 // Update src crop of PTOR layer
954 hwc_layer_1_t* layer = &list->hwLayers[index];
955 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
956 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
957 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
958 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
959
960 // Store & update w, h, format of PTOR layer
961 private_handle_t *hnd = (private_handle_t *)layer->handle;
962 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
963 layerWhf[j] = whf;
964 hnd->width = renderBuf->width;
965 hnd->height = renderBuf->height;
966 hnd->format = renderBuf->format;
967
Xu Yangcda012c2014-07-30 21:57:21 +0800968 // Store & update blending mode, planeAlpha and transform of PTOR layer
969 blending[j] = layer->blending;
970 planeAlpha[j] = layer->planeAlpha;
971 transform[j] = layer->transform;
972 layer->blending = HWC_BLENDING_NONE;
973 layer->planeAlpha = 0xFF;
974 layer->transform = 0;
975
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700976 // Remove overlap from crop & displayFrame of below layers
977 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700978 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700979 if(!isValidRect(getIntersection(layer->displayFrame,
980 overlapRect[j]))) {
981 continue;
982 }
983 // Update layer attributes
984 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
985 hwc_rect_t destRect = deductRect(layer->displayFrame,
986 overlapRect[j]);
987 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
988 layer->transform);
989 layer->sourceCropf.left = (float)srcCrop.left;
990 layer->sourceCropf.top = (float)srcCrop.top;
991 layer->sourceCropf.right = (float)srcCrop.right;
992 layer->sourceCropf.bottom = (float)srcCrop.bottom;
993 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700994 }
995
996 mCurrentFrame.mdpCount = numAppLayers;
997 mCurrentFrame.fbCount = 0;
998 mCurrentFrame.fbZ = -1;
999
1000 for (int j = 0; j < numAppLayers; j++)
1001 mCurrentFrame.isFBComposed[j] = false;
1002
1003 bool result = postHeuristicsHandling(ctx, list);
1004
1005 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001006 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001007 hwc_layer_1_t* layer = &list->hwLayers[i];
1008 layer->displayFrame = displayFrame[i];
1009 layer->sourceCropf.left = (float)sourceCrop[i].left;
1010 layer->sourceCropf.top = (float)sourceCrop[i].top;
1011 layer->sourceCropf.right = (float)sourceCrop[i].right;
1012 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1013 }
1014
Xu Yangcda012c2014-07-30 21:57:21 +08001015 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001016 for (int i = 0; i < numPTORLayersFound; i++) {
1017 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001018 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001019 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1020 hnd->width = layerWhf[i].w;
1021 hnd->height = layerWhf[i].h;
1022 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001023 layer->blending = blending[i];
1024 layer->planeAlpha = planeAlpha[i];
1025 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001026 }
1027
Sushil Chauhandefd3522014-05-13 18:17:12 -07001028 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001029 // reset PTOR
1030 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001031 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001032 } else {
1033 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1034 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001035 }
1036
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001037 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1038 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001039 return result;
1040}
1041
Saurabh Shahaa236822013-04-24 18:07:26 -07001042bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1043{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001044 if(!sEnableMixedMode) {
1045 //Mixed mode is disabled. No need to even try caching.
1046 return false;
1047 }
1048
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001049 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001050 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001051 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001052 cacheBasedComp(ctx, list);
1053 } else {
1054 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001055 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001056 }
1057
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001058 return ret;
1059}
1060
1061bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1062 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001063 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1064 return false;
1065
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001066 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001067 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001068 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001069
1070 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1071 for(int i = 0; i < numAppLayers; i++) {
1072 if(!mCurrentFrame.isFBComposed[i]) {
1073 hwc_layer_1_t* layer = &list->hwLayers[i];
1074 if(not isSupportedForMDPComp(ctx, layer)) {
1075 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1076 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001077 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001078 return false;
1079 }
1080 }
1081 }
1082
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001083 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001084 /* mark secure RGB layers for MDP comp */
1085 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301086 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001087 if(!ret) {
1088 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001089 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001090 return false;
1091 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001092
1093 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001094
Raj Kamal389d6e32014-08-04 14:43:24 +05301095 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001096 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301097 }
1098
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001099 //Will benefit cases where a video has non-updating background.
1100 if((mDpy > HWC_DISPLAY_PRIMARY) and
1101 (mdpCount > MAX_SEC_LAYERS)) {
1102 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001103 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001104 return false;
1105 }
1106
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001107 if(!postHeuristicsHandling(ctx, list)) {
1108 ALOGD_IF(isDebug(), "post heuristic handling failed");
1109 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001110 return false;
1111 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001112 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1113 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001114
Saurabh Shahaa236822013-04-24 18:07:26 -07001115 return true;
1116}
1117
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001118bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001119 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001120 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1121 return false;
1122
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001123 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001124 return false;
1125 }
1126
Saurabh Shahb772ae32013-11-18 15:40:02 -08001127 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001128 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1129 const int stagesForMDP = min(sMaxPipesPerMixer,
1130 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001131
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001132 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1133 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1134 int lastMDPSupportedIndex = numAppLayers;
1135 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001136
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001137 //Find the minimum MDP batch size
1138 for(int i = 0; i < numAppLayers;i++) {
1139 if(mCurrentFrame.drop[i]) {
1140 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001141 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001142 }
1143 hwc_layer_1_t* layer = &list->hwLayers[i];
1144 if(not isSupportedForMDPComp(ctx, layer)) {
1145 lastMDPSupportedIndex = i;
1146 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1147 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001148 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001149 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001150 }
1151
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001152 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1153 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1154 mCurrentFrame.dropCount);
1155
1156 //Start at a point where the fb batch should at least have 2 layers, for
1157 //this mode to be justified.
1158 while(fbBatchSize < 2) {
1159 ++fbBatchSize;
1160 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001161 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001162
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001163 //If there are no layers for MDP, this mode doesnt make sense.
1164 if(mdpBatchSize < 1) {
1165 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1166 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001167 return false;
1168 }
1169
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001170 mCurrentFrame.reset(numAppLayers);
1171
1172 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1173 while(mdpBatchSize > 0) {
1174 //Mark layers for MDP comp
1175 int mdpBatchLeft = mdpBatchSize;
1176 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1177 if(mCurrentFrame.drop[i]) {
1178 continue;
1179 }
1180 mCurrentFrame.isFBComposed[i] = false;
1181 --mdpBatchLeft;
1182 }
1183
1184 mCurrentFrame.fbZ = mdpBatchSize;
1185 mCurrentFrame.fbCount = fbBatchSize;
1186 mCurrentFrame.mdpCount = mdpBatchSize;
1187
1188 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1189 __FUNCTION__, mdpBatchSize, fbBatchSize,
1190 mCurrentFrame.dropCount);
1191
1192 if(postHeuristicsHandling(ctx, list)) {
1193 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001194 __FUNCTION__);
1195 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1196 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001197 return true;
1198 }
1199
1200 reset(ctx);
1201 --mdpBatchSize;
1202 ++fbBatchSize;
1203 }
1204
1205 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001206}
1207
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001208bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301209 if(mDpy or isSecurePresent(ctx, mDpy) or
1210 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001211 return false;
1212 }
1213 return true;
1214}
1215
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001216bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1217 hwc_display_contents_1_t* list){
1218 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1219 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1220 mDpy ) {
1221 return false;
1222 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001223 if(ctx->listStats[mDpy].secureUI)
1224 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001225 return true;
1226}
1227
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001228bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1229 hwc_display_contents_1_t* list) {
1230 const bool secureOnly = true;
1231 return videoOnlyComp(ctx, list, not secureOnly) or
1232 videoOnlyComp(ctx, list, secureOnly);
1233}
1234
1235bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001236 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001237 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1238 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001239 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001240
Saurabh Shahaa236822013-04-24 18:07:26 -07001241 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001242 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001243 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001244 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001245
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001246 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1247 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001248 return false;
1249 }
1250
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001251 /* Bail out if we are processing only secured video layers
1252 * and we dont have any */
1253 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001254 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001255 return false;
1256 }
1257
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001258 if(mCurrentFrame.fbCount)
1259 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001260
Raj Kamal389d6e32014-08-04 14:43:24 +05301261 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001262 adjustForSourceSplit(ctx, list);
1263 }
1264
1265 if(!postHeuristicsHandling(ctx, list)) {
1266 ALOGD_IF(isDebug(), "post heuristic handling failed");
1267 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001268 return false;
1269 }
1270
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001271 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1272 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001273 return true;
1274}
1275
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001276/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1277bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1278 hwc_display_contents_1_t* list) {
1279 const bool secureOnly = true;
1280 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1281 mdpOnlyLayersComp(ctx, list, secureOnly);
1282
1283}
1284
1285bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1286 hwc_display_contents_1_t* list, bool secureOnly) {
1287
1288 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1289 return false;
1290
1291 /* Bail out if we are processing only secured video layers
1292 * and we dont have any */
1293 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1294 reset(ctx);
1295 return false;
1296 }
1297
1298 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1299 mCurrentFrame.reset(numAppLayers);
1300 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1301
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001302 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001303 /* mark secure RGB layers for MDP comp */
1304 updateSecureRGB(ctx, list);
1305
1306 if(mCurrentFrame.mdpCount == 0) {
1307 reset(ctx);
1308 return false;
1309 }
1310
1311 /* find the maximum batch of layers to be marked for framebuffer */
1312 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1313 if(!ret) {
1314 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1315 reset(ctx);
1316 return false;
1317 }
1318
1319 if(sEnableYUVsplit){
1320 adjustForSourceSplit(ctx, list);
1321 }
1322
1323 if(!postHeuristicsHandling(ctx, list)) {
1324 ALOGD_IF(isDebug(), "post heuristic handling failed");
1325 reset(ctx);
1326 return false;
1327 }
1328
1329 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1330 __FUNCTION__);
1331 return true;
1332}
1333
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001334/* Checks for conditions where YUV layers cannot be bypassed */
1335bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001336 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001337 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001338 return false;
1339 }
1340
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001341 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001342 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1343 return false;
1344 }
1345
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001346 if(isSecuring(ctx, layer)) {
1347 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1348 return false;
1349 }
1350
Saurabh Shah4fdde762013-04-30 18:47:33 -07001351 if(!isValidDimension(ctx, layer)) {
1352 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1353 __FUNCTION__);
1354 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001355 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001356
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001357 if(layer->planeAlpha < 0xFF) {
1358 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1359 in video only mode",
1360 __FUNCTION__);
1361 return false;
1362 }
1363
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001364 return true;
1365}
1366
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001367/* Checks for conditions where Secure RGB layers cannot be bypassed */
1368bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1369 if(isSkipLayer(layer)) {
1370 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1371 __FUNCTION__, mDpy);
1372 return false;
1373 }
1374
1375 if(isSecuring(ctx, layer)) {
1376 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1377 return false;
1378 }
1379
1380 if(not isSupportedForMDPComp(ctx, layer)) {
1381 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1382 __FUNCTION__);
1383 return false;
1384 }
1385 return true;
1386}
1387
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301388/* starts at fromIndex and check for each layer to find
1389 * if it it has overlapping with any Updating layer above it in zorder
1390 * till the end of the batch. returns true if it finds any intersection */
1391bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1392 int fromIndex, int toIndex) {
1393 for(int i = fromIndex; i < toIndex; i++) {
1394 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1395 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1396 return false;
1397 }
1398 }
1399 }
1400 return true;
1401}
1402
1403/* Checks if given layer at targetLayerIndex has any
1404 * intersection with all the updating layers in beween
1405 * fromIndex and toIndex. Returns true if it finds intersectiion */
1406bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1407 int fromIndex, int toIndex, int targetLayerIndex) {
1408 for(int i = fromIndex; i <= toIndex; i++) {
1409 if(!mCurrentFrame.isFBComposed[i]) {
1410 if(areLayersIntersecting(&list->hwLayers[i],
1411 &list->hwLayers[targetLayerIndex])) {
1412 return true;
1413 }
1414 }
1415 }
1416 return false;
1417}
1418
1419int MDPComp::getBatch(hwc_display_contents_1_t* list,
1420 int& maxBatchStart, int& maxBatchEnd,
1421 int& maxBatchCount) {
1422 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301423 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001424 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301425 while (i < mCurrentFrame.layerCount) {
1426 int batchCount = 0;
1427 int batchStart = i;
1428 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001429 /* Adjust batch Z order with the dropped layers so far */
1430 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301431 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301432 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301433 while(i < mCurrentFrame.layerCount) {
1434 if(!mCurrentFrame.isFBComposed[i]) {
1435 if(!batchCount) {
1436 i++;
1437 break;
1438 }
1439 updatingLayersAbove++;
1440 i++;
1441 continue;
1442 } else {
1443 if(mCurrentFrame.drop[i]) {
1444 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001445 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301446 continue;
1447 } else if(updatingLayersAbove <= 0) {
1448 batchCount++;
1449 batchEnd = i;
1450 i++;
1451 continue;
1452 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1453
1454 // We have a valid updating layer already. If layer-i not
1455 // have overlapping with all updating layers in between
1456 // batch-start and i, then we can add layer i to batch.
1457 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1458 batchCount++;
1459 batchEnd = i;
1460 i++;
1461 continue;
1462 } else if(canPushBatchToTop(list, batchStart, i)) {
1463 //If All the non-updating layers with in this batch
1464 //does not have intersection with the updating layers
1465 //above in z-order, then we can safely move the batch to
1466 //higher z-order. Increment fbZ as it is moving up.
1467 if( firstZReverseIndex < 0) {
1468 firstZReverseIndex = i;
1469 }
1470 batchCount++;
1471 batchEnd = i;
1472 fbZ += updatingLayersAbove;
1473 i++;
1474 updatingLayersAbove = 0;
1475 continue;
1476 } else {
1477 //both failed.start the loop again from here.
1478 if(firstZReverseIndex >= 0) {
1479 i = firstZReverseIndex;
1480 }
1481 break;
1482 }
1483 }
1484 }
1485 }
1486 if(batchCount > maxBatchCount) {
1487 maxBatchCount = batchCount;
1488 maxBatchStart = batchStart;
1489 maxBatchEnd = batchEnd;
1490 fbZOrder = fbZ;
1491 }
1492 }
1493 return fbZOrder;
1494}
1495
1496bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1497 hwc_display_contents_1_t* list) {
1498 /* Idea is to keep as many non-updating(cached) layers in FB and
1499 * send rest of them through MDP. This is done in 2 steps.
1500 * 1. Find the maximum contiguous batch of non-updating layers.
1501 * 2. See if we can improve this batch size for caching by adding
1502 * opaque layers around the batch, if they don't have
1503 * any overlapping with the updating layers in between.
1504 * NEVER mark an updating layer for caching.
1505 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001506
1507 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001508 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001509 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301510 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001511
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001512 /* Nothing is cached. No batching needed */
1513 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001514 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001515 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001516
1517 /* No MDP comp layers, try to use other comp modes */
1518 if(mCurrentFrame.mdpCount == 0) {
1519 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001520 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001521
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301522 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001523
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301524 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001525 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001526 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001527 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301528 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001529 if(!mCurrentFrame.drop[i]){
1530 //If an unsupported layer is being attempted to
1531 //be pulled out we should fail
1532 if(not isSupportedForMDPComp(ctx, layer)) {
1533 return false;
1534 }
1535 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001536 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001537 }
1538 }
1539
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301540 // update the frame data
1541 mCurrentFrame.fbZ = fbZ;
1542 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001543 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001544 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001545
1546 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301547 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001548
1549 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001550}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001551
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001552void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001553 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001554 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001555 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001556
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001557 for(int i = 0; i < numAppLayers; i++) {
1558 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001559 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001560 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001561 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001562 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001563 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001564 }
1565 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001566
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001567 frame.fbCount = fbCount;
1568 frame.mdpCount = frame.layerCount - frame.fbCount
1569 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001570
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001571 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1572 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001573}
1574
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001575void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001576 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001577 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1578 for(int index = 0;index < nYuvCount; index++){
1579 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1580 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1581
1582 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001583 if(!frame.isFBComposed[nYuvIndex]) {
1584 frame.isFBComposed[nYuvIndex] = true;
1585 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001586 }
1587 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001588 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001589 private_handle_t *hnd = (private_handle_t *)layer->handle;
1590 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001591 frame.isFBComposed[nYuvIndex] = false;
1592 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001593 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001594 }
1595 }
1596 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001597
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001598 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1599 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001600}
1601
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001602void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1603 hwc_display_contents_1_t* list) {
1604 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1605 for(int index = 0;index < nSecureRGBCount; index++){
1606 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1607 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1608
1609 if(!isSecureRGBDoable(ctx, layer)) {
1610 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1611 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1612 mCurrentFrame.fbCount++;
1613 }
1614 } else {
1615 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1616 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1617 mCurrentFrame.fbCount--;
1618 }
1619 }
1620 }
1621
1622 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1623 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1624 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1625 mCurrentFrame.fbCount);
1626}
1627
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001628hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1629 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001630 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001631
1632 /* Update only the region of FB needed for composition */
1633 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1634 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1635 hwc_layer_1_t* layer = &list->hwLayers[i];
1636 hwc_rect_t dst = layer->displayFrame;
1637 fbRect = getUnion(fbRect, dst);
1638 }
1639 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001640 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001641 return fbRect;
1642}
1643
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001644bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1645 hwc_display_contents_1_t* list) {
1646
1647 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001648 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001649 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1650 return false;
1651 }
1652
1653 //Limitations checks
1654 if(!hwLimitationsCheck(ctx, list)) {
1655 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1656 return false;
1657 }
1658
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001659 //Configure framebuffer first if applicable
1660 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001661 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001662 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1663 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001664 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1665 __FUNCTION__);
1666 return false;
1667 }
1668 }
1669
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001670 mCurrentFrame.map();
1671
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001672 if(!allocLayerPipes(ctx, list)) {
1673 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001674 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001675 }
1676
1677 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001678 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001679 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001680 int mdpIndex = mCurrentFrame.layerToMDP[index];
1681 hwc_layer_1_t* layer = &list->hwLayers[index];
1682
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301683 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1684 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1685 mdpNextZOrder++;
1686 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001687 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1688 cur_pipe->zOrder = mdpNextZOrder++;
1689
radhakrishnac9a67412013-09-25 17:40:42 +05301690 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301691 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301692 if(configure4k2kYuv(ctx, layer,
1693 mCurrentFrame.mdpToLayer[mdpIndex])
1694 != 0 ){
1695 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1696 for layer %d",__FUNCTION__, index);
1697 return false;
1698 }
1699 else{
1700 mdpNextZOrder++;
1701 }
1702 continue;
1703 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001704 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1705 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301706 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001707 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001708 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001709 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001710 }
1711
Saurabh Shaha36be922013-12-16 18:18:39 -08001712 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1713 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1714 ,__FUNCTION__, mDpy);
1715 return false;
1716 }
1717
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001718 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001719 return true;
1720}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001721
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001722bool MDPComp::resourceCheck(hwc_context_t* ctx,
1723 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001724 const bool fbUsed = mCurrentFrame.fbCount;
1725 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1726 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1727 return false;
1728 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001729 // Init rotCount to number of rotate sessions used by other displays
1730 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1731 // Count the number of rotator sessions required for current display
1732 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1733 if(!mCurrentFrame.isFBComposed[index]) {
1734 hwc_layer_1_t* layer = &list->hwLayers[index];
1735 private_handle_t *hnd = (private_handle_t *)layer->handle;
1736 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1737 rotCount++;
1738 }
1739 }
1740 }
1741 // if number of layers to rotate exceeds max rotator sessions, bail out.
1742 if(rotCount > RotMgr::MAX_ROT_SESS) {
1743 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1744 __FUNCTION__, mDpy);
1745 return false;
1746 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001747 return true;
1748}
1749
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301750bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1751 hwc_display_contents_1_t* list) {
1752
1753 //A-family hw limitation:
1754 //If a layer need alpha scaling, MDP can not support.
1755 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1756 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1757 if(!mCurrentFrame.isFBComposed[i] &&
1758 isAlphaScaled( &list->hwLayers[i])) {
1759 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1760 return false;
1761 }
1762 }
1763 }
1764
1765 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1766 //If multiple layers requires downscaling and also they are overlapping
1767 //fall back to GPU since MDSS can not handle it.
1768 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1769 qdutils::MDPVersion::getInstance().is8x26()) {
1770 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1771 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1772 if(!mCurrentFrame.isFBComposed[i] &&
1773 isDownscaleRequired(botLayer)) {
1774 //if layer-i is marked for MDP and needs downscaling
1775 //check if any MDP layer on top of i & overlaps with layer-i
1776 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1777 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1778 if(!mCurrentFrame.isFBComposed[j] &&
1779 isDownscaleRequired(topLayer)) {
1780 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1781 topLayer->displayFrame);
1782 if(isValidRect(r))
1783 return false;
1784 }
1785 }
1786 }
1787 }
1788 }
1789 return true;
1790}
1791
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001792int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001793 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001794 char property[PROPERTY_VALUE_MAX];
1795
Raj Kamal4393eaa2014-06-06 13:45:20 +05301796 if(!ctx || !list) {
1797 ALOGE("%s: Invalid context or list",__FUNCTION__);
1798 mCachedFrame.reset();
1799 return -1;
1800 }
1801
1802 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001803 if(mDpy == HWC_DISPLAY_PRIMARY) {
1804 sSimulationFlags = 0;
1805 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1806 int currentFlags = atoi(property);
1807 if(currentFlags != sSimulationFlags) {
1808 sSimulationFlags = currentFlags;
1809 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1810 sSimulationFlags, sSimulationFlags);
1811 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001812 }
1813 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001814 // reset PTOR
1815 if(!mDpy)
1816 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001817
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301818 //Do not cache the information for next draw cycle.
1819 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1820 ALOGI("%s: Unsupported layer count for mdp composition",
1821 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001822 mCachedFrame.reset();
1823 return -1;
1824 }
1825
Saurabh Shahb39f8152013-08-22 10:21:44 -07001826 //reset old data
1827 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001828 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1829 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301830
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001831 // Detect the start of animation and fall back to GPU only once to cache
1832 // all the layers in FB and display FB content untill animation completes.
1833 if(ctx->listStats[mDpy].isDisplayAnimating) {
1834 mCurrentFrame.needsRedraw = false;
1835 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1836 mCurrentFrame.needsRedraw = true;
1837 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1838 }
1839 setMDPCompLayerFlags(ctx, list);
1840 mCachedFrame.updateCounts(mCurrentFrame);
1841 ret = -1;
1842 return ret;
1843 } else {
1844 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1845 }
1846
Saurabh Shahb39f8152013-08-22 10:21:44 -07001847 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001848 if(isFrameDoable(ctx)) {
1849 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001850
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001851 // if tryFullFrame fails, try to push all video and secure RGB layers
1852 // to MDP for composition.
1853 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
1854 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301855 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001856 setMDPCompLayerFlags(ctx, list);
1857 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001858 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001859 reset(ctx);
1860 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1861 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001862 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001863 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1864 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001865 }
1866 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001867 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1868 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001869 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001870 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001871
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001872 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001873 ALOGD("GEOMETRY change: %d",
1874 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001875 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001876 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001877 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001878 }
1879
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001880#ifdef DYNAMIC_FPS
1881 //For primary display, set the dynamic refreshrate
1882 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported()) {
1883 FrameInfo frame;
1884 frame.reset(mCurrentFrame.layerCount);
1885 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
1886 __FUNCTION__);
1887 updateLayerCache(ctx, list, frame);
1888 updateYUV(ctx, list, false /*secure only*/, frame);
1889 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1890 //Set the new fresh rate, if there is only one updating YUV layer
1891 //or there is one single RGB layer with this request
1892 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1893 (frame.layerCount == 1)) {
1894 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1895 }
1896 setRefreshRate(ctx, mDpy, refreshRate);
1897 }
1898#endif
1899
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001900 mCachedFrame.cacheAll(list);
1901 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001902 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001903}
1904
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001905bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301906
1907 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301908 int mdpIndex = mCurrentFrame.layerToMDP[index];
1909 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1910 info.pipeInfo = new MdpYUVPipeInfo;
1911 info.rot = NULL;
1912 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301913
1914 pipe_info.lIndex = ovutils::OV_INVALID;
1915 pipe_info.rIndex = ovutils::OV_INVALID;
1916
Saurabh Shahc62f3982014-03-05 14:28:26 -08001917 Overlay::PipeSpecs pipeSpecs;
1918 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1919 pipeSpecs.needsScaling = true;
1920 pipeSpecs.dpy = mDpy;
1921 pipeSpecs.fb = false;
1922
1923 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301924 if(pipe_info.lIndex == ovutils::OV_INVALID){
1925 bRet = false;
1926 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1927 __FUNCTION__);
1928 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001929 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301930 if(pipe_info.rIndex == ovutils::OV_INVALID){
1931 bRet = false;
1932 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1933 __FUNCTION__);
1934 }
1935 return bRet;
1936}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001937
1938int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1939 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001940 if (ctx->mPtorInfo.isActive()) {
1941 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001942 if (fd < 0) {
1943 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001944 }
1945 }
1946 return fd;
1947}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001948//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001949
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001950void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301951 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001952 //If 4k2k Yuv layer split is possible, and if
1953 //fbz is above 4k2k layer, increment fb zorder by 1
1954 //as we split 4k2k layer and increment zorder for right half
1955 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07001956 if(!ctx)
1957 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001958 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301959 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1960 index++) {
1961 if(!mCurrentFrame.isFBComposed[index]) {
1962 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1963 mdpNextZOrder++;
1964 }
1965 mdpNextZOrder++;
1966 hwc_layer_1_t* layer = &list->hwLayers[index];
1967 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301968 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301969 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1970 mCurrentFrame.fbZ += 1;
1971 mdpNextZOrder++;
1972 //As we split 4kx2k yuv layer and program to 2 VG pipes
1973 //(if available) increase mdpcount by 1.
1974 mCurrentFrame.mdpCount++;
1975 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001976 }
1977 }
1978 }
radhakrishnac9a67412013-09-25 17:40:42 +05301979}
1980
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001981/*
1982 * Configures pipe(s) for MDP composition
1983 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001984int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001985 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001986 MdpPipeInfoNonSplit& mdp_info =
1987 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001988 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1989 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08001990 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001991
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001992 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1993 __FUNCTION__, layer, zOrder, dest);
1994
Saurabh Shah2c8ad052014-08-15 13:27:46 -07001995 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001996 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001997}
1998
Saurabh Shah88e4d272013-09-03 13:31:29 -07001999bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002000 hwc_display_contents_1_t* list) {
2001 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002002
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002003 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002004
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002005 hwc_layer_1_t* layer = &list->hwLayers[index];
2006 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302007 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002008 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302009 continue;
2010 }
2011 }
2012
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002013 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002014 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002015 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002016 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002017 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002018
Saurabh Shahc62f3982014-03-05 14:28:26 -08002019 Overlay::PipeSpecs pipeSpecs;
2020 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2021 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2022 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2023 (qdutils::MDPVersion::getInstance().is8x26() and
2024 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2025 pipeSpecs.dpy = mDpy;
2026 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002027 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002028
Saurabh Shahc62f3982014-03-05 14:28:26 -08002029 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2030
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002031 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002032 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002033 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002034 }
2035 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002036 return true;
2037}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002038
radhakrishnac9a67412013-09-25 17:40:42 +05302039int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2040 PipeLayerPair& PipeLayerPair) {
2041 MdpYUVPipeInfo& mdp_info =
2042 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2043 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302044 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2045 eDest lDest = mdp_info.lIndex;
2046 eDest rDest = mdp_info.rIndex;
2047
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002048 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302049 lDest, rDest, &PipeLayerPair.rot);
2050}
2051
Saurabh Shah88e4d272013-09-03 13:31:29 -07002052bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002053
Raj Kamal4393eaa2014-06-06 13:45:20 +05302054 if(!isEnabled() or !mModeOn) {
2055 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302056 return true;
2057 }
2058
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002059 // Set the Handle timeout to true for MDP or MIXED composition.
2060 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2061 sHandleTimeout = true;
2062 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002063
2064 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002065 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002066
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002067 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2068 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002069 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002070 if(mCurrentFrame.isFBComposed[i]) continue;
2071
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002072 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002073 private_handle_t *hnd = (private_handle_t *)layer->handle;
2074 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002075 if (!(layer->flags & HWC_COLOR_FILL)) {
2076 ALOGE("%s handle null", __FUNCTION__);
2077 return false;
2078 }
2079 // No PLAY for Color layer
2080 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2081 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002082 }
2083
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002084 int mdpIndex = mCurrentFrame.layerToMDP[i];
2085
Raj Kamal389d6e32014-08-04 14:43:24 +05302086 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302087 {
2088 MdpYUVPipeInfo& pipe_info =
2089 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2090 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2091 ovutils::eDest indexL = pipe_info.lIndex;
2092 ovutils::eDest indexR = pipe_info.rIndex;
2093 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302094 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302095 if(rot) {
2096 rot->queueBuffer(fd, offset);
2097 fd = rot->getDstMemId();
2098 offset = rot->getDstOffset();
2099 }
2100 if(indexL != ovutils::OV_INVALID) {
2101 ovutils::eDest destL = (ovutils::eDest)indexL;
2102 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2103 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2104 if (!ov.queueBuffer(fd, offset, destL)) {
2105 ALOGE("%s: queueBuffer failed for display:%d",
2106 __FUNCTION__, mDpy);
2107 return false;
2108 }
2109 }
2110
2111 if(indexR != ovutils::OV_INVALID) {
2112 ovutils::eDest destR = (ovutils::eDest)indexR;
2113 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2114 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2115 if (!ov.queueBuffer(fd, offset, destR)) {
2116 ALOGE("%s: queueBuffer failed for display:%d",
2117 __FUNCTION__, mDpy);
2118 return false;
2119 }
2120 }
2121 }
2122 else{
2123 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002124 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302125 ovutils::eDest dest = pipe_info.index;
2126 if(dest == ovutils::OV_INVALID) {
2127 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002128 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302129 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002130
radhakrishnac9a67412013-09-25 17:40:42 +05302131 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2132 continue;
2133 }
2134
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002135 int fd = hnd->fd;
2136 uint32_t offset = (uint32_t)hnd->offset;
2137 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2138 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002139 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002140 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002141 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002142 }
2143
radhakrishnac9a67412013-09-25 17:40:42 +05302144 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2145 using pipe: %d", __FUNCTION__, layer,
2146 hnd, dest );
2147
radhakrishnac9a67412013-09-25 17:40:42 +05302148 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2149 if(rot) {
2150 if(!rot->queueBuffer(fd, offset))
2151 return false;
2152 fd = rot->getDstMemId();
2153 offset = rot->getDstOffset();
2154 }
2155
2156 if (!ov.queueBuffer(fd, offset, dest)) {
2157 ALOGE("%s: queueBuffer failed for display:%d ",
2158 __FUNCTION__, mDpy);
2159 return false;
2160 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002161 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002162
2163 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002164 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002165 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002166}
2167
Saurabh Shah88e4d272013-09-03 13:31:29 -07002168//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002169
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002170void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302171 hwc_display_contents_1_t* list){
2172 //if 4kx2k yuv layer is totally present in either in left half
2173 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302174 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302175 if(mCurrentFrame.fbZ >= 0) {
2176 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2177 index++) {
2178 if(!mCurrentFrame.isFBComposed[index]) {
2179 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2180 mdpNextZOrder++;
2181 }
2182 mdpNextZOrder++;
2183 hwc_layer_1_t* layer = &list->hwLayers[index];
2184 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302185 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302186 hwc_rect_t dst = layer->displayFrame;
2187 if((dst.left > lSplit) || (dst.right < lSplit)) {
2188 mCurrentFrame.mdpCount += 1;
2189 }
2190 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2191 mCurrentFrame.fbZ += 1;
2192 mdpNextZOrder++;
2193 }
2194 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002195 }
radhakrishnac9a67412013-09-25 17:40:42 +05302196 }
2197}
2198
Saurabh Shah88e4d272013-09-03 13:31:29 -07002199bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002200 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002201
Saurabh Shahc62f3982014-03-05 14:28:26 -08002202 const int lSplit = getLeftSplit(ctx, mDpy);
2203 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002204 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002205 pipe_info.lIndex = ovutils::OV_INVALID;
2206 pipe_info.rIndex = ovutils::OV_INVALID;
2207
Saurabh Shahc62f3982014-03-05 14:28:26 -08002208 Overlay::PipeSpecs pipeSpecs;
2209 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2210 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2211 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2212 pipeSpecs.dpy = mDpy;
2213 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2214 pipeSpecs.fb = false;
2215
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002216 // Acquire pipe only for the updating half
2217 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2218 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2219
2220 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002221 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002222 if(pipe_info.lIndex == ovutils::OV_INVALID)
2223 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002224 }
2225
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002226 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002227 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2228 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002229 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002230 return false;
2231 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002232
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002233 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002234}
2235
Saurabh Shah88e4d272013-09-03 13:31:29 -07002236bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002237 hwc_display_contents_1_t* list) {
2238 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002239
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002240 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002241
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002242 hwc_layer_1_t* layer = &list->hwLayers[index];
2243 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302244 hwc_rect_t dst = layer->displayFrame;
2245 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302246 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302247 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002248 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302249 continue;
2250 }
2251 }
2252 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002253 int mdpIndex = mCurrentFrame.layerToMDP[index];
2254 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002255 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002256 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002257 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002258
Saurabh Shahc62f3982014-03-05 14:28:26 -08002259 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2260 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2261 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002262 return false;
2263 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002264 }
2265 return true;
2266}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002267
radhakrishnac9a67412013-09-25 17:40:42 +05302268int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2269 PipeLayerPair& PipeLayerPair) {
2270 const int lSplit = getLeftSplit(ctx, mDpy);
2271 hwc_rect_t dst = layer->displayFrame;
2272 if((dst.left > lSplit)||(dst.right < lSplit)){
2273 MdpYUVPipeInfo& mdp_info =
2274 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2275 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302276 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2277 eDest lDest = mdp_info.lIndex;
2278 eDest rDest = mdp_info.rIndex;
2279
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002280 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302281 lDest, rDest, &PipeLayerPair.rot);
2282 }
2283 else{
2284 return configure(ctx, layer, PipeLayerPair);
2285 }
2286}
2287
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002288/*
2289 * Configures pipe(s) for MDP composition
2290 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002291int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002292 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002293 MdpPipeInfoSplit& mdp_info =
2294 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002295 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002296 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2297 eDest lDest = mdp_info.lIndex;
2298 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002299
2300 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2301 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2302
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002303 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002304 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002305}
2306
Saurabh Shah88e4d272013-09-03 13:31:29 -07002307bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002308
Raj Kamal4393eaa2014-06-06 13:45:20 +05302309 if(!isEnabled() or !mModeOn) {
2310 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302311 return true;
2312 }
2313
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002314 // Set the Handle timeout to true for MDP or MIXED composition.
2315 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2316 sHandleTimeout = true;
2317 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002318
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002319 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002320 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002321
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002322 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2323 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002324 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002325 if(mCurrentFrame.isFBComposed[i]) continue;
2326
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002327 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002328 private_handle_t *hnd = (private_handle_t *)layer->handle;
2329 if(!hnd) {
2330 ALOGE("%s handle null", __FUNCTION__);
2331 return false;
2332 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002333
2334 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2335 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002336 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002337
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002338 int mdpIndex = mCurrentFrame.layerToMDP[i];
2339
Raj Kamal389d6e32014-08-04 14:43:24 +05302340 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302341 {
2342 MdpYUVPipeInfo& pipe_info =
2343 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2344 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2345 ovutils::eDest indexL = pipe_info.lIndex;
2346 ovutils::eDest indexR = pipe_info.rIndex;
2347 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302348 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302349 if(rot) {
2350 rot->queueBuffer(fd, offset);
2351 fd = rot->getDstMemId();
2352 offset = rot->getDstOffset();
2353 }
2354 if(indexL != ovutils::OV_INVALID) {
2355 ovutils::eDest destL = (ovutils::eDest)indexL;
2356 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2357 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2358 if (!ov.queueBuffer(fd, offset, destL)) {
2359 ALOGE("%s: queueBuffer failed for display:%d",
2360 __FUNCTION__, mDpy);
2361 return false;
2362 }
2363 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002364
radhakrishnac9a67412013-09-25 17:40:42 +05302365 if(indexR != ovutils::OV_INVALID) {
2366 ovutils::eDest destR = (ovutils::eDest)indexR;
2367 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2368 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2369 if (!ov.queueBuffer(fd, offset, destR)) {
2370 ALOGE("%s: queueBuffer failed for display:%d",
2371 __FUNCTION__, mDpy);
2372 return false;
2373 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002374 }
2375 }
radhakrishnac9a67412013-09-25 17:40:42 +05302376 else{
2377 MdpPipeInfoSplit& pipe_info =
2378 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2379 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002380
radhakrishnac9a67412013-09-25 17:40:42 +05302381 ovutils::eDest indexL = pipe_info.lIndex;
2382 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002383
radhakrishnac9a67412013-09-25 17:40:42 +05302384 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002385 uint32_t offset = (uint32_t)hnd->offset;
2386 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2387 if (!mDpy && (index != -1)) {
2388 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2389 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002390 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002391 }
radhakrishnac9a67412013-09-25 17:40:42 +05302392
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002393 if(ctx->mAD->draw(ctx, fd, offset)) {
2394 fd = ctx->mAD->getDstFd();
2395 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002396 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002397
radhakrishnac9a67412013-09-25 17:40:42 +05302398 if(rot) {
2399 rot->queueBuffer(fd, offset);
2400 fd = rot->getDstMemId();
2401 offset = rot->getDstOffset();
2402 }
2403
2404 //************* play left mixer **********
2405 if(indexL != ovutils::OV_INVALID) {
2406 ovutils::eDest destL = (ovutils::eDest)indexL;
2407 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2408 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2409 if (!ov.queueBuffer(fd, offset, destL)) {
2410 ALOGE("%s: queueBuffer failed for left mixer",
2411 __FUNCTION__);
2412 return false;
2413 }
2414 }
2415
2416 //************* play right mixer **********
2417 if(indexR != ovutils::OV_INVALID) {
2418 ovutils::eDest destR = (ovutils::eDest)indexR;
2419 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2420 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2421 if (!ov.queueBuffer(fd, offset, destR)) {
2422 ALOGE("%s: queueBuffer failed for right mixer",
2423 __FUNCTION__);
2424 return false;
2425 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002426 }
2427 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002428
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002429 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2430 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002431
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002432 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002433}
Saurabh Shahab47c692014-02-12 18:45:57 -08002434
2435//================MDPCompSrcSplit==============================================
2436bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002437 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002438 private_handle_t *hnd = (private_handle_t *)layer->handle;
2439 hwc_rect_t dst = layer->displayFrame;
2440 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2441 pipe_info.lIndex = ovutils::OV_INVALID;
2442 pipe_info.rIndex = ovutils::OV_INVALID;
2443
2444 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2445 //should have a higher priority than the right one. Pipe priorities are
2446 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002447
Saurabh Shahc62f3982014-03-05 14:28:26 -08002448 Overlay::PipeSpecs pipeSpecs;
2449 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2450 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2451 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2452 pipeSpecs.dpy = mDpy;
2453 pipeSpecs.fb = false;
2454
Saurabh Shahab47c692014-02-12 18:45:57 -08002455 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002456 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002457 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002458 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002459 }
2460
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002461 /* Use 2 pipes IF
2462 a) Layer's crop width is > 2048 or
2463 b) Layer's dest width > 2048 or
2464 c) On primary, driver has indicated with caps to split always. This is
2465 based on an empirically derived value of panel height. Applied only
2466 if the layer's width is > mixer's width
2467 */
2468
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302469 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002470 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302471 mdpHw.isSrcSplitAlways();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002472 int lSplit = getLeftSplit(ctx, mDpy);
2473 int dstWidth = dst.right - dst.left;
2474 int cropWidth = crop.right - crop.left;
2475
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002476 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2477 //pipe line length, we are still using 2 pipes. This is fine just because
2478 //this is source split where destination doesn't matter. Evaluate later to
2479 //see if going through all the calcs to save a pipe is worth it
Naseer Ahmed9eb5e092014-09-25 13:24:44 -04002480 if(dstWidth > (int) mdpHw.getMaxMixerWidth() or
2481 cropWidth > (int) mdpHw.getMaxMixerWidth() or
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002482 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002483 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002484 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002485 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002486 }
2487
2488 // Return values
2489 // 1 Left pipe is higher priority, do nothing.
2490 // 0 Pipes of same priority.
2491 //-1 Right pipe is of higher priority, needs swap.
2492 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2493 pipe_info.rIndex) == -1) {
2494 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002495 }
2496 }
2497
2498 return true;
2499}
2500
Saurabh Shahab47c692014-02-12 18:45:57 -08002501int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2502 PipeLayerPair& PipeLayerPair) {
2503 private_handle_t *hnd = (private_handle_t *)layer->handle;
2504 if(!hnd) {
2505 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2506 return -1;
2507 }
2508 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2509 MdpPipeInfoSplit& mdp_info =
2510 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2511 Rotator **rot = &PipeLayerPair.rot;
2512 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002513 eDest lDest = mdp_info.lIndex;
2514 eDest rDest = mdp_info.rIndex;
2515 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2516 hwc_rect_t dst = layer->displayFrame;
2517 int transform = layer->transform;
2518 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002519 int rotFlags = ROT_FLAGS_NONE;
2520 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2521 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2522
2523 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2524 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2525
2526 // Handle R/B swap
2527 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2528 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2529 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2530 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2531 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2532 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002533 /* Calculate the external display position based on MDP downscale,
2534 ActionSafe, and extorientation features. */
2535 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002536
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002537 int downscale = getRotDownscale(ctx, layer);
Saurabh Shah97e2d802014-04-14 18:03:54 -07002538 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002539 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002540
2541 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2542 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002543 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002544 }
2545
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002546 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002547 (*rot) = ctx->mRotMgr->getNext();
2548 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002549 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002550 //If the video is using a single pipe, enable BWC
2551 if(rDest == OV_INVALID) {
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002552 BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002553 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002554 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002555 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002556 ALOGE("%s: configRotator failed!", __FUNCTION__);
2557 return -1;
2558 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002559 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002560 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002561 }
2562
2563 //If 2 pipes being used, divide layer into half, crop and dst
2564 hwc_rect_t cropL = crop;
2565 hwc_rect_t cropR = crop;
2566 hwc_rect_t dstL = dst;
2567 hwc_rect_t dstR = dst;
2568 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2569 cropL.right = (crop.right + crop.left) / 2;
2570 cropR.left = cropL.right;
2571 sanitizeSourceCrop(cropL, cropR, hnd);
2572
Saurabh Shahb729b192014-08-15 18:04:24 -07002573 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002574 //Swap crops on H flip since 2 pipes are being used
2575 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2576 hwc_rect_t tmp = cropL;
2577 cropL = cropR;
2578 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002579 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002580 }
2581
Saurabh Shahb729b192014-08-15 18:04:24 -07002582 //cropSwap trick: If the src and dst widths are both odd, let us say
2583 //2507, then splitting both into half would cause left width to be 1253
2584 //and right 1254. If crop is swapped because of H flip, this will cause
2585 //left crop width to be 1254, whereas left dst width remains 1253, thus
2586 //inducing a scaling that is unaccounted for. To overcome that we add 1
2587 //to the dst width if there is a cropSwap. So if the original width was
2588 //2507, the left dst width will be 1254. Even if the original width was
2589 //even for ex: 2508, the left dst width will still remain 1254.
2590 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002591 dstR.left = dstL.right;
2592 }
2593
2594 //For the mdp, since either we are pre-rotating or MDP does flips
2595 orient = OVERLAY_TRANSFORM_0;
2596 transform = 0;
2597
2598 //configure left pipe
2599 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002600 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002601 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2602 (ovutils::eBlending) getBlending(layer->blending));
2603
2604 if(configMdp(ctx->mOverlay, pargL, orient,
2605 cropL, dstL, metadata, lDest) < 0) {
2606 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2607 return -1;
2608 }
2609 }
2610
2611 //configure right pipe
2612 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002613 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002614 static_cast<eRotFlags>(rotFlags),
2615 layer->planeAlpha,
2616 (ovutils::eBlending) getBlending(layer->blending));
2617 if(configMdp(ctx->mOverlay, pargR, orient,
2618 cropR, dstR, metadata, rDest) < 0) {
2619 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2620 return -1;
2621 }
2622 }
2623
2624 return 0;
2625}
2626
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002627}; //namespace
2628