blob: 2620f732072dabde50f5d5f09321cef6aa2e4635 [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002 * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003 * Not a Contribution, Apache license notifications and license are retained
4 * for attribution purposes only.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
Saurabh Shah4fdde762013-04-30 18:47:33 -070019#include <math.h>
Naseer Ahmed7c958d42012-07-31 18:57:03 -070020#include "hwc_mdpcomp.h"
Naseer Ahmed54821fe2012-11-28 18:44:38 -050021#include <sys/ioctl.h>
Saurabh Shah56f610d2012-08-07 15:27:06 -070022#include "external.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080023#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080024#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070025#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070026#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080027#include <overlayRotator.h>
Sushil Chauhandefd3522014-05-13 18:17:12 -070028#include "hwc_copybit.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080029
Saurabh Shah85234ec2013-04-12 17:09:00 -070030using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070031using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080032using namespace overlay::utils;
33namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070034
Naseer Ahmed7c958d42012-07-31 18:57:03 -070035namespace qhwc {
36
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080037//==============MDPComp========================================================
38
Naseer Ahmed7c958d42012-07-31 18:57:03 -070039IdleInvalidator *MDPComp::idleInvalidator = NULL;
40bool MDPComp::sIdleFallBack = false;
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -080041bool MDPComp::sHandleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070042bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050043bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070044bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -070045int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080046int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Raj Kamal389d6e32014-08-04 14:43:24 +053047bool MDPComp::sEnableYUVsplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070048bool MDPComp::sSrcSplitEnabled = false;
Saurabh Shah88e4d272013-09-03 13:31:29 -070049MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070050 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
51 sSrcSplitEnabled = true;
52 return new MDPCompSrcSplit(dpy);
53 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070054 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080055 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070056 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080057}
58
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080059MDPComp::MDPComp(int dpy):mDpy(dpy){};
60
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070061void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080062{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070063 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
64 return;
65
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080066 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070067 (mDpy == 0) ? "\"PRIMARY\"" :
68 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070069 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
70 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080071 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
72 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
73 (mCurrentFrame.needsRedraw? "YES" : "NO"),
74 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070075 if(isDisplaySplit(ctx, mDpy)) {
76 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
77 "Right: [%d, %d, %d, %d] \n",
78 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
79 ctx->listStats[mDpy].lRoi.right,
80 ctx->listStats[mDpy].lRoi.bottom,
81 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
82 ctx->listStats[mDpy].rRoi.right,
83 ctx->listStats[mDpy].rRoi.bottom);
84 } else {
85 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
86 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
87 ctx->listStats[mDpy].lRoi.right,
88 ctx->listStats[mDpy].lRoi.bottom);
89 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080090 dumpsys_log(buf," --------------------------------------------- \n");
91 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
92 dumpsys_log(buf," --------------------------------------------- \n");
93 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
94 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
95 index,
96 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070097 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080098 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070099 (mCurrentFrame.drop[index] ? "DROP" :
100 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800101 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
102 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
103 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800104}
105
106bool MDPComp::init(hwc_context_t *ctx) {
107
108 if(!ctx) {
109 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
110 return false;
111 }
112
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800113 char property[PROPERTY_VALUE_MAX];
114
115 sEnabled = false;
116 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800117 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
118 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800119 sEnabled = true;
120 }
121
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700122 sEnableMixedMode = true;
123 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
124 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
125 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
126 sEnableMixedMode = false;
127 }
128
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800129 sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Saurabh Shah85234ec2013-04-12 17:09:00 -0700130 if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
131 int val = atoi(property);
132 if(val >= 0)
133 sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800134 }
135
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400136 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
137 // Idle invalidation is not necessary on command mode panels
138 long idle_timeout = DEFAULT_IDLE_TIME;
139 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
140 if(atoi(property) != 0)
141 idle_timeout = atoi(property);
142 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800143
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400144 //create Idle Invalidator only when not disabled through property
145 if(idle_timeout != -1)
146 idleInvalidator = IdleInvalidator::getInstance();
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800147
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400148 if(idleInvalidator == NULL) {
149 ALOGE("%s: failed to instantiate idleInvalidator object",
150 __FUNCTION__);
151 } else {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530152 idleInvalidator->init(timeout_handler, ctx,
153 (unsigned int)idle_timeout);
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400154 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800155 }
radhakrishnac9a67412013-09-25 17:40:42 +0530156
Saurabh Shah7c727642014-06-02 15:47:14 -0700157 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700158 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700159 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
160 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
161 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530162 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530163 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700164
165 if ((property_get("persist.hwc.ptor.enable", property, NULL) > 0) &&
166 ((!strncasecmp(property, "true", PROPERTY_VALUE_MAX )) ||
167 (!strncmp(property, "1", PROPERTY_VALUE_MAX )))) {
168 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
169 HWC_DISPLAY_PRIMARY);
170 }
171
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700172 return true;
173}
174
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800175void MDPComp::reset(hwc_context_t *ctx) {
176 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700177 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800178 ctx->mOverlay->clear(mDpy);
179 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700180}
181
Raj Kamal4393eaa2014-06-06 13:45:20 +0530182void MDPComp::reset() {
183 sHandleTimeout = false;
184 mModeOn = false;
185}
186
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700187void MDPComp::timeout_handler(void *udata) {
188 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
189
190 if(!ctx) {
191 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
192 return;
193 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800194 Locker::Autolock _l(ctx->mDrawLock);
195 // Handle timeout event only if the previous composition is MDP or MIXED.
196 if(!sHandleTimeout) {
197 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
198 return;
199 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700200 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700201 ALOGE("%s: HWC proc not registered", __FUNCTION__);
202 return;
203 }
204 sIdleFallBack = true;
205 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700206 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700207}
208
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800209void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800210 hwc_display_contents_1_t* list) {
211 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800212
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800213 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800214 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800215 if(!mCurrentFrame.isFBComposed[index]) {
216 layerProp[index].mFlags |= HWC_MDPCOMP;
217 layer->compositionType = HWC_OVERLAY;
218 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800219 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700220 /* Drop the layer when its already present in FB OR when it lies
221 * outside frame's ROI */
222 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800223 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700224 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800225 }
226 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700227}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500228
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800229void MDPComp::setRedraw(hwc_context_t *ctx,
230 hwc_display_contents_1_t* list) {
231 mCurrentFrame.needsRedraw = false;
232 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
233 (list->flags & HWC_GEOMETRY_CHANGED) ||
234 isSkipPresent(ctx, mDpy)) {
235 mCurrentFrame.needsRedraw = true;
236 }
237}
238
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800239MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700240 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700241 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800242}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800243
Saurabh Shahaa236822013-04-24 18:07:26 -0700244void MDPComp::FrameInfo::reset(const int& numLayers) {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700245 for(int i = 0; i < MAX_PIPES_PER_MIXER; i++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800246 if(mdpToLayer[i].pipeInfo) {
247 delete mdpToLayer[i].pipeInfo;
248 mdpToLayer[i].pipeInfo = NULL;
249 //We dont own the rotator
250 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800251 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800252 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800253
254 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
255 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700256 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800257
Saurabh Shahaa236822013-04-24 18:07:26 -0700258 layerCount = numLayers;
259 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800260 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700261 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800262 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800263}
264
Saurabh Shahaa236822013-04-24 18:07:26 -0700265void MDPComp::FrameInfo::map() {
266 // populate layer and MDP maps
267 int mdpIdx = 0;
268 for(int idx = 0; idx < layerCount; idx++) {
269 if(!isFBComposed[idx]) {
270 mdpToLayer[mdpIdx].listIndex = idx;
271 layerToMDP[idx] = mdpIdx++;
272 }
273 }
274}
275
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800276MDPComp::LayerCache::LayerCache() {
277 reset();
278}
279
280void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700281 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530282 memset(&isFBComposed, true, sizeof(isFBComposed));
283 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800284 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700285}
286
287void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530288 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700289 for(int i = 0; i < numAppLayers; i++) {
290 hnd[i] = list->hwLayers[i].handle;
291 }
292}
293
294void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700295 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530296 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
297 memcpy(&drop, &curFrame.drop, sizeof(drop));
298}
299
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800300bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
301 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530302 if(layerCount != curFrame.layerCount)
303 return false;
304 for(int i = 0; i < curFrame.layerCount; i++) {
305 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
306 (curFrame.drop[i] != drop[i])) {
307 return false;
308 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800309 if(curFrame.isFBComposed[i] &&
310 (hnd[i] != list->hwLayers[i].handle)){
311 return false;
312 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530313 }
314 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800315}
316
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700317bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
318 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800319 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700320 (not isValidDimension(ctx,layer))
321 //More conditions here, SKIP, sRGB+Blend etc
322 ) {
323 return false;
324 }
325 return true;
326}
327
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530328bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800329 private_handle_t *hnd = (private_handle_t *)layer->handle;
330
331 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700332 if (layer->flags & HWC_COLOR_FILL) {
333 // Color layer
334 return true;
335 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700336 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800337 return false;
338 }
339
Naseer Ahmede850a802013-09-06 13:12:52 -0400340 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400341 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400342 return false;
343
Saurabh Shah62e1d732013-09-17 10:44:05 -0700344 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700345 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700346 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700347 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
348 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700349 int dst_w = dst.right - dst.left;
350 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800351 float w_scale = ((float)crop_w / (float)dst_w);
352 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530353 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700354
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800355 /* Workaround for MDP HW limitation in DSI command mode panels where
356 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
357 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530358 * There also is a HW limilation in MDP, minimum block size is 2x2
359 * Fallback to GPU if height is less than 2.
360 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700361 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800362 return false;
363
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800364 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530365 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800366 const float w_dscale = w_scale;
367 const float h_dscale = h_scale;
368
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800369 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700370
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530371 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700372 /* On targets that doesnt support Decimation (eg.,8x26)
373 * maximum downscale support is overlay pipe downscale.
374 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400375 if(crop_w > (int) mdpHw.getMaxMixerWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530376 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700377 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800378 return false;
379 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700380 // Decimation on macrotile format layers is not supported.
381 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530382 /* Bail out if
383 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700384 * 2. exceeds maximum downscale limit
385 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400386 if(((crop_w > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530387 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700388 w_dscale > maxMDPDownscale ||
389 h_dscale > maxMDPDownscale) {
390 return false;
391 }
392 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800393 return false;
394 }
395 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700396 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700397 return false;
398 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700399 }
400
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800401 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530402 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800403 const float w_uscale = 1.0f / w_scale;
404 const float h_uscale = 1.0f / h_scale;
405
406 if(w_uscale > upscale || h_uscale > upscale)
407 return false;
408 }
409
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800410 return true;
411}
412
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800413bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700414 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800415
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800416 if(!isEnabled()) {
417 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700418 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530419 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530420 qdutils::MDPVersion::getInstance().is8x16() ||
421 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800422 ctx->mVideoTransFlag &&
423 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700424 //1 Padding round to shift pipes across mixers
425 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
426 __FUNCTION__);
427 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700428 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
429 /* TODO: freeing up all the resources only for the targets having total
430 number of pipes < 8. Need to analyze number of VIG pipes used
431 for primary in previous draw cycle and accordingly decide
432 whether to fall back to full GPU comp or video only comp
433 */
434 if(isSecondaryConfiguring(ctx)) {
435 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
436 __FUNCTION__);
437 ret = false;
438 } else if(ctx->isPaddingRound) {
439 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
440 __FUNCTION__,mDpy);
441 ret = false;
442 }
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700443 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700444 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800445}
446
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800447void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
448 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
449 fbRect = getIntersection(fbRect, roi);
450}
451
452/* 1) Identify layers that are not visible or lying outside the updating ROI and
453 * drop them from composition.
454 * 2) If we have a scaling layer which needs cropping against generated
455 * ROI, reset ROI to full resolution. */
456bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
457 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700458 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800459 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800460
461 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800462 if(!isValidRect(visibleRect)) {
463 mCurrentFrame.drop[i] = true;
464 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800465 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800466 }
467
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700468 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700469 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800470 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700471
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700472 if(!isValidRect(res)) {
473 mCurrentFrame.drop[i] = true;
474 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800475 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700476 /* Reset frame ROI when any layer which needs scaling also needs ROI
477 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800478 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800479 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700480 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
481 mCurrentFrame.dropCount = 0;
482 return false;
483 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800484
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800485 /* deduct any opaque region from visibleRect */
486 if (layer->blending == HWC_BLENDING_NONE)
487 visibleRect = deductRect(visibleRect, res);
488 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700489 }
490 return true;
491}
492
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800493/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
494 * are updating. If DirtyRegion is applicable, calculate it by accounting all
495 * the changing layer's dirtyRegion. */
496void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
497 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700498 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800499 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700500 return;
501
502 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800503 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
504 (int)ctx->dpyAttr[mDpy].yres};
505
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700506 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800507 hwc_layer_1_t* layer = &list->hwLayers[index];
508 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800509 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700510 hwc_rect_t dst = layer->displayFrame;
511 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800512
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800513#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800514 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700515 {
516 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
517 int x_off = dst.left - src.left;
518 int y_off = dst.top - src.top;
519 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
520 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800521#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800522
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800523 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700524 }
525 }
526
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800527 /* No layer is updating. Still SF wants a refresh.*/
528 if(!isValidRect(roi))
529 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800530
531 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800532 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800533
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800534 ctx->listStats[mDpy].lRoi = roi;
535 if(!validateAndApplyROI(ctx, list))
536 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700537
538 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800539 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
540 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
541}
542
543void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
544 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
545 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
546
547 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
548 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
549 fbRect = getUnion(l_fbRect, r_fbRect);
550}
551/* 1) Identify layers that are not visible or lying outside BOTH the updating
552 * ROI's and drop them from composition. If a layer is spanning across both
553 * the halves of the screen but needed by only ROI, the non-contributing
554 * half will not be programmed for MDP.
555 * 2) If we have a scaling layer which needs cropping against generated
556 * ROI, reset ROI to full resolution. */
557bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
558 hwc_display_contents_1_t* list) {
559
560 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
561
562 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
563 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
564
565 for(int i = numAppLayers - 1; i >= 0; i--){
566 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
567 {
568 mCurrentFrame.drop[i] = true;
569 mCurrentFrame.dropCount++;
570 continue;
571 }
572
573 const hwc_layer_1_t* layer = &list->hwLayers[i];
574 hwc_rect_t dstRect = layer->displayFrame;
575
576 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
577 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
578 hwc_rect_t res = getUnion(l_res, r_res);
579
580 if(!isValidRect(l_res) && !isValidRect(r_res)) {
581 mCurrentFrame.drop[i] = true;
582 mCurrentFrame.dropCount++;
583 } else {
584 /* Reset frame ROI when any layer which needs scaling also needs ROI
585 * cropping */
586 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
587 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
588 mCurrentFrame.dropCount = 0;
589 return false;
590 }
591
592 if (layer->blending == HWC_BLENDING_NONE) {
593 visibleRectL = deductRect(visibleRectL, l_res);
594 visibleRectR = deductRect(visibleRectR, r_res);
595 }
596 }
597 }
598 return true;
599}
600/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
601 * are updating. If DirtyRegion is applicable, calculate it by accounting all
602 * the changing layer's dirtyRegion. */
603void MDPCompSplit::generateROI(hwc_context_t *ctx,
604 hwc_display_contents_1_t* list) {
605 if(!canPartialUpdate(ctx, list))
606 return;
607
608 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
609 int lSplit = getLeftSplit(ctx, mDpy);
610
611 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
612 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
613
614 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
615 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
616
617 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
618 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
619
620 for(int index = 0; index < numAppLayers; index++ ) {
621 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800622 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800623 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800624 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700625 hwc_rect_t dst = layer->displayFrame;
626 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800627
628#ifdef QCOM_BSP
629 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700630 {
631 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
632 int x_off = dst.left - src.left;
633 int y_off = dst.top - src.top;
634 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
635 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800636#endif
637
638 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
639 if(isValidRect(l_dst))
640 l_roi = getUnion(l_roi, l_dst);
641
642 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
643 if(isValidRect(r_dst))
644 r_roi = getUnion(r_roi, r_dst);
645 }
646 }
647
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700648 /* For panels that cannot accept commands in both the interfaces, we cannot
649 * send two ROI's (for each half). We merge them into single ROI and split
650 * them across lSplit for MDP mixer use. The ROI's will be merged again
651 * finally before udpating the panel in the driver. */
652 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
653 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
654 l_roi = getIntersection(temp_roi, l_frame);
655 r_roi = getIntersection(temp_roi, r_frame);
656 }
657
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800658 /* No layer is updating. Still SF wants a refresh. */
659 if(!isValidRect(l_roi) && !isValidRect(r_roi))
660 return;
661
662 l_roi = getSanitizeROI(l_roi, l_frame);
663 r_roi = getSanitizeROI(r_roi, r_frame);
664
665 ctx->listStats[mDpy].lRoi = l_roi;
666 ctx->listStats[mDpy].rRoi = r_roi;
667
668 if(!validateAndApplyROI(ctx, list))
669 resetROI(ctx, mDpy);
670
671 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
672 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
673 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
674 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
675 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
676 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700677}
678
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800679/* Checks for conditions where all the layers marked for MDP comp cannot be
680 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800681bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800682 hwc_display_contents_1_t* list){
683
Saurabh Shahaa236822013-04-24 18:07:26 -0700684 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800685 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800686
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -0700687 // No Idle fall back, if secure display or secure RGB layers are present
688 if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
689 !ctx->listStats[mDpy].secureRGBCount)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700690 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
691 return false;
692 }
693
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800694 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700695 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
696 __FUNCTION__,
697 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800698 return false;
699 }
700
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700701 // if secondary is configuring or Padding round, fall back to video only
702 // composition and release all assigned non VIG pipes from primary.
703 if(isSecondaryConfiguring(ctx)) {
704 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
705 __FUNCTION__);
706 return false;
707 } else if(ctx->isPaddingRound) {
708 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
709 __FUNCTION__,mDpy);
710 return false;
711 }
712
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530713 MDPVersion& mdpHw = MDPVersion::getInstance();
714 if(mDpy > HWC_DISPLAY_PRIMARY &&
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400715 (priDispW > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530716 (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800717 // Disable MDP comp on Secondary when the primary is highres panel and
718 // the secondary is a normal 1080p, because, MDP comp on secondary under
719 // in such usecase, decimation gets used for downscale and there will be
720 // a quality mismatch when there will be a fallback to GPU comp
721 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
722 __FUNCTION__);
723 return false;
724 }
725
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700726 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800727 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700728 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800729 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
730 return false;
731 }
732
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800733 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800734 hwc_layer_1_t* layer = &list->hwLayers[i];
735 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800736
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800737 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700738 if(!canUseRotator(ctx, mDpy)) {
739 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
740 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700741 return false;
742 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800743 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530744
745 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
746 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700747 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530748 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
749 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
750 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800751 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700752
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700753 if(ctx->mAD->isDoable()) {
754 return false;
755 }
756
Saurabh Shahaa236822013-04-24 18:07:26 -0700757 //If all above hard conditions are met we can do full or partial MDP comp.
758 bool ret = false;
759 if(fullMDPComp(ctx, list)) {
760 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700761 } else if(fullMDPCompWithPTOR(ctx, list)) {
762 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700763 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700764 ret = true;
765 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530766
Saurabh Shahaa236822013-04-24 18:07:26 -0700767 return ret;
768}
769
770bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700771
772 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
773 return false;
774
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700775 //Will benefit presentation / secondary-only layer.
776 if((mDpy > HWC_DISPLAY_PRIMARY) &&
777 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
778 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
779 return false;
780 }
781
782 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
783 for(int i = 0; i < numAppLayers; i++) {
784 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700785 if(not mCurrentFrame.drop[i] and
786 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700787 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
788 return false;
789 }
790 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800791
Saurabh Shahaa236822013-04-24 18:07:26 -0700792 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700793 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
794 sizeof(mCurrentFrame.isFBComposed));
795 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
796 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700797
Raj Kamal389d6e32014-08-04 14:43:24 +0530798 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800799 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530800 }
801
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800802 if(!postHeuristicsHandling(ctx, list)) {
803 ALOGD_IF(isDebug(), "post heuristic handling failed");
804 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700805 return false;
806 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700807 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
808 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700809 return true;
810}
811
Sushil Chauhandefd3522014-05-13 18:17:12 -0700812/* Full MDP Composition with Peripheral Tiny Overlap Removal.
813 * MDP bandwidth limitations can be avoided, if the overlap region
814 * covered by the smallest layer at a higher z-order, gets composed
815 * by Copybit on a render buffer, which can be queued to MDP.
816 */
817bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
818 hwc_display_contents_1_t* list) {
819
820 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
821 const int stagesForMDP = min(sMaxPipesPerMixer,
822 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
823
824 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700825 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700826 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
827 return false;
828 }
829
830 // Frame level checks
831 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
832 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
833 isSecurePresent(ctx, mDpy)) {
834 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
835 return false;
836 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700837 // MDP comp checks
838 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700839 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700840 if(not isSupportedForMDPComp(ctx, layer)) {
841 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
842 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700843 }
844 }
845
Sushil Chauhandefd3522014-05-13 18:17:12 -0700846 /* We cannot use this composition mode, if:
847 1. A below layer needs scaling.
848 2. Overlap is not peripheral to display.
849 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700850 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700851 */
852
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700853 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
854 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
855 memset(overlapRect, 0, sizeof(overlapRect));
856 int layerPixelCount, minPixelCount = 0;
857 int numPTORLayersFound = 0;
858 for (int i = numAppLayers-1; (i >= 0 &&
859 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700860 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700861 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700862 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700863 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
864 // PTOR layer should be peripheral and cannot have transform
865 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
866 has90Transform(layer)) {
867 continue;
868 }
869 if((3 * (layerPixelCount + minPixelCount)) >
870 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
871 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
872 continue;
873 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700874 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700875 for (int j = i-1; j >= 0; j--) {
876 // Check if the layers below this layer qualifies for PTOR comp
877 hwc_layer_1_t* layer = &list->hwLayers[j];
878 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700879 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700880 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700881 if (isValidRect(getIntersection(dispFrame, disFrame))) {
882 if (has90Transform(layer) || needsScaling(layer)) {
883 found = false;
884 break;
885 }
886 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700887 }
888 }
889 // Store the minLayer Index
890 if(found) {
891 minLayerIndex[numPTORLayersFound] = i;
892 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
893 minPixelCount += layerPixelCount;
894 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700895 }
896 }
897
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700898 // No overlap layers
899 if (!numPTORLayersFound)
900 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700901
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700902 // Store the displayFrame and the sourceCrops of the layers
903 hwc_rect_t displayFrame[numAppLayers];
904 hwc_rect_t sourceCrop[numAppLayers];
905 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700906 hwc_layer_1_t* layer = &list->hwLayers[i];
907 displayFrame[i] = layer->displayFrame;
908 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700909 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700910
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530911 /**
912 * It's possible that 2 PTOR layers might have overlapping.
913 * In such case, remove the intersection(again if peripheral)
914 * from the lower PTOR layer to avoid overlapping.
915 * If intersection is not on peripheral then compromise
916 * by reducing number of PTOR layers.
917 **/
918 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
919 if(isValidRect(commonRect)) {
920 overlapRect[1] = deductRect(overlapRect[1], commonRect);
921 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
922 }
923
924 ctx->mPtorInfo.count = numPTORLayersFound;
925 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
926 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
927 }
928
929 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
930 // reset PTOR
931 ctx->mPtorInfo.count = 0;
932 if(isValidRect(commonRect)) {
933 // If PTORs are intersecting restore displayframe of PTOR[1]
934 // before returning, as we have modified it above.
935 list->hwLayers[minLayerIndex[1]].displayFrame =
936 displayFrame[minLayerIndex[1]];
937 }
938 return false;
939 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700940 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
941 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
942
Xu Yangcda012c2014-07-30 21:57:21 +0800943 // Store the blending mode, planeAlpha, and transform of PTOR layers
944 int32_t blending[numPTORLayersFound];
945 uint8_t planeAlpha[numPTORLayersFound];
946 uint32_t transform[numPTORLayersFound];
947
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700948 for(int j = 0; j < numPTORLayersFound; j++) {
949 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700950
951 // Update src crop of PTOR layer
952 hwc_layer_1_t* layer = &list->hwLayers[index];
953 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
954 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
955 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
956 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
957
958 // Store & update w, h, format of PTOR layer
959 private_handle_t *hnd = (private_handle_t *)layer->handle;
960 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
961 layerWhf[j] = whf;
962 hnd->width = renderBuf->width;
963 hnd->height = renderBuf->height;
964 hnd->format = renderBuf->format;
965
Xu Yangcda012c2014-07-30 21:57:21 +0800966 // Store & update blending mode, planeAlpha and transform of PTOR layer
967 blending[j] = layer->blending;
968 planeAlpha[j] = layer->planeAlpha;
969 transform[j] = layer->transform;
970 layer->blending = HWC_BLENDING_NONE;
971 layer->planeAlpha = 0xFF;
972 layer->transform = 0;
973
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700974 // Remove overlap from crop & displayFrame of below layers
975 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700976 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700977 if(!isValidRect(getIntersection(layer->displayFrame,
978 overlapRect[j]))) {
979 continue;
980 }
981 // Update layer attributes
982 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
983 hwc_rect_t destRect = deductRect(layer->displayFrame,
984 overlapRect[j]);
985 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
986 layer->transform);
987 layer->sourceCropf.left = (float)srcCrop.left;
988 layer->sourceCropf.top = (float)srcCrop.top;
989 layer->sourceCropf.right = (float)srcCrop.right;
990 layer->sourceCropf.bottom = (float)srcCrop.bottom;
991 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700992 }
993
994 mCurrentFrame.mdpCount = numAppLayers;
995 mCurrentFrame.fbCount = 0;
996 mCurrentFrame.fbZ = -1;
997
998 for (int j = 0; j < numAppLayers; j++)
999 mCurrentFrame.isFBComposed[j] = false;
1000
1001 bool result = postHeuristicsHandling(ctx, list);
1002
1003 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001004 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001005 hwc_layer_1_t* layer = &list->hwLayers[i];
1006 layer->displayFrame = displayFrame[i];
1007 layer->sourceCropf.left = (float)sourceCrop[i].left;
1008 layer->sourceCropf.top = (float)sourceCrop[i].top;
1009 layer->sourceCropf.right = (float)sourceCrop[i].right;
1010 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1011 }
1012
Xu Yangcda012c2014-07-30 21:57:21 +08001013 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001014 for (int i = 0; i < numPTORLayersFound; i++) {
1015 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001016 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001017 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1018 hnd->width = layerWhf[i].w;
1019 hnd->height = layerWhf[i].h;
1020 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001021 layer->blending = blending[i];
1022 layer->planeAlpha = planeAlpha[i];
1023 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001024 }
1025
Sushil Chauhandefd3522014-05-13 18:17:12 -07001026 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001027 // reset PTOR
1028 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001029 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001030 } else {
1031 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1032 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001033 }
1034
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001035 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1036 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001037 return result;
1038}
1039
Saurabh Shahaa236822013-04-24 18:07:26 -07001040bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1041{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001042 if(!sEnableMixedMode) {
1043 //Mixed mode is disabled. No need to even try caching.
1044 return false;
1045 }
1046
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001047 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001048 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001049 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001050 cacheBasedComp(ctx, list);
1051 } else {
1052 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001053 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001054 }
1055
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001056 return ret;
1057}
1058
1059bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1060 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001061 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1062 return false;
1063
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001064 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001065 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001066 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001067
1068 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1069 for(int i = 0; i < numAppLayers; i++) {
1070 if(!mCurrentFrame.isFBComposed[i]) {
1071 hwc_layer_1_t* layer = &list->hwLayers[i];
1072 if(not isSupportedForMDPComp(ctx, layer)) {
1073 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1074 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001075 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001076 return false;
1077 }
1078 }
1079 }
1080
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001081 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001082 /* mark secure RGB layers for MDP comp */
1083 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301084 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001085 if(!ret) {
1086 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001087 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001088 return false;
1089 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001090
1091 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001092
Raj Kamal389d6e32014-08-04 14:43:24 +05301093 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001094 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301095 }
1096
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001097 //Will benefit cases where a video has non-updating background.
1098 if((mDpy > HWC_DISPLAY_PRIMARY) and
1099 (mdpCount > MAX_SEC_LAYERS)) {
1100 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001101 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001102 return false;
1103 }
1104
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001105 if(!postHeuristicsHandling(ctx, list)) {
1106 ALOGD_IF(isDebug(), "post heuristic handling failed");
1107 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001108 return false;
1109 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001110 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1111 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001112
Saurabh Shahaa236822013-04-24 18:07:26 -07001113 return true;
1114}
1115
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001116bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001117 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001118 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1119 return false;
1120
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001121 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001122 return false;
1123 }
1124
Saurabh Shahb772ae32013-11-18 15:40:02 -08001125 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001126 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1127 const int stagesForMDP = min(sMaxPipesPerMixer,
1128 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001129
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001130 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1131 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1132 int lastMDPSupportedIndex = numAppLayers;
1133 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001134
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001135 //Find the minimum MDP batch size
1136 for(int i = 0; i < numAppLayers;i++) {
1137 if(mCurrentFrame.drop[i]) {
1138 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001139 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001140 }
1141 hwc_layer_1_t* layer = &list->hwLayers[i];
1142 if(not isSupportedForMDPComp(ctx, layer)) {
1143 lastMDPSupportedIndex = i;
1144 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1145 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001146 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001147 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001148 }
1149
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001150 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1151 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1152 mCurrentFrame.dropCount);
1153
1154 //Start at a point where the fb batch should at least have 2 layers, for
1155 //this mode to be justified.
1156 while(fbBatchSize < 2) {
1157 ++fbBatchSize;
1158 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001159 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001160
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001161 //If there are no layers for MDP, this mode doesnt make sense.
1162 if(mdpBatchSize < 1) {
1163 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1164 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001165 return false;
1166 }
1167
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001168 mCurrentFrame.reset(numAppLayers);
1169
1170 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1171 while(mdpBatchSize > 0) {
1172 //Mark layers for MDP comp
1173 int mdpBatchLeft = mdpBatchSize;
1174 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1175 if(mCurrentFrame.drop[i]) {
1176 continue;
1177 }
1178 mCurrentFrame.isFBComposed[i] = false;
1179 --mdpBatchLeft;
1180 }
1181
1182 mCurrentFrame.fbZ = mdpBatchSize;
1183 mCurrentFrame.fbCount = fbBatchSize;
1184 mCurrentFrame.mdpCount = mdpBatchSize;
1185
1186 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1187 __FUNCTION__, mdpBatchSize, fbBatchSize,
1188 mCurrentFrame.dropCount);
1189
1190 if(postHeuristicsHandling(ctx, list)) {
1191 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001192 __FUNCTION__);
1193 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1194 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001195 return true;
1196 }
1197
1198 reset(ctx);
1199 --mdpBatchSize;
1200 ++fbBatchSize;
1201 }
1202
1203 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001204}
1205
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001206bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301207 if(mDpy or isSecurePresent(ctx, mDpy) or
1208 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001209 return false;
1210 }
1211 return true;
1212}
1213
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001214bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1215 hwc_display_contents_1_t* list){
1216 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1217 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1218 mDpy ) {
1219 return false;
1220 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001221 if(ctx->listStats[mDpy].secureUI)
1222 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001223 return true;
1224}
1225
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001226bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1227 hwc_display_contents_1_t* list) {
1228 const bool secureOnly = true;
1229 return videoOnlyComp(ctx, list, not secureOnly) or
1230 videoOnlyComp(ctx, list, secureOnly);
1231}
1232
1233bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001234 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001235 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1236 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001237 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001238
Saurabh Shahaa236822013-04-24 18:07:26 -07001239 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001240 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001241 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001242 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001243
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001244 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1245 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001246 return false;
1247 }
1248
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001249 /* Bail out if we are processing only secured video layers
1250 * and we dont have any */
1251 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001252 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001253 return false;
1254 }
1255
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001256 if(mCurrentFrame.fbCount)
1257 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001258
Raj Kamal389d6e32014-08-04 14:43:24 +05301259 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001260 adjustForSourceSplit(ctx, list);
1261 }
1262
1263 if(!postHeuristicsHandling(ctx, list)) {
1264 ALOGD_IF(isDebug(), "post heuristic handling failed");
1265 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001266 return false;
1267 }
1268
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001269 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1270 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001271 return true;
1272}
1273
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001274/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1275bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1276 hwc_display_contents_1_t* list) {
1277 const bool secureOnly = true;
1278 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1279 mdpOnlyLayersComp(ctx, list, secureOnly);
1280
1281}
1282
1283bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1284 hwc_display_contents_1_t* list, bool secureOnly) {
1285
1286 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1287 return false;
1288
1289 /* Bail out if we are processing only secured video layers
1290 * and we dont have any */
1291 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1292 reset(ctx);
1293 return false;
1294 }
1295
1296 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1297 mCurrentFrame.reset(numAppLayers);
1298 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1299
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001300 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001301 /* mark secure RGB layers for MDP comp */
1302 updateSecureRGB(ctx, list);
1303
1304 if(mCurrentFrame.mdpCount == 0) {
1305 reset(ctx);
1306 return false;
1307 }
1308
1309 /* find the maximum batch of layers to be marked for framebuffer */
1310 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1311 if(!ret) {
1312 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1313 reset(ctx);
1314 return false;
1315 }
1316
1317 if(sEnableYUVsplit){
1318 adjustForSourceSplit(ctx, list);
1319 }
1320
1321 if(!postHeuristicsHandling(ctx, list)) {
1322 ALOGD_IF(isDebug(), "post heuristic handling failed");
1323 reset(ctx);
1324 return false;
1325 }
1326
1327 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1328 __FUNCTION__);
1329 return true;
1330}
1331
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001332/* Checks for conditions where YUV layers cannot be bypassed */
1333bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001334 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001335 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001336 return false;
1337 }
1338
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001339 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001340 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1341 return false;
1342 }
1343
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001344 if(isSecuring(ctx, layer)) {
1345 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1346 return false;
1347 }
1348
Saurabh Shah4fdde762013-04-30 18:47:33 -07001349 if(!isValidDimension(ctx, layer)) {
1350 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1351 __FUNCTION__);
1352 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001353 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001354
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001355 if(layer->planeAlpha < 0xFF) {
1356 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1357 in video only mode",
1358 __FUNCTION__);
1359 return false;
1360 }
1361
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001362 return true;
1363}
1364
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001365/* Checks for conditions where Secure RGB layers cannot be bypassed */
1366bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1367 if(isSkipLayer(layer)) {
1368 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1369 __FUNCTION__, mDpy);
1370 return false;
1371 }
1372
1373 if(isSecuring(ctx, layer)) {
1374 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1375 return false;
1376 }
1377
1378 if(not isSupportedForMDPComp(ctx, layer)) {
1379 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1380 __FUNCTION__);
1381 return false;
1382 }
1383 return true;
1384}
1385
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301386/* starts at fromIndex and check for each layer to find
1387 * if it it has overlapping with any Updating layer above it in zorder
1388 * till the end of the batch. returns true if it finds any intersection */
1389bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1390 int fromIndex, int toIndex) {
1391 for(int i = fromIndex; i < toIndex; i++) {
1392 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1393 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1394 return false;
1395 }
1396 }
1397 }
1398 return true;
1399}
1400
1401/* Checks if given layer at targetLayerIndex has any
1402 * intersection with all the updating layers in beween
1403 * fromIndex and toIndex. Returns true if it finds intersectiion */
1404bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1405 int fromIndex, int toIndex, int targetLayerIndex) {
1406 for(int i = fromIndex; i <= toIndex; i++) {
1407 if(!mCurrentFrame.isFBComposed[i]) {
1408 if(areLayersIntersecting(&list->hwLayers[i],
1409 &list->hwLayers[targetLayerIndex])) {
1410 return true;
1411 }
1412 }
1413 }
1414 return false;
1415}
1416
1417int MDPComp::getBatch(hwc_display_contents_1_t* list,
1418 int& maxBatchStart, int& maxBatchEnd,
1419 int& maxBatchCount) {
1420 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301421 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001422 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301423 while (i < mCurrentFrame.layerCount) {
1424 int batchCount = 0;
1425 int batchStart = i;
1426 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001427 /* Adjust batch Z order with the dropped layers so far */
1428 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301429 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301430 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301431 while(i < mCurrentFrame.layerCount) {
1432 if(!mCurrentFrame.isFBComposed[i]) {
1433 if(!batchCount) {
1434 i++;
1435 break;
1436 }
1437 updatingLayersAbove++;
1438 i++;
1439 continue;
1440 } else {
1441 if(mCurrentFrame.drop[i]) {
1442 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001443 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301444 continue;
1445 } else if(updatingLayersAbove <= 0) {
1446 batchCount++;
1447 batchEnd = i;
1448 i++;
1449 continue;
1450 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1451
1452 // We have a valid updating layer already. If layer-i not
1453 // have overlapping with all updating layers in between
1454 // batch-start and i, then we can add layer i to batch.
1455 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1456 batchCount++;
1457 batchEnd = i;
1458 i++;
1459 continue;
1460 } else if(canPushBatchToTop(list, batchStart, i)) {
1461 //If All the non-updating layers with in this batch
1462 //does not have intersection with the updating layers
1463 //above in z-order, then we can safely move the batch to
1464 //higher z-order. Increment fbZ as it is moving up.
1465 if( firstZReverseIndex < 0) {
1466 firstZReverseIndex = i;
1467 }
1468 batchCount++;
1469 batchEnd = i;
1470 fbZ += updatingLayersAbove;
1471 i++;
1472 updatingLayersAbove = 0;
1473 continue;
1474 } else {
1475 //both failed.start the loop again from here.
1476 if(firstZReverseIndex >= 0) {
1477 i = firstZReverseIndex;
1478 }
1479 break;
1480 }
1481 }
1482 }
1483 }
1484 if(batchCount > maxBatchCount) {
1485 maxBatchCount = batchCount;
1486 maxBatchStart = batchStart;
1487 maxBatchEnd = batchEnd;
1488 fbZOrder = fbZ;
1489 }
1490 }
1491 return fbZOrder;
1492}
1493
1494bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1495 hwc_display_contents_1_t* list) {
1496 /* Idea is to keep as many non-updating(cached) layers in FB and
1497 * send rest of them through MDP. This is done in 2 steps.
1498 * 1. Find the maximum contiguous batch of non-updating layers.
1499 * 2. See if we can improve this batch size for caching by adding
1500 * opaque layers around the batch, if they don't have
1501 * any overlapping with the updating layers in between.
1502 * NEVER mark an updating layer for caching.
1503 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001504
1505 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001506 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001507 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301508 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001509
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001510 /* Nothing is cached. No batching needed */
1511 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001512 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001513 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001514
1515 /* No MDP comp layers, try to use other comp modes */
1516 if(mCurrentFrame.mdpCount == 0) {
1517 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001518 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001519
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301520 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001521
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301522 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001523 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001524 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001525 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301526 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001527 if(!mCurrentFrame.drop[i]){
1528 //If an unsupported layer is being attempted to
1529 //be pulled out we should fail
1530 if(not isSupportedForMDPComp(ctx, layer)) {
1531 return false;
1532 }
1533 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001534 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001535 }
1536 }
1537
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301538 // update the frame data
1539 mCurrentFrame.fbZ = fbZ;
1540 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001541 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001542 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001543
1544 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301545 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001546
1547 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001548}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001549
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001550void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001551 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001552 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001553 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001554
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001555 for(int i = 0; i < numAppLayers; i++) {
1556 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001557 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001558 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001559 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001560 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001561 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001562 }
1563 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001564
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001565 frame.fbCount = fbCount;
1566 frame.mdpCount = frame.layerCount - frame.fbCount
1567 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001568
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001569 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1570 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001571}
1572
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001573void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001574 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001575 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1576 for(int index = 0;index < nYuvCount; index++){
1577 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1578 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1579
1580 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001581 if(!frame.isFBComposed[nYuvIndex]) {
1582 frame.isFBComposed[nYuvIndex] = true;
1583 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001584 }
1585 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001586 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001587 private_handle_t *hnd = (private_handle_t *)layer->handle;
1588 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001589 frame.isFBComposed[nYuvIndex] = false;
1590 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001591 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001592 }
1593 }
1594 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001595
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001596 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1597 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001598}
1599
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001600void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1601 hwc_display_contents_1_t* list) {
1602 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1603 for(int index = 0;index < nSecureRGBCount; index++){
1604 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1605 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1606
1607 if(!isSecureRGBDoable(ctx, layer)) {
1608 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1609 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1610 mCurrentFrame.fbCount++;
1611 }
1612 } else {
1613 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1614 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1615 mCurrentFrame.fbCount--;
1616 }
1617 }
1618 }
1619
1620 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1621 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1622 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1623 mCurrentFrame.fbCount);
1624}
1625
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001626hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1627 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001628 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001629
1630 /* Update only the region of FB needed for composition */
1631 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1632 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1633 hwc_layer_1_t* layer = &list->hwLayers[i];
1634 hwc_rect_t dst = layer->displayFrame;
1635 fbRect = getUnion(fbRect, dst);
1636 }
1637 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001638 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001639 return fbRect;
1640}
1641
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001642bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1643 hwc_display_contents_1_t* list) {
1644
1645 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001646 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001647 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1648 return false;
1649 }
1650
1651 //Limitations checks
1652 if(!hwLimitationsCheck(ctx, list)) {
1653 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1654 return false;
1655 }
1656
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001657 //Configure framebuffer first if applicable
1658 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001659 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001660 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1661 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001662 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1663 __FUNCTION__);
1664 return false;
1665 }
1666 }
1667
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001668 mCurrentFrame.map();
1669
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001670 if(!allocLayerPipes(ctx, list)) {
1671 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001672 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001673 }
1674
1675 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001676 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001677 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001678 int mdpIndex = mCurrentFrame.layerToMDP[index];
1679 hwc_layer_1_t* layer = &list->hwLayers[index];
1680
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301681 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1682 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1683 mdpNextZOrder++;
1684 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001685 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1686 cur_pipe->zOrder = mdpNextZOrder++;
1687
radhakrishnac9a67412013-09-25 17:40:42 +05301688 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301689 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301690 if(configure4k2kYuv(ctx, layer,
1691 mCurrentFrame.mdpToLayer[mdpIndex])
1692 != 0 ){
1693 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1694 for layer %d",__FUNCTION__, index);
1695 return false;
1696 }
1697 else{
1698 mdpNextZOrder++;
1699 }
1700 continue;
1701 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001702 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1703 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301704 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001705 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001706 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001707 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001708 }
1709
Saurabh Shaha36be922013-12-16 18:18:39 -08001710 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1711 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1712 ,__FUNCTION__, mDpy);
1713 return false;
1714 }
1715
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001716 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001717 return true;
1718}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001719
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001720bool MDPComp::resourceCheck(hwc_context_t* ctx,
1721 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001722 const bool fbUsed = mCurrentFrame.fbCount;
1723 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1724 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1725 return false;
1726 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001727 // Init rotCount to number of rotate sessions used by other displays
1728 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1729 // Count the number of rotator sessions required for current display
1730 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1731 if(!mCurrentFrame.isFBComposed[index]) {
1732 hwc_layer_1_t* layer = &list->hwLayers[index];
1733 private_handle_t *hnd = (private_handle_t *)layer->handle;
1734 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1735 rotCount++;
1736 }
1737 }
1738 }
1739 // if number of layers to rotate exceeds max rotator sessions, bail out.
1740 if(rotCount > RotMgr::MAX_ROT_SESS) {
1741 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1742 __FUNCTION__, mDpy);
1743 return false;
1744 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001745 return true;
1746}
1747
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301748bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1749 hwc_display_contents_1_t* list) {
1750
1751 //A-family hw limitation:
1752 //If a layer need alpha scaling, MDP can not support.
1753 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1754 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1755 if(!mCurrentFrame.isFBComposed[i] &&
1756 isAlphaScaled( &list->hwLayers[i])) {
1757 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1758 return false;
1759 }
1760 }
1761 }
1762
1763 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1764 //If multiple layers requires downscaling and also they are overlapping
1765 //fall back to GPU since MDSS can not handle it.
1766 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1767 qdutils::MDPVersion::getInstance().is8x26()) {
1768 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1769 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1770 if(!mCurrentFrame.isFBComposed[i] &&
1771 isDownscaleRequired(botLayer)) {
1772 //if layer-i is marked for MDP and needs downscaling
1773 //check if any MDP layer on top of i & overlaps with layer-i
1774 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1775 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1776 if(!mCurrentFrame.isFBComposed[j] &&
1777 isDownscaleRequired(topLayer)) {
1778 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1779 topLayer->displayFrame);
1780 if(isValidRect(r))
1781 return false;
1782 }
1783 }
1784 }
1785 }
1786 }
1787 return true;
1788}
1789
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001790int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001791 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001792 char property[PROPERTY_VALUE_MAX];
1793
Raj Kamal4393eaa2014-06-06 13:45:20 +05301794 if(!ctx || !list) {
1795 ALOGE("%s: Invalid context or list",__FUNCTION__);
1796 mCachedFrame.reset();
1797 return -1;
1798 }
1799
1800 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001801 if(mDpy == HWC_DISPLAY_PRIMARY) {
1802 sSimulationFlags = 0;
1803 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1804 int currentFlags = atoi(property);
1805 if(currentFlags != sSimulationFlags) {
1806 sSimulationFlags = currentFlags;
1807 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1808 sSimulationFlags, sSimulationFlags);
1809 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001810 }
1811 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001812 // reset PTOR
1813 if(!mDpy)
1814 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001815
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301816 //Do not cache the information for next draw cycle.
1817 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1818 ALOGI("%s: Unsupported layer count for mdp composition",
1819 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001820 mCachedFrame.reset();
1821 return -1;
1822 }
1823
Saurabh Shahb39f8152013-08-22 10:21:44 -07001824 //reset old data
1825 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001826 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1827 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301828
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001829 // Detect the start of animation and fall back to GPU only once to cache
1830 // all the layers in FB and display FB content untill animation completes.
1831 if(ctx->listStats[mDpy].isDisplayAnimating) {
1832 mCurrentFrame.needsRedraw = false;
1833 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1834 mCurrentFrame.needsRedraw = true;
1835 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1836 }
1837 setMDPCompLayerFlags(ctx, list);
1838 mCachedFrame.updateCounts(mCurrentFrame);
1839 ret = -1;
1840 return ret;
1841 } else {
1842 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1843 }
1844
Saurabh Shahb39f8152013-08-22 10:21:44 -07001845 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001846 if(isFrameDoable(ctx)) {
1847 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001848
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001849 // if tryFullFrame fails, try to push all video and secure RGB layers
1850 // to MDP for composition.
1851 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
1852 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301853 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001854 setMDPCompLayerFlags(ctx, list);
1855 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001856 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001857 reset(ctx);
1858 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1859 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001860 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001861 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1862 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001863 }
1864 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001865 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1866 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001867 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001868 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001869
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001870 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001871 ALOGD("GEOMETRY change: %d",
1872 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001873 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001874 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001875 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001876 }
1877
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001878#ifdef DYNAMIC_FPS
1879 //For primary display, set the dynamic refreshrate
1880 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported()) {
1881 FrameInfo frame;
1882 frame.reset(mCurrentFrame.layerCount);
1883 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
1884 __FUNCTION__);
1885 updateLayerCache(ctx, list, frame);
1886 updateYUV(ctx, list, false /*secure only*/, frame);
1887 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1888 //Set the new fresh rate, if there is only one updating YUV layer
1889 //or there is one single RGB layer with this request
1890 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1891 (frame.layerCount == 1)) {
1892 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1893 }
1894 setRefreshRate(ctx, mDpy, refreshRate);
1895 }
1896#endif
1897
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001898 mCachedFrame.cacheAll(list);
1899 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001900 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001901}
1902
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001903bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301904
1905 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301906 int mdpIndex = mCurrentFrame.layerToMDP[index];
1907 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1908 info.pipeInfo = new MdpYUVPipeInfo;
1909 info.rot = NULL;
1910 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301911
1912 pipe_info.lIndex = ovutils::OV_INVALID;
1913 pipe_info.rIndex = ovutils::OV_INVALID;
1914
Saurabh Shahc62f3982014-03-05 14:28:26 -08001915 Overlay::PipeSpecs pipeSpecs;
1916 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1917 pipeSpecs.needsScaling = true;
1918 pipeSpecs.dpy = mDpy;
1919 pipeSpecs.fb = false;
1920
1921 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301922 if(pipe_info.lIndex == ovutils::OV_INVALID){
1923 bRet = false;
1924 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1925 __FUNCTION__);
1926 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001927 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301928 if(pipe_info.rIndex == ovutils::OV_INVALID){
1929 bRet = false;
1930 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1931 __FUNCTION__);
1932 }
1933 return bRet;
1934}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001935
1936int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1937 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001938 if (ctx->mPtorInfo.isActive()) {
1939 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001940 if (fd < 0) {
1941 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001942 }
1943 }
1944 return fd;
1945}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001946//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001947
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001948void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301949 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001950 //If 4k2k Yuv layer split is possible, and if
1951 //fbz is above 4k2k layer, increment fb zorder by 1
1952 //as we split 4k2k layer and increment zorder for right half
1953 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07001954 if(!ctx)
1955 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001956 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301957 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1958 index++) {
1959 if(!mCurrentFrame.isFBComposed[index]) {
1960 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1961 mdpNextZOrder++;
1962 }
1963 mdpNextZOrder++;
1964 hwc_layer_1_t* layer = &list->hwLayers[index];
1965 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301966 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301967 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1968 mCurrentFrame.fbZ += 1;
1969 mdpNextZOrder++;
1970 //As we split 4kx2k yuv layer and program to 2 VG pipes
1971 //(if available) increase mdpcount by 1.
1972 mCurrentFrame.mdpCount++;
1973 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001974 }
1975 }
1976 }
radhakrishnac9a67412013-09-25 17:40:42 +05301977}
1978
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001979/*
1980 * Configures pipe(s) for MDP composition
1981 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001982int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001983 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001984 MdpPipeInfoNonSplit& mdp_info =
1985 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001986 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1987 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08001988 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001989
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001990 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1991 __FUNCTION__, layer, zOrder, dest);
1992
Saurabh Shah2c8ad052014-08-15 13:27:46 -07001993 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001994 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001995}
1996
Saurabh Shah88e4d272013-09-03 13:31:29 -07001997bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001998 hwc_display_contents_1_t* list) {
1999 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002000
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002001 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002002
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002003 hwc_layer_1_t* layer = &list->hwLayers[index];
2004 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302005 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002006 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302007 continue;
2008 }
2009 }
2010
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002011 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002012 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002013 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002014 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002015 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002016
Saurabh Shahc62f3982014-03-05 14:28:26 -08002017 Overlay::PipeSpecs pipeSpecs;
2018 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2019 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2020 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2021 (qdutils::MDPVersion::getInstance().is8x26() and
2022 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2023 pipeSpecs.dpy = mDpy;
2024 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002025 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002026
Saurabh Shahc62f3982014-03-05 14:28:26 -08002027 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2028
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002029 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002030 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002031 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002032 }
2033 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002034 return true;
2035}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002036
radhakrishnac9a67412013-09-25 17:40:42 +05302037int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2038 PipeLayerPair& PipeLayerPair) {
2039 MdpYUVPipeInfo& mdp_info =
2040 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2041 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302042 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2043 eDest lDest = mdp_info.lIndex;
2044 eDest rDest = mdp_info.rIndex;
2045
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002046 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302047 lDest, rDest, &PipeLayerPair.rot);
2048}
2049
Saurabh Shah88e4d272013-09-03 13:31:29 -07002050bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002051
Raj Kamal4393eaa2014-06-06 13:45:20 +05302052 if(!isEnabled() or !mModeOn) {
2053 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302054 return true;
2055 }
2056
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002057 // Set the Handle timeout to true for MDP or MIXED composition.
2058 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2059 sHandleTimeout = true;
2060 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002061
2062 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002063 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002064
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002065 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2066 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002067 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002068 if(mCurrentFrame.isFBComposed[i]) continue;
2069
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002070 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002071 private_handle_t *hnd = (private_handle_t *)layer->handle;
2072 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002073 if (!(layer->flags & HWC_COLOR_FILL)) {
2074 ALOGE("%s handle null", __FUNCTION__);
2075 return false;
2076 }
2077 // No PLAY for Color layer
2078 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2079 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002080 }
2081
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002082 int mdpIndex = mCurrentFrame.layerToMDP[i];
2083
Raj Kamal389d6e32014-08-04 14:43:24 +05302084 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302085 {
2086 MdpYUVPipeInfo& pipe_info =
2087 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2088 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2089 ovutils::eDest indexL = pipe_info.lIndex;
2090 ovutils::eDest indexR = pipe_info.rIndex;
2091 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302092 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302093 if(rot) {
2094 rot->queueBuffer(fd, offset);
2095 fd = rot->getDstMemId();
2096 offset = rot->getDstOffset();
2097 }
2098 if(indexL != ovutils::OV_INVALID) {
2099 ovutils::eDest destL = (ovutils::eDest)indexL;
2100 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2101 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2102 if (!ov.queueBuffer(fd, offset, destL)) {
2103 ALOGE("%s: queueBuffer failed for display:%d",
2104 __FUNCTION__, mDpy);
2105 return false;
2106 }
2107 }
2108
2109 if(indexR != ovutils::OV_INVALID) {
2110 ovutils::eDest destR = (ovutils::eDest)indexR;
2111 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2112 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2113 if (!ov.queueBuffer(fd, offset, destR)) {
2114 ALOGE("%s: queueBuffer failed for display:%d",
2115 __FUNCTION__, mDpy);
2116 return false;
2117 }
2118 }
2119 }
2120 else{
2121 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002122 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302123 ovutils::eDest dest = pipe_info.index;
2124 if(dest == ovutils::OV_INVALID) {
2125 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002126 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302127 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002128
radhakrishnac9a67412013-09-25 17:40:42 +05302129 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2130 continue;
2131 }
2132
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002133 int fd = hnd->fd;
2134 uint32_t offset = (uint32_t)hnd->offset;
2135 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2136 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002137 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002138 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002139 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002140 }
2141
radhakrishnac9a67412013-09-25 17:40:42 +05302142 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2143 using pipe: %d", __FUNCTION__, layer,
2144 hnd, dest );
2145
radhakrishnac9a67412013-09-25 17:40:42 +05302146 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2147 if(rot) {
2148 if(!rot->queueBuffer(fd, offset))
2149 return false;
2150 fd = rot->getDstMemId();
2151 offset = rot->getDstOffset();
2152 }
2153
2154 if (!ov.queueBuffer(fd, offset, dest)) {
2155 ALOGE("%s: queueBuffer failed for display:%d ",
2156 __FUNCTION__, mDpy);
2157 return false;
2158 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002159 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002160
2161 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002162 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002163 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002164}
2165
Saurabh Shah88e4d272013-09-03 13:31:29 -07002166//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002167
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002168void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302169 hwc_display_contents_1_t* list){
2170 //if 4kx2k yuv layer is totally present in either in left half
2171 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302172 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302173 if(mCurrentFrame.fbZ >= 0) {
2174 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2175 index++) {
2176 if(!mCurrentFrame.isFBComposed[index]) {
2177 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2178 mdpNextZOrder++;
2179 }
2180 mdpNextZOrder++;
2181 hwc_layer_1_t* layer = &list->hwLayers[index];
2182 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302183 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302184 hwc_rect_t dst = layer->displayFrame;
2185 if((dst.left > lSplit) || (dst.right < lSplit)) {
2186 mCurrentFrame.mdpCount += 1;
2187 }
2188 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2189 mCurrentFrame.fbZ += 1;
2190 mdpNextZOrder++;
2191 }
2192 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002193 }
radhakrishnac9a67412013-09-25 17:40:42 +05302194 }
2195}
2196
Saurabh Shah88e4d272013-09-03 13:31:29 -07002197bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002198 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002199
Saurabh Shahc62f3982014-03-05 14:28:26 -08002200 const int lSplit = getLeftSplit(ctx, mDpy);
2201 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002202 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002203 pipe_info.lIndex = ovutils::OV_INVALID;
2204 pipe_info.rIndex = ovutils::OV_INVALID;
2205
Saurabh Shahc62f3982014-03-05 14:28:26 -08002206 Overlay::PipeSpecs pipeSpecs;
2207 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2208 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2209 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2210 pipeSpecs.dpy = mDpy;
2211 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2212 pipeSpecs.fb = false;
2213
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002214 // Acquire pipe only for the updating half
2215 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2216 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2217
2218 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002219 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002220 if(pipe_info.lIndex == ovutils::OV_INVALID)
2221 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002222 }
2223
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002224 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002225 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2226 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002227 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002228 return false;
2229 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002230
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002231 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002232}
2233
Saurabh Shah88e4d272013-09-03 13:31:29 -07002234bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002235 hwc_display_contents_1_t* list) {
2236 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002237
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002238 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002239
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002240 hwc_layer_1_t* layer = &list->hwLayers[index];
2241 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302242 hwc_rect_t dst = layer->displayFrame;
2243 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302244 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302245 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002246 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302247 continue;
2248 }
2249 }
2250 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002251 int mdpIndex = mCurrentFrame.layerToMDP[index];
2252 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002253 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002254 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002255 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002256
Saurabh Shahc62f3982014-03-05 14:28:26 -08002257 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2258 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2259 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002260 return false;
2261 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002262 }
2263 return true;
2264}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002265
radhakrishnac9a67412013-09-25 17:40:42 +05302266int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2267 PipeLayerPair& PipeLayerPair) {
2268 const int lSplit = getLeftSplit(ctx, mDpy);
2269 hwc_rect_t dst = layer->displayFrame;
2270 if((dst.left > lSplit)||(dst.right < lSplit)){
2271 MdpYUVPipeInfo& mdp_info =
2272 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2273 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302274 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2275 eDest lDest = mdp_info.lIndex;
2276 eDest rDest = mdp_info.rIndex;
2277
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002278 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302279 lDest, rDest, &PipeLayerPair.rot);
2280 }
2281 else{
2282 return configure(ctx, layer, PipeLayerPair);
2283 }
2284}
2285
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002286/*
2287 * Configures pipe(s) for MDP composition
2288 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002289int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002290 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002291 MdpPipeInfoSplit& mdp_info =
2292 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002293 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002294 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2295 eDest lDest = mdp_info.lIndex;
2296 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002297
2298 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2299 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2300
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002301 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002302 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002303}
2304
Saurabh Shah88e4d272013-09-03 13:31:29 -07002305bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002306
Raj Kamal4393eaa2014-06-06 13:45:20 +05302307 if(!isEnabled() or !mModeOn) {
2308 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302309 return true;
2310 }
2311
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002312 // Set the Handle timeout to true for MDP or MIXED composition.
2313 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2314 sHandleTimeout = true;
2315 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002316
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002317 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002318 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002319
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002320 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2321 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002322 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002323 if(mCurrentFrame.isFBComposed[i]) continue;
2324
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002325 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002326 private_handle_t *hnd = (private_handle_t *)layer->handle;
2327 if(!hnd) {
2328 ALOGE("%s handle null", __FUNCTION__);
2329 return false;
2330 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002331
2332 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2333 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002334 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002335
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002336 int mdpIndex = mCurrentFrame.layerToMDP[i];
2337
Raj Kamal389d6e32014-08-04 14:43:24 +05302338 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302339 {
2340 MdpYUVPipeInfo& pipe_info =
2341 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2342 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2343 ovutils::eDest indexL = pipe_info.lIndex;
2344 ovutils::eDest indexR = pipe_info.rIndex;
2345 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302346 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302347 if(rot) {
2348 rot->queueBuffer(fd, offset);
2349 fd = rot->getDstMemId();
2350 offset = rot->getDstOffset();
2351 }
2352 if(indexL != ovutils::OV_INVALID) {
2353 ovutils::eDest destL = (ovutils::eDest)indexL;
2354 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2355 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2356 if (!ov.queueBuffer(fd, offset, destL)) {
2357 ALOGE("%s: queueBuffer failed for display:%d",
2358 __FUNCTION__, mDpy);
2359 return false;
2360 }
2361 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002362
radhakrishnac9a67412013-09-25 17:40:42 +05302363 if(indexR != ovutils::OV_INVALID) {
2364 ovutils::eDest destR = (ovutils::eDest)indexR;
2365 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2366 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2367 if (!ov.queueBuffer(fd, offset, destR)) {
2368 ALOGE("%s: queueBuffer failed for display:%d",
2369 __FUNCTION__, mDpy);
2370 return false;
2371 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002372 }
2373 }
radhakrishnac9a67412013-09-25 17:40:42 +05302374 else{
2375 MdpPipeInfoSplit& pipe_info =
2376 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2377 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002378
radhakrishnac9a67412013-09-25 17:40:42 +05302379 ovutils::eDest indexL = pipe_info.lIndex;
2380 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002381
radhakrishnac9a67412013-09-25 17:40:42 +05302382 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002383 uint32_t offset = (uint32_t)hnd->offset;
2384 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2385 if (!mDpy && (index != -1)) {
2386 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2387 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002388 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002389 }
radhakrishnac9a67412013-09-25 17:40:42 +05302390
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002391 if(ctx->mAD->draw(ctx, fd, offset)) {
2392 fd = ctx->mAD->getDstFd();
2393 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002394 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002395
radhakrishnac9a67412013-09-25 17:40:42 +05302396 if(rot) {
2397 rot->queueBuffer(fd, offset);
2398 fd = rot->getDstMemId();
2399 offset = rot->getDstOffset();
2400 }
2401
2402 //************* play left mixer **********
2403 if(indexL != ovutils::OV_INVALID) {
2404 ovutils::eDest destL = (ovutils::eDest)indexL;
2405 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2406 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2407 if (!ov.queueBuffer(fd, offset, destL)) {
2408 ALOGE("%s: queueBuffer failed for left mixer",
2409 __FUNCTION__);
2410 return false;
2411 }
2412 }
2413
2414 //************* play right mixer **********
2415 if(indexR != ovutils::OV_INVALID) {
2416 ovutils::eDest destR = (ovutils::eDest)indexR;
2417 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2418 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2419 if (!ov.queueBuffer(fd, offset, destR)) {
2420 ALOGE("%s: queueBuffer failed for right mixer",
2421 __FUNCTION__);
2422 return false;
2423 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002424 }
2425 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002426
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002427 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2428 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002429
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002430 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002431}
Saurabh Shahab47c692014-02-12 18:45:57 -08002432
2433//================MDPCompSrcSplit==============================================
2434bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002435 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002436 private_handle_t *hnd = (private_handle_t *)layer->handle;
2437 hwc_rect_t dst = layer->displayFrame;
2438 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2439 pipe_info.lIndex = ovutils::OV_INVALID;
2440 pipe_info.rIndex = ovutils::OV_INVALID;
2441
2442 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2443 //should have a higher priority than the right one. Pipe priorities are
2444 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002445
Saurabh Shahc62f3982014-03-05 14:28:26 -08002446 Overlay::PipeSpecs pipeSpecs;
2447 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2448 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2449 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2450 pipeSpecs.dpy = mDpy;
2451 pipeSpecs.fb = false;
2452
Saurabh Shahab47c692014-02-12 18:45:57 -08002453 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002454 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002455 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002456 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002457 }
2458
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002459 /* Use 2 pipes IF
2460 a) Layer's crop width is > 2048 or
2461 b) Layer's dest width > 2048 or
2462 c) On primary, driver has indicated with caps to split always. This is
2463 based on an empirically derived value of panel height. Applied only
2464 if the layer's width is > mixer's width
2465 */
2466
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302467 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002468 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302469 mdpHw.isSrcSplitAlways();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002470 int lSplit = getLeftSplit(ctx, mDpy);
2471 int dstWidth = dst.right - dst.left;
Saurabh Shah189f23d2014-09-26 17:21:00 -07002472 int cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
2473 crop.right - crop.left;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002474
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002475 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2476 //pipe line length, we are still using 2 pipes. This is fine just because
2477 //this is source split where destination doesn't matter. Evaluate later to
2478 //see if going through all the calcs to save a pipe is worth it
Naseer Ahmed9eb5e092014-09-25 13:24:44 -04002479 if(dstWidth > (int) mdpHw.getMaxMixerWidth() or
2480 cropWidth > (int) mdpHw.getMaxMixerWidth() or
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002481 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002482 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002483 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002484 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002485 }
2486
2487 // Return values
2488 // 1 Left pipe is higher priority, do nothing.
2489 // 0 Pipes of same priority.
2490 //-1 Right pipe is of higher priority, needs swap.
2491 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2492 pipe_info.rIndex) == -1) {
2493 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002494 }
2495 }
2496
2497 return true;
2498}
2499
Saurabh Shahab47c692014-02-12 18:45:57 -08002500int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2501 PipeLayerPair& PipeLayerPair) {
2502 private_handle_t *hnd = (private_handle_t *)layer->handle;
2503 if(!hnd) {
2504 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2505 return -1;
2506 }
2507 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2508 MdpPipeInfoSplit& mdp_info =
2509 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2510 Rotator **rot = &PipeLayerPair.rot;
2511 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002512 eDest lDest = mdp_info.lIndex;
2513 eDest rDest = mdp_info.rIndex;
2514 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2515 hwc_rect_t dst = layer->displayFrame;
2516 int transform = layer->transform;
2517 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002518 int rotFlags = ROT_FLAGS_NONE;
2519 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2520 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2521
2522 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2523 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2524
2525 // Handle R/B swap
2526 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2527 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2528 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2529 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2530 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2531 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002532 /* Calculate the external display position based on MDP downscale,
2533 ActionSafe, and extorientation features. */
2534 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002535
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002536 int downscale = getRotDownscale(ctx, layer);
Saurabh Shah97e2d802014-04-14 18:03:54 -07002537 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002538 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002539
2540 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2541 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002542 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002543 }
2544
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002545 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002546 (*rot) = ctx->mRotMgr->getNext();
2547 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002548 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002549 //If the video is using a single pipe, enable BWC
2550 if(rDest == OV_INVALID) {
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002551 BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002552 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002553 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002554 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002555 ALOGE("%s: configRotator failed!", __FUNCTION__);
2556 return -1;
2557 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002558 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002559 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002560 }
2561
2562 //If 2 pipes being used, divide layer into half, crop and dst
2563 hwc_rect_t cropL = crop;
2564 hwc_rect_t cropR = crop;
2565 hwc_rect_t dstL = dst;
2566 hwc_rect_t dstR = dst;
2567 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2568 cropL.right = (crop.right + crop.left) / 2;
2569 cropR.left = cropL.right;
2570 sanitizeSourceCrop(cropL, cropR, hnd);
2571
Saurabh Shahb729b192014-08-15 18:04:24 -07002572 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002573 //Swap crops on H flip since 2 pipes are being used
2574 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2575 hwc_rect_t tmp = cropL;
2576 cropL = cropR;
2577 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002578 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002579 }
2580
Saurabh Shahb729b192014-08-15 18:04:24 -07002581 //cropSwap trick: If the src and dst widths are both odd, let us say
2582 //2507, then splitting both into half would cause left width to be 1253
2583 //and right 1254. If crop is swapped because of H flip, this will cause
2584 //left crop width to be 1254, whereas left dst width remains 1253, thus
2585 //inducing a scaling that is unaccounted for. To overcome that we add 1
2586 //to the dst width if there is a cropSwap. So if the original width was
2587 //2507, the left dst width will be 1254. Even if the original width was
2588 //even for ex: 2508, the left dst width will still remain 1254.
2589 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002590 dstR.left = dstL.right;
2591 }
2592
2593 //For the mdp, since either we are pre-rotating or MDP does flips
2594 orient = OVERLAY_TRANSFORM_0;
2595 transform = 0;
2596
2597 //configure left pipe
2598 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002599 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002600 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2601 (ovutils::eBlending) getBlending(layer->blending));
2602
2603 if(configMdp(ctx->mOverlay, pargL, orient,
2604 cropL, dstL, metadata, lDest) < 0) {
2605 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2606 return -1;
2607 }
2608 }
2609
2610 //configure right pipe
2611 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002612 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002613 static_cast<eRotFlags>(rotFlags),
2614 layer->planeAlpha,
2615 (ovutils::eBlending) getBlending(layer->blending));
2616 if(configMdp(ctx->mOverlay, pargR, orient,
2617 cropR, dstR, metadata, rDest) < 0) {
2618 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2619 return -1;
2620 }
2621 }
2622
2623 return 0;
2624}
2625
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002626}; //namespace
2627