blob: 13e04a7cdbc02261fbd7abd340714a19e514bb8a [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
Dileep Kumar Reddic6ef3472014-09-24 19:07:08 +0530165 bool defaultPTOR = false;
166 //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
167 //8x16 and 8x39 targets by default
168 if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
169 (qdutils::MDPVersion::getInstance().is8x16() ||
170 qdutils::MDPVersion::getInstance().is8x39())) {
171 defaultPTOR = true;
172 }
173
174 if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
175 (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700176 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
177 HWC_DISPLAY_PRIMARY);
178 }
179
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700180 return true;
181}
182
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800183void MDPComp::reset(hwc_context_t *ctx) {
184 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700185 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800186 ctx->mOverlay->clear(mDpy);
187 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700188}
189
Raj Kamal4393eaa2014-06-06 13:45:20 +0530190void MDPComp::reset() {
191 sHandleTimeout = false;
192 mModeOn = false;
193}
194
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700195void MDPComp::timeout_handler(void *udata) {
196 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
197
198 if(!ctx) {
199 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
200 return;
201 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800202 Locker::Autolock _l(ctx->mDrawLock);
203 // Handle timeout event only if the previous composition is MDP or MIXED.
204 if(!sHandleTimeout) {
205 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
206 return;
207 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700208 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700209 ALOGE("%s: HWC proc not registered", __FUNCTION__);
210 return;
211 }
212 sIdleFallBack = true;
213 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700214 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700215}
216
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800217void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800218 hwc_display_contents_1_t* list) {
219 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800220
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800221 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800222 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800223 if(!mCurrentFrame.isFBComposed[index]) {
224 layerProp[index].mFlags |= HWC_MDPCOMP;
225 layer->compositionType = HWC_OVERLAY;
226 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800227 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700228 /* Drop the layer when its already present in FB OR when it lies
229 * outside frame's ROI */
230 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800231 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700232 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800233 }
234 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700235}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500236
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800237void MDPComp::setRedraw(hwc_context_t *ctx,
238 hwc_display_contents_1_t* list) {
239 mCurrentFrame.needsRedraw = false;
240 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
241 (list->flags & HWC_GEOMETRY_CHANGED) ||
242 isSkipPresent(ctx, mDpy)) {
243 mCurrentFrame.needsRedraw = true;
244 }
245}
246
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800247MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700248 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700249 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800250}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800251
Saurabh Shahaa236822013-04-24 18:07:26 -0700252void MDPComp::FrameInfo::reset(const int& numLayers) {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700253 for(int i = 0; i < MAX_PIPES_PER_MIXER; i++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800254 if(mdpToLayer[i].pipeInfo) {
255 delete mdpToLayer[i].pipeInfo;
256 mdpToLayer[i].pipeInfo = NULL;
257 //We dont own the rotator
258 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800259 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800260 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800261
262 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
263 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700264 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800265
Saurabh Shahaa236822013-04-24 18:07:26 -0700266 layerCount = numLayers;
267 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800268 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700269 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800270 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800271}
272
Saurabh Shahaa236822013-04-24 18:07:26 -0700273void MDPComp::FrameInfo::map() {
274 // populate layer and MDP maps
275 int mdpIdx = 0;
276 for(int idx = 0; idx < layerCount; idx++) {
277 if(!isFBComposed[idx]) {
278 mdpToLayer[mdpIdx].listIndex = idx;
279 layerToMDP[idx] = mdpIdx++;
280 }
281 }
282}
283
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800284MDPComp::LayerCache::LayerCache() {
285 reset();
286}
287
288void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700289 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530290 memset(&isFBComposed, true, sizeof(isFBComposed));
291 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800292 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700293}
294
295void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530296 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700297 for(int i = 0; i < numAppLayers; i++) {
298 hnd[i] = list->hwLayers[i].handle;
299 }
300}
301
302void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700303 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530304 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
305 memcpy(&drop, &curFrame.drop, sizeof(drop));
306}
307
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800308bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
309 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530310 if(layerCount != curFrame.layerCount)
311 return false;
312 for(int i = 0; i < curFrame.layerCount; i++) {
313 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
314 (curFrame.drop[i] != drop[i])) {
315 return false;
316 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800317 if(curFrame.isFBComposed[i] &&
318 (hnd[i] != list->hwLayers[i].handle)){
319 return false;
320 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530321 }
322 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800323}
324
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700325bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
326 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800327 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700328 (not isValidDimension(ctx,layer))
329 //More conditions here, SKIP, sRGB+Blend etc
330 ) {
331 return false;
332 }
333 return true;
334}
335
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530336bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800337 private_handle_t *hnd = (private_handle_t *)layer->handle;
338
339 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700340 if (layer->flags & HWC_COLOR_FILL) {
341 // Color layer
342 return true;
343 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700344 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800345 return false;
346 }
347
Naseer Ahmede850a802013-09-06 13:12:52 -0400348 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400349 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400350 return false;
351
Saurabh Shah62e1d732013-09-17 10:44:05 -0700352 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700353 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700354 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700355 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
356 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700357 int dst_w = dst.right - dst.left;
358 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800359 float w_scale = ((float)crop_w / (float)dst_w);
360 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530361 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700362
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800363 /* Workaround for MDP HW limitation in DSI command mode panels where
364 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
365 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530366 * There also is a HW limilation in MDP, minimum block size is 2x2
367 * Fallback to GPU if height is less than 2.
368 */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800369 if((crop_w < 5)||(crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800370 return false;
371
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800372 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530373 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800374 const float w_dscale = w_scale;
375 const float h_dscale = h_scale;
376
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800377 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700378
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530379 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700380 /* On targets that doesnt support Decimation (eg.,8x26)
381 * maximum downscale support is overlay pipe downscale.
382 */
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530383 if(crop_w > mdpHw.getMaxMixerWidth() ||
384 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700385 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800386 return false;
387 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700388 // Decimation on macrotile format layers is not supported.
389 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530390 /* Bail out if
391 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700392 * 2. exceeds maximum downscale limit
393 */
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530394 if(((crop_w > mdpHw.getMaxMixerWidth()) &&
395 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700396 w_dscale > maxMDPDownscale ||
397 h_dscale > maxMDPDownscale) {
398 return false;
399 }
400 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800401 return false;
402 }
403 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700404 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700405 return false;
406 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700407 }
408
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800409 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530410 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800411 const float w_uscale = 1.0f / w_scale;
412 const float h_uscale = 1.0f / h_scale;
413
414 if(w_uscale > upscale || h_uscale > upscale)
415 return false;
416 }
417
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800418 return true;
419}
420
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800421bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700422 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800423
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800424 if(!isEnabled()) {
425 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700426 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530427 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530428 qdutils::MDPVersion::getInstance().is8x16() ||
429 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800430 ctx->mVideoTransFlag &&
431 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700432 //1 Padding round to shift pipes across mixers
433 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
434 __FUNCTION__);
435 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700436 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
437 /* TODO: freeing up all the resources only for the targets having total
438 number of pipes < 8. Need to analyze number of VIG pipes used
439 for primary in previous draw cycle and accordingly decide
440 whether to fall back to full GPU comp or video only comp
441 */
442 if(isSecondaryConfiguring(ctx)) {
443 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
444 __FUNCTION__);
445 ret = false;
446 } else if(ctx->isPaddingRound) {
447 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
448 __FUNCTION__,mDpy);
449 ret = false;
450 }
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700451 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700452 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800453}
454
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800455void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
456 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
457 fbRect = getIntersection(fbRect, roi);
458}
459
460/* 1) Identify layers that are not visible or lying outside the updating ROI and
461 * drop them from composition.
462 * 2) If we have a scaling layer which needs cropping against generated
463 * ROI, reset ROI to full resolution. */
464bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
465 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700466 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800467 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800468
469 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800470 if(!isValidRect(visibleRect)) {
471 mCurrentFrame.drop[i] = true;
472 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800473 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800474 }
475
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700476 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700477 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800478 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700479
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700480 if(!isValidRect(res)) {
481 mCurrentFrame.drop[i] = true;
482 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800483 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700484 /* Reset frame ROI when any layer which needs scaling also needs ROI
485 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800486 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800487 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700488 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
489 mCurrentFrame.dropCount = 0;
490 return false;
491 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800492
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800493 /* deduct any opaque region from visibleRect */
494 if (layer->blending == HWC_BLENDING_NONE)
495 visibleRect = deductRect(visibleRect, res);
496 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700497 }
498 return true;
499}
500
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800501/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
502 * are updating. If DirtyRegion is applicable, calculate it by accounting all
503 * the changing layer's dirtyRegion. */
504void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
505 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700506 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800507 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700508 return;
509
510 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800511 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
512 (int)ctx->dpyAttr[mDpy].yres};
513
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700514 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800515 hwc_layer_1_t* layer = &list->hwLayers[index];
516 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800517 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700518 hwc_rect_t dst = layer->displayFrame;
519 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800520
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800521#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800522 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700523 {
524 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
525 int x_off = dst.left - src.left;
526 int y_off = dst.top - src.top;
527 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
528 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800529#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800530
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800531 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700532 }
533 }
534
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800535 /* No layer is updating. Still SF wants a refresh.*/
536 if(!isValidRect(roi))
537 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800538
539 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800540 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800541
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800542 ctx->listStats[mDpy].lRoi = roi;
543 if(!validateAndApplyROI(ctx, list))
544 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700545
546 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800547 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
548 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
549}
550
551void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
552 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
553 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
554
555 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
556 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
557 fbRect = getUnion(l_fbRect, r_fbRect);
558}
559/* 1) Identify layers that are not visible or lying outside BOTH the updating
560 * ROI's and drop them from composition. If a layer is spanning across both
561 * the halves of the screen but needed by only ROI, the non-contributing
562 * half will not be programmed for MDP.
563 * 2) If we have a scaling layer which needs cropping against generated
564 * ROI, reset ROI to full resolution. */
565bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
566 hwc_display_contents_1_t* list) {
567
568 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
569
570 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
571 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
572
573 for(int i = numAppLayers - 1; i >= 0; i--){
574 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
575 {
576 mCurrentFrame.drop[i] = true;
577 mCurrentFrame.dropCount++;
578 continue;
579 }
580
581 const hwc_layer_1_t* layer = &list->hwLayers[i];
582 hwc_rect_t dstRect = layer->displayFrame;
583
584 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
585 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
586 hwc_rect_t res = getUnion(l_res, r_res);
587
588 if(!isValidRect(l_res) && !isValidRect(r_res)) {
589 mCurrentFrame.drop[i] = true;
590 mCurrentFrame.dropCount++;
591 } else {
592 /* Reset frame ROI when any layer which needs scaling also needs ROI
593 * cropping */
594 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
595 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
596 mCurrentFrame.dropCount = 0;
597 return false;
598 }
599
600 if (layer->blending == HWC_BLENDING_NONE) {
601 visibleRectL = deductRect(visibleRectL, l_res);
602 visibleRectR = deductRect(visibleRectR, r_res);
603 }
604 }
605 }
606 return true;
607}
608/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
609 * are updating. If DirtyRegion is applicable, calculate it by accounting all
610 * the changing layer's dirtyRegion. */
611void MDPCompSplit::generateROI(hwc_context_t *ctx,
612 hwc_display_contents_1_t* list) {
613 if(!canPartialUpdate(ctx, list))
614 return;
615
616 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
617 int lSplit = getLeftSplit(ctx, mDpy);
618
619 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
620 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
621
622 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
623 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
624
625 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
626 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
627
628 for(int index = 0; index < numAppLayers; index++ ) {
629 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800630 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800631 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800632 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700633 hwc_rect_t dst = layer->displayFrame;
634 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800635
636#ifdef QCOM_BSP
637 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700638 {
639 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
640 int x_off = dst.left - src.left;
641 int y_off = dst.top - src.top;
642 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
643 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800644#endif
645
646 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
647 if(isValidRect(l_dst))
648 l_roi = getUnion(l_roi, l_dst);
649
650 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
651 if(isValidRect(r_dst))
652 r_roi = getUnion(r_roi, r_dst);
653 }
654 }
655
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700656 /* For panels that cannot accept commands in both the interfaces, we cannot
657 * send two ROI's (for each half). We merge them into single ROI and split
658 * them across lSplit for MDP mixer use. The ROI's will be merged again
659 * finally before udpating the panel in the driver. */
660 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
661 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
662 l_roi = getIntersection(temp_roi, l_frame);
663 r_roi = getIntersection(temp_roi, r_frame);
664 }
665
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800666 /* No layer is updating. Still SF wants a refresh. */
667 if(!isValidRect(l_roi) && !isValidRect(r_roi))
668 return;
669
670 l_roi = getSanitizeROI(l_roi, l_frame);
671 r_roi = getSanitizeROI(r_roi, r_frame);
672
673 ctx->listStats[mDpy].lRoi = l_roi;
674 ctx->listStats[mDpy].rRoi = r_roi;
675
676 if(!validateAndApplyROI(ctx, list))
677 resetROI(ctx, mDpy);
678
679 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
680 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
681 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
682 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
683 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
684 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700685}
686
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800687/* Checks for conditions where all the layers marked for MDP comp cannot be
688 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800689bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800690 hwc_display_contents_1_t* list){
691
Saurabh Shahaa236822013-04-24 18:07:26 -0700692 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800693 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800694
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -0700695 // No Idle fall back, if secure display or secure RGB layers are present
696 if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
697 !ctx->listStats[mDpy].secureRGBCount)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700698 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
699 return false;
700 }
701
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800702 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700703 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
704 __FUNCTION__,
705 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800706 return false;
707 }
708
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700709 // if secondary is configuring or Padding round, fall back to video only
710 // composition and release all assigned non VIG pipes from primary.
711 if(isSecondaryConfiguring(ctx)) {
712 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
713 __FUNCTION__);
714 return false;
715 } else if(ctx->isPaddingRound) {
716 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
717 __FUNCTION__,mDpy);
718 return false;
719 }
720
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530721 MDPVersion& mdpHw = MDPVersion::getInstance();
722 if(mDpy > HWC_DISPLAY_PRIMARY &&
723 (priDispW > mdpHw.getMaxMixerWidth()) &&
724 (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800725 // Disable MDP comp on Secondary when the primary is highres panel and
726 // the secondary is a normal 1080p, because, MDP comp on secondary under
727 // in such usecase, decimation gets used for downscale and there will be
728 // a quality mismatch when there will be a fallback to GPU comp
729 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
730 __FUNCTION__);
731 return false;
732 }
733
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700734 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800735 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700736 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800737 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
738 return false;
739 }
740
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800741 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800742 hwc_layer_1_t* layer = &list->hwLayers[i];
743 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800744
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800745 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700746 if(!canUseRotator(ctx, mDpy)) {
747 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
748 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700749 return false;
750 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800751 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530752
753 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
754 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700755 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530756 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
757 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
758 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800759 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700760
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700761 if(ctx->mAD->isDoable()) {
762 return false;
763 }
764
Saurabh Shahaa236822013-04-24 18:07:26 -0700765 //If all above hard conditions are met we can do full or partial MDP comp.
766 bool ret = false;
767 if(fullMDPComp(ctx, list)) {
768 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700769 } else if(fullMDPCompWithPTOR(ctx, list)) {
770 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700771 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700772 ret = true;
773 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530774
Saurabh Shahaa236822013-04-24 18:07:26 -0700775 return ret;
776}
777
778bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700779
780 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
781 return false;
782
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700783 //Will benefit presentation / secondary-only layer.
784 if((mDpy > HWC_DISPLAY_PRIMARY) &&
785 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
786 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
787 return false;
788 }
789
790 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
791 for(int i = 0; i < numAppLayers; i++) {
792 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700793 if(not mCurrentFrame.drop[i] and
794 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700795 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
796 return false;
797 }
798 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800799
Saurabh Shahaa236822013-04-24 18:07:26 -0700800 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700801 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
802 sizeof(mCurrentFrame.isFBComposed));
803 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
804 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700805
Raj Kamal389d6e32014-08-04 14:43:24 +0530806 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800807 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530808 }
809
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800810 if(!postHeuristicsHandling(ctx, list)) {
811 ALOGD_IF(isDebug(), "post heuristic handling failed");
812 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700813 return false;
814 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700815 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
816 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700817 return true;
818}
819
Sushil Chauhandefd3522014-05-13 18:17:12 -0700820/* Full MDP Composition with Peripheral Tiny Overlap Removal.
821 * MDP bandwidth limitations can be avoided, if the overlap region
822 * covered by the smallest layer at a higher z-order, gets composed
823 * by Copybit on a render buffer, which can be queued to MDP.
824 */
825bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
826 hwc_display_contents_1_t* list) {
827
828 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
829 const int stagesForMDP = min(sMaxPipesPerMixer,
830 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
831
832 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700833 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700834 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
835 return false;
836 }
837
838 // Frame level checks
839 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
840 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
841 isSecurePresent(ctx, mDpy)) {
842 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
843 return false;
844 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700845 // MDP comp checks
846 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700847 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700848 if(not isSupportedForMDPComp(ctx, layer)) {
849 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
850 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700851 }
852 }
853
Sushil Chauhandefd3522014-05-13 18:17:12 -0700854 /* We cannot use this composition mode, if:
855 1. A below layer needs scaling.
856 2. Overlap is not peripheral to display.
857 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700858 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700859 */
860
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700861 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
862 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
863 memset(overlapRect, 0, sizeof(overlapRect));
864 int layerPixelCount, minPixelCount = 0;
865 int numPTORLayersFound = 0;
866 for (int i = numAppLayers-1; (i >= 0 &&
867 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700868 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700869 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700870 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700871 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
872 // PTOR layer should be peripheral and cannot have transform
873 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
874 has90Transform(layer)) {
875 continue;
876 }
877 if((3 * (layerPixelCount + minPixelCount)) >
878 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
879 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
880 continue;
881 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700882 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700883 for (int j = i-1; j >= 0; j--) {
884 // Check if the layers below this layer qualifies for PTOR comp
885 hwc_layer_1_t* layer = &list->hwLayers[j];
886 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700887 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700888 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700889 if (isValidRect(getIntersection(dispFrame, disFrame))) {
890 if (has90Transform(layer) || needsScaling(layer)) {
891 found = false;
892 break;
893 }
894 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700895 }
896 }
897 // Store the minLayer Index
898 if(found) {
899 minLayerIndex[numPTORLayersFound] = i;
900 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
901 minPixelCount += layerPixelCount;
902 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700903 }
904 }
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 // Store the displayFrame and the sourceCrops of the layers
911 hwc_rect_t displayFrame[numAppLayers];
912 hwc_rect_t sourceCrop[numAppLayers];
913 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700914 hwc_layer_1_t* layer = &list->hwLayers[i];
915 displayFrame[i] = layer->displayFrame;
916 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700917 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700918
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530919 /**
920 * It's possible that 2 PTOR layers might have overlapping.
921 * In such case, remove the intersection(again if peripheral)
922 * from the lower PTOR layer to avoid overlapping.
923 * If intersection is not on peripheral then compromise
924 * by reducing number of PTOR layers.
925 **/
926 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
927 if(isValidRect(commonRect)) {
928 overlapRect[1] = deductRect(overlapRect[1], commonRect);
929 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
930 }
931
932 ctx->mPtorInfo.count = numPTORLayersFound;
933 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
934 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
935 }
936
937 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
938 // reset PTOR
939 ctx->mPtorInfo.count = 0;
940 if(isValidRect(commonRect)) {
941 // If PTORs are intersecting restore displayframe of PTOR[1]
942 // before returning, as we have modified it above.
943 list->hwLayers[minLayerIndex[1]].displayFrame =
944 displayFrame[minLayerIndex[1]];
945 }
946 return false;
947 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700948 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
949 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
950
Xu Yangcda012c2014-07-30 21:57:21 +0800951 // Store the blending mode, planeAlpha, and transform of PTOR layers
952 int32_t blending[numPTORLayersFound];
953 uint8_t planeAlpha[numPTORLayersFound];
954 uint32_t transform[numPTORLayersFound];
955
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700956 for(int j = 0; j < numPTORLayersFound; j++) {
957 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700958
959 // Update src crop of PTOR layer
960 hwc_layer_1_t* layer = &list->hwLayers[index];
961 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
962 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
963 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
964 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
965
966 // Store & update w, h, format of PTOR layer
967 private_handle_t *hnd = (private_handle_t *)layer->handle;
968 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
969 layerWhf[j] = whf;
970 hnd->width = renderBuf->width;
971 hnd->height = renderBuf->height;
972 hnd->format = renderBuf->format;
973
Xu Yangcda012c2014-07-30 21:57:21 +0800974 // Store & update blending mode, planeAlpha and transform of PTOR layer
975 blending[j] = layer->blending;
976 planeAlpha[j] = layer->planeAlpha;
977 transform[j] = layer->transform;
978 layer->blending = HWC_BLENDING_NONE;
979 layer->planeAlpha = 0xFF;
980 layer->transform = 0;
981
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700982 // Remove overlap from crop & displayFrame of below layers
983 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700984 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700985 if(!isValidRect(getIntersection(layer->displayFrame,
986 overlapRect[j]))) {
987 continue;
988 }
989 // Update layer attributes
990 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
991 hwc_rect_t destRect = deductRect(layer->displayFrame,
992 overlapRect[j]);
993 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
994 layer->transform);
995 layer->sourceCropf.left = (float)srcCrop.left;
996 layer->sourceCropf.top = (float)srcCrop.top;
997 layer->sourceCropf.right = (float)srcCrop.right;
998 layer->sourceCropf.bottom = (float)srcCrop.bottom;
999 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001000 }
1001
1002 mCurrentFrame.mdpCount = numAppLayers;
1003 mCurrentFrame.fbCount = 0;
1004 mCurrentFrame.fbZ = -1;
1005
1006 for (int j = 0; j < numAppLayers; j++)
1007 mCurrentFrame.isFBComposed[j] = false;
1008
1009 bool result = postHeuristicsHandling(ctx, list);
1010
1011 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001012 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001013 hwc_layer_1_t* layer = &list->hwLayers[i];
1014 layer->displayFrame = displayFrame[i];
1015 layer->sourceCropf.left = (float)sourceCrop[i].left;
1016 layer->sourceCropf.top = (float)sourceCrop[i].top;
1017 layer->sourceCropf.right = (float)sourceCrop[i].right;
1018 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1019 }
1020
Xu Yangcda012c2014-07-30 21:57:21 +08001021 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001022 for (int i = 0; i < numPTORLayersFound; i++) {
1023 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001024 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001025 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1026 hnd->width = layerWhf[i].w;
1027 hnd->height = layerWhf[i].h;
1028 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001029 layer->blending = blending[i];
1030 layer->planeAlpha = planeAlpha[i];
1031 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001032 }
1033
Sushil Chauhandefd3522014-05-13 18:17:12 -07001034 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001035 // reset PTOR
1036 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001037 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001038 } else {
1039 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1040 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001041 }
1042
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001043 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1044 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001045 return result;
1046}
1047
Saurabh Shahaa236822013-04-24 18:07:26 -07001048bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1049{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001050 if(!sEnableMixedMode) {
1051 //Mixed mode is disabled. No need to even try caching.
1052 return false;
1053 }
1054
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001055 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001056 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001057 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001058 cacheBasedComp(ctx, list);
1059 } else {
1060 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001061 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001062 }
1063
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001064 return ret;
1065}
1066
1067bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1068 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001069 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1070 return false;
1071
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001072 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001073 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001074 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001075
1076 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1077 for(int i = 0; i < numAppLayers; i++) {
1078 if(!mCurrentFrame.isFBComposed[i]) {
1079 hwc_layer_1_t* layer = &list->hwLayers[i];
1080 if(not isSupportedForMDPComp(ctx, layer)) {
1081 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1082 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001083 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001084 return false;
1085 }
1086 }
1087 }
1088
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001089 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001090 /* mark secure RGB layers for MDP comp */
1091 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301092 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001093 if(!ret) {
1094 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001095 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001096 return false;
1097 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001098
1099 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001100
Raj Kamal389d6e32014-08-04 14:43:24 +05301101 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001102 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301103 }
1104
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001105 //Will benefit cases where a video has non-updating background.
1106 if((mDpy > HWC_DISPLAY_PRIMARY) and
1107 (mdpCount > MAX_SEC_LAYERS)) {
1108 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001109 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001110 return false;
1111 }
1112
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001113 if(!postHeuristicsHandling(ctx, list)) {
1114 ALOGD_IF(isDebug(), "post heuristic handling failed");
1115 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001116 return false;
1117 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001118 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1119 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001120
Saurabh Shahaa236822013-04-24 18:07:26 -07001121 return true;
1122}
1123
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001124bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001125 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001126 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1127 return false;
1128
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001129 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001130 return false;
1131 }
1132
Saurabh Shahb772ae32013-11-18 15:40:02 -08001133 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001134 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1135 const int stagesForMDP = min(sMaxPipesPerMixer,
1136 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001137
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001138 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1139 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1140 int lastMDPSupportedIndex = numAppLayers;
1141 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001142
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001143 //Find the minimum MDP batch size
1144 for(int i = 0; i < numAppLayers;i++) {
1145 if(mCurrentFrame.drop[i]) {
1146 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001147 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001148 }
1149 hwc_layer_1_t* layer = &list->hwLayers[i];
1150 if(not isSupportedForMDPComp(ctx, layer)) {
1151 lastMDPSupportedIndex = i;
1152 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1153 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001154 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001155 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001156 }
1157
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001158 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1159 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1160 mCurrentFrame.dropCount);
1161
1162 //Start at a point where the fb batch should at least have 2 layers, for
1163 //this mode to be justified.
1164 while(fbBatchSize < 2) {
1165 ++fbBatchSize;
1166 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001167 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001168
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001169 //If there are no layers for MDP, this mode doesnt make sense.
1170 if(mdpBatchSize < 1) {
1171 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1172 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001173 return false;
1174 }
1175
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001176 mCurrentFrame.reset(numAppLayers);
1177
1178 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1179 while(mdpBatchSize > 0) {
1180 //Mark layers for MDP comp
1181 int mdpBatchLeft = mdpBatchSize;
1182 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1183 if(mCurrentFrame.drop[i]) {
1184 continue;
1185 }
1186 mCurrentFrame.isFBComposed[i] = false;
1187 --mdpBatchLeft;
1188 }
1189
1190 mCurrentFrame.fbZ = mdpBatchSize;
1191 mCurrentFrame.fbCount = fbBatchSize;
1192 mCurrentFrame.mdpCount = mdpBatchSize;
1193
1194 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1195 __FUNCTION__, mdpBatchSize, fbBatchSize,
1196 mCurrentFrame.dropCount);
1197
1198 if(postHeuristicsHandling(ctx, list)) {
1199 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001200 __FUNCTION__);
1201 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1202 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001203 return true;
1204 }
1205
1206 reset(ctx);
1207 --mdpBatchSize;
1208 ++fbBatchSize;
1209 }
1210
1211 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001212}
1213
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001214bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301215 if(mDpy or isSecurePresent(ctx, mDpy) or
1216 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001217 return false;
1218 }
1219 return true;
1220}
1221
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001222bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1223 hwc_display_contents_1_t* list){
1224 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1225 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1226 mDpy ) {
1227 return false;
1228 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001229 if(ctx->listStats[mDpy].secureUI)
1230 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001231 return true;
1232}
1233
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001234bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1235 hwc_display_contents_1_t* list) {
1236 const bool secureOnly = true;
1237 return videoOnlyComp(ctx, list, not secureOnly) or
1238 videoOnlyComp(ctx, list, secureOnly);
1239}
1240
1241bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001242 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001243 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1244 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001245 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001246
Saurabh Shahaa236822013-04-24 18:07:26 -07001247 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001248 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001249 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001250 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001251
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001252 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1253 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001254 return false;
1255 }
1256
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001257 /* Bail out if we are processing only secured video layers
1258 * and we dont have any */
1259 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001260 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001261 return false;
1262 }
1263
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001264 if(mCurrentFrame.fbCount)
1265 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001266
Raj Kamal389d6e32014-08-04 14:43:24 +05301267 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001268 adjustForSourceSplit(ctx, list);
1269 }
1270
1271 if(!postHeuristicsHandling(ctx, list)) {
1272 ALOGD_IF(isDebug(), "post heuristic handling failed");
1273 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001274 return false;
1275 }
1276
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001277 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1278 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001279 return true;
1280}
1281
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001282/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1283bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1284 hwc_display_contents_1_t* list) {
1285 const bool secureOnly = true;
1286 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1287 mdpOnlyLayersComp(ctx, list, secureOnly);
1288
1289}
1290
1291bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1292 hwc_display_contents_1_t* list, bool secureOnly) {
1293
1294 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1295 return false;
1296
1297 /* Bail out if we are processing only secured video layers
1298 * and we dont have any */
1299 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1300 reset(ctx);
1301 return false;
1302 }
1303
1304 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1305 mCurrentFrame.reset(numAppLayers);
1306 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1307
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001308 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001309 /* mark secure RGB layers for MDP comp */
1310 updateSecureRGB(ctx, list);
1311
1312 if(mCurrentFrame.mdpCount == 0) {
1313 reset(ctx);
1314 return false;
1315 }
1316
1317 /* find the maximum batch of layers to be marked for framebuffer */
1318 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1319 if(!ret) {
1320 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1321 reset(ctx);
1322 return false;
1323 }
1324
1325 if(sEnableYUVsplit){
1326 adjustForSourceSplit(ctx, list);
1327 }
1328
1329 if(!postHeuristicsHandling(ctx, list)) {
1330 ALOGD_IF(isDebug(), "post heuristic handling failed");
1331 reset(ctx);
1332 return false;
1333 }
1334
1335 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1336 __FUNCTION__);
1337 return true;
1338}
1339
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001340/* Checks for conditions where YUV layers cannot be bypassed */
1341bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001342 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001343 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001344 return false;
1345 }
1346
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001347 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001348 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1349 return false;
1350 }
1351
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001352 if(isSecuring(ctx, layer)) {
1353 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1354 return false;
1355 }
1356
Saurabh Shah4fdde762013-04-30 18:47:33 -07001357 if(!isValidDimension(ctx, layer)) {
1358 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1359 __FUNCTION__);
1360 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001361 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001362
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001363 if(layer->planeAlpha < 0xFF) {
1364 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1365 in video only mode",
1366 __FUNCTION__);
1367 return false;
1368 }
1369
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001370 return true;
1371}
1372
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001373/* Checks for conditions where Secure RGB layers cannot be bypassed */
1374bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1375 if(isSkipLayer(layer)) {
1376 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1377 __FUNCTION__, mDpy);
1378 return false;
1379 }
1380
1381 if(isSecuring(ctx, layer)) {
1382 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1383 return false;
1384 }
1385
1386 if(not isSupportedForMDPComp(ctx, layer)) {
1387 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1388 __FUNCTION__);
1389 return false;
1390 }
1391 return true;
1392}
1393
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301394/* starts at fromIndex and check for each layer to find
1395 * if it it has overlapping with any Updating layer above it in zorder
1396 * till the end of the batch. returns true if it finds any intersection */
1397bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1398 int fromIndex, int toIndex) {
1399 for(int i = fromIndex; i < toIndex; i++) {
1400 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1401 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1402 return false;
1403 }
1404 }
1405 }
1406 return true;
1407}
1408
1409/* Checks if given layer at targetLayerIndex has any
1410 * intersection with all the updating layers in beween
1411 * fromIndex and toIndex. Returns true if it finds intersectiion */
1412bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1413 int fromIndex, int toIndex, int targetLayerIndex) {
1414 for(int i = fromIndex; i <= toIndex; i++) {
1415 if(!mCurrentFrame.isFBComposed[i]) {
1416 if(areLayersIntersecting(&list->hwLayers[i],
1417 &list->hwLayers[targetLayerIndex])) {
1418 return true;
1419 }
1420 }
1421 }
1422 return false;
1423}
1424
1425int MDPComp::getBatch(hwc_display_contents_1_t* list,
1426 int& maxBatchStart, int& maxBatchEnd,
1427 int& maxBatchCount) {
1428 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301429 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001430 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301431 while (i < mCurrentFrame.layerCount) {
1432 int batchCount = 0;
1433 int batchStart = i;
1434 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001435 /* Adjust batch Z order with the dropped layers so far */
1436 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301437 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301438 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301439 while(i < mCurrentFrame.layerCount) {
1440 if(!mCurrentFrame.isFBComposed[i]) {
1441 if(!batchCount) {
1442 i++;
1443 break;
1444 }
1445 updatingLayersAbove++;
1446 i++;
1447 continue;
1448 } else {
1449 if(mCurrentFrame.drop[i]) {
1450 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001451 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301452 continue;
1453 } else if(updatingLayersAbove <= 0) {
1454 batchCount++;
1455 batchEnd = i;
1456 i++;
1457 continue;
1458 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1459
1460 // We have a valid updating layer already. If layer-i not
1461 // have overlapping with all updating layers in between
1462 // batch-start and i, then we can add layer i to batch.
1463 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1464 batchCount++;
1465 batchEnd = i;
1466 i++;
1467 continue;
1468 } else if(canPushBatchToTop(list, batchStart, i)) {
1469 //If All the non-updating layers with in this batch
1470 //does not have intersection with the updating layers
1471 //above in z-order, then we can safely move the batch to
1472 //higher z-order. Increment fbZ as it is moving up.
1473 if( firstZReverseIndex < 0) {
1474 firstZReverseIndex = i;
1475 }
1476 batchCount++;
1477 batchEnd = i;
1478 fbZ += updatingLayersAbove;
1479 i++;
1480 updatingLayersAbove = 0;
1481 continue;
1482 } else {
1483 //both failed.start the loop again from here.
1484 if(firstZReverseIndex >= 0) {
1485 i = firstZReverseIndex;
1486 }
1487 break;
1488 }
1489 }
1490 }
1491 }
1492 if(batchCount > maxBatchCount) {
1493 maxBatchCount = batchCount;
1494 maxBatchStart = batchStart;
1495 maxBatchEnd = batchEnd;
1496 fbZOrder = fbZ;
1497 }
1498 }
1499 return fbZOrder;
1500}
1501
1502bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1503 hwc_display_contents_1_t* list) {
1504 /* Idea is to keep as many non-updating(cached) layers in FB and
1505 * send rest of them through MDP. This is done in 2 steps.
1506 * 1. Find the maximum contiguous batch of non-updating layers.
1507 * 2. See if we can improve this batch size for caching by adding
1508 * opaque layers around the batch, if they don't have
1509 * any overlapping with the updating layers in between.
1510 * NEVER mark an updating layer for caching.
1511 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001512
1513 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001514 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001515 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301516 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001517
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001518 /* Nothing is cached. No batching needed */
1519 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001520 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001521 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001522
1523 /* No MDP comp layers, try to use other comp modes */
1524 if(mCurrentFrame.mdpCount == 0) {
1525 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001526 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001527
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301528 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001529
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301530 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001531 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001532 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001533 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301534 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001535 if(!mCurrentFrame.drop[i]){
1536 //If an unsupported layer is being attempted to
1537 //be pulled out we should fail
1538 if(not isSupportedForMDPComp(ctx, layer)) {
1539 return false;
1540 }
1541 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001542 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001543 }
1544 }
1545
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301546 // update the frame data
1547 mCurrentFrame.fbZ = fbZ;
1548 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001549 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001550 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001551
1552 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301553 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001554
1555 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001556}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001557
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001558void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001559 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001560 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001561 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001562
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001563 for(int i = 0; i < numAppLayers; i++) {
1564 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001565 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001566 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001567 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001568 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001569 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001570 }
1571 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001572
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001573 frame.fbCount = fbCount;
1574 frame.mdpCount = frame.layerCount - frame.fbCount
1575 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001576
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001577 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1578 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001579}
1580
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001581void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001582 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001583 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1584 for(int index = 0;index < nYuvCount; index++){
1585 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1586 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1587
1588 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001589 if(!frame.isFBComposed[nYuvIndex]) {
1590 frame.isFBComposed[nYuvIndex] = true;
1591 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001592 }
1593 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001594 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001595 private_handle_t *hnd = (private_handle_t *)layer->handle;
1596 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001597 frame.isFBComposed[nYuvIndex] = false;
1598 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001599 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001600 }
1601 }
1602 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001603
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001604 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1605 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001606}
1607
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001608void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1609 hwc_display_contents_1_t* list) {
1610 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1611 for(int index = 0;index < nSecureRGBCount; index++){
1612 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1613 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1614
1615 if(!isSecureRGBDoable(ctx, layer)) {
1616 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1617 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1618 mCurrentFrame.fbCount++;
1619 }
1620 } else {
1621 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1622 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1623 mCurrentFrame.fbCount--;
1624 }
1625 }
1626 }
1627
1628 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1629 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1630 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1631 mCurrentFrame.fbCount);
1632}
1633
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001634hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1635 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001636 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001637
1638 /* Update only the region of FB needed for composition */
1639 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1640 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1641 hwc_layer_1_t* layer = &list->hwLayers[i];
1642 hwc_rect_t dst = layer->displayFrame;
1643 fbRect = getUnion(fbRect, dst);
1644 }
1645 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001646 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001647 return fbRect;
1648}
1649
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001650bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1651 hwc_display_contents_1_t* list) {
1652
1653 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001654 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001655 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1656 return false;
1657 }
1658
1659 //Limitations checks
1660 if(!hwLimitationsCheck(ctx, list)) {
1661 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1662 return false;
1663 }
1664
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001665 //Configure framebuffer first if applicable
1666 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001667 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001668 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1669 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001670 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1671 __FUNCTION__);
1672 return false;
1673 }
1674 }
1675
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001676 mCurrentFrame.map();
1677
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001678 if(!allocLayerPipes(ctx, list)) {
1679 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001680 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001681 }
1682
1683 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001684 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001685 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001686 int mdpIndex = mCurrentFrame.layerToMDP[index];
1687 hwc_layer_1_t* layer = &list->hwLayers[index];
1688
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301689 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1690 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1691 mdpNextZOrder++;
1692 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001693 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1694 cur_pipe->zOrder = mdpNextZOrder++;
1695
radhakrishnac9a67412013-09-25 17:40:42 +05301696 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301697 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301698 if(configure4k2kYuv(ctx, layer,
1699 mCurrentFrame.mdpToLayer[mdpIndex])
1700 != 0 ){
1701 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1702 for layer %d",__FUNCTION__, index);
1703 return false;
1704 }
1705 else{
1706 mdpNextZOrder++;
1707 }
1708 continue;
1709 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001710 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1711 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301712 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001713 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001714 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001715 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001716 }
1717
Saurabh Shaha36be922013-12-16 18:18:39 -08001718 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1719 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1720 ,__FUNCTION__, mDpy);
1721 return false;
1722 }
1723
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001724 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001725 return true;
1726}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001727
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001728bool MDPComp::resourceCheck(hwc_context_t* ctx,
1729 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001730 const bool fbUsed = mCurrentFrame.fbCount;
1731 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1732 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1733 return false;
1734 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001735 // Init rotCount to number of rotate sessions used by other displays
1736 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1737 // Count the number of rotator sessions required for current display
1738 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1739 if(!mCurrentFrame.isFBComposed[index]) {
1740 hwc_layer_1_t* layer = &list->hwLayers[index];
1741 private_handle_t *hnd = (private_handle_t *)layer->handle;
1742 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1743 rotCount++;
1744 }
1745 }
1746 }
1747 // if number of layers to rotate exceeds max rotator sessions, bail out.
1748 if(rotCount > RotMgr::MAX_ROT_SESS) {
1749 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1750 __FUNCTION__, mDpy);
1751 return false;
1752 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001753 return true;
1754}
1755
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301756bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1757 hwc_display_contents_1_t* list) {
1758
1759 //A-family hw limitation:
1760 //If a layer need alpha scaling, MDP can not support.
1761 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1762 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1763 if(!mCurrentFrame.isFBComposed[i] &&
1764 isAlphaScaled( &list->hwLayers[i])) {
1765 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1766 return false;
1767 }
1768 }
1769 }
1770
1771 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1772 //If multiple layers requires downscaling and also they are overlapping
1773 //fall back to GPU since MDSS can not handle it.
1774 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1775 qdutils::MDPVersion::getInstance().is8x26()) {
1776 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1777 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1778 if(!mCurrentFrame.isFBComposed[i] &&
1779 isDownscaleRequired(botLayer)) {
1780 //if layer-i is marked for MDP and needs downscaling
1781 //check if any MDP layer on top of i & overlaps with layer-i
1782 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1783 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1784 if(!mCurrentFrame.isFBComposed[j] &&
1785 isDownscaleRequired(topLayer)) {
1786 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1787 topLayer->displayFrame);
1788 if(isValidRect(r))
1789 return false;
1790 }
1791 }
1792 }
1793 }
1794 }
1795 return true;
1796}
1797
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001798int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001799 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001800 char property[PROPERTY_VALUE_MAX];
1801
Raj Kamal4393eaa2014-06-06 13:45:20 +05301802 if(!ctx || !list) {
1803 ALOGE("%s: Invalid context or list",__FUNCTION__);
1804 mCachedFrame.reset();
1805 return -1;
1806 }
1807
1808 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001809 if(mDpy == HWC_DISPLAY_PRIMARY) {
1810 sSimulationFlags = 0;
1811 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1812 int currentFlags = atoi(property);
1813 if(currentFlags != sSimulationFlags) {
1814 sSimulationFlags = currentFlags;
1815 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1816 sSimulationFlags, sSimulationFlags);
1817 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001818 }
1819 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001820 // reset PTOR
1821 if(!mDpy)
1822 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001823
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301824 //Do not cache the information for next draw cycle.
1825 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1826 ALOGI("%s: Unsupported layer count for mdp composition",
1827 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001828 mCachedFrame.reset();
1829 return -1;
1830 }
1831
Saurabh Shahb39f8152013-08-22 10:21:44 -07001832 //reset old data
1833 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001834 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1835 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301836
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001837 // Detect the start of animation and fall back to GPU only once to cache
1838 // all the layers in FB and display FB content untill animation completes.
1839 if(ctx->listStats[mDpy].isDisplayAnimating) {
1840 mCurrentFrame.needsRedraw = false;
1841 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1842 mCurrentFrame.needsRedraw = true;
1843 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1844 }
1845 setMDPCompLayerFlags(ctx, list);
1846 mCachedFrame.updateCounts(mCurrentFrame);
1847 ret = -1;
1848 return ret;
1849 } else {
1850 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1851 }
1852
Saurabh Shahb39f8152013-08-22 10:21:44 -07001853 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001854 if(isFrameDoable(ctx)) {
1855 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001856
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001857 // if tryFullFrame fails, try to push all video and secure RGB layers
1858 // to MDP for composition.
1859 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
1860 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301861 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001862 setMDPCompLayerFlags(ctx, list);
1863 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001864 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001865 reset(ctx);
1866 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1867 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001868 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001869 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1870 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001871 }
1872 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001873 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1874 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001875 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001876 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001877
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001878 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001879 ALOGD("GEOMETRY change: %d",
1880 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001881 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001882 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001883 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001884 }
1885
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001886#ifdef DYNAMIC_FPS
1887 //For primary display, set the dynamic refreshrate
1888 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported()) {
1889 FrameInfo frame;
1890 frame.reset(mCurrentFrame.layerCount);
1891 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
1892 __FUNCTION__);
1893 updateLayerCache(ctx, list, frame);
1894 updateYUV(ctx, list, false /*secure only*/, frame);
1895 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1896 //Set the new fresh rate, if there is only one updating YUV layer
1897 //or there is one single RGB layer with this request
1898 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1899 (frame.layerCount == 1)) {
1900 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1901 }
1902 setRefreshRate(ctx, mDpy, refreshRate);
1903 }
1904#endif
1905
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001906 mCachedFrame.cacheAll(list);
1907 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001908 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001909}
1910
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001911bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301912
1913 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301914 int mdpIndex = mCurrentFrame.layerToMDP[index];
1915 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1916 info.pipeInfo = new MdpYUVPipeInfo;
1917 info.rot = NULL;
1918 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301919
1920 pipe_info.lIndex = ovutils::OV_INVALID;
1921 pipe_info.rIndex = ovutils::OV_INVALID;
1922
Saurabh Shahc62f3982014-03-05 14:28:26 -08001923 Overlay::PipeSpecs pipeSpecs;
1924 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1925 pipeSpecs.needsScaling = true;
1926 pipeSpecs.dpy = mDpy;
1927 pipeSpecs.fb = false;
1928
1929 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301930 if(pipe_info.lIndex == ovutils::OV_INVALID){
1931 bRet = false;
1932 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1933 __FUNCTION__);
1934 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001935 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301936 if(pipe_info.rIndex == ovutils::OV_INVALID){
1937 bRet = false;
1938 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1939 __FUNCTION__);
1940 }
1941 return bRet;
1942}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001943
1944int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1945 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001946 if (ctx->mPtorInfo.isActive()) {
1947 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001948 if (fd < 0) {
1949 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001950 }
1951 }
1952 return fd;
1953}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001954//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001955
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001956void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301957 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001958 //If 4k2k Yuv layer split is possible, and if
1959 //fbz is above 4k2k layer, increment fb zorder by 1
1960 //as we split 4k2k layer and increment zorder for right half
1961 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07001962 if(!ctx)
1963 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001964 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301965 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1966 index++) {
1967 if(!mCurrentFrame.isFBComposed[index]) {
1968 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1969 mdpNextZOrder++;
1970 }
1971 mdpNextZOrder++;
1972 hwc_layer_1_t* layer = &list->hwLayers[index];
1973 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301974 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301975 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1976 mCurrentFrame.fbZ += 1;
1977 mdpNextZOrder++;
1978 //As we split 4kx2k yuv layer and program to 2 VG pipes
1979 //(if available) increase mdpcount by 1.
1980 mCurrentFrame.mdpCount++;
1981 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001982 }
1983 }
1984 }
radhakrishnac9a67412013-09-25 17:40:42 +05301985}
1986
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001987/*
1988 * Configures pipe(s) for MDP composition
1989 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001990int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001991 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001992 MdpPipeInfoNonSplit& mdp_info =
1993 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001994 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1995 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08001996 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001997
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001998 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1999 __FUNCTION__, layer, zOrder, dest);
2000
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002001 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002002 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002003}
2004
Saurabh Shah88e4d272013-09-03 13:31:29 -07002005bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002006 hwc_display_contents_1_t* list) {
2007 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002008
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002009 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002010
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002011 hwc_layer_1_t* layer = &list->hwLayers[index];
2012 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302013 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002014 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302015 continue;
2016 }
2017 }
2018
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002019 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002020 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002021 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002022 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002023 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002024
Saurabh Shahc62f3982014-03-05 14:28:26 -08002025 Overlay::PipeSpecs pipeSpecs;
2026 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2027 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2028 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2029 (qdutils::MDPVersion::getInstance().is8x26() and
2030 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2031 pipeSpecs.dpy = mDpy;
2032 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002033 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002034
Saurabh Shahc62f3982014-03-05 14:28:26 -08002035 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2036
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002037 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002038 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002039 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002040 }
2041 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002042 return true;
2043}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002044
radhakrishnac9a67412013-09-25 17:40:42 +05302045int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2046 PipeLayerPair& PipeLayerPair) {
2047 MdpYUVPipeInfo& mdp_info =
2048 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2049 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302050 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2051 eDest lDest = mdp_info.lIndex;
2052 eDest rDest = mdp_info.rIndex;
2053
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002054 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302055 lDest, rDest, &PipeLayerPair.rot);
2056}
2057
Saurabh Shah88e4d272013-09-03 13:31:29 -07002058bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002059
Raj Kamal4393eaa2014-06-06 13:45:20 +05302060 if(!isEnabled() or !mModeOn) {
2061 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302062 return true;
2063 }
2064
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002065 // Set the Handle timeout to true for MDP or MIXED composition.
2066 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2067 sHandleTimeout = true;
2068 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002069
2070 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002071 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002072
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002073 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2074 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002075 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002076 if(mCurrentFrame.isFBComposed[i]) continue;
2077
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002078 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002079 private_handle_t *hnd = (private_handle_t *)layer->handle;
2080 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002081 if (!(layer->flags & HWC_COLOR_FILL)) {
2082 ALOGE("%s handle null", __FUNCTION__);
2083 return false;
2084 }
2085 // No PLAY for Color layer
2086 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2087 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002088 }
2089
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002090 int mdpIndex = mCurrentFrame.layerToMDP[i];
2091
Raj Kamal389d6e32014-08-04 14:43:24 +05302092 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302093 {
2094 MdpYUVPipeInfo& pipe_info =
2095 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2096 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2097 ovutils::eDest indexL = pipe_info.lIndex;
2098 ovutils::eDest indexR = pipe_info.rIndex;
2099 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302100 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302101 if(rot) {
2102 rot->queueBuffer(fd, offset);
2103 fd = rot->getDstMemId();
2104 offset = rot->getDstOffset();
2105 }
2106 if(indexL != ovutils::OV_INVALID) {
2107 ovutils::eDest destL = (ovutils::eDest)indexL;
2108 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2109 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2110 if (!ov.queueBuffer(fd, offset, destL)) {
2111 ALOGE("%s: queueBuffer failed for display:%d",
2112 __FUNCTION__, mDpy);
2113 return false;
2114 }
2115 }
2116
2117 if(indexR != ovutils::OV_INVALID) {
2118 ovutils::eDest destR = (ovutils::eDest)indexR;
2119 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2120 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2121 if (!ov.queueBuffer(fd, offset, destR)) {
2122 ALOGE("%s: queueBuffer failed for display:%d",
2123 __FUNCTION__, mDpy);
2124 return false;
2125 }
2126 }
2127 }
2128 else{
2129 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002130 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302131 ovutils::eDest dest = pipe_info.index;
2132 if(dest == ovutils::OV_INVALID) {
2133 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002134 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302135 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002136
radhakrishnac9a67412013-09-25 17:40:42 +05302137 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2138 continue;
2139 }
2140
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002141 int fd = hnd->fd;
2142 uint32_t offset = (uint32_t)hnd->offset;
2143 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2144 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002145 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002146 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002147 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002148 }
2149
radhakrishnac9a67412013-09-25 17:40:42 +05302150 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2151 using pipe: %d", __FUNCTION__, layer,
2152 hnd, dest );
2153
radhakrishnac9a67412013-09-25 17:40:42 +05302154 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2155 if(rot) {
2156 if(!rot->queueBuffer(fd, offset))
2157 return false;
2158 fd = rot->getDstMemId();
2159 offset = rot->getDstOffset();
2160 }
2161
2162 if (!ov.queueBuffer(fd, offset, dest)) {
2163 ALOGE("%s: queueBuffer failed for display:%d ",
2164 __FUNCTION__, mDpy);
2165 return false;
2166 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002167 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002168
2169 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002170 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002171 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002172}
2173
Saurabh Shah88e4d272013-09-03 13:31:29 -07002174//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002175
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002176void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302177 hwc_display_contents_1_t* list){
2178 //if 4kx2k yuv layer is totally present in either in left half
2179 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302180 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302181 if(mCurrentFrame.fbZ >= 0) {
2182 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2183 index++) {
2184 if(!mCurrentFrame.isFBComposed[index]) {
2185 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2186 mdpNextZOrder++;
2187 }
2188 mdpNextZOrder++;
2189 hwc_layer_1_t* layer = &list->hwLayers[index];
2190 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302191 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302192 hwc_rect_t dst = layer->displayFrame;
2193 if((dst.left > lSplit) || (dst.right < lSplit)) {
2194 mCurrentFrame.mdpCount += 1;
2195 }
2196 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2197 mCurrentFrame.fbZ += 1;
2198 mdpNextZOrder++;
2199 }
2200 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002201 }
radhakrishnac9a67412013-09-25 17:40:42 +05302202 }
2203}
2204
Saurabh Shah88e4d272013-09-03 13:31:29 -07002205bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002206 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002207
Saurabh Shahc62f3982014-03-05 14:28:26 -08002208 const int lSplit = getLeftSplit(ctx, mDpy);
2209 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002210 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002211 pipe_info.lIndex = ovutils::OV_INVALID;
2212 pipe_info.rIndex = ovutils::OV_INVALID;
2213
Saurabh Shahc62f3982014-03-05 14:28:26 -08002214 Overlay::PipeSpecs pipeSpecs;
2215 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2216 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2217 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2218 pipeSpecs.dpy = mDpy;
2219 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2220 pipeSpecs.fb = false;
2221
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002222 // Acquire pipe only for the updating half
2223 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2224 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2225
2226 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002227 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002228 if(pipe_info.lIndex == ovutils::OV_INVALID)
2229 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002230 }
2231
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002232 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002233 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2234 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002235 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002236 return false;
2237 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002238
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002239 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002240}
2241
Saurabh Shah88e4d272013-09-03 13:31:29 -07002242bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002243 hwc_display_contents_1_t* list) {
2244 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002245
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002246 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002247
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002248 hwc_layer_1_t* layer = &list->hwLayers[index];
2249 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302250 hwc_rect_t dst = layer->displayFrame;
2251 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302252 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302253 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002254 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302255 continue;
2256 }
2257 }
2258 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002259 int mdpIndex = mCurrentFrame.layerToMDP[index];
2260 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002261 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002262 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002263 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002264
Saurabh Shahc62f3982014-03-05 14:28:26 -08002265 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2266 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2267 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002268 return false;
2269 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002270 }
2271 return true;
2272}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002273
radhakrishnac9a67412013-09-25 17:40:42 +05302274int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2275 PipeLayerPair& PipeLayerPair) {
2276 const int lSplit = getLeftSplit(ctx, mDpy);
2277 hwc_rect_t dst = layer->displayFrame;
2278 if((dst.left > lSplit)||(dst.right < lSplit)){
2279 MdpYUVPipeInfo& mdp_info =
2280 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2281 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302282 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2283 eDest lDest = mdp_info.lIndex;
2284 eDest rDest = mdp_info.rIndex;
2285
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002286 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302287 lDest, rDest, &PipeLayerPair.rot);
2288 }
2289 else{
2290 return configure(ctx, layer, PipeLayerPair);
2291 }
2292}
2293
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002294/*
2295 * Configures pipe(s) for MDP composition
2296 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002297int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002298 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002299 MdpPipeInfoSplit& mdp_info =
2300 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002301 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002302 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2303 eDest lDest = mdp_info.lIndex;
2304 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002305
2306 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2307 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2308
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002309 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002310 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002311}
2312
Saurabh Shah88e4d272013-09-03 13:31:29 -07002313bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002314
Raj Kamal4393eaa2014-06-06 13:45:20 +05302315 if(!isEnabled() or !mModeOn) {
2316 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302317 return true;
2318 }
2319
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002320 // Set the Handle timeout to true for MDP or MIXED composition.
2321 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2322 sHandleTimeout = true;
2323 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002324
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002325 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002326 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002327
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002328 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2329 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002330 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002331 if(mCurrentFrame.isFBComposed[i]) continue;
2332
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002333 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002334 private_handle_t *hnd = (private_handle_t *)layer->handle;
2335 if(!hnd) {
2336 ALOGE("%s handle null", __FUNCTION__);
2337 return false;
2338 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002339
2340 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2341 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002342 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002343
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002344 int mdpIndex = mCurrentFrame.layerToMDP[i];
2345
Raj Kamal389d6e32014-08-04 14:43:24 +05302346 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302347 {
2348 MdpYUVPipeInfo& pipe_info =
2349 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2350 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2351 ovutils::eDest indexL = pipe_info.lIndex;
2352 ovutils::eDest indexR = pipe_info.rIndex;
2353 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302354 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302355 if(rot) {
2356 rot->queueBuffer(fd, offset);
2357 fd = rot->getDstMemId();
2358 offset = rot->getDstOffset();
2359 }
2360 if(indexL != ovutils::OV_INVALID) {
2361 ovutils::eDest destL = (ovutils::eDest)indexL;
2362 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2363 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2364 if (!ov.queueBuffer(fd, offset, destL)) {
2365 ALOGE("%s: queueBuffer failed for display:%d",
2366 __FUNCTION__, mDpy);
2367 return false;
2368 }
2369 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002370
radhakrishnac9a67412013-09-25 17:40:42 +05302371 if(indexR != ovutils::OV_INVALID) {
2372 ovutils::eDest destR = (ovutils::eDest)indexR;
2373 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2374 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2375 if (!ov.queueBuffer(fd, offset, destR)) {
2376 ALOGE("%s: queueBuffer failed for display:%d",
2377 __FUNCTION__, mDpy);
2378 return false;
2379 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002380 }
2381 }
radhakrishnac9a67412013-09-25 17:40:42 +05302382 else{
2383 MdpPipeInfoSplit& pipe_info =
2384 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2385 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002386
radhakrishnac9a67412013-09-25 17:40:42 +05302387 ovutils::eDest indexL = pipe_info.lIndex;
2388 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002389
radhakrishnac9a67412013-09-25 17:40:42 +05302390 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002391 uint32_t offset = (uint32_t)hnd->offset;
2392 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2393 if (!mDpy && (index != -1)) {
2394 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2395 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002396 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002397 }
radhakrishnac9a67412013-09-25 17:40:42 +05302398
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002399 if(ctx->mAD->draw(ctx, fd, offset)) {
2400 fd = ctx->mAD->getDstFd();
2401 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002402 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002403
radhakrishnac9a67412013-09-25 17:40:42 +05302404 if(rot) {
2405 rot->queueBuffer(fd, offset);
2406 fd = rot->getDstMemId();
2407 offset = rot->getDstOffset();
2408 }
2409
2410 //************* play left mixer **********
2411 if(indexL != ovutils::OV_INVALID) {
2412 ovutils::eDest destL = (ovutils::eDest)indexL;
2413 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2414 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2415 if (!ov.queueBuffer(fd, offset, destL)) {
2416 ALOGE("%s: queueBuffer failed for left mixer",
2417 __FUNCTION__);
2418 return false;
2419 }
2420 }
2421
2422 //************* play right mixer **********
2423 if(indexR != ovutils::OV_INVALID) {
2424 ovutils::eDest destR = (ovutils::eDest)indexR;
2425 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2426 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2427 if (!ov.queueBuffer(fd, offset, destR)) {
2428 ALOGE("%s: queueBuffer failed for right mixer",
2429 __FUNCTION__);
2430 return false;
2431 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002432 }
2433 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002434
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002435 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2436 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002437
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002438 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002439}
Saurabh Shahab47c692014-02-12 18:45:57 -08002440
2441//================MDPCompSrcSplit==============================================
2442bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002443 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002444 private_handle_t *hnd = (private_handle_t *)layer->handle;
2445 hwc_rect_t dst = layer->displayFrame;
2446 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2447 pipe_info.lIndex = ovutils::OV_INVALID;
2448 pipe_info.rIndex = ovutils::OV_INVALID;
2449
2450 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2451 //should have a higher priority than the right one. Pipe priorities are
2452 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002453
Saurabh Shahc62f3982014-03-05 14:28:26 -08002454 Overlay::PipeSpecs pipeSpecs;
2455 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2456 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2457 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2458 pipeSpecs.dpy = mDpy;
2459 pipeSpecs.fb = false;
2460
Saurabh Shahab47c692014-02-12 18:45:57 -08002461 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002462 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002463 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002464 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002465 }
2466
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002467 /* Use 2 pipes IF
2468 a) Layer's crop width is > 2048 or
2469 b) Layer's dest width > 2048 or
2470 c) On primary, driver has indicated with caps to split always. This is
2471 based on an empirically derived value of panel height. Applied only
2472 if the layer's width is > mixer's width
2473 */
2474
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302475 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002476 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302477 mdpHw.isSrcSplitAlways();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002478 int lSplit = getLeftSplit(ctx, mDpy);
2479 int dstWidth = dst.right - dst.left;
2480 int cropWidth = crop.right - crop.left;
2481
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002482 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2483 //pipe line length, we are still using 2 pipes. This is fine just because
2484 //this is source split where destination doesn't matter. Evaluate later to
2485 //see if going through all the calcs to save a pipe is worth it
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302486 if(dstWidth > mdpHw.getMaxMixerWidth() or
2487 cropWidth > mdpHw.getMaxMixerWidth() or
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002488 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002489 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002490 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002491 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002492 }
2493
2494 // Return values
2495 // 1 Left pipe is higher priority, do nothing.
2496 // 0 Pipes of same priority.
2497 //-1 Right pipe is of higher priority, needs swap.
2498 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2499 pipe_info.rIndex) == -1) {
2500 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002501 }
2502 }
2503
2504 return true;
2505}
2506
Saurabh Shahab47c692014-02-12 18:45:57 -08002507int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2508 PipeLayerPair& PipeLayerPair) {
2509 private_handle_t *hnd = (private_handle_t *)layer->handle;
2510 if(!hnd) {
2511 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2512 return -1;
2513 }
2514 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2515 MdpPipeInfoSplit& mdp_info =
2516 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2517 Rotator **rot = &PipeLayerPair.rot;
2518 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002519 eDest lDest = mdp_info.lIndex;
2520 eDest rDest = mdp_info.rIndex;
2521 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2522 hwc_rect_t dst = layer->displayFrame;
2523 int transform = layer->transform;
2524 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002525 int rotFlags = ROT_FLAGS_NONE;
2526 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2527 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2528
2529 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2530 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2531
2532 // Handle R/B swap
2533 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2534 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2535 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2536 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2537 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2538 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002539 /* Calculate the external display position based on MDP downscale,
2540 ActionSafe, and extorientation features. */
2541 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002542
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002543 int downscale = getRotDownscale(ctx, layer);
Saurabh Shah97e2d802014-04-14 18:03:54 -07002544 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002545 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002546
2547 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2548 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002549 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002550 }
2551
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002552 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002553 (*rot) = ctx->mRotMgr->getNext();
2554 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002555 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002556 //If the video is using a single pipe, enable BWC
2557 if(rDest == OV_INVALID) {
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002558 BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002559 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002560 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002561 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002562 ALOGE("%s: configRotator failed!", __FUNCTION__);
2563 return -1;
2564 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002565 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002566 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002567 }
2568
2569 //If 2 pipes being used, divide layer into half, crop and dst
2570 hwc_rect_t cropL = crop;
2571 hwc_rect_t cropR = crop;
2572 hwc_rect_t dstL = dst;
2573 hwc_rect_t dstR = dst;
2574 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2575 cropL.right = (crop.right + crop.left) / 2;
2576 cropR.left = cropL.right;
2577 sanitizeSourceCrop(cropL, cropR, hnd);
2578
Saurabh Shahb729b192014-08-15 18:04:24 -07002579 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002580 //Swap crops on H flip since 2 pipes are being used
2581 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2582 hwc_rect_t tmp = cropL;
2583 cropL = cropR;
2584 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002585 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002586 }
2587
Saurabh Shahb729b192014-08-15 18:04:24 -07002588 //cropSwap trick: If the src and dst widths are both odd, let us say
2589 //2507, then splitting both into half would cause left width to be 1253
2590 //and right 1254. If crop is swapped because of H flip, this will cause
2591 //left crop width to be 1254, whereas left dst width remains 1253, thus
2592 //inducing a scaling that is unaccounted for. To overcome that we add 1
2593 //to the dst width if there is a cropSwap. So if the original width was
2594 //2507, the left dst width will be 1254. Even if the original width was
2595 //even for ex: 2508, the left dst width will still remain 1254.
2596 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002597 dstR.left = dstL.right;
2598 }
2599
2600 //For the mdp, since either we are pre-rotating or MDP does flips
2601 orient = OVERLAY_TRANSFORM_0;
2602 transform = 0;
2603
2604 //configure left pipe
2605 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002606 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002607 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2608 (ovutils::eBlending) getBlending(layer->blending));
2609
2610 if(configMdp(ctx->mOverlay, pargL, orient,
2611 cropL, dstL, metadata, lDest) < 0) {
2612 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2613 return -1;
2614 }
2615 }
2616
2617 //configure right pipe
2618 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002619 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002620 static_cast<eRotFlags>(rotFlags),
2621 layer->planeAlpha,
2622 (ovutils::eBlending) getBlending(layer->blending));
2623 if(configMdp(ctx->mOverlay, pargR, orient,
2624 cropR, dstR, metadata, rDest) < 0) {
2625 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2626 return -1;
2627 }
2628 }
2629
2630 return 0;
2631}
2632
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002633}; //namespace
2634