blob: 5bf7e9462c217ac10c58b6fd748ec7f5b2f61984 [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"
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070023#include "virtual.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080024#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080025#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070026#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070027#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080028#include <overlayRotator.h>
Sushil Chauhandefd3522014-05-13 18:17:12 -070029#include "hwc_copybit.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080030
Saurabh Shah85234ec2013-04-12 17:09:00 -070031using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070032using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080033using namespace overlay::utils;
34namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070035
Naseer Ahmed7c958d42012-07-31 18:57:03 -070036namespace qhwc {
37
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080038//==============MDPComp========================================================
39
Naseer Ahmed7c958d42012-07-31 18:57:03 -070040IdleInvalidator *MDPComp::idleInvalidator = NULL;
41bool MDPComp::sIdleFallBack = false;
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -080042bool MDPComp::sHandleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070043bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050044bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070045bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -070046int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080047int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Raj Kamal389d6e32014-08-04 14:43:24 +053048bool MDPComp::sEnableYUVsplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070049bool MDPComp::sSrcSplitEnabled = false;
Saurabh Shah88e4d272013-09-03 13:31:29 -070050MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070051 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
52 sSrcSplitEnabled = true;
53 return new MDPCompSrcSplit(dpy);
54 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070055 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080056 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070057 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080058}
59
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080060MDPComp::MDPComp(int dpy):mDpy(dpy){};
61
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070062void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080063{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070064 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
65 return;
66
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080067 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070068 (mDpy == 0) ? "\"PRIMARY\"" :
69 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070070 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
71 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080072 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
73 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
74 (mCurrentFrame.needsRedraw? "YES" : "NO"),
75 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070076 if(isDisplaySplit(ctx, mDpy)) {
77 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
78 "Right: [%d, %d, %d, %d] \n",
79 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
80 ctx->listStats[mDpy].lRoi.right,
81 ctx->listStats[mDpy].lRoi.bottom,
82 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
83 ctx->listStats[mDpy].rRoi.right,
84 ctx->listStats[mDpy].rRoi.bottom);
85 } else {
86 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
87 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
88 ctx->listStats[mDpy].lRoi.right,
89 ctx->listStats[mDpy].lRoi.bottom);
90 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080091 dumpsys_log(buf," --------------------------------------------- \n");
92 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
93 dumpsys_log(buf," --------------------------------------------- \n");
94 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
95 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
96 index,
97 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070098 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080099 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700100 (mCurrentFrame.drop[index] ? "DROP" :
101 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800102 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
103 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
104 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800105}
106
107bool MDPComp::init(hwc_context_t *ctx) {
108
109 if(!ctx) {
110 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
111 return false;
112 }
113
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800114 char property[PROPERTY_VALUE_MAX];
115
116 sEnabled = false;
117 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800118 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
119 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800120 sEnabled = true;
121 }
122
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700123 sEnableMixedMode = true;
124 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
125 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
126 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
127 sEnableMixedMode = false;
128 }
129
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800130 sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Saurabh Shah85234ec2013-04-12 17:09:00 -0700131 if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
132 int val = atoi(property);
133 if(val >= 0)
134 sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800135 }
136
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400137 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
138 // Idle invalidation is not necessary on command mode panels
139 long idle_timeout = DEFAULT_IDLE_TIME;
140 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
141 if(atoi(property) != 0)
142 idle_timeout = atoi(property);
143 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800144
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400145 //create Idle Invalidator only when not disabled through property
146 if(idle_timeout != -1)
147 idleInvalidator = IdleInvalidator::getInstance();
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800148
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400149 if(idleInvalidator == NULL) {
150 ALOGE("%s: failed to instantiate idleInvalidator object",
151 __FUNCTION__);
152 } else {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530153 idleInvalidator->init(timeout_handler, ctx,
154 (unsigned int)idle_timeout);
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400155 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800156 }
radhakrishnac9a67412013-09-25 17:40:42 +0530157
Saurabh Shah7c727642014-06-02 15:47:14 -0700158 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700159 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700160 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
161 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
162 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530163 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530164 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700165
166 if ((property_get("persist.hwc.ptor.enable", property, NULL) > 0) &&
167 ((!strncasecmp(property, "true", PROPERTY_VALUE_MAX )) ||
168 (!strncmp(property, "1", PROPERTY_VALUE_MAX )))) {
169 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
170 HWC_DISPLAY_PRIMARY);
171 }
172
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700173 return true;
174}
175
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800176void MDPComp::reset(hwc_context_t *ctx) {
177 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700178 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800179 ctx->mOverlay->clear(mDpy);
180 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700181}
182
Raj Kamal4393eaa2014-06-06 13:45:20 +0530183void MDPComp::reset() {
184 sHandleTimeout = false;
185 mModeOn = false;
186}
187
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700188void MDPComp::timeout_handler(void *udata) {
189 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
190
191 if(!ctx) {
192 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
193 return;
194 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800195 Locker::Autolock _l(ctx->mDrawLock);
196 // Handle timeout event only if the previous composition is MDP or MIXED.
197 if(!sHandleTimeout) {
198 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
199 return;
200 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700201 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700202 ALOGE("%s: HWC proc not registered", __FUNCTION__);
203 return;
204 }
205 sIdleFallBack = true;
206 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700207 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700208}
209
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800210void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800211 hwc_display_contents_1_t* list) {
212 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800213
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800214 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800215 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800216 if(!mCurrentFrame.isFBComposed[index]) {
217 layerProp[index].mFlags |= HWC_MDPCOMP;
218 layer->compositionType = HWC_OVERLAY;
219 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800220 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700221 /* Drop the layer when its already present in FB OR when it lies
222 * outside frame's ROI */
223 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800224 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700225 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800226 }
227 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700228}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500229
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800230void MDPComp::setRedraw(hwc_context_t *ctx,
231 hwc_display_contents_1_t* list) {
232 mCurrentFrame.needsRedraw = false;
233 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
234 (list->flags & HWC_GEOMETRY_CHANGED) ||
235 isSkipPresent(ctx, mDpy)) {
236 mCurrentFrame.needsRedraw = true;
237 }
238}
239
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800240MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700241 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700242 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800243}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800244
Saurabh Shahaa236822013-04-24 18:07:26 -0700245void MDPComp::FrameInfo::reset(const int& numLayers) {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700246 for(int i = 0; i < MAX_PIPES_PER_MIXER; i++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800247 if(mdpToLayer[i].pipeInfo) {
248 delete mdpToLayer[i].pipeInfo;
249 mdpToLayer[i].pipeInfo = NULL;
250 //We dont own the rotator
251 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800252 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800253 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800254
255 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
256 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700257 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800258
Saurabh Shahaa236822013-04-24 18:07:26 -0700259 layerCount = numLayers;
260 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800261 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700262 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800263 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800264}
265
Saurabh Shahaa236822013-04-24 18:07:26 -0700266void MDPComp::FrameInfo::map() {
267 // populate layer and MDP maps
268 int mdpIdx = 0;
269 for(int idx = 0; idx < layerCount; idx++) {
270 if(!isFBComposed[idx]) {
271 mdpToLayer[mdpIdx].listIndex = idx;
272 layerToMDP[idx] = mdpIdx++;
273 }
274 }
275}
276
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800277MDPComp::LayerCache::LayerCache() {
278 reset();
279}
280
281void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700282 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530283 memset(&isFBComposed, true, sizeof(isFBComposed));
284 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800285 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700286}
287
288void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530289 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700290 for(int i = 0; i < numAppLayers; i++) {
291 hnd[i] = list->hwLayers[i].handle;
292 }
293}
294
295void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700296 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530297 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
298 memcpy(&drop, &curFrame.drop, sizeof(drop));
299}
300
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800301bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
302 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530303 if(layerCount != curFrame.layerCount)
304 return false;
305 for(int i = 0; i < curFrame.layerCount; i++) {
306 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
307 (curFrame.drop[i] != drop[i])) {
308 return false;
309 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800310 if(curFrame.isFBComposed[i] &&
311 (hnd[i] != list->hwLayers[i].handle)){
312 return false;
313 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530314 }
315 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800316}
317
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700318bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
319 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800320 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700321 (not isValidDimension(ctx,layer))
322 //More conditions here, SKIP, sRGB+Blend etc
323 ) {
324 return false;
325 }
326 return true;
327}
328
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530329bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800330 private_handle_t *hnd = (private_handle_t *)layer->handle;
331
332 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700333 if (layer->flags & HWC_COLOR_FILL) {
334 // Color layer
335 return true;
336 }
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800337 ALOGE("%s: layer handle is NULL", __FUNCTION__);
338 return false;
339 }
340
Naseer Ahmede850a802013-09-06 13:12:52 -0400341 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400342 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400343 return false;
344
Saurabh Shah62e1d732013-09-17 10:44:05 -0700345 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700346 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700347 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700348 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
349 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700350 int dst_w = dst.right - dst.left;
351 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800352 float w_scale = ((float)crop_w / (float)dst_w);
353 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530354 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700355
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800356 /* Workaround for MDP HW limitation in DSI command mode panels where
357 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
358 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530359 * There also is a HW limilation in MDP, minimum block size is 2x2
360 * Fallback to GPU if height is less than 2.
361 */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800362 if((crop_w < 5)||(crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800363 return false;
364
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800365 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530366 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800367 const float w_dscale = w_scale;
368 const float h_dscale = h_scale;
369
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800370 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700371
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530372 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700373 /* On targets that doesnt support Decimation (eg.,8x26)
374 * maximum downscale support is overlay pipe downscale.
375 */
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530376 if(crop_w > mdpHw.getMaxMixerWidth() ||
377 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700378 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800379 return false;
380 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700381 // Decimation on macrotile format layers is not supported.
382 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530383 /* Bail out if
384 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700385 * 2. exceeds maximum downscale limit
386 */
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530387 if(((crop_w > mdpHw.getMaxMixerWidth()) &&
388 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700389 w_dscale > maxMDPDownscale ||
390 h_dscale > maxMDPDownscale) {
391 return false;
392 }
393 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800394 return false;
395 }
396 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700397 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700398 return false;
399 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700400 }
401
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800402 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530403 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800404 const float w_uscale = 1.0f / w_scale;
405 const float h_uscale = 1.0f / h_scale;
406
407 if(w_uscale > upscale || h_uscale > upscale)
408 return false;
409 }
410
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800411 return true;
412}
413
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800414bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700415 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800416
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800417 if(!isEnabled()) {
418 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700419 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530420 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530421 qdutils::MDPVersion::getInstance().is8x16() ||
422 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800423 ctx->mVideoTransFlag &&
424 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700425 //1 Padding round to shift pipes across mixers
426 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
427 __FUNCTION__);
428 ret = false;
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800429 } else if(isSecondaryConfiguring(ctx)) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800430 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800431 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700432 ret = false;
Saurabh Shahaa236822013-04-24 18:07:26 -0700433 } else if(ctx->isPaddingRound) {
Raj Kamal9ed3d6b2014-02-07 16:15:17 +0530434 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
435 __FUNCTION__,mDpy);
Saurabh Shahaa236822013-04-24 18:07:26 -0700436 ret = false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700437 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700438 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800439}
440
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800441void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
442 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
443 fbRect = getIntersection(fbRect, roi);
444}
445
446/* 1) Identify layers that are not visible or lying outside the updating ROI and
447 * drop them from composition.
448 * 2) If we have a scaling layer which needs cropping against generated
449 * ROI, reset ROI to full resolution. */
450bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
451 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700452 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800453 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800454
455 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800456 if(!isValidRect(visibleRect)) {
457 mCurrentFrame.drop[i] = true;
458 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800459 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800460 }
461
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700462 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700463 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800464 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700465
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700466 if(!isValidRect(res)) {
467 mCurrentFrame.drop[i] = true;
468 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800469 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700470 /* Reset frame ROI when any layer which needs scaling also needs ROI
471 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800472 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800473 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700474 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
475 mCurrentFrame.dropCount = 0;
476 return false;
477 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800478
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800479 /* deduct any opaque region from visibleRect */
480 if (layer->blending == HWC_BLENDING_NONE)
481 visibleRect = deductRect(visibleRect, res);
482 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700483 }
484 return true;
485}
486
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800487/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
488 * are updating. If DirtyRegion is applicable, calculate it by accounting all
489 * the changing layer's dirtyRegion. */
490void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
491 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700492 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800493 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700494 return;
495
496 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800497 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
498 (int)ctx->dpyAttr[mDpy].yres};
499
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700500 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800501 hwc_layer_1_t* layer = &list->hwLayers[index];
502 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800503 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700504 hwc_rect_t dst = layer->displayFrame;
505 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800506
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800507#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800508 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700509 {
510 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
511 int x_off = dst.left - src.left;
512 int y_off = dst.top - src.top;
513 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
514 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800515#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800516
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800517 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700518 }
519 }
520
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800521 /* No layer is updating. Still SF wants a refresh.*/
522 if(!isValidRect(roi))
523 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800524
525 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800526 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800527
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800528 ctx->listStats[mDpy].lRoi = roi;
529 if(!validateAndApplyROI(ctx, list))
530 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700531
532 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800533 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
534 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
535}
536
537void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
538 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
539 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
540
541 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
542 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
543 fbRect = getUnion(l_fbRect, r_fbRect);
544}
545/* 1) Identify layers that are not visible or lying outside BOTH the updating
546 * ROI's and drop them from composition. If a layer is spanning across both
547 * the halves of the screen but needed by only ROI, the non-contributing
548 * half will not be programmed for MDP.
549 * 2) If we have a scaling layer which needs cropping against generated
550 * ROI, reset ROI to full resolution. */
551bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
552 hwc_display_contents_1_t* list) {
553
554 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
555
556 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
557 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
558
559 for(int i = numAppLayers - 1; i >= 0; i--){
560 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
561 {
562 mCurrentFrame.drop[i] = true;
563 mCurrentFrame.dropCount++;
564 continue;
565 }
566
567 const hwc_layer_1_t* layer = &list->hwLayers[i];
568 hwc_rect_t dstRect = layer->displayFrame;
569
570 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
571 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
572 hwc_rect_t res = getUnion(l_res, r_res);
573
574 if(!isValidRect(l_res) && !isValidRect(r_res)) {
575 mCurrentFrame.drop[i] = true;
576 mCurrentFrame.dropCount++;
577 } else {
578 /* Reset frame ROI when any layer which needs scaling also needs ROI
579 * cropping */
580 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
581 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
582 mCurrentFrame.dropCount = 0;
583 return false;
584 }
585
586 if (layer->blending == HWC_BLENDING_NONE) {
587 visibleRectL = deductRect(visibleRectL, l_res);
588 visibleRectR = deductRect(visibleRectR, r_res);
589 }
590 }
591 }
592 return true;
593}
594/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
595 * are updating. If DirtyRegion is applicable, calculate it by accounting all
596 * the changing layer's dirtyRegion. */
597void MDPCompSplit::generateROI(hwc_context_t *ctx,
598 hwc_display_contents_1_t* list) {
599 if(!canPartialUpdate(ctx, list))
600 return;
601
602 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
603 int lSplit = getLeftSplit(ctx, mDpy);
604
605 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
606 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
607
608 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
609 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
610
611 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
612 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
613
614 for(int index = 0; index < numAppLayers; index++ ) {
615 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800616 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800617 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800618 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700619 hwc_rect_t dst = layer->displayFrame;
620 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800621
622#ifdef QCOM_BSP
623 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700624 {
625 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
626 int x_off = dst.left - src.left;
627 int y_off = dst.top - src.top;
628 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
629 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800630#endif
631
632 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
633 if(isValidRect(l_dst))
634 l_roi = getUnion(l_roi, l_dst);
635
636 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
637 if(isValidRect(r_dst))
638 r_roi = getUnion(r_roi, r_dst);
639 }
640 }
641
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700642 /* For panels that cannot accept commands in both the interfaces, we cannot
643 * send two ROI's (for each half). We merge them into single ROI and split
644 * them across lSplit for MDP mixer use. The ROI's will be merged again
645 * finally before udpating the panel in the driver. */
646 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
647 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
648 l_roi = getIntersection(temp_roi, l_frame);
649 r_roi = getIntersection(temp_roi, r_frame);
650 }
651
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800652 /* No layer is updating. Still SF wants a refresh. */
653 if(!isValidRect(l_roi) && !isValidRect(r_roi))
654 return;
655
656 l_roi = getSanitizeROI(l_roi, l_frame);
657 r_roi = getSanitizeROI(r_roi, r_frame);
658
659 ctx->listStats[mDpy].lRoi = l_roi;
660 ctx->listStats[mDpy].rRoi = r_roi;
661
662 if(!validateAndApplyROI(ctx, list))
663 resetROI(ctx, mDpy);
664
665 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
666 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
667 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
668 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
669 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
670 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700671}
672
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800673/* Checks for conditions where all the layers marked for MDP comp cannot be
674 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800675bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800676 hwc_display_contents_1_t* list){
677
Saurabh Shahaa236822013-04-24 18:07:26 -0700678 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800679 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800680
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -0700681 // No Idle fall back, if secure display or secure RGB layers are present
682 if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
683 !ctx->listStats[mDpy].secureRGBCount)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700684 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
685 return false;
686 }
687
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800688 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700689 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
690 __FUNCTION__,
691 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800692 return false;
693 }
694
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530695 MDPVersion& mdpHw = MDPVersion::getInstance();
696 if(mDpy > HWC_DISPLAY_PRIMARY &&
697 (priDispW > mdpHw.getMaxMixerWidth()) &&
698 (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800699 // Disable MDP comp on Secondary when the primary is highres panel and
700 // the secondary is a normal 1080p, because, MDP comp on secondary under
701 // in such usecase, decimation gets used for downscale and there will be
702 // a quality mismatch when there will be a fallback to GPU comp
703 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
704 __FUNCTION__);
705 return false;
706 }
707
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800708 // check for action safe flag and downscale mode which requires scaling.
709 if(ctx->dpyAttr[mDpy].mActionSafePresent
710 || ctx->dpyAttr[mDpy].mDownScaleMode) {
711 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
712 return false;
713 }
714
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800715 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800716 hwc_layer_1_t* layer = &list->hwLayers[i];
717 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800718
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800719 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700720 if(!canUseRotator(ctx, mDpy)) {
721 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
722 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700723 return false;
724 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800725 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530726
727 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
728 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700729 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530730 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
731 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
732 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800733 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700734
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700735 if(ctx->mAD->isDoable()) {
736 return false;
737 }
738
Saurabh Shahaa236822013-04-24 18:07:26 -0700739 //If all above hard conditions are met we can do full or partial MDP comp.
740 bool ret = false;
741 if(fullMDPComp(ctx, list)) {
742 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700743 } else if(fullMDPCompWithPTOR(ctx, list)) {
744 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700745 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700746 ret = true;
747 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530748
Saurabh Shahaa236822013-04-24 18:07:26 -0700749 return ret;
750}
751
752bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700753
754 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
755 return false;
756
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700757 //Will benefit presentation / secondary-only layer.
758 if((mDpy > HWC_DISPLAY_PRIMARY) &&
759 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
760 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
761 return false;
762 }
763
764 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
765 for(int i = 0; i < numAppLayers; i++) {
766 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700767 if(not mCurrentFrame.drop[i] and
768 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700769 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
770 return false;
771 }
772 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800773
Saurabh Shahaa236822013-04-24 18:07:26 -0700774 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700775 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
776 sizeof(mCurrentFrame.isFBComposed));
777 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
778 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700779
Raj Kamal389d6e32014-08-04 14:43:24 +0530780 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800781 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530782 }
783
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800784 if(!postHeuristicsHandling(ctx, list)) {
785 ALOGD_IF(isDebug(), "post heuristic handling failed");
786 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700787 return false;
788 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700789 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
790 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700791 return true;
792}
793
Sushil Chauhandefd3522014-05-13 18:17:12 -0700794/* Full MDP Composition with Peripheral Tiny Overlap Removal.
795 * MDP bandwidth limitations can be avoided, if the overlap region
796 * covered by the smallest layer at a higher z-order, gets composed
797 * by Copybit on a render buffer, which can be queued to MDP.
798 */
799bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
800 hwc_display_contents_1_t* list) {
801
802 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
803 const int stagesForMDP = min(sMaxPipesPerMixer,
804 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
805
806 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700807 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700808 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
809 return false;
810 }
811
812 // Frame level checks
813 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
814 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
815 isSecurePresent(ctx, mDpy)) {
816 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
817 return false;
818 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700819 // MDP comp checks
820 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700821 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700822 if(not isSupportedForMDPComp(ctx, layer)) {
823 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
824 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700825 }
826 }
827
Sushil Chauhandefd3522014-05-13 18:17:12 -0700828 /* We cannot use this composition mode, if:
829 1. A below layer needs scaling.
830 2. Overlap is not peripheral to display.
831 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700832 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700833 */
834
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700835 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
836 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
837 memset(overlapRect, 0, sizeof(overlapRect));
838 int layerPixelCount, minPixelCount = 0;
839 int numPTORLayersFound = 0;
840 for (int i = numAppLayers-1; (i >= 0 &&
841 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700842 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700843 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700844 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700845 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
846 // PTOR layer should be peripheral and cannot have transform
847 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
848 has90Transform(layer)) {
849 continue;
850 }
851 if((3 * (layerPixelCount + minPixelCount)) >
852 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
853 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
854 continue;
855 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700856 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700857 for (int j = i-1; j >= 0; j--) {
858 // Check if the layers below this layer qualifies for PTOR comp
859 hwc_layer_1_t* layer = &list->hwLayers[j];
860 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700861 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700862 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700863 if (isValidRect(getIntersection(dispFrame, disFrame))) {
864 if (has90Transform(layer) || needsScaling(layer)) {
865 found = false;
866 break;
867 }
868 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700869 }
870 }
871 // Store the minLayer Index
872 if(found) {
873 minLayerIndex[numPTORLayersFound] = i;
874 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
875 minPixelCount += layerPixelCount;
876 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700877 }
878 }
879
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700880 if(isValidRect(getIntersection(overlapRect[0], overlapRect[1]))) {
881 ALOGD_IF(isDebug(), "%s: Ignore Rect2 its intersects with Rect1",
882 __FUNCTION__);
883 // reset second minLayerIndex[1];
884 minLayerIndex[1] = -1;
885 numPTORLayersFound--;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700886 }
887
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700888 // No overlap layers
889 if (!numPTORLayersFound)
890 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700891
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700892 ctx->mPtorInfo.count = numPTORLayersFound;
893 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
894 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
895 }
896
897 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
898 // reset PTOR
899 ctx->mPtorInfo.count = 0;
900 return false;
901 }
902 // 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
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700911 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
912 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
913
Xu Yangcda012c2014-07-30 21:57:21 +0800914 // Store the blending mode, planeAlpha, and transform of PTOR layers
915 int32_t blending[numPTORLayersFound];
916 uint8_t planeAlpha[numPTORLayersFound];
917 uint32_t transform[numPTORLayersFound];
918
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700919 for(int j = 0; j < numPTORLayersFound; j++) {
920 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700921
922 // Update src crop of PTOR layer
923 hwc_layer_1_t* layer = &list->hwLayers[index];
924 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
925 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
926 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
927 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
928
929 // Store & update w, h, format of PTOR layer
930 private_handle_t *hnd = (private_handle_t *)layer->handle;
931 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
932 layerWhf[j] = whf;
933 hnd->width = renderBuf->width;
934 hnd->height = renderBuf->height;
935 hnd->format = renderBuf->format;
936
Xu Yangcda012c2014-07-30 21:57:21 +0800937 // Store & update blending mode, planeAlpha and transform of PTOR layer
938 blending[j] = layer->blending;
939 planeAlpha[j] = layer->planeAlpha;
940 transform[j] = layer->transform;
941 layer->blending = HWC_BLENDING_NONE;
942 layer->planeAlpha = 0xFF;
943 layer->transform = 0;
944
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700945 // Remove overlap from crop & displayFrame of below layers
946 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700947 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700948 if(!isValidRect(getIntersection(layer->displayFrame,
949 overlapRect[j]))) {
950 continue;
951 }
952 // Update layer attributes
953 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
954 hwc_rect_t destRect = deductRect(layer->displayFrame,
955 overlapRect[j]);
956 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
957 layer->transform);
958 layer->sourceCropf.left = (float)srcCrop.left;
959 layer->sourceCropf.top = (float)srcCrop.top;
960 layer->sourceCropf.right = (float)srcCrop.right;
961 layer->sourceCropf.bottom = (float)srcCrop.bottom;
962 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700963 }
964
965 mCurrentFrame.mdpCount = numAppLayers;
966 mCurrentFrame.fbCount = 0;
967 mCurrentFrame.fbZ = -1;
968
969 for (int j = 0; j < numAppLayers; j++)
970 mCurrentFrame.isFBComposed[j] = false;
971
972 bool result = postHeuristicsHandling(ctx, list);
973
974 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700975 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700976 hwc_layer_1_t* layer = &list->hwLayers[i];
977 layer->displayFrame = displayFrame[i];
978 layer->sourceCropf.left = (float)sourceCrop[i].left;
979 layer->sourceCropf.top = (float)sourceCrop[i].top;
980 layer->sourceCropf.right = (float)sourceCrop[i].right;
981 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
982 }
983
Xu Yangcda012c2014-07-30 21:57:21 +0800984 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700985 for (int i = 0; i < numPTORLayersFound; i++) {
986 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +0800987 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700988 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
989 hnd->width = layerWhf[i].w;
990 hnd->height = layerWhf[i].h;
991 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +0800992 layer->blending = blending[i];
993 layer->planeAlpha = planeAlpha[i];
994 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700995 }
996
Sushil Chauhandefd3522014-05-13 18:17:12 -0700997 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700998 // reset PTOR
999 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001000 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001001 } else {
1002 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1003 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001004 }
1005
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001006 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1007 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001008 return result;
1009}
1010
Saurabh Shahaa236822013-04-24 18:07:26 -07001011bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1012{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001013 if(!sEnableMixedMode) {
1014 //Mixed mode is disabled. No need to even try caching.
1015 return false;
1016 }
1017
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001018 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001019 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001020 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001021 cacheBasedComp(ctx, list);
1022 } else {
1023 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001024 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001025 }
1026
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001027 return ret;
1028}
1029
1030bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1031 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001032 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1033 return false;
1034
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001035 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001036 mCurrentFrame.reset(numAppLayers);
1037 updateLayerCache(ctx, list);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001038
1039 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1040 for(int i = 0; i < numAppLayers; i++) {
1041 if(!mCurrentFrame.isFBComposed[i]) {
1042 hwc_layer_1_t* layer = &list->hwLayers[i];
1043 if(not isSupportedForMDPComp(ctx, layer)) {
1044 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1045 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001046 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001047 return false;
1048 }
1049 }
1050 }
1051
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001052 updateYUV(ctx, list, false /*secure only*/);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001053 /* mark secure RGB layers for MDP comp */
1054 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301055 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001056 if(!ret) {
1057 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001058 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001059 return false;
1060 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001061
1062 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001063
Raj Kamal389d6e32014-08-04 14:43:24 +05301064 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001065 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301066 }
1067
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001068 //Will benefit cases where a video has non-updating background.
1069 if((mDpy > HWC_DISPLAY_PRIMARY) and
1070 (mdpCount > MAX_SEC_LAYERS)) {
1071 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001072 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001073 return false;
1074 }
1075
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001076 if(!postHeuristicsHandling(ctx, list)) {
1077 ALOGD_IF(isDebug(), "post heuristic handling failed");
1078 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001079 return false;
1080 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001081 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1082 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001083
Saurabh Shahaa236822013-04-24 18:07:26 -07001084 return true;
1085}
1086
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001087bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001088 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001089 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1090 return false;
1091
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001092 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001093 return false;
1094 }
1095
Saurabh Shahb772ae32013-11-18 15:40:02 -08001096 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001097 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1098 const int stagesForMDP = min(sMaxPipesPerMixer,
1099 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001100
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001101 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1102 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1103 int lastMDPSupportedIndex = numAppLayers;
1104 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001105
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001106 //Find the minimum MDP batch size
1107 for(int i = 0; i < numAppLayers;i++) {
1108 if(mCurrentFrame.drop[i]) {
1109 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001110 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001111 }
1112 hwc_layer_1_t* layer = &list->hwLayers[i];
1113 if(not isSupportedForMDPComp(ctx, layer)) {
1114 lastMDPSupportedIndex = i;
1115 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1116 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001117 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001118 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001119 }
1120
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001121 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1122 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1123 mCurrentFrame.dropCount);
1124
1125 //Start at a point where the fb batch should at least have 2 layers, for
1126 //this mode to be justified.
1127 while(fbBatchSize < 2) {
1128 ++fbBatchSize;
1129 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001130 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001131
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001132 //If there are no layers for MDP, this mode doesnt make sense.
1133 if(mdpBatchSize < 1) {
1134 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1135 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001136 return false;
1137 }
1138
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001139 mCurrentFrame.reset(numAppLayers);
1140
1141 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1142 while(mdpBatchSize > 0) {
1143 //Mark layers for MDP comp
1144 int mdpBatchLeft = mdpBatchSize;
1145 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1146 if(mCurrentFrame.drop[i]) {
1147 continue;
1148 }
1149 mCurrentFrame.isFBComposed[i] = false;
1150 --mdpBatchLeft;
1151 }
1152
1153 mCurrentFrame.fbZ = mdpBatchSize;
1154 mCurrentFrame.fbCount = fbBatchSize;
1155 mCurrentFrame.mdpCount = mdpBatchSize;
1156
1157 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1158 __FUNCTION__, mdpBatchSize, fbBatchSize,
1159 mCurrentFrame.dropCount);
1160
1161 if(postHeuristicsHandling(ctx, list)) {
1162 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001163 __FUNCTION__);
1164 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1165 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001166 return true;
1167 }
1168
1169 reset(ctx);
1170 --mdpBatchSize;
1171 ++fbBatchSize;
1172 }
1173
1174 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001175}
1176
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001177bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301178 if(mDpy or isSecurePresent(ctx, mDpy) or
1179 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001180 return false;
1181 }
1182 return true;
1183}
1184
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001185bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1186 hwc_display_contents_1_t* list){
1187 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1188 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1189 mDpy ) {
1190 return false;
1191 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001192 if(ctx->listStats[mDpy].secureUI)
1193 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001194 return true;
1195}
1196
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001197bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1198 hwc_display_contents_1_t* list) {
1199 const bool secureOnly = true;
1200 return videoOnlyComp(ctx, list, not secureOnly) or
1201 videoOnlyComp(ctx, list, secureOnly);
1202}
1203
1204bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001205 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001206 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1207 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001208 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001209
Saurabh Shahaa236822013-04-24 18:07:26 -07001210 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001211 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001212 updateYUV(ctx, list, secureOnly);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001213 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001214
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001215 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1216 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001217 return false;
1218 }
1219
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001220 /* Bail out if we are processing only secured video layers
1221 * and we dont have any */
1222 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001223 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001224 return false;
1225 }
1226
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001227 if(mCurrentFrame.fbCount)
1228 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001229
Raj Kamal389d6e32014-08-04 14:43:24 +05301230 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001231 adjustForSourceSplit(ctx, list);
1232 }
1233
1234 if(!postHeuristicsHandling(ctx, list)) {
1235 ALOGD_IF(isDebug(), "post heuristic handling failed");
1236 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001237 return false;
1238 }
1239
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001240 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1241 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001242 return true;
1243}
1244
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001245/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1246bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1247 hwc_display_contents_1_t* list) {
1248 const bool secureOnly = true;
1249 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1250 mdpOnlyLayersComp(ctx, list, secureOnly);
1251
1252}
1253
1254bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1255 hwc_display_contents_1_t* list, bool secureOnly) {
1256
1257 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1258 return false;
1259
1260 /* Bail out if we are processing only secured video layers
1261 * and we dont have any */
1262 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1263 reset(ctx);
1264 return false;
1265 }
1266
1267 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1268 mCurrentFrame.reset(numAppLayers);
1269 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1270
1271 updateYUV(ctx, list, secureOnly);
1272 /* mark secure RGB layers for MDP comp */
1273 updateSecureRGB(ctx, list);
1274
1275 if(mCurrentFrame.mdpCount == 0) {
1276 reset(ctx);
1277 return false;
1278 }
1279
1280 /* find the maximum batch of layers to be marked for framebuffer */
1281 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1282 if(!ret) {
1283 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1284 reset(ctx);
1285 return false;
1286 }
1287
1288 if(sEnableYUVsplit){
1289 adjustForSourceSplit(ctx, list);
1290 }
1291
1292 if(!postHeuristicsHandling(ctx, list)) {
1293 ALOGD_IF(isDebug(), "post heuristic handling failed");
1294 reset(ctx);
1295 return false;
1296 }
1297
1298 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1299 __FUNCTION__);
1300 return true;
1301}
1302
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001303/* Checks for conditions where YUV layers cannot be bypassed */
1304bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001305 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001306 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001307 return false;
1308 }
1309
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001310 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001311 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1312 return false;
1313 }
1314
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001315 if(isSecuring(ctx, layer)) {
1316 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1317 return false;
1318 }
1319
Saurabh Shah4fdde762013-04-30 18:47:33 -07001320 if(!isValidDimension(ctx, layer)) {
1321 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1322 __FUNCTION__);
1323 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001324 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001325
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001326 if(layer->planeAlpha < 0xFF) {
1327 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1328 in video only mode",
1329 __FUNCTION__);
1330 return false;
1331 }
1332
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001333 return true;
1334}
1335
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001336/* Checks for conditions where Secure RGB layers cannot be bypassed */
1337bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1338 if(isSkipLayer(layer)) {
1339 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1340 __FUNCTION__, mDpy);
1341 return false;
1342 }
1343
1344 if(isSecuring(ctx, layer)) {
1345 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1346 return false;
1347 }
1348
1349 if(not isSupportedForMDPComp(ctx, layer)) {
1350 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1351 __FUNCTION__);
1352 return false;
1353 }
1354 return true;
1355}
1356
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301357/* starts at fromIndex and check for each layer to find
1358 * if it it has overlapping with any Updating layer above it in zorder
1359 * till the end of the batch. returns true if it finds any intersection */
1360bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1361 int fromIndex, int toIndex) {
1362 for(int i = fromIndex; i < toIndex; i++) {
1363 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1364 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1365 return false;
1366 }
1367 }
1368 }
1369 return true;
1370}
1371
1372/* Checks if given layer at targetLayerIndex has any
1373 * intersection with all the updating layers in beween
1374 * fromIndex and toIndex. Returns true if it finds intersectiion */
1375bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1376 int fromIndex, int toIndex, int targetLayerIndex) {
1377 for(int i = fromIndex; i <= toIndex; i++) {
1378 if(!mCurrentFrame.isFBComposed[i]) {
1379 if(areLayersIntersecting(&list->hwLayers[i],
1380 &list->hwLayers[targetLayerIndex])) {
1381 return true;
1382 }
1383 }
1384 }
1385 return false;
1386}
1387
1388int MDPComp::getBatch(hwc_display_contents_1_t* list,
1389 int& maxBatchStart, int& maxBatchEnd,
1390 int& maxBatchCount) {
1391 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301392 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001393 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301394 while (i < mCurrentFrame.layerCount) {
1395 int batchCount = 0;
1396 int batchStart = i;
1397 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001398 /* Adjust batch Z order with the dropped layers so far */
1399 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301400 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301401 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301402 while(i < mCurrentFrame.layerCount) {
1403 if(!mCurrentFrame.isFBComposed[i]) {
1404 if(!batchCount) {
1405 i++;
1406 break;
1407 }
1408 updatingLayersAbove++;
1409 i++;
1410 continue;
1411 } else {
1412 if(mCurrentFrame.drop[i]) {
1413 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001414 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301415 continue;
1416 } else if(updatingLayersAbove <= 0) {
1417 batchCount++;
1418 batchEnd = i;
1419 i++;
1420 continue;
1421 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1422
1423 // We have a valid updating layer already. If layer-i not
1424 // have overlapping with all updating layers in between
1425 // batch-start and i, then we can add layer i to batch.
1426 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1427 batchCount++;
1428 batchEnd = i;
1429 i++;
1430 continue;
1431 } else if(canPushBatchToTop(list, batchStart, i)) {
1432 //If All the non-updating layers with in this batch
1433 //does not have intersection with the updating layers
1434 //above in z-order, then we can safely move the batch to
1435 //higher z-order. Increment fbZ as it is moving up.
1436 if( firstZReverseIndex < 0) {
1437 firstZReverseIndex = i;
1438 }
1439 batchCount++;
1440 batchEnd = i;
1441 fbZ += updatingLayersAbove;
1442 i++;
1443 updatingLayersAbove = 0;
1444 continue;
1445 } else {
1446 //both failed.start the loop again from here.
1447 if(firstZReverseIndex >= 0) {
1448 i = firstZReverseIndex;
1449 }
1450 break;
1451 }
1452 }
1453 }
1454 }
1455 if(batchCount > maxBatchCount) {
1456 maxBatchCount = batchCount;
1457 maxBatchStart = batchStart;
1458 maxBatchEnd = batchEnd;
1459 fbZOrder = fbZ;
1460 }
1461 }
1462 return fbZOrder;
1463}
1464
1465bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1466 hwc_display_contents_1_t* list) {
1467 /* Idea is to keep as many non-updating(cached) layers in FB and
1468 * send rest of them through MDP. This is done in 2 steps.
1469 * 1. Find the maximum contiguous batch of non-updating layers.
1470 * 2. See if we can improve this batch size for caching by adding
1471 * opaque layers around the batch, if they don't have
1472 * any overlapping with the updating layers in between.
1473 * NEVER mark an updating layer for caching.
1474 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001475
1476 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001477 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001478 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301479 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001480
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001481 /* Nothing is cached. No batching needed */
1482 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001483 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001484 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001485
1486 /* No MDP comp layers, try to use other comp modes */
1487 if(mCurrentFrame.mdpCount == 0) {
1488 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001489 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001490
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301491 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001492
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301493 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001494 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001495 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001496 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301497 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001498 if(!mCurrentFrame.drop[i]){
1499 //If an unsupported layer is being attempted to
1500 //be pulled out we should fail
1501 if(not isSupportedForMDPComp(ctx, layer)) {
1502 return false;
1503 }
1504 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001505 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001506 }
1507 }
1508
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301509 // update the frame data
1510 mCurrentFrame.fbZ = fbZ;
1511 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001512 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001513 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001514
1515 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301516 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001517
1518 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001519}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001520
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001521void MDPComp::updateLayerCache(hwc_context_t* ctx,
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001522 hwc_display_contents_1_t* list) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001523 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001524 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001525
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001526 for(int i = 0; i < numAppLayers; i++) {
1527 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001528 if(!mCurrentFrame.drop[i])
1529 fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001530 mCurrentFrame.isFBComposed[i] = true;
1531 } else {
Saurabh Shahaa236822013-04-24 18:07:26 -07001532 mCurrentFrame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001533 }
1534 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001535
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001536 mCurrentFrame.fbCount = fbCount;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001537 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
1538 - mCurrentFrame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001539
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001540 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d"
1541 ,__FUNCTION__, mCurrentFrame.mdpCount, mCurrentFrame.fbCount,
1542 mCurrentFrame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001543}
1544
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001545void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
1546 bool secureOnly) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001547 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1548 for(int index = 0;index < nYuvCount; index++){
1549 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1550 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1551
1552 if(!isYUVDoable(ctx, layer)) {
1553 if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
1554 mCurrentFrame.isFBComposed[nYuvIndex] = true;
1555 mCurrentFrame.fbCount++;
1556 }
1557 } else {
1558 if(mCurrentFrame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001559 private_handle_t *hnd = (private_handle_t *)layer->handle;
1560 if(!secureOnly || isSecureBuffer(hnd)) {
1561 mCurrentFrame.isFBComposed[nYuvIndex] = false;
1562 mCurrentFrame.fbCount--;
1563 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001564 }
1565 }
1566 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001567
1568 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001569 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1570 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001571 mCurrentFrame.fbCount);
1572}
1573
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001574void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1575 hwc_display_contents_1_t* list) {
1576 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1577 for(int index = 0;index < nSecureRGBCount; index++){
1578 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1579 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1580
1581 if(!isSecureRGBDoable(ctx, layer)) {
1582 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1583 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1584 mCurrentFrame.fbCount++;
1585 }
1586 } else {
1587 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1588 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1589 mCurrentFrame.fbCount--;
1590 }
1591 }
1592 }
1593
1594 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1595 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1596 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1597 mCurrentFrame.fbCount);
1598}
1599
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001600hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1601 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001602 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001603
1604 /* Update only the region of FB needed for composition */
1605 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1606 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1607 hwc_layer_1_t* layer = &list->hwLayers[i];
1608 hwc_rect_t dst = layer->displayFrame;
1609 fbRect = getUnion(fbRect, dst);
1610 }
1611 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001612 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001613 return fbRect;
1614}
1615
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001616bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1617 hwc_display_contents_1_t* list) {
1618
1619 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001620 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001621 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1622 return false;
1623 }
1624
1625 //Limitations checks
1626 if(!hwLimitationsCheck(ctx, list)) {
1627 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1628 return false;
1629 }
1630
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001631 //Configure framebuffer first if applicable
1632 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001633 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001634 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1635 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001636 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1637 __FUNCTION__);
1638 return false;
1639 }
1640 }
1641
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001642 mCurrentFrame.map();
1643
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001644 if(!allocLayerPipes(ctx, list)) {
1645 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001646 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001647 }
1648
1649 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001650 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001651 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001652 int mdpIndex = mCurrentFrame.layerToMDP[index];
1653 hwc_layer_1_t* layer = &list->hwLayers[index];
1654
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301655 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1656 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1657 mdpNextZOrder++;
1658 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001659 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1660 cur_pipe->zOrder = mdpNextZOrder++;
1661
radhakrishnac9a67412013-09-25 17:40:42 +05301662 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301663 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301664 if(configure4k2kYuv(ctx, layer,
1665 mCurrentFrame.mdpToLayer[mdpIndex])
1666 != 0 ){
1667 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1668 for layer %d",__FUNCTION__, index);
1669 return false;
1670 }
1671 else{
1672 mdpNextZOrder++;
1673 }
1674 continue;
1675 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001676 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1677 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301678 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001679 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001680 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001681 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001682 }
1683
Saurabh Shaha36be922013-12-16 18:18:39 -08001684 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1685 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1686 ,__FUNCTION__, mDpy);
1687 return false;
1688 }
1689
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001690 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001691 return true;
1692}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001693
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001694bool MDPComp::resourceCheck(hwc_context_t* ctx,
1695 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001696 const bool fbUsed = mCurrentFrame.fbCount;
1697 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1698 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1699 return false;
1700 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001701 // Init rotCount to number of rotate sessions used by other displays
1702 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1703 // Count the number of rotator sessions required for current display
1704 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1705 if(!mCurrentFrame.isFBComposed[index]) {
1706 hwc_layer_1_t* layer = &list->hwLayers[index];
1707 private_handle_t *hnd = (private_handle_t *)layer->handle;
1708 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1709 rotCount++;
1710 }
1711 }
1712 }
1713 // if number of layers to rotate exceeds max rotator sessions, bail out.
1714 if(rotCount > RotMgr::MAX_ROT_SESS) {
1715 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1716 __FUNCTION__, mDpy);
1717 return false;
1718 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001719 return true;
1720}
1721
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301722bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1723 hwc_display_contents_1_t* list) {
1724
1725 //A-family hw limitation:
1726 //If a layer need alpha scaling, MDP can not support.
1727 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1728 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1729 if(!mCurrentFrame.isFBComposed[i] &&
1730 isAlphaScaled( &list->hwLayers[i])) {
1731 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1732 return false;
1733 }
1734 }
1735 }
1736
1737 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1738 //If multiple layers requires downscaling and also they are overlapping
1739 //fall back to GPU since MDSS can not handle it.
1740 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1741 qdutils::MDPVersion::getInstance().is8x26()) {
1742 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1743 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1744 if(!mCurrentFrame.isFBComposed[i] &&
1745 isDownscaleRequired(botLayer)) {
1746 //if layer-i is marked for MDP and needs downscaling
1747 //check if any MDP layer on top of i & overlaps with layer-i
1748 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1749 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1750 if(!mCurrentFrame.isFBComposed[j] &&
1751 isDownscaleRequired(topLayer)) {
1752 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1753 topLayer->displayFrame);
1754 if(isValidRect(r))
1755 return false;
1756 }
1757 }
1758 }
1759 }
1760 }
1761 return true;
1762}
1763
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001764int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001765 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001766 char property[PROPERTY_VALUE_MAX];
1767
Raj Kamal4393eaa2014-06-06 13:45:20 +05301768 if(!ctx || !list) {
1769 ALOGE("%s: Invalid context or list",__FUNCTION__);
1770 mCachedFrame.reset();
1771 return -1;
1772 }
1773
1774 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001775 if(mDpy == HWC_DISPLAY_PRIMARY) {
1776 sSimulationFlags = 0;
1777 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1778 int currentFlags = atoi(property);
1779 if(currentFlags != sSimulationFlags) {
1780 sSimulationFlags = currentFlags;
1781 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1782 sSimulationFlags, sSimulationFlags);
1783 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001784 }
1785 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001786 // reset PTOR
1787 if(!mDpy)
1788 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001789
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301790 //Do not cache the information for next draw cycle.
1791 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1792 ALOGI("%s: Unsupported layer count for mdp composition",
1793 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001794 mCachedFrame.reset();
1795 return -1;
1796 }
1797
Saurabh Shahb39f8152013-08-22 10:21:44 -07001798 //reset old data
1799 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001800 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1801 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301802
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001803 // Detect the start of animation and fall back to GPU only once to cache
1804 // all the layers in FB and display FB content untill animation completes.
1805 if(ctx->listStats[mDpy].isDisplayAnimating) {
1806 mCurrentFrame.needsRedraw = false;
1807 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1808 mCurrentFrame.needsRedraw = true;
1809 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1810 }
1811 setMDPCompLayerFlags(ctx, list);
1812 mCachedFrame.updateCounts(mCurrentFrame);
1813 ret = -1;
1814 return ret;
1815 } else {
1816 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1817 }
1818
Saurabh Shahb39f8152013-08-22 10:21:44 -07001819 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001820 if(isFrameDoable(ctx)) {
1821 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001822
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001823 // if tryFullFrame fails, try to push all video and secure RGB layers
1824 // to MDP for composition.
1825 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
1826 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301827 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001828 setMDPCompLayerFlags(ctx, list);
1829 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001830 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001831 reset(ctx);
1832 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1833 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001834 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001835 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1836 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001837 }
1838 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001839 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1840 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001841 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001842 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001843
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001844 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001845 ALOGD("GEOMETRY change: %d",
1846 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001847 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001848 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001849 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001850 }
1851
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001852 mCachedFrame.cacheAll(list);
1853 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001854 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001855}
1856
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001857bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301858
1859 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301860 int mdpIndex = mCurrentFrame.layerToMDP[index];
1861 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1862 info.pipeInfo = new MdpYUVPipeInfo;
1863 info.rot = NULL;
1864 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301865
1866 pipe_info.lIndex = ovutils::OV_INVALID;
1867 pipe_info.rIndex = ovutils::OV_INVALID;
1868
Saurabh Shahc62f3982014-03-05 14:28:26 -08001869 Overlay::PipeSpecs pipeSpecs;
1870 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1871 pipeSpecs.needsScaling = true;
1872 pipeSpecs.dpy = mDpy;
1873 pipeSpecs.fb = false;
1874
1875 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301876 if(pipe_info.lIndex == ovutils::OV_INVALID){
1877 bRet = false;
1878 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1879 __FUNCTION__);
1880 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001881 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301882 if(pipe_info.rIndex == ovutils::OV_INVALID){
1883 bRet = false;
1884 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1885 __FUNCTION__);
1886 }
1887 return bRet;
1888}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001889
1890int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1891 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001892 if (ctx->mPtorInfo.isActive()) {
1893 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001894 if (fd < 0) {
1895 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001896 }
1897 }
1898 return fd;
1899}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001900//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001901
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001902void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301903 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001904 //If 4k2k Yuv layer split is possible, and if
1905 //fbz is above 4k2k layer, increment fb zorder by 1
1906 //as we split 4k2k layer and increment zorder for right half
1907 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07001908 if(!ctx)
1909 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001910 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301911 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1912 index++) {
1913 if(!mCurrentFrame.isFBComposed[index]) {
1914 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1915 mdpNextZOrder++;
1916 }
1917 mdpNextZOrder++;
1918 hwc_layer_1_t* layer = &list->hwLayers[index];
1919 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301920 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301921 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1922 mCurrentFrame.fbZ += 1;
1923 mdpNextZOrder++;
1924 //As we split 4kx2k yuv layer and program to 2 VG pipes
1925 //(if available) increase mdpcount by 1.
1926 mCurrentFrame.mdpCount++;
1927 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001928 }
1929 }
1930 }
radhakrishnac9a67412013-09-25 17:40:42 +05301931}
1932
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001933/*
1934 * Configures pipe(s) for MDP composition
1935 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001936int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001937 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001938 MdpPipeInfoNonSplit& mdp_info =
1939 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001940 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1941 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08001942 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001943
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001944 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1945 __FUNCTION__, layer, zOrder, dest);
1946
Saurabh Shah2c8ad052014-08-15 13:27:46 -07001947 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001948 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001949}
1950
Saurabh Shah88e4d272013-09-03 13:31:29 -07001951bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001952 hwc_display_contents_1_t* list) {
1953 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001954
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001955 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001956
Jeykumar Sankarancf537002013-01-21 21:19:15 -08001957 hwc_layer_1_t* layer = &list->hwLayers[index];
1958 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301959 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001960 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301961 continue;
1962 }
1963 }
1964
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001965 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001966 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001967 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08001968 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001969 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001970
Saurabh Shahc62f3982014-03-05 14:28:26 -08001971 Overlay::PipeSpecs pipeSpecs;
1972 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1973 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1974 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
1975 (qdutils::MDPVersion::getInstance().is8x26() and
1976 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
1977 pipeSpecs.dpy = mDpy;
1978 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08001979 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001980
Saurabh Shahc62f3982014-03-05 14:28:26 -08001981 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
1982
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001983 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001984 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001985 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001986 }
1987 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001988 return true;
1989}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001990
radhakrishnac9a67412013-09-25 17:40:42 +05301991int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1992 PipeLayerPair& PipeLayerPair) {
1993 MdpYUVPipeInfo& mdp_info =
1994 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
1995 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05301996 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1997 eDest lDest = mdp_info.lIndex;
1998 eDest rDest = mdp_info.rIndex;
1999
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002000 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302001 lDest, rDest, &PipeLayerPair.rot);
2002}
2003
Saurabh Shah88e4d272013-09-03 13:31:29 -07002004bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002005
Raj Kamal4393eaa2014-06-06 13:45:20 +05302006 if(!isEnabled() or !mModeOn) {
2007 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302008 return true;
2009 }
2010
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002011 // Set the Handle timeout to true for MDP or MIXED composition.
2012 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2013 sHandleTimeout = true;
2014 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002015
2016 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002017 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002018
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002019 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2020 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002021 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002022 if(mCurrentFrame.isFBComposed[i]) continue;
2023
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002024 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002025 private_handle_t *hnd = (private_handle_t *)layer->handle;
2026 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002027 if (!(layer->flags & HWC_COLOR_FILL)) {
2028 ALOGE("%s handle null", __FUNCTION__);
2029 return false;
2030 }
2031 // No PLAY for Color layer
2032 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2033 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002034 }
2035
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002036 int mdpIndex = mCurrentFrame.layerToMDP[i];
2037
Raj Kamal389d6e32014-08-04 14:43:24 +05302038 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302039 {
2040 MdpYUVPipeInfo& pipe_info =
2041 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2042 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2043 ovutils::eDest indexL = pipe_info.lIndex;
2044 ovutils::eDest indexR = pipe_info.rIndex;
2045 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302046 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302047 if(rot) {
2048 rot->queueBuffer(fd, offset);
2049 fd = rot->getDstMemId();
2050 offset = rot->getDstOffset();
2051 }
2052 if(indexL != ovutils::OV_INVALID) {
2053 ovutils::eDest destL = (ovutils::eDest)indexL;
2054 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2055 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2056 if (!ov.queueBuffer(fd, offset, destL)) {
2057 ALOGE("%s: queueBuffer failed for display:%d",
2058 __FUNCTION__, mDpy);
2059 return false;
2060 }
2061 }
2062
2063 if(indexR != ovutils::OV_INVALID) {
2064 ovutils::eDest destR = (ovutils::eDest)indexR;
2065 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2066 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2067 if (!ov.queueBuffer(fd, offset, destR)) {
2068 ALOGE("%s: queueBuffer failed for display:%d",
2069 __FUNCTION__, mDpy);
2070 return false;
2071 }
2072 }
2073 }
2074 else{
2075 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002076 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302077 ovutils::eDest dest = pipe_info.index;
2078 if(dest == ovutils::OV_INVALID) {
2079 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002080 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302081 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002082
radhakrishnac9a67412013-09-25 17:40:42 +05302083 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2084 continue;
2085 }
2086
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002087 int fd = hnd->fd;
2088 uint32_t offset = (uint32_t)hnd->offset;
2089 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2090 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002091 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002092 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002093 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002094 }
2095
radhakrishnac9a67412013-09-25 17:40:42 +05302096 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2097 using pipe: %d", __FUNCTION__, layer,
2098 hnd, dest );
2099
radhakrishnac9a67412013-09-25 17:40:42 +05302100 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2101 if(rot) {
2102 if(!rot->queueBuffer(fd, offset))
2103 return false;
2104 fd = rot->getDstMemId();
2105 offset = rot->getDstOffset();
2106 }
2107
2108 if (!ov.queueBuffer(fd, offset, dest)) {
2109 ALOGE("%s: queueBuffer failed for display:%d ",
2110 __FUNCTION__, mDpy);
2111 return false;
2112 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002113 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002114
2115 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002116 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002117 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002118}
2119
Saurabh Shah88e4d272013-09-03 13:31:29 -07002120//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002121
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002122void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302123 hwc_display_contents_1_t* list){
2124 //if 4kx2k yuv layer is totally present in either in left half
2125 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302126 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302127 if(mCurrentFrame.fbZ >= 0) {
2128 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2129 index++) {
2130 if(!mCurrentFrame.isFBComposed[index]) {
2131 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2132 mdpNextZOrder++;
2133 }
2134 mdpNextZOrder++;
2135 hwc_layer_1_t* layer = &list->hwLayers[index];
2136 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302137 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302138 hwc_rect_t dst = layer->displayFrame;
2139 if((dst.left > lSplit) || (dst.right < lSplit)) {
2140 mCurrentFrame.mdpCount += 1;
2141 }
2142 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2143 mCurrentFrame.fbZ += 1;
2144 mdpNextZOrder++;
2145 }
2146 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002147 }
radhakrishnac9a67412013-09-25 17:40:42 +05302148 }
2149}
2150
Saurabh Shah88e4d272013-09-03 13:31:29 -07002151bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002152 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002153
Saurabh Shahc62f3982014-03-05 14:28:26 -08002154 const int lSplit = getLeftSplit(ctx, mDpy);
2155 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002156 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002157 pipe_info.lIndex = ovutils::OV_INVALID;
2158 pipe_info.rIndex = ovutils::OV_INVALID;
2159
Saurabh Shahc62f3982014-03-05 14:28:26 -08002160 Overlay::PipeSpecs pipeSpecs;
2161 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2162 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2163 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2164 pipeSpecs.dpy = mDpy;
2165 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2166 pipeSpecs.fb = false;
2167
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002168 // Acquire pipe only for the updating half
2169 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2170 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2171
2172 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002173 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002174 if(pipe_info.lIndex == ovutils::OV_INVALID)
2175 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002176 }
2177
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002178 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002179 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2180 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002181 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002182 return false;
2183 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002184
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002185 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002186}
2187
Saurabh Shah88e4d272013-09-03 13:31:29 -07002188bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002189 hwc_display_contents_1_t* list) {
2190 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002191
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002192 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002193
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002194 hwc_layer_1_t* layer = &list->hwLayers[index];
2195 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302196 hwc_rect_t dst = layer->displayFrame;
2197 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302198 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302199 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002200 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302201 continue;
2202 }
2203 }
2204 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002205 int mdpIndex = mCurrentFrame.layerToMDP[index];
2206 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002207 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002208 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002209 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002210
Saurabh Shahc62f3982014-03-05 14:28:26 -08002211 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2212 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2213 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002214 return false;
2215 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002216 }
2217 return true;
2218}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002219
radhakrishnac9a67412013-09-25 17:40:42 +05302220int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2221 PipeLayerPair& PipeLayerPair) {
2222 const int lSplit = getLeftSplit(ctx, mDpy);
2223 hwc_rect_t dst = layer->displayFrame;
2224 if((dst.left > lSplit)||(dst.right < lSplit)){
2225 MdpYUVPipeInfo& mdp_info =
2226 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2227 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302228 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2229 eDest lDest = mdp_info.lIndex;
2230 eDest rDest = mdp_info.rIndex;
2231
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002232 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302233 lDest, rDest, &PipeLayerPair.rot);
2234 }
2235 else{
2236 return configure(ctx, layer, PipeLayerPair);
2237 }
2238}
2239
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002240/*
2241 * Configures pipe(s) for MDP composition
2242 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002243int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002244 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002245 MdpPipeInfoSplit& mdp_info =
2246 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002247 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002248 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2249 eDest lDest = mdp_info.lIndex;
2250 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002251
2252 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2253 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2254
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002255 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002256 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002257}
2258
Saurabh Shah88e4d272013-09-03 13:31:29 -07002259bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002260
Raj Kamal4393eaa2014-06-06 13:45:20 +05302261 if(!isEnabled() or !mModeOn) {
2262 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302263 return true;
2264 }
2265
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002266 // Set the Handle timeout to true for MDP or MIXED composition.
2267 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2268 sHandleTimeout = true;
2269 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002270
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002271 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002272 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002273
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002274 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2275 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002276 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002277 if(mCurrentFrame.isFBComposed[i]) continue;
2278
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002279 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002280 private_handle_t *hnd = (private_handle_t *)layer->handle;
2281 if(!hnd) {
2282 ALOGE("%s handle null", __FUNCTION__);
2283 return false;
2284 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002285
2286 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2287 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002288 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002289
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002290 int mdpIndex = mCurrentFrame.layerToMDP[i];
2291
Raj Kamal389d6e32014-08-04 14:43:24 +05302292 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302293 {
2294 MdpYUVPipeInfo& pipe_info =
2295 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2296 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2297 ovutils::eDest indexL = pipe_info.lIndex;
2298 ovutils::eDest indexR = pipe_info.rIndex;
2299 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302300 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302301 if(rot) {
2302 rot->queueBuffer(fd, offset);
2303 fd = rot->getDstMemId();
2304 offset = rot->getDstOffset();
2305 }
2306 if(indexL != ovutils::OV_INVALID) {
2307 ovutils::eDest destL = (ovutils::eDest)indexL;
2308 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2309 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2310 if (!ov.queueBuffer(fd, offset, destL)) {
2311 ALOGE("%s: queueBuffer failed for display:%d",
2312 __FUNCTION__, mDpy);
2313 return false;
2314 }
2315 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002316
radhakrishnac9a67412013-09-25 17:40:42 +05302317 if(indexR != ovutils::OV_INVALID) {
2318 ovutils::eDest destR = (ovutils::eDest)indexR;
2319 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2320 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2321 if (!ov.queueBuffer(fd, offset, destR)) {
2322 ALOGE("%s: queueBuffer failed for display:%d",
2323 __FUNCTION__, mDpy);
2324 return false;
2325 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002326 }
2327 }
radhakrishnac9a67412013-09-25 17:40:42 +05302328 else{
2329 MdpPipeInfoSplit& pipe_info =
2330 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2331 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002332
radhakrishnac9a67412013-09-25 17:40:42 +05302333 ovutils::eDest indexL = pipe_info.lIndex;
2334 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002335
radhakrishnac9a67412013-09-25 17:40:42 +05302336 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002337 uint32_t offset = (uint32_t)hnd->offset;
2338 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2339 if (!mDpy && (index != -1)) {
2340 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2341 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002342 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002343 }
radhakrishnac9a67412013-09-25 17:40:42 +05302344
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002345 if(ctx->mAD->draw(ctx, fd, offset)) {
2346 fd = ctx->mAD->getDstFd();
2347 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002348 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002349
radhakrishnac9a67412013-09-25 17:40:42 +05302350 if(rot) {
2351 rot->queueBuffer(fd, offset);
2352 fd = rot->getDstMemId();
2353 offset = rot->getDstOffset();
2354 }
2355
2356 //************* play left mixer **********
2357 if(indexL != ovutils::OV_INVALID) {
2358 ovutils::eDest destL = (ovutils::eDest)indexL;
2359 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2360 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2361 if (!ov.queueBuffer(fd, offset, destL)) {
2362 ALOGE("%s: queueBuffer failed for left mixer",
2363 __FUNCTION__);
2364 return false;
2365 }
2366 }
2367
2368 //************* play right mixer **********
2369 if(indexR != ovutils::OV_INVALID) {
2370 ovutils::eDest destR = (ovutils::eDest)indexR;
2371 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2372 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2373 if (!ov.queueBuffer(fd, offset, destR)) {
2374 ALOGE("%s: queueBuffer failed for right mixer",
2375 __FUNCTION__);
2376 return false;
2377 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002378 }
2379 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002380
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002381 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2382 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002383
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002384 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002385}
Saurabh Shahab47c692014-02-12 18:45:57 -08002386
2387//================MDPCompSrcSplit==============================================
2388bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002389 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002390 private_handle_t *hnd = (private_handle_t *)layer->handle;
2391 hwc_rect_t dst = layer->displayFrame;
2392 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2393 pipe_info.lIndex = ovutils::OV_INVALID;
2394 pipe_info.rIndex = ovutils::OV_INVALID;
2395
2396 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2397 //should have a higher priority than the right one. Pipe priorities are
2398 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002399
Saurabh Shahc62f3982014-03-05 14:28:26 -08002400 Overlay::PipeSpecs pipeSpecs;
2401 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2402 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2403 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2404 pipeSpecs.dpy = mDpy;
2405 pipeSpecs.fb = false;
2406
Saurabh Shahab47c692014-02-12 18:45:57 -08002407 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002408 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002409 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002410 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002411 }
2412
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002413 /* Use 2 pipes IF
2414 a) Layer's crop width is > 2048 or
2415 b) Layer's dest width > 2048 or
2416 c) On primary, driver has indicated with caps to split always. This is
2417 based on an empirically derived value of panel height. Applied only
2418 if the layer's width is > mixer's width
2419 */
2420
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302421 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002422 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302423 mdpHw.isSrcSplitAlways();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002424 int lSplit = getLeftSplit(ctx, mDpy);
2425 int dstWidth = dst.right - dst.left;
2426 int cropWidth = crop.right - crop.left;
2427
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002428 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2429 //pipe line length, we are still using 2 pipes. This is fine just because
2430 //this is source split where destination doesn't matter. Evaluate later to
2431 //see if going through all the calcs to save a pipe is worth it
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302432 if(dstWidth > mdpHw.getMaxMixerWidth() or
2433 cropWidth > mdpHw.getMaxMixerWidth() or
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002434 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002435 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002436 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002437 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002438 }
2439
2440 // Return values
2441 // 1 Left pipe is higher priority, do nothing.
2442 // 0 Pipes of same priority.
2443 //-1 Right pipe is of higher priority, needs swap.
2444 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2445 pipe_info.rIndex) == -1) {
2446 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002447 }
2448 }
2449
2450 return true;
2451}
2452
Saurabh Shahab47c692014-02-12 18:45:57 -08002453int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2454 PipeLayerPair& PipeLayerPair) {
2455 private_handle_t *hnd = (private_handle_t *)layer->handle;
2456 if(!hnd) {
2457 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2458 return -1;
2459 }
2460 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2461 MdpPipeInfoSplit& mdp_info =
2462 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2463 Rotator **rot = &PipeLayerPair.rot;
2464 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002465 eDest lDest = mdp_info.lIndex;
2466 eDest rDest = mdp_info.rIndex;
2467 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2468 hwc_rect_t dst = layer->displayFrame;
2469 int transform = layer->transform;
2470 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002471 int rotFlags = ROT_FLAGS_NONE;
2472 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2473 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2474
2475 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2476 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2477
2478 // Handle R/B swap
2479 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2480 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2481 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2482 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2483 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2484 }
2485
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002486 int downscale = getRotDownscale(ctx, layer);
Saurabh Shah97e2d802014-04-14 18:03:54 -07002487 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002488 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002489
2490 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2491 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002492 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002493 }
2494
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002495 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002496 (*rot) = ctx->mRotMgr->getNext();
2497 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002498 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002499 //If the video is using a single pipe, enable BWC
2500 if(rDest == OV_INVALID) {
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002501 BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002502 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002503 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002504 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002505 ALOGE("%s: configRotator failed!", __FUNCTION__);
2506 return -1;
2507 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002508 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002509 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002510 }
2511
2512 //If 2 pipes being used, divide layer into half, crop and dst
2513 hwc_rect_t cropL = crop;
2514 hwc_rect_t cropR = crop;
2515 hwc_rect_t dstL = dst;
2516 hwc_rect_t dstR = dst;
2517 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2518 cropL.right = (crop.right + crop.left) / 2;
2519 cropR.left = cropL.right;
2520 sanitizeSourceCrop(cropL, cropR, hnd);
2521
Saurabh Shahb729b192014-08-15 18:04:24 -07002522 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002523 //Swap crops on H flip since 2 pipes are being used
2524 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2525 hwc_rect_t tmp = cropL;
2526 cropL = cropR;
2527 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002528 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002529 }
2530
Saurabh Shahb729b192014-08-15 18:04:24 -07002531 //cropSwap trick: If the src and dst widths are both odd, let us say
2532 //2507, then splitting both into half would cause left width to be 1253
2533 //and right 1254. If crop is swapped because of H flip, this will cause
2534 //left crop width to be 1254, whereas left dst width remains 1253, thus
2535 //inducing a scaling that is unaccounted for. To overcome that we add 1
2536 //to the dst width if there is a cropSwap. So if the original width was
2537 //2507, the left dst width will be 1254. Even if the original width was
2538 //even for ex: 2508, the left dst width will still remain 1254.
2539 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002540 dstR.left = dstL.right;
2541 }
2542
2543 //For the mdp, since either we are pre-rotating or MDP does flips
2544 orient = OVERLAY_TRANSFORM_0;
2545 transform = 0;
2546
2547 //configure left pipe
2548 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002549 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002550 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2551 (ovutils::eBlending) getBlending(layer->blending));
2552
2553 if(configMdp(ctx->mOverlay, pargL, orient,
2554 cropL, dstL, metadata, lDest) < 0) {
2555 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2556 return -1;
2557 }
2558 }
2559
2560 //configure right pipe
2561 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002562 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002563 static_cast<eRotFlags>(rotFlags),
2564 layer->planeAlpha,
2565 (ovutils::eBlending) getBlending(layer->blending));
2566 if(configMdp(ctx->mOverlay, pargR, orient,
2567 cropR, dstR, metadata, rDest) < 0) {
2568 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2569 return -1;
2570 }
2571 }
2572
2573 return 0;
2574}
2575
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002576}; //namespace
2577