blob: 6eeb62ddffd2133f47b9a1e2dcaa0dab5cb7a473 [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002 * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003 * Not a Contribution, Apache license notifications and license are retained
4 * for attribution purposes only.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
Saurabh Shah4fdde762013-04-30 18:47:33 -070019#include <math.h>
Naseer Ahmed7c958d42012-07-31 18:57:03 -070020#include "hwc_mdpcomp.h"
Naseer Ahmed54821fe2012-11-28 18:44:38 -050021#include <sys/ioctl.h>
Saurabh Shah56f610d2012-08-07 15:27:06 -070022#include "external.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080023#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080024#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070025#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070026#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080027#include <overlayRotator.h>
Sushil Chauhandefd3522014-05-13 18:17:12 -070028#include "hwc_copybit.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080029
Saurabh Shah85234ec2013-04-12 17:09:00 -070030using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070031using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080032using namespace overlay::utils;
33namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070034
Naseer Ahmed7c958d42012-07-31 18:57:03 -070035namespace qhwc {
36
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080037//==============MDPComp========================================================
38
Naseer Ahmed7c958d42012-07-31 18:57:03 -070039IdleInvalidator *MDPComp::idleInvalidator = NULL;
40bool MDPComp::sIdleFallBack = false;
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -080041bool MDPComp::sHandleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070042bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050043bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070044bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -070045int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080046int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Raj Kamal389d6e32014-08-04 14:43:24 +053047bool MDPComp::sEnableYUVsplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070048bool MDPComp::sSrcSplitEnabled = false;
Saurabh Shah88e4d272013-09-03 13:31:29 -070049MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070050 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
51 sSrcSplitEnabled = true;
52 return new MDPCompSrcSplit(dpy);
53 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070054 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080055 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070056 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080057}
58
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080059MDPComp::MDPComp(int dpy):mDpy(dpy){};
60
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070061void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080062{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070063 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
64 return;
65
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080066 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070067 (mDpy == 0) ? "\"PRIMARY\"" :
68 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070069 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
70 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080071 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
72 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
73 (mCurrentFrame.needsRedraw? "YES" : "NO"),
74 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070075 if(isDisplaySplit(ctx, mDpy)) {
76 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
77 "Right: [%d, %d, %d, %d] \n",
78 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
79 ctx->listStats[mDpy].lRoi.right,
80 ctx->listStats[mDpy].lRoi.bottom,
81 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
82 ctx->listStats[mDpy].rRoi.right,
83 ctx->listStats[mDpy].rRoi.bottom);
84 } else {
85 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
86 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
87 ctx->listStats[mDpy].lRoi.right,
88 ctx->listStats[mDpy].lRoi.bottom);
89 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080090 dumpsys_log(buf," --------------------------------------------- \n");
91 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
92 dumpsys_log(buf," --------------------------------------------- \n");
93 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
94 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
95 index,
96 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070097 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080098 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070099 (mCurrentFrame.drop[index] ? "DROP" :
100 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800101 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
102 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
103 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800104}
105
106bool MDPComp::init(hwc_context_t *ctx) {
107
108 if(!ctx) {
109 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
110 return false;
111 }
112
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800113 char property[PROPERTY_VALUE_MAX];
114
115 sEnabled = false;
116 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800117 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
118 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800119 sEnabled = true;
120 }
121
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700122 sEnableMixedMode = true;
123 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
124 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
125 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
126 sEnableMixedMode = false;
127 }
128
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800129 sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Saurabh Shah85234ec2013-04-12 17:09:00 -0700130 if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
131 int val = atoi(property);
132 if(val >= 0)
133 sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800134 }
135
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400136 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
137 // Idle invalidation is not necessary on command mode panels
138 long idle_timeout = DEFAULT_IDLE_TIME;
139 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
140 if(atoi(property) != 0)
141 idle_timeout = atoi(property);
142 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800143
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400144 //create Idle Invalidator only when not disabled through property
145 if(idle_timeout != -1)
146 idleInvalidator = IdleInvalidator::getInstance();
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800147
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400148 if(idleInvalidator == NULL) {
149 ALOGE("%s: failed to instantiate idleInvalidator object",
150 __FUNCTION__);
151 } else {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530152 idleInvalidator->init(timeout_handler, ctx,
153 (unsigned int)idle_timeout);
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400154 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800155 }
radhakrishnac9a67412013-09-25 17:40:42 +0530156
Saurabh Shah7c727642014-06-02 15:47:14 -0700157 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700158 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700159 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
160 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
161 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530162 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530163 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700164
165 if ((property_get("persist.hwc.ptor.enable", property, NULL) > 0) &&
166 ((!strncasecmp(property, "true", PROPERTY_VALUE_MAX )) ||
167 (!strncmp(property, "1", PROPERTY_VALUE_MAX )))) {
168 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
169 HWC_DISPLAY_PRIMARY);
170 }
171
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700172 return true;
173}
174
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800175void MDPComp::reset(hwc_context_t *ctx) {
176 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700177 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800178 ctx->mOverlay->clear(mDpy);
179 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700180}
181
Raj Kamal4393eaa2014-06-06 13:45:20 +0530182void MDPComp::reset() {
183 sHandleTimeout = false;
184 mModeOn = false;
185}
186
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700187void MDPComp::timeout_handler(void *udata) {
188 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
189
190 if(!ctx) {
191 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
192 return;
193 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800194 Locker::Autolock _l(ctx->mDrawLock);
195 // Handle timeout event only if the previous composition is MDP or MIXED.
196 if(!sHandleTimeout) {
197 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
198 return;
199 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700200 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700201 ALOGE("%s: HWC proc not registered", __FUNCTION__);
202 return;
203 }
204 sIdleFallBack = true;
205 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700206 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700207}
208
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800209void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800210 hwc_display_contents_1_t* list) {
211 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800212
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800213 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800214 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800215 if(!mCurrentFrame.isFBComposed[index]) {
216 layerProp[index].mFlags |= HWC_MDPCOMP;
217 layer->compositionType = HWC_OVERLAY;
218 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800219 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700220 /* Drop the layer when its already present in FB OR when it lies
221 * outside frame's ROI */
222 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800223 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700224 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800225 }
226 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700227}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500228
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800229void MDPComp::setRedraw(hwc_context_t *ctx,
230 hwc_display_contents_1_t* list) {
231 mCurrentFrame.needsRedraw = false;
232 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
233 (list->flags & HWC_GEOMETRY_CHANGED) ||
234 isSkipPresent(ctx, mDpy)) {
235 mCurrentFrame.needsRedraw = true;
236 }
237}
238
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800239MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700240 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700241 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800242}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800243
Saurabh Shahaa236822013-04-24 18:07:26 -0700244void MDPComp::FrameInfo::reset(const int& numLayers) {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700245 for(int i = 0; i < MAX_PIPES_PER_MIXER; i++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800246 if(mdpToLayer[i].pipeInfo) {
247 delete mdpToLayer[i].pipeInfo;
248 mdpToLayer[i].pipeInfo = NULL;
249 //We dont own the rotator
250 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800251 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800252 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800253
254 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
255 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700256 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800257
Saurabh Shahaa236822013-04-24 18:07:26 -0700258 layerCount = numLayers;
259 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800260 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700261 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800262 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800263}
264
Saurabh Shahaa236822013-04-24 18:07:26 -0700265void MDPComp::FrameInfo::map() {
266 // populate layer and MDP maps
267 int mdpIdx = 0;
268 for(int idx = 0; idx < layerCount; idx++) {
269 if(!isFBComposed[idx]) {
270 mdpToLayer[mdpIdx].listIndex = idx;
271 layerToMDP[idx] = mdpIdx++;
272 }
273 }
274}
275
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800276MDPComp::LayerCache::LayerCache() {
277 reset();
278}
279
280void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700281 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530282 memset(&isFBComposed, true, sizeof(isFBComposed));
283 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800284 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700285}
286
287void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530288 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700289 for(int i = 0; i < numAppLayers; i++) {
290 hnd[i] = list->hwLayers[i].handle;
291 }
292}
293
294void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700295 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530296 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
297 memcpy(&drop, &curFrame.drop, sizeof(drop));
298}
299
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800300bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
301 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530302 if(layerCount != curFrame.layerCount)
303 return false;
304 for(int i = 0; i < curFrame.layerCount; i++) {
305 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
306 (curFrame.drop[i] != drop[i])) {
307 return false;
308 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800309 if(curFrame.isFBComposed[i] &&
310 (hnd[i] != list->hwLayers[i].handle)){
311 return false;
312 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530313 }
314 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800315}
316
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700317bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
318 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800319 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700320 (not isValidDimension(ctx,layer))
321 //More conditions here, SKIP, sRGB+Blend etc
322 ) {
323 return false;
324 }
325 return true;
326}
327
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530328bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800329 private_handle_t *hnd = (private_handle_t *)layer->handle;
330
331 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700332 if (layer->flags & HWC_COLOR_FILL) {
333 // Color layer
334 return true;
335 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700336 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800337 return false;
338 }
339
Naseer Ahmede850a802013-09-06 13:12:52 -0400340 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400341 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400342 return false;
343
Saurabh Shah62e1d732013-09-17 10:44:05 -0700344 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700345 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700346 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700347 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
348 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700349 int dst_w = dst.right - dst.left;
350 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800351 float w_scale = ((float)crop_w / (float)dst_w);
352 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530353 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700354
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800355 /* Workaround for MDP HW limitation in DSI command mode panels where
356 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
357 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530358 * There also is a HW limilation in MDP, minimum block size is 2x2
359 * Fallback to GPU if height is less than 2.
360 */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800361 if((crop_w < 5)||(crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800362 return false;
363
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800364 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530365 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800366 const float w_dscale = w_scale;
367 const float h_dscale = h_scale;
368
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800369 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700370
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530371 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700372 /* On targets that doesnt support Decimation (eg.,8x26)
373 * maximum downscale support is overlay pipe downscale.
374 */
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530375 if(crop_w > mdpHw.getMaxMixerWidth() ||
376 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700377 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800378 return false;
379 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700380 // Decimation on macrotile format layers is not supported.
381 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530382 /* Bail out if
383 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700384 * 2. exceeds maximum downscale limit
385 */
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530386 if(((crop_w > mdpHw.getMaxMixerWidth()) &&
387 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700388 w_dscale > maxMDPDownscale ||
389 h_dscale > maxMDPDownscale) {
390 return false;
391 }
392 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800393 return false;
394 }
395 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700396 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700397 return false;
398 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700399 }
400
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800401 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530402 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800403 const float w_uscale = 1.0f / w_scale;
404 const float h_uscale = 1.0f / h_scale;
405
406 if(w_uscale > upscale || h_uscale > upscale)
407 return false;
408 }
409
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800410 return true;
411}
412
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800413bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700414 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800415
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800416 if(!isEnabled()) {
417 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700418 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530419 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530420 qdutils::MDPVersion::getInstance().is8x16() ||
421 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800422 ctx->mVideoTransFlag &&
423 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700424 //1 Padding round to shift pipes across mixers
425 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
426 __FUNCTION__);
427 ret = false;
Ramkumar 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
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -0700687 // No Idle fall back, if secure display or secure RGB layers are present
688 if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
689 !ctx->listStats[mDpy].secureRGBCount)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700690 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
691 return false;
692 }
693
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800694 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700695 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
696 __FUNCTION__,
697 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800698 return false;
699 }
700
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700701 // if secondary is configuring or Padding round, fall back to video only
702 // composition and release all assigned non VIG pipes from primary.
703 if(isSecondaryConfiguring(ctx)) {
704 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
705 __FUNCTION__);
706 return false;
707 } else if(ctx->isPaddingRound) {
708 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
709 __FUNCTION__,mDpy);
710 return false;
711 }
712
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530713 MDPVersion& mdpHw = MDPVersion::getInstance();
714 if(mDpy > HWC_DISPLAY_PRIMARY &&
715 (priDispW > mdpHw.getMaxMixerWidth()) &&
716 (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800717 // Disable MDP comp on Secondary when the primary is highres panel and
718 // the secondary is a normal 1080p, because, MDP comp on secondary under
719 // in such usecase, decimation gets used for downscale and there will be
720 // a quality mismatch when there will be a fallback to GPU comp
721 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
722 __FUNCTION__);
723 return false;
724 }
725
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800726 // check for action safe flag and downscale mode which requires scaling.
727 if(ctx->dpyAttr[mDpy].mActionSafePresent
728 || ctx->dpyAttr[mDpy].mDownScaleMode) {
729 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
730 return false;
731 }
732
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800733 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800734 hwc_layer_1_t* layer = &list->hwLayers[i];
735 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800736
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800737 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700738 if(!canUseRotator(ctx, mDpy)) {
739 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
740 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700741 return false;
742 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800743 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530744
745 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
746 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700747 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530748 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
749 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
750 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800751 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700752
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700753 if(ctx->mAD->isDoable()) {
754 return false;
755 }
756
Saurabh Shahaa236822013-04-24 18:07:26 -0700757 //If all above hard conditions are met we can do full or partial MDP comp.
758 bool ret = false;
759 if(fullMDPComp(ctx, list)) {
760 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700761 } else if(fullMDPCompWithPTOR(ctx, list)) {
762 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700763 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700764 ret = true;
765 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530766
Saurabh Shahaa236822013-04-24 18:07:26 -0700767 return ret;
768}
769
770bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700771
772 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
773 return false;
774
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700775 //Will benefit presentation / secondary-only layer.
776 if((mDpy > HWC_DISPLAY_PRIMARY) &&
777 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
778 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
779 return false;
780 }
781
782 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
783 for(int i = 0; i < numAppLayers; i++) {
784 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700785 if(not mCurrentFrame.drop[i] and
786 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700787 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
788 return false;
789 }
790 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800791
Saurabh Shahaa236822013-04-24 18:07:26 -0700792 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700793 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
794 sizeof(mCurrentFrame.isFBComposed));
795 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
796 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700797
Raj Kamal389d6e32014-08-04 14:43:24 +0530798 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800799 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530800 }
801
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800802 if(!postHeuristicsHandling(ctx, list)) {
803 ALOGD_IF(isDebug(), "post heuristic handling failed");
804 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700805 return false;
806 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700807 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
808 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700809 return true;
810}
811
Sushil Chauhandefd3522014-05-13 18:17:12 -0700812/* Full MDP Composition with Peripheral Tiny Overlap Removal.
813 * MDP bandwidth limitations can be avoided, if the overlap region
814 * covered by the smallest layer at a higher z-order, gets composed
815 * by Copybit on a render buffer, which can be queued to MDP.
816 */
817bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
818 hwc_display_contents_1_t* list) {
819
820 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
821 const int stagesForMDP = min(sMaxPipesPerMixer,
822 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
823
824 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700825 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700826 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
827 return false;
828 }
829
830 // Frame level checks
831 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
832 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
833 isSecurePresent(ctx, mDpy)) {
834 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
835 return false;
836 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700837 // MDP comp checks
838 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700839 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700840 if(not isSupportedForMDPComp(ctx, layer)) {
841 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
842 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700843 }
844 }
845
Sushil Chauhandefd3522014-05-13 18:17:12 -0700846 /* We cannot use this composition mode, if:
847 1. A below layer needs scaling.
848 2. Overlap is not peripheral to display.
849 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700850 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700851 */
852
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700853 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
854 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
855 memset(overlapRect, 0, sizeof(overlapRect));
856 int layerPixelCount, minPixelCount = 0;
857 int numPTORLayersFound = 0;
858 for (int i = numAppLayers-1; (i >= 0 &&
859 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700860 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700861 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700862 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700863 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
864 // PTOR layer should be peripheral and cannot have transform
865 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
866 has90Transform(layer)) {
867 continue;
868 }
869 if((3 * (layerPixelCount + minPixelCount)) >
870 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
871 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
872 continue;
873 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700874 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700875 for (int j = i-1; j >= 0; j--) {
876 // Check if the layers below this layer qualifies for PTOR comp
877 hwc_layer_1_t* layer = &list->hwLayers[j];
878 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700879 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700880 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700881 if (isValidRect(getIntersection(dispFrame, disFrame))) {
882 if (has90Transform(layer) || needsScaling(layer)) {
883 found = false;
884 break;
885 }
886 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700887 }
888 }
889 // Store the minLayer Index
890 if(found) {
891 minLayerIndex[numPTORLayersFound] = i;
892 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
893 minPixelCount += layerPixelCount;
894 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700895 }
896 }
897
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700898 if(isValidRect(getIntersection(overlapRect[0], overlapRect[1]))) {
899 ALOGD_IF(isDebug(), "%s: Ignore Rect2 its intersects with Rect1",
900 __FUNCTION__);
901 // reset second minLayerIndex[1];
902 minLayerIndex[1] = -1;
903 numPTORLayersFound--;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700904 }
905
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700906 // No overlap layers
907 if (!numPTORLayersFound)
908 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700909
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700910 ctx->mPtorInfo.count = numPTORLayersFound;
911 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
912 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
913 }
914
915 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
916 // reset PTOR
917 ctx->mPtorInfo.count = 0;
918 return false;
919 }
920 // Store the displayFrame and the sourceCrops of the layers
921 hwc_rect_t displayFrame[numAppLayers];
922 hwc_rect_t sourceCrop[numAppLayers];
923 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700924 hwc_layer_1_t* layer = &list->hwLayers[i];
925 displayFrame[i] = layer->displayFrame;
926 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700927 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700928
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700929 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
930 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
931
Xu Yangcda012c2014-07-30 21:57:21 +0800932 // Store the blending mode, planeAlpha, and transform of PTOR layers
933 int32_t blending[numPTORLayersFound];
934 uint8_t planeAlpha[numPTORLayersFound];
935 uint32_t transform[numPTORLayersFound];
936
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700937 for(int j = 0; j < numPTORLayersFound; j++) {
938 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700939
940 // Update src crop of PTOR layer
941 hwc_layer_1_t* layer = &list->hwLayers[index];
942 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
943 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
944 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
945 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
946
947 // Store & update w, h, format of PTOR layer
948 private_handle_t *hnd = (private_handle_t *)layer->handle;
949 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
950 layerWhf[j] = whf;
951 hnd->width = renderBuf->width;
952 hnd->height = renderBuf->height;
953 hnd->format = renderBuf->format;
954
Xu Yangcda012c2014-07-30 21:57:21 +0800955 // Store & update blending mode, planeAlpha and transform of PTOR layer
956 blending[j] = layer->blending;
957 planeAlpha[j] = layer->planeAlpha;
958 transform[j] = layer->transform;
959 layer->blending = HWC_BLENDING_NONE;
960 layer->planeAlpha = 0xFF;
961 layer->transform = 0;
962
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700963 // Remove overlap from crop & displayFrame of below layers
964 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700965 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700966 if(!isValidRect(getIntersection(layer->displayFrame,
967 overlapRect[j]))) {
968 continue;
969 }
970 // Update layer attributes
971 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
972 hwc_rect_t destRect = deductRect(layer->displayFrame,
973 overlapRect[j]);
974 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
975 layer->transform);
976 layer->sourceCropf.left = (float)srcCrop.left;
977 layer->sourceCropf.top = (float)srcCrop.top;
978 layer->sourceCropf.right = (float)srcCrop.right;
979 layer->sourceCropf.bottom = (float)srcCrop.bottom;
980 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700981 }
982
983 mCurrentFrame.mdpCount = numAppLayers;
984 mCurrentFrame.fbCount = 0;
985 mCurrentFrame.fbZ = -1;
986
987 for (int j = 0; j < numAppLayers; j++)
988 mCurrentFrame.isFBComposed[j] = false;
989
990 bool result = postHeuristicsHandling(ctx, list);
991
992 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700993 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700994 hwc_layer_1_t* layer = &list->hwLayers[i];
995 layer->displayFrame = displayFrame[i];
996 layer->sourceCropf.left = (float)sourceCrop[i].left;
997 layer->sourceCropf.top = (float)sourceCrop[i].top;
998 layer->sourceCropf.right = (float)sourceCrop[i].right;
999 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1000 }
1001
Xu Yangcda012c2014-07-30 21:57:21 +08001002 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001003 for (int i = 0; i < numPTORLayersFound; i++) {
1004 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001005 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001006 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1007 hnd->width = layerWhf[i].w;
1008 hnd->height = layerWhf[i].h;
1009 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001010 layer->blending = blending[i];
1011 layer->planeAlpha = planeAlpha[i];
1012 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001013 }
1014
Sushil Chauhandefd3522014-05-13 18:17:12 -07001015 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001016 // reset PTOR
1017 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001018 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001019 } else {
1020 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1021 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001022 }
1023
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001024 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1025 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001026 return result;
1027}
1028
Saurabh Shahaa236822013-04-24 18:07:26 -07001029bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1030{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001031 if(!sEnableMixedMode) {
1032 //Mixed mode is disabled. No need to even try caching.
1033 return false;
1034 }
1035
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001036 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001037 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001038 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001039 cacheBasedComp(ctx, list);
1040 } else {
1041 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001042 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001043 }
1044
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001045 return ret;
1046}
1047
1048bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1049 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001050 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1051 return false;
1052
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001053 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001054 mCurrentFrame.reset(numAppLayers);
1055 updateLayerCache(ctx, list);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001056
1057 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1058 for(int i = 0; i < numAppLayers; i++) {
1059 if(!mCurrentFrame.isFBComposed[i]) {
1060 hwc_layer_1_t* layer = &list->hwLayers[i];
1061 if(not isSupportedForMDPComp(ctx, layer)) {
1062 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1063 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001064 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001065 return false;
1066 }
1067 }
1068 }
1069
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001070 updateYUV(ctx, list, false /*secure only*/);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001071 /* mark secure RGB layers for MDP comp */
1072 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301073 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001074 if(!ret) {
1075 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001076 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001077 return false;
1078 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001079
1080 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001081
Raj Kamal389d6e32014-08-04 14:43:24 +05301082 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001083 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301084 }
1085
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001086 //Will benefit cases where a video has non-updating background.
1087 if((mDpy > HWC_DISPLAY_PRIMARY) and
1088 (mdpCount > MAX_SEC_LAYERS)) {
1089 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001090 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001091 return false;
1092 }
1093
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001094 if(!postHeuristicsHandling(ctx, list)) {
1095 ALOGD_IF(isDebug(), "post heuristic handling failed");
1096 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001097 return false;
1098 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001099 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1100 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001101
Saurabh Shahaa236822013-04-24 18:07:26 -07001102 return true;
1103}
1104
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001105bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001106 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001107 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1108 return false;
1109
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001110 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001111 return false;
1112 }
1113
Saurabh Shahb772ae32013-11-18 15:40:02 -08001114 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001115 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1116 const int stagesForMDP = min(sMaxPipesPerMixer,
1117 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001118
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001119 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1120 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1121 int lastMDPSupportedIndex = numAppLayers;
1122 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001123
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001124 //Find the minimum MDP batch size
1125 for(int i = 0; i < numAppLayers;i++) {
1126 if(mCurrentFrame.drop[i]) {
1127 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001128 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001129 }
1130 hwc_layer_1_t* layer = &list->hwLayers[i];
1131 if(not isSupportedForMDPComp(ctx, layer)) {
1132 lastMDPSupportedIndex = i;
1133 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1134 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001135 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001136 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001137 }
1138
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001139 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1140 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1141 mCurrentFrame.dropCount);
1142
1143 //Start at a point where the fb batch should at least have 2 layers, for
1144 //this mode to be justified.
1145 while(fbBatchSize < 2) {
1146 ++fbBatchSize;
1147 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001148 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001149
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001150 //If there are no layers for MDP, this mode doesnt make sense.
1151 if(mdpBatchSize < 1) {
1152 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1153 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001154 return false;
1155 }
1156
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001157 mCurrentFrame.reset(numAppLayers);
1158
1159 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1160 while(mdpBatchSize > 0) {
1161 //Mark layers for MDP comp
1162 int mdpBatchLeft = mdpBatchSize;
1163 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1164 if(mCurrentFrame.drop[i]) {
1165 continue;
1166 }
1167 mCurrentFrame.isFBComposed[i] = false;
1168 --mdpBatchLeft;
1169 }
1170
1171 mCurrentFrame.fbZ = mdpBatchSize;
1172 mCurrentFrame.fbCount = fbBatchSize;
1173 mCurrentFrame.mdpCount = mdpBatchSize;
1174
1175 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1176 __FUNCTION__, mdpBatchSize, fbBatchSize,
1177 mCurrentFrame.dropCount);
1178
1179 if(postHeuristicsHandling(ctx, list)) {
1180 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001181 __FUNCTION__);
1182 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1183 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001184 return true;
1185 }
1186
1187 reset(ctx);
1188 --mdpBatchSize;
1189 ++fbBatchSize;
1190 }
1191
1192 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001193}
1194
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001195bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301196 if(mDpy or isSecurePresent(ctx, mDpy) or
1197 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001198 return false;
1199 }
1200 return true;
1201}
1202
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001203bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1204 hwc_display_contents_1_t* list){
1205 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1206 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1207 mDpy ) {
1208 return false;
1209 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001210 if(ctx->listStats[mDpy].secureUI)
1211 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001212 return true;
1213}
1214
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001215bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1216 hwc_display_contents_1_t* list) {
1217 const bool secureOnly = true;
1218 return videoOnlyComp(ctx, list, not secureOnly) or
1219 videoOnlyComp(ctx, list, secureOnly);
1220}
1221
1222bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001223 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001224 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1225 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001226 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001227
Saurabh Shahaa236822013-04-24 18:07:26 -07001228 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001229 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001230 updateYUV(ctx, list, secureOnly);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001231 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001232
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001233 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1234 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001235 return false;
1236 }
1237
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001238 /* Bail out if we are processing only secured video layers
1239 * and we dont have any */
1240 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001241 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001242 return false;
1243 }
1244
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001245 if(mCurrentFrame.fbCount)
1246 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001247
Raj Kamal389d6e32014-08-04 14:43:24 +05301248 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001249 adjustForSourceSplit(ctx, list);
1250 }
1251
1252 if(!postHeuristicsHandling(ctx, list)) {
1253 ALOGD_IF(isDebug(), "post heuristic handling failed");
1254 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001255 return false;
1256 }
1257
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001258 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1259 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001260 return true;
1261}
1262
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001263/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1264bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1265 hwc_display_contents_1_t* list) {
1266 const bool secureOnly = true;
1267 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1268 mdpOnlyLayersComp(ctx, list, secureOnly);
1269
1270}
1271
1272bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1273 hwc_display_contents_1_t* list, bool secureOnly) {
1274
1275 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1276 return false;
1277
1278 /* Bail out if we are processing only secured video layers
1279 * and we dont have any */
1280 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1281 reset(ctx);
1282 return false;
1283 }
1284
1285 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1286 mCurrentFrame.reset(numAppLayers);
1287 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1288
1289 updateYUV(ctx, list, secureOnly);
1290 /* mark secure RGB layers for MDP comp */
1291 updateSecureRGB(ctx, list);
1292
1293 if(mCurrentFrame.mdpCount == 0) {
1294 reset(ctx);
1295 return false;
1296 }
1297
1298 /* find the maximum batch of layers to be marked for framebuffer */
1299 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1300 if(!ret) {
1301 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1302 reset(ctx);
1303 return false;
1304 }
1305
1306 if(sEnableYUVsplit){
1307 adjustForSourceSplit(ctx, list);
1308 }
1309
1310 if(!postHeuristicsHandling(ctx, list)) {
1311 ALOGD_IF(isDebug(), "post heuristic handling failed");
1312 reset(ctx);
1313 return false;
1314 }
1315
1316 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1317 __FUNCTION__);
1318 return true;
1319}
1320
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001321/* Checks for conditions where YUV layers cannot be bypassed */
1322bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001323 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001324 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001325 return false;
1326 }
1327
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001328 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001329 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1330 return false;
1331 }
1332
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001333 if(isSecuring(ctx, layer)) {
1334 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1335 return false;
1336 }
1337
Saurabh Shah4fdde762013-04-30 18:47:33 -07001338 if(!isValidDimension(ctx, layer)) {
1339 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1340 __FUNCTION__);
1341 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001342 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001343
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001344 if(layer->planeAlpha < 0xFF) {
1345 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1346 in video only mode",
1347 __FUNCTION__);
1348 return false;
1349 }
1350
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001351 return true;
1352}
1353
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001354/* Checks for conditions where Secure RGB layers cannot be bypassed */
1355bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1356 if(isSkipLayer(layer)) {
1357 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1358 __FUNCTION__, mDpy);
1359 return false;
1360 }
1361
1362 if(isSecuring(ctx, layer)) {
1363 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1364 return false;
1365 }
1366
1367 if(not isSupportedForMDPComp(ctx, layer)) {
1368 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1369 __FUNCTION__);
1370 return false;
1371 }
1372 return true;
1373}
1374
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301375/* starts at fromIndex and check for each layer to find
1376 * if it it has overlapping with any Updating layer above it in zorder
1377 * till the end of the batch. returns true if it finds any intersection */
1378bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1379 int fromIndex, int toIndex) {
1380 for(int i = fromIndex; i < toIndex; i++) {
1381 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1382 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1383 return false;
1384 }
1385 }
1386 }
1387 return true;
1388}
1389
1390/* Checks if given layer at targetLayerIndex has any
1391 * intersection with all the updating layers in beween
1392 * fromIndex and toIndex. Returns true if it finds intersectiion */
1393bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1394 int fromIndex, int toIndex, int targetLayerIndex) {
1395 for(int i = fromIndex; i <= toIndex; i++) {
1396 if(!mCurrentFrame.isFBComposed[i]) {
1397 if(areLayersIntersecting(&list->hwLayers[i],
1398 &list->hwLayers[targetLayerIndex])) {
1399 return true;
1400 }
1401 }
1402 }
1403 return false;
1404}
1405
1406int MDPComp::getBatch(hwc_display_contents_1_t* list,
1407 int& maxBatchStart, int& maxBatchEnd,
1408 int& maxBatchCount) {
1409 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301410 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001411 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301412 while (i < mCurrentFrame.layerCount) {
1413 int batchCount = 0;
1414 int batchStart = i;
1415 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001416 /* Adjust batch Z order with the dropped layers so far */
1417 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301418 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301419 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301420 while(i < mCurrentFrame.layerCount) {
1421 if(!mCurrentFrame.isFBComposed[i]) {
1422 if(!batchCount) {
1423 i++;
1424 break;
1425 }
1426 updatingLayersAbove++;
1427 i++;
1428 continue;
1429 } else {
1430 if(mCurrentFrame.drop[i]) {
1431 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001432 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301433 continue;
1434 } else if(updatingLayersAbove <= 0) {
1435 batchCount++;
1436 batchEnd = i;
1437 i++;
1438 continue;
1439 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1440
1441 // We have a valid updating layer already. If layer-i not
1442 // have overlapping with all updating layers in between
1443 // batch-start and i, then we can add layer i to batch.
1444 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1445 batchCount++;
1446 batchEnd = i;
1447 i++;
1448 continue;
1449 } else if(canPushBatchToTop(list, batchStart, i)) {
1450 //If All the non-updating layers with in this batch
1451 //does not have intersection with the updating layers
1452 //above in z-order, then we can safely move the batch to
1453 //higher z-order. Increment fbZ as it is moving up.
1454 if( firstZReverseIndex < 0) {
1455 firstZReverseIndex = i;
1456 }
1457 batchCount++;
1458 batchEnd = i;
1459 fbZ += updatingLayersAbove;
1460 i++;
1461 updatingLayersAbove = 0;
1462 continue;
1463 } else {
1464 //both failed.start the loop again from here.
1465 if(firstZReverseIndex >= 0) {
1466 i = firstZReverseIndex;
1467 }
1468 break;
1469 }
1470 }
1471 }
1472 }
1473 if(batchCount > maxBatchCount) {
1474 maxBatchCount = batchCount;
1475 maxBatchStart = batchStart;
1476 maxBatchEnd = batchEnd;
1477 fbZOrder = fbZ;
1478 }
1479 }
1480 return fbZOrder;
1481}
1482
1483bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1484 hwc_display_contents_1_t* list) {
1485 /* Idea is to keep as many non-updating(cached) layers in FB and
1486 * send rest of them through MDP. This is done in 2 steps.
1487 * 1. Find the maximum contiguous batch of non-updating layers.
1488 * 2. See if we can improve this batch size for caching by adding
1489 * opaque layers around the batch, if they don't have
1490 * any overlapping with the updating layers in between.
1491 * NEVER mark an updating layer for caching.
1492 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001493
1494 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001495 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001496 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301497 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001498
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001499 /* Nothing is cached. No batching needed */
1500 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001501 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001502 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001503
1504 /* No MDP comp layers, try to use other comp modes */
1505 if(mCurrentFrame.mdpCount == 0) {
1506 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001507 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001508
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301509 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001510
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301511 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001512 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001513 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001514 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301515 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001516 if(!mCurrentFrame.drop[i]){
1517 //If an unsupported layer is being attempted to
1518 //be pulled out we should fail
1519 if(not isSupportedForMDPComp(ctx, layer)) {
1520 return false;
1521 }
1522 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001523 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001524 }
1525 }
1526
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301527 // update the frame data
1528 mCurrentFrame.fbZ = fbZ;
1529 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001530 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001531 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001532
1533 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301534 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001535
1536 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001537}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001538
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001539void MDPComp::updateLayerCache(hwc_context_t* ctx,
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001540 hwc_display_contents_1_t* list) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001541 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001542 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001543
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001544 for(int i = 0; i < numAppLayers; i++) {
1545 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001546 if(!mCurrentFrame.drop[i])
1547 fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001548 mCurrentFrame.isFBComposed[i] = true;
1549 } else {
Saurabh Shahaa236822013-04-24 18:07:26 -07001550 mCurrentFrame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001551 }
1552 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001553
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001554 mCurrentFrame.fbCount = fbCount;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001555 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
1556 - mCurrentFrame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001557
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001558 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d"
1559 ,__FUNCTION__, mCurrentFrame.mdpCount, mCurrentFrame.fbCount,
1560 mCurrentFrame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001561}
1562
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001563void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
1564 bool secureOnly) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001565 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1566 for(int index = 0;index < nYuvCount; index++){
1567 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1568 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1569
1570 if(!isYUVDoable(ctx, layer)) {
1571 if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
1572 mCurrentFrame.isFBComposed[nYuvIndex] = true;
1573 mCurrentFrame.fbCount++;
1574 }
1575 } else {
1576 if(mCurrentFrame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001577 private_handle_t *hnd = (private_handle_t *)layer->handle;
1578 if(!secureOnly || isSecureBuffer(hnd)) {
1579 mCurrentFrame.isFBComposed[nYuvIndex] = false;
1580 mCurrentFrame.fbCount--;
1581 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001582 }
1583 }
1584 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001585
1586 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001587 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1588 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001589 mCurrentFrame.fbCount);
1590}
1591
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001592void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1593 hwc_display_contents_1_t* list) {
1594 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1595 for(int index = 0;index < nSecureRGBCount; index++){
1596 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1597 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1598
1599 if(!isSecureRGBDoable(ctx, layer)) {
1600 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1601 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1602 mCurrentFrame.fbCount++;
1603 }
1604 } else {
1605 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1606 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1607 mCurrentFrame.fbCount--;
1608 }
1609 }
1610 }
1611
1612 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1613 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1614 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1615 mCurrentFrame.fbCount);
1616}
1617
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001618hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1619 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001620 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001621
1622 /* Update only the region of FB needed for composition */
1623 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1624 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1625 hwc_layer_1_t* layer = &list->hwLayers[i];
1626 hwc_rect_t dst = layer->displayFrame;
1627 fbRect = getUnion(fbRect, dst);
1628 }
1629 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001630 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001631 return fbRect;
1632}
1633
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001634bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1635 hwc_display_contents_1_t* list) {
1636
1637 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001638 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001639 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1640 return false;
1641 }
1642
1643 //Limitations checks
1644 if(!hwLimitationsCheck(ctx, list)) {
1645 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1646 return false;
1647 }
1648
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001649 //Configure framebuffer first if applicable
1650 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001651 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001652 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1653 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001654 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1655 __FUNCTION__);
1656 return false;
1657 }
1658 }
1659
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001660 mCurrentFrame.map();
1661
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001662 if(!allocLayerPipes(ctx, list)) {
1663 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001664 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001665 }
1666
1667 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001668 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001669 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001670 int mdpIndex = mCurrentFrame.layerToMDP[index];
1671 hwc_layer_1_t* layer = &list->hwLayers[index];
1672
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301673 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1674 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1675 mdpNextZOrder++;
1676 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001677 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1678 cur_pipe->zOrder = mdpNextZOrder++;
1679
radhakrishnac9a67412013-09-25 17:40:42 +05301680 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301681 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301682 if(configure4k2kYuv(ctx, layer,
1683 mCurrentFrame.mdpToLayer[mdpIndex])
1684 != 0 ){
1685 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1686 for layer %d",__FUNCTION__, index);
1687 return false;
1688 }
1689 else{
1690 mdpNextZOrder++;
1691 }
1692 continue;
1693 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001694 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1695 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301696 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001697 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001698 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001699 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001700 }
1701
Saurabh Shaha36be922013-12-16 18:18:39 -08001702 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1703 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1704 ,__FUNCTION__, mDpy);
1705 return false;
1706 }
1707
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001708 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001709 return true;
1710}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001711
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001712bool MDPComp::resourceCheck(hwc_context_t* ctx,
1713 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001714 const bool fbUsed = mCurrentFrame.fbCount;
1715 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1716 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1717 return false;
1718 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001719 // Init rotCount to number of rotate sessions used by other displays
1720 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1721 // Count the number of rotator sessions required for current display
1722 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1723 if(!mCurrentFrame.isFBComposed[index]) {
1724 hwc_layer_1_t* layer = &list->hwLayers[index];
1725 private_handle_t *hnd = (private_handle_t *)layer->handle;
1726 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1727 rotCount++;
1728 }
1729 }
1730 }
1731 // if number of layers to rotate exceeds max rotator sessions, bail out.
1732 if(rotCount > RotMgr::MAX_ROT_SESS) {
1733 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1734 __FUNCTION__, mDpy);
1735 return false;
1736 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001737 return true;
1738}
1739
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301740bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1741 hwc_display_contents_1_t* list) {
1742
1743 //A-family hw limitation:
1744 //If a layer need alpha scaling, MDP can not support.
1745 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1746 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1747 if(!mCurrentFrame.isFBComposed[i] &&
1748 isAlphaScaled( &list->hwLayers[i])) {
1749 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1750 return false;
1751 }
1752 }
1753 }
1754
1755 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1756 //If multiple layers requires downscaling and also they are overlapping
1757 //fall back to GPU since MDSS can not handle it.
1758 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1759 qdutils::MDPVersion::getInstance().is8x26()) {
1760 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1761 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1762 if(!mCurrentFrame.isFBComposed[i] &&
1763 isDownscaleRequired(botLayer)) {
1764 //if layer-i is marked for MDP and needs downscaling
1765 //check if any MDP layer on top of i & overlaps with layer-i
1766 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1767 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1768 if(!mCurrentFrame.isFBComposed[j] &&
1769 isDownscaleRequired(topLayer)) {
1770 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1771 topLayer->displayFrame);
1772 if(isValidRect(r))
1773 return false;
1774 }
1775 }
1776 }
1777 }
1778 }
1779 return true;
1780}
1781
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001782int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001783 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001784 char property[PROPERTY_VALUE_MAX];
1785
Raj Kamal4393eaa2014-06-06 13:45:20 +05301786 if(!ctx || !list) {
1787 ALOGE("%s: Invalid context or list",__FUNCTION__);
1788 mCachedFrame.reset();
1789 return -1;
1790 }
1791
1792 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001793 if(mDpy == HWC_DISPLAY_PRIMARY) {
1794 sSimulationFlags = 0;
1795 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1796 int currentFlags = atoi(property);
1797 if(currentFlags != sSimulationFlags) {
1798 sSimulationFlags = currentFlags;
1799 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1800 sSimulationFlags, sSimulationFlags);
1801 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001802 }
1803 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001804 // reset PTOR
1805 if(!mDpy)
1806 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001807
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301808 //Do not cache the information for next draw cycle.
1809 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1810 ALOGI("%s: Unsupported layer count for mdp composition",
1811 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001812 mCachedFrame.reset();
1813 return -1;
1814 }
1815
Saurabh Shahb39f8152013-08-22 10:21:44 -07001816 //reset old data
1817 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001818 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1819 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301820
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001821 // Detect the start of animation and fall back to GPU only once to cache
1822 // all the layers in FB and display FB content untill animation completes.
1823 if(ctx->listStats[mDpy].isDisplayAnimating) {
1824 mCurrentFrame.needsRedraw = false;
1825 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1826 mCurrentFrame.needsRedraw = true;
1827 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1828 }
1829 setMDPCompLayerFlags(ctx, list);
1830 mCachedFrame.updateCounts(mCurrentFrame);
1831 ret = -1;
1832 return ret;
1833 } else {
1834 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1835 }
1836
Saurabh Shahb39f8152013-08-22 10:21:44 -07001837 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001838 if(isFrameDoable(ctx)) {
1839 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001840
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001841 // if tryFullFrame fails, try to push all video and secure RGB layers
1842 // to MDP for composition.
1843 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
1844 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301845 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001846 setMDPCompLayerFlags(ctx, list);
1847 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001848 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001849 reset(ctx);
1850 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1851 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001852 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001853 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1854 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001855 }
1856 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001857 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1858 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001859 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001860 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001861
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001862 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001863 ALOGD("GEOMETRY change: %d",
1864 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001865 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001866 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001867 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001868 }
1869
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001870 mCachedFrame.cacheAll(list);
1871 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001872 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001873}
1874
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001875bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301876
1877 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301878 int mdpIndex = mCurrentFrame.layerToMDP[index];
1879 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1880 info.pipeInfo = new MdpYUVPipeInfo;
1881 info.rot = NULL;
1882 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301883
1884 pipe_info.lIndex = ovutils::OV_INVALID;
1885 pipe_info.rIndex = ovutils::OV_INVALID;
1886
Saurabh Shahc62f3982014-03-05 14:28:26 -08001887 Overlay::PipeSpecs pipeSpecs;
1888 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1889 pipeSpecs.needsScaling = true;
1890 pipeSpecs.dpy = mDpy;
1891 pipeSpecs.fb = false;
1892
1893 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301894 if(pipe_info.lIndex == ovutils::OV_INVALID){
1895 bRet = false;
1896 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1897 __FUNCTION__);
1898 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001899 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301900 if(pipe_info.rIndex == ovutils::OV_INVALID){
1901 bRet = false;
1902 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1903 __FUNCTION__);
1904 }
1905 return bRet;
1906}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001907
1908int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1909 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001910 if (ctx->mPtorInfo.isActive()) {
1911 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001912 if (fd < 0) {
1913 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001914 }
1915 }
1916 return fd;
1917}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001918//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001919
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001920void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301921 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001922 //If 4k2k Yuv layer split is possible, and if
1923 //fbz is above 4k2k layer, increment fb zorder by 1
1924 //as we split 4k2k layer and increment zorder for right half
1925 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07001926 if(!ctx)
1927 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001928 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301929 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1930 index++) {
1931 if(!mCurrentFrame.isFBComposed[index]) {
1932 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1933 mdpNextZOrder++;
1934 }
1935 mdpNextZOrder++;
1936 hwc_layer_1_t* layer = &list->hwLayers[index];
1937 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301938 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301939 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1940 mCurrentFrame.fbZ += 1;
1941 mdpNextZOrder++;
1942 //As we split 4kx2k yuv layer and program to 2 VG pipes
1943 //(if available) increase mdpcount by 1.
1944 mCurrentFrame.mdpCount++;
1945 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001946 }
1947 }
1948 }
radhakrishnac9a67412013-09-25 17:40:42 +05301949}
1950
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001951/*
1952 * Configures pipe(s) for MDP composition
1953 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001954int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001955 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001956 MdpPipeInfoNonSplit& mdp_info =
1957 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001958 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1959 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08001960 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001961
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001962 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1963 __FUNCTION__, layer, zOrder, dest);
1964
Saurabh Shah2c8ad052014-08-15 13:27:46 -07001965 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001966 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001967}
1968
Saurabh Shah88e4d272013-09-03 13:31:29 -07001969bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001970 hwc_display_contents_1_t* list) {
1971 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001972
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001973 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001974
Jeykumar Sankarancf537002013-01-21 21:19:15 -08001975 hwc_layer_1_t* layer = &list->hwLayers[index];
1976 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301977 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001978 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301979 continue;
1980 }
1981 }
1982
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001983 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001984 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001985 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08001986 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001987 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001988
Saurabh Shahc62f3982014-03-05 14:28:26 -08001989 Overlay::PipeSpecs pipeSpecs;
1990 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1991 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1992 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
1993 (qdutils::MDPVersion::getInstance().is8x26() and
1994 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
1995 pipeSpecs.dpy = mDpy;
1996 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08001997 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001998
Saurabh Shahc62f3982014-03-05 14:28:26 -08001999 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2000
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002001 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002002 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002003 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002004 }
2005 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002006 return true;
2007}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002008
radhakrishnac9a67412013-09-25 17:40:42 +05302009int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2010 PipeLayerPair& PipeLayerPair) {
2011 MdpYUVPipeInfo& mdp_info =
2012 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2013 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302014 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2015 eDest lDest = mdp_info.lIndex;
2016 eDest rDest = mdp_info.rIndex;
2017
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002018 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302019 lDest, rDest, &PipeLayerPair.rot);
2020}
2021
Saurabh Shah88e4d272013-09-03 13:31:29 -07002022bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002023
Raj Kamal4393eaa2014-06-06 13:45:20 +05302024 if(!isEnabled() or !mModeOn) {
2025 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302026 return true;
2027 }
2028
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002029 // Set the Handle timeout to true for MDP or MIXED composition.
2030 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2031 sHandleTimeout = true;
2032 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002033
2034 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002035 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002036
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002037 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2038 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002039 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002040 if(mCurrentFrame.isFBComposed[i]) continue;
2041
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002042 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002043 private_handle_t *hnd = (private_handle_t *)layer->handle;
2044 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002045 if (!(layer->flags & HWC_COLOR_FILL)) {
2046 ALOGE("%s handle null", __FUNCTION__);
2047 return false;
2048 }
2049 // No PLAY for Color layer
2050 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2051 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002052 }
2053
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002054 int mdpIndex = mCurrentFrame.layerToMDP[i];
2055
Raj Kamal389d6e32014-08-04 14:43:24 +05302056 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302057 {
2058 MdpYUVPipeInfo& pipe_info =
2059 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2060 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2061 ovutils::eDest indexL = pipe_info.lIndex;
2062 ovutils::eDest indexR = pipe_info.rIndex;
2063 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302064 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302065 if(rot) {
2066 rot->queueBuffer(fd, offset);
2067 fd = rot->getDstMemId();
2068 offset = rot->getDstOffset();
2069 }
2070 if(indexL != ovutils::OV_INVALID) {
2071 ovutils::eDest destL = (ovutils::eDest)indexL;
2072 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2073 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2074 if (!ov.queueBuffer(fd, offset, destL)) {
2075 ALOGE("%s: queueBuffer failed for display:%d",
2076 __FUNCTION__, mDpy);
2077 return false;
2078 }
2079 }
2080
2081 if(indexR != ovutils::OV_INVALID) {
2082 ovutils::eDest destR = (ovutils::eDest)indexR;
2083 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2084 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2085 if (!ov.queueBuffer(fd, offset, destR)) {
2086 ALOGE("%s: queueBuffer failed for display:%d",
2087 __FUNCTION__, mDpy);
2088 return false;
2089 }
2090 }
2091 }
2092 else{
2093 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002094 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302095 ovutils::eDest dest = pipe_info.index;
2096 if(dest == ovutils::OV_INVALID) {
2097 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002098 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302099 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002100
radhakrishnac9a67412013-09-25 17:40:42 +05302101 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2102 continue;
2103 }
2104
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002105 int fd = hnd->fd;
2106 uint32_t offset = (uint32_t)hnd->offset;
2107 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2108 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002109 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002110 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002111 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002112 }
2113
radhakrishnac9a67412013-09-25 17:40:42 +05302114 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2115 using pipe: %d", __FUNCTION__, layer,
2116 hnd, dest );
2117
radhakrishnac9a67412013-09-25 17:40:42 +05302118 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2119 if(rot) {
2120 if(!rot->queueBuffer(fd, offset))
2121 return false;
2122 fd = rot->getDstMemId();
2123 offset = rot->getDstOffset();
2124 }
2125
2126 if (!ov.queueBuffer(fd, offset, dest)) {
2127 ALOGE("%s: queueBuffer failed for display:%d ",
2128 __FUNCTION__, mDpy);
2129 return false;
2130 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002131 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002132
2133 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002134 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002135 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002136}
2137
Saurabh Shah88e4d272013-09-03 13:31:29 -07002138//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002139
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002140void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302141 hwc_display_contents_1_t* list){
2142 //if 4kx2k yuv layer is totally present in either in left half
2143 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302144 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302145 if(mCurrentFrame.fbZ >= 0) {
2146 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2147 index++) {
2148 if(!mCurrentFrame.isFBComposed[index]) {
2149 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2150 mdpNextZOrder++;
2151 }
2152 mdpNextZOrder++;
2153 hwc_layer_1_t* layer = &list->hwLayers[index];
2154 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302155 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302156 hwc_rect_t dst = layer->displayFrame;
2157 if((dst.left > lSplit) || (dst.right < lSplit)) {
2158 mCurrentFrame.mdpCount += 1;
2159 }
2160 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2161 mCurrentFrame.fbZ += 1;
2162 mdpNextZOrder++;
2163 }
2164 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002165 }
radhakrishnac9a67412013-09-25 17:40:42 +05302166 }
2167}
2168
Saurabh Shah88e4d272013-09-03 13:31:29 -07002169bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002170 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002171
Saurabh Shahc62f3982014-03-05 14:28:26 -08002172 const int lSplit = getLeftSplit(ctx, mDpy);
2173 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002174 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002175 pipe_info.lIndex = ovutils::OV_INVALID;
2176 pipe_info.rIndex = ovutils::OV_INVALID;
2177
Saurabh Shahc62f3982014-03-05 14:28:26 -08002178 Overlay::PipeSpecs pipeSpecs;
2179 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2180 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2181 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2182 pipeSpecs.dpy = mDpy;
2183 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2184 pipeSpecs.fb = false;
2185
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002186 // Acquire pipe only for the updating half
2187 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2188 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2189
2190 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002191 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002192 if(pipe_info.lIndex == ovutils::OV_INVALID)
2193 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002194 }
2195
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002196 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002197 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2198 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002199 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002200 return false;
2201 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002202
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002203 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002204}
2205
Saurabh Shah88e4d272013-09-03 13:31:29 -07002206bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002207 hwc_display_contents_1_t* list) {
2208 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002209
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002210 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002211
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002212 hwc_layer_1_t* layer = &list->hwLayers[index];
2213 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302214 hwc_rect_t dst = layer->displayFrame;
2215 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302216 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302217 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002218 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302219 continue;
2220 }
2221 }
2222 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002223 int mdpIndex = mCurrentFrame.layerToMDP[index];
2224 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002225 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002226 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002227 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002228
Saurabh Shahc62f3982014-03-05 14:28:26 -08002229 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2230 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2231 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002232 return false;
2233 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002234 }
2235 return true;
2236}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002237
radhakrishnac9a67412013-09-25 17:40:42 +05302238int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2239 PipeLayerPair& PipeLayerPair) {
2240 const int lSplit = getLeftSplit(ctx, mDpy);
2241 hwc_rect_t dst = layer->displayFrame;
2242 if((dst.left > lSplit)||(dst.right < lSplit)){
2243 MdpYUVPipeInfo& mdp_info =
2244 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2245 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302246 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2247 eDest lDest = mdp_info.lIndex;
2248 eDest rDest = mdp_info.rIndex;
2249
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002250 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302251 lDest, rDest, &PipeLayerPair.rot);
2252 }
2253 else{
2254 return configure(ctx, layer, PipeLayerPair);
2255 }
2256}
2257
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002258/*
2259 * Configures pipe(s) for MDP composition
2260 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002261int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002262 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002263 MdpPipeInfoSplit& mdp_info =
2264 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002265 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002266 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2267 eDest lDest = mdp_info.lIndex;
2268 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002269
2270 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2271 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2272
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002273 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002274 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002275}
2276
Saurabh Shah88e4d272013-09-03 13:31:29 -07002277bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002278
Raj Kamal4393eaa2014-06-06 13:45:20 +05302279 if(!isEnabled() or !mModeOn) {
2280 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302281 return true;
2282 }
2283
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002284 // Set the Handle timeout to true for MDP or MIXED composition.
2285 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2286 sHandleTimeout = true;
2287 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002288
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002289 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002290 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002291
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002292 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2293 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002294 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002295 if(mCurrentFrame.isFBComposed[i]) continue;
2296
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002297 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002298 private_handle_t *hnd = (private_handle_t *)layer->handle;
2299 if(!hnd) {
2300 ALOGE("%s handle null", __FUNCTION__);
2301 return false;
2302 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002303
2304 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2305 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002306 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002307
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002308 int mdpIndex = mCurrentFrame.layerToMDP[i];
2309
Raj Kamal389d6e32014-08-04 14:43:24 +05302310 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302311 {
2312 MdpYUVPipeInfo& pipe_info =
2313 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2314 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2315 ovutils::eDest indexL = pipe_info.lIndex;
2316 ovutils::eDest indexR = pipe_info.rIndex;
2317 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302318 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302319 if(rot) {
2320 rot->queueBuffer(fd, offset);
2321 fd = rot->getDstMemId();
2322 offset = rot->getDstOffset();
2323 }
2324 if(indexL != ovutils::OV_INVALID) {
2325 ovutils::eDest destL = (ovutils::eDest)indexL;
2326 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2327 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2328 if (!ov.queueBuffer(fd, offset, destL)) {
2329 ALOGE("%s: queueBuffer failed for display:%d",
2330 __FUNCTION__, mDpy);
2331 return false;
2332 }
2333 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002334
radhakrishnac9a67412013-09-25 17:40:42 +05302335 if(indexR != ovutils::OV_INVALID) {
2336 ovutils::eDest destR = (ovutils::eDest)indexR;
2337 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2338 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2339 if (!ov.queueBuffer(fd, offset, destR)) {
2340 ALOGE("%s: queueBuffer failed for display:%d",
2341 __FUNCTION__, mDpy);
2342 return false;
2343 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002344 }
2345 }
radhakrishnac9a67412013-09-25 17:40:42 +05302346 else{
2347 MdpPipeInfoSplit& pipe_info =
2348 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2349 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002350
radhakrishnac9a67412013-09-25 17:40:42 +05302351 ovutils::eDest indexL = pipe_info.lIndex;
2352 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002353
radhakrishnac9a67412013-09-25 17:40:42 +05302354 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002355 uint32_t offset = (uint32_t)hnd->offset;
2356 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2357 if (!mDpy && (index != -1)) {
2358 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2359 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002360 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002361 }
radhakrishnac9a67412013-09-25 17:40:42 +05302362
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002363 if(ctx->mAD->draw(ctx, fd, offset)) {
2364 fd = ctx->mAD->getDstFd();
2365 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002366 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002367
radhakrishnac9a67412013-09-25 17:40:42 +05302368 if(rot) {
2369 rot->queueBuffer(fd, offset);
2370 fd = rot->getDstMemId();
2371 offset = rot->getDstOffset();
2372 }
2373
2374 //************* play left mixer **********
2375 if(indexL != ovutils::OV_INVALID) {
2376 ovutils::eDest destL = (ovutils::eDest)indexL;
2377 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2378 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2379 if (!ov.queueBuffer(fd, offset, destL)) {
2380 ALOGE("%s: queueBuffer failed for left mixer",
2381 __FUNCTION__);
2382 return false;
2383 }
2384 }
2385
2386 //************* play right mixer **********
2387 if(indexR != ovutils::OV_INVALID) {
2388 ovutils::eDest destR = (ovutils::eDest)indexR;
2389 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2390 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2391 if (!ov.queueBuffer(fd, offset, destR)) {
2392 ALOGE("%s: queueBuffer failed for right mixer",
2393 __FUNCTION__);
2394 return false;
2395 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002396 }
2397 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002398
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002399 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2400 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002401
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002402 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002403}
Saurabh Shahab47c692014-02-12 18:45:57 -08002404
2405//================MDPCompSrcSplit==============================================
2406bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002407 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002408 private_handle_t *hnd = (private_handle_t *)layer->handle;
2409 hwc_rect_t dst = layer->displayFrame;
2410 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2411 pipe_info.lIndex = ovutils::OV_INVALID;
2412 pipe_info.rIndex = ovutils::OV_INVALID;
2413
2414 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2415 //should have a higher priority than the right one. Pipe priorities are
2416 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002417
Saurabh Shahc62f3982014-03-05 14:28:26 -08002418 Overlay::PipeSpecs pipeSpecs;
2419 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2420 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2421 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2422 pipeSpecs.dpy = mDpy;
2423 pipeSpecs.fb = false;
2424
Saurabh Shahab47c692014-02-12 18:45:57 -08002425 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002426 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002427 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002428 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002429 }
2430
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002431 /* Use 2 pipes IF
2432 a) Layer's crop width is > 2048 or
2433 b) Layer's dest width > 2048 or
2434 c) On primary, driver has indicated with caps to split always. This is
2435 based on an empirically derived value of panel height. Applied only
2436 if the layer's width is > mixer's width
2437 */
2438
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302439 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002440 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302441 mdpHw.isSrcSplitAlways();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002442 int lSplit = getLeftSplit(ctx, mDpy);
2443 int dstWidth = dst.right - dst.left;
2444 int cropWidth = crop.right - crop.left;
2445
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002446 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2447 //pipe line length, we are still using 2 pipes. This is fine just because
2448 //this is source split where destination doesn't matter. Evaluate later to
2449 //see if going through all the calcs to save a pipe is worth it
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302450 if(dstWidth > mdpHw.getMaxMixerWidth() or
2451 cropWidth > mdpHw.getMaxMixerWidth() or
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002452 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002453 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002454 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002455 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002456 }
2457
2458 // Return values
2459 // 1 Left pipe is higher priority, do nothing.
2460 // 0 Pipes of same priority.
2461 //-1 Right pipe is of higher priority, needs swap.
2462 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2463 pipe_info.rIndex) == -1) {
2464 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002465 }
2466 }
2467
2468 return true;
2469}
2470
Saurabh Shahab47c692014-02-12 18:45:57 -08002471int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2472 PipeLayerPair& PipeLayerPair) {
2473 private_handle_t *hnd = (private_handle_t *)layer->handle;
2474 if(!hnd) {
2475 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2476 return -1;
2477 }
2478 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2479 MdpPipeInfoSplit& mdp_info =
2480 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2481 Rotator **rot = &PipeLayerPair.rot;
2482 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002483 eDest lDest = mdp_info.lIndex;
2484 eDest rDest = mdp_info.rIndex;
2485 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2486 hwc_rect_t dst = layer->displayFrame;
2487 int transform = layer->transform;
2488 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002489 int rotFlags = ROT_FLAGS_NONE;
2490 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2491 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2492
2493 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2494 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2495
2496 // Handle R/B swap
2497 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2498 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2499 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2500 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2501 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2502 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002503 /* Calculate the external display position based on MDP downscale,
2504 ActionSafe, and extorientation features. */
2505 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002506
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002507 int downscale = getRotDownscale(ctx, layer);
Saurabh Shah97e2d802014-04-14 18:03:54 -07002508 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002509 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002510
2511 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2512 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002513 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002514 }
2515
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002516 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002517 (*rot) = ctx->mRotMgr->getNext();
2518 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002519 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002520 //If the video is using a single pipe, enable BWC
2521 if(rDest == OV_INVALID) {
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002522 BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002523 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002524 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002525 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002526 ALOGE("%s: configRotator failed!", __FUNCTION__);
2527 return -1;
2528 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002529 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002530 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002531 }
2532
2533 //If 2 pipes being used, divide layer into half, crop and dst
2534 hwc_rect_t cropL = crop;
2535 hwc_rect_t cropR = crop;
2536 hwc_rect_t dstL = dst;
2537 hwc_rect_t dstR = dst;
2538 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2539 cropL.right = (crop.right + crop.left) / 2;
2540 cropR.left = cropL.right;
2541 sanitizeSourceCrop(cropL, cropR, hnd);
2542
Saurabh Shahb729b192014-08-15 18:04:24 -07002543 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002544 //Swap crops on H flip since 2 pipes are being used
2545 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2546 hwc_rect_t tmp = cropL;
2547 cropL = cropR;
2548 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002549 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002550 }
2551
Saurabh Shahb729b192014-08-15 18:04:24 -07002552 //cropSwap trick: If the src and dst widths are both odd, let us say
2553 //2507, then splitting both into half would cause left width to be 1253
2554 //and right 1254. If crop is swapped because of H flip, this will cause
2555 //left crop width to be 1254, whereas left dst width remains 1253, thus
2556 //inducing a scaling that is unaccounted for. To overcome that we add 1
2557 //to the dst width if there is a cropSwap. So if the original width was
2558 //2507, the left dst width will be 1254. Even if the original width was
2559 //even for ex: 2508, the left dst width will still remain 1254.
2560 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002561 dstR.left = dstL.right;
2562 }
2563
2564 //For the mdp, since either we are pre-rotating or MDP does flips
2565 orient = OVERLAY_TRANSFORM_0;
2566 transform = 0;
2567
2568 //configure left pipe
2569 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002570 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002571 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2572 (ovutils::eBlending) getBlending(layer->blending));
2573
2574 if(configMdp(ctx->mOverlay, pargL, orient,
2575 cropL, dstL, metadata, lDest) < 0) {
2576 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2577 return -1;
2578 }
2579 }
2580
2581 //configure right pipe
2582 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002583 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002584 static_cast<eRotFlags>(rotFlags),
2585 layer->planeAlpha,
2586 (ovutils::eBlending) getBlending(layer->blending));
2587 if(configMdp(ctx->mOverlay, pargR, orient,
2588 cropR, dstR, metadata, rDest) < 0) {
2589 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2590 return -1;
2591 }
2592 }
2593
2594 return 0;
2595}
2596
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002597}; //namespace
2598