blob: 6b114a9966f2cb073558da2c27170a16ed3b5c5b [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;
1775
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001776 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1777 int currentFlags = atoi(property);
1778 if(currentFlags != sSimulationFlags) {
1779 sSimulationFlags = currentFlags;
1780 ALOGE("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1781 sSimulationFlags, sSimulationFlags);
1782 }
1783 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001784 // reset PTOR
1785 if(!mDpy)
1786 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001787
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301788 //Do not cache the information for next draw cycle.
1789 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1790 ALOGI("%s: Unsupported layer count for mdp composition",
1791 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001792 mCachedFrame.reset();
1793 return -1;
1794 }
1795
Saurabh Shahb39f8152013-08-22 10:21:44 -07001796 //reset old data
1797 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001798 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1799 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301800
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001801 // Detect the start of animation and fall back to GPU only once to cache
1802 // all the layers in FB and display FB content untill animation completes.
1803 if(ctx->listStats[mDpy].isDisplayAnimating) {
1804 mCurrentFrame.needsRedraw = false;
1805 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1806 mCurrentFrame.needsRedraw = true;
1807 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1808 }
1809 setMDPCompLayerFlags(ctx, list);
1810 mCachedFrame.updateCounts(mCurrentFrame);
1811 ret = -1;
1812 return ret;
1813 } else {
1814 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1815 }
1816
Saurabh Shahb39f8152013-08-22 10:21:44 -07001817 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001818 if(isFrameDoable(ctx)) {
1819 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001820
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001821 // if tryFullFrame fails, try to push all video and secure RGB layers
1822 // to MDP for composition.
1823 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
1824 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301825 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001826 setMDPCompLayerFlags(ctx, list);
1827 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001828 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001829 reset(ctx);
1830 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1831 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001832 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001833 }
1834 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001835 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1836 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001837 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001838 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001839
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001840 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001841 ALOGD("GEOMETRY change: %d",
1842 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001843 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001844 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001845 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001846 }
1847
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001848 mCachedFrame.cacheAll(list);
1849 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001850 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001851}
1852
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001853bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301854
1855 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301856 int mdpIndex = mCurrentFrame.layerToMDP[index];
1857 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1858 info.pipeInfo = new MdpYUVPipeInfo;
1859 info.rot = NULL;
1860 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301861
1862 pipe_info.lIndex = ovutils::OV_INVALID;
1863 pipe_info.rIndex = ovutils::OV_INVALID;
1864
Saurabh Shahc62f3982014-03-05 14:28:26 -08001865 Overlay::PipeSpecs pipeSpecs;
1866 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1867 pipeSpecs.needsScaling = true;
1868 pipeSpecs.dpy = mDpy;
1869 pipeSpecs.fb = false;
1870
1871 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301872 if(pipe_info.lIndex == ovutils::OV_INVALID){
1873 bRet = false;
1874 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1875 __FUNCTION__);
1876 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001877 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301878 if(pipe_info.rIndex == ovutils::OV_INVALID){
1879 bRet = false;
1880 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1881 __FUNCTION__);
1882 }
1883 return bRet;
1884}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001885
1886int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1887 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001888 if (ctx->mPtorInfo.isActive()) {
1889 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001890 if (fd < 0) {
1891 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001892 }
1893 }
1894 return fd;
1895}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001896//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001897
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001898void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301899 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001900 //If 4k2k Yuv layer split is possible, and if
1901 //fbz is above 4k2k layer, increment fb zorder by 1
1902 //as we split 4k2k layer and increment zorder for right half
1903 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07001904 if(!ctx)
1905 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001906 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301907 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1908 index++) {
1909 if(!mCurrentFrame.isFBComposed[index]) {
1910 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1911 mdpNextZOrder++;
1912 }
1913 mdpNextZOrder++;
1914 hwc_layer_1_t* layer = &list->hwLayers[index];
1915 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301916 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301917 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1918 mCurrentFrame.fbZ += 1;
1919 mdpNextZOrder++;
1920 //As we split 4kx2k yuv layer and program to 2 VG pipes
1921 //(if available) increase mdpcount by 1.
1922 mCurrentFrame.mdpCount++;
1923 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001924 }
1925 }
1926 }
radhakrishnac9a67412013-09-25 17:40:42 +05301927}
1928
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001929/*
1930 * Configures pipe(s) for MDP composition
1931 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001932int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001933 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001934 MdpPipeInfoNonSplit& mdp_info =
1935 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001936 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1937 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08001938 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001939
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001940 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1941 __FUNCTION__, layer, zOrder, dest);
1942
Saurabh Shah2c8ad052014-08-15 13:27:46 -07001943 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001944 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001945}
1946
Saurabh Shah88e4d272013-09-03 13:31:29 -07001947bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001948 hwc_display_contents_1_t* list) {
1949 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001950
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001951 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001952
Jeykumar Sankarancf537002013-01-21 21:19:15 -08001953 hwc_layer_1_t* layer = &list->hwLayers[index];
1954 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301955 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001956 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301957 continue;
1958 }
1959 }
1960
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001961 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001962 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001963 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08001964 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001965 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001966
Saurabh Shahc62f3982014-03-05 14:28:26 -08001967 Overlay::PipeSpecs pipeSpecs;
1968 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1969 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1970 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
1971 (qdutils::MDPVersion::getInstance().is8x26() and
1972 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
1973 pipeSpecs.dpy = mDpy;
1974 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08001975 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001976
Saurabh Shahc62f3982014-03-05 14:28:26 -08001977 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
1978
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001979 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001980 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001981 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001982 }
1983 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001984 return true;
1985}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001986
radhakrishnac9a67412013-09-25 17:40:42 +05301987int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1988 PipeLayerPair& PipeLayerPair) {
1989 MdpYUVPipeInfo& mdp_info =
1990 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
1991 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05301992 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1993 eDest lDest = mdp_info.lIndex;
1994 eDest rDest = mdp_info.rIndex;
1995
Saurabh Shah2c8ad052014-08-15 13:27:46 -07001996 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05301997 lDest, rDest, &PipeLayerPair.rot);
1998}
1999
Saurabh Shah88e4d272013-09-03 13:31:29 -07002000bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002001
Raj Kamal4393eaa2014-06-06 13:45:20 +05302002 if(!isEnabled() or !mModeOn) {
2003 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302004 return true;
2005 }
2006
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002007 // Set the Handle timeout to true for MDP or MIXED composition.
2008 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2009 sHandleTimeout = true;
2010 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002011
2012 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002013 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002014
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002015 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2016 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002017 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002018 if(mCurrentFrame.isFBComposed[i]) continue;
2019
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002020 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002021 private_handle_t *hnd = (private_handle_t *)layer->handle;
2022 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002023 if (!(layer->flags & HWC_COLOR_FILL)) {
2024 ALOGE("%s handle null", __FUNCTION__);
2025 return false;
2026 }
2027 // No PLAY for Color layer
2028 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2029 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002030 }
2031
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002032 int mdpIndex = mCurrentFrame.layerToMDP[i];
2033
Raj Kamal389d6e32014-08-04 14:43:24 +05302034 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302035 {
2036 MdpYUVPipeInfo& pipe_info =
2037 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2038 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2039 ovutils::eDest indexL = pipe_info.lIndex;
2040 ovutils::eDest indexR = pipe_info.rIndex;
2041 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302042 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302043 if(rot) {
2044 rot->queueBuffer(fd, offset);
2045 fd = rot->getDstMemId();
2046 offset = rot->getDstOffset();
2047 }
2048 if(indexL != ovutils::OV_INVALID) {
2049 ovutils::eDest destL = (ovutils::eDest)indexL;
2050 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2051 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2052 if (!ov.queueBuffer(fd, offset, destL)) {
2053 ALOGE("%s: queueBuffer failed for display:%d",
2054 __FUNCTION__, mDpy);
2055 return false;
2056 }
2057 }
2058
2059 if(indexR != ovutils::OV_INVALID) {
2060 ovutils::eDest destR = (ovutils::eDest)indexR;
2061 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2062 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2063 if (!ov.queueBuffer(fd, offset, destR)) {
2064 ALOGE("%s: queueBuffer failed for display:%d",
2065 __FUNCTION__, mDpy);
2066 return false;
2067 }
2068 }
2069 }
2070 else{
2071 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002072 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302073 ovutils::eDest dest = pipe_info.index;
2074 if(dest == ovutils::OV_INVALID) {
2075 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002076 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302077 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002078
radhakrishnac9a67412013-09-25 17:40:42 +05302079 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2080 continue;
2081 }
2082
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002083 int fd = hnd->fd;
2084 uint32_t offset = (uint32_t)hnd->offset;
2085 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2086 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002087 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002088 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002089 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002090 }
2091
radhakrishnac9a67412013-09-25 17:40:42 +05302092 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2093 using pipe: %d", __FUNCTION__, layer,
2094 hnd, dest );
2095
radhakrishnac9a67412013-09-25 17:40:42 +05302096 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2097 if(rot) {
2098 if(!rot->queueBuffer(fd, offset))
2099 return false;
2100 fd = rot->getDstMemId();
2101 offset = rot->getDstOffset();
2102 }
2103
2104 if (!ov.queueBuffer(fd, offset, dest)) {
2105 ALOGE("%s: queueBuffer failed for display:%d ",
2106 __FUNCTION__, mDpy);
2107 return false;
2108 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002109 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002110
2111 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002112 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002113 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002114}
2115
Saurabh Shah88e4d272013-09-03 13:31:29 -07002116//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002117
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002118void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302119 hwc_display_contents_1_t* list){
2120 //if 4kx2k yuv layer is totally present in either in left half
2121 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302122 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302123 if(mCurrentFrame.fbZ >= 0) {
2124 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2125 index++) {
2126 if(!mCurrentFrame.isFBComposed[index]) {
2127 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2128 mdpNextZOrder++;
2129 }
2130 mdpNextZOrder++;
2131 hwc_layer_1_t* layer = &list->hwLayers[index];
2132 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302133 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302134 hwc_rect_t dst = layer->displayFrame;
2135 if((dst.left > lSplit) || (dst.right < lSplit)) {
2136 mCurrentFrame.mdpCount += 1;
2137 }
2138 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2139 mCurrentFrame.fbZ += 1;
2140 mdpNextZOrder++;
2141 }
2142 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002143 }
radhakrishnac9a67412013-09-25 17:40:42 +05302144 }
2145}
2146
Saurabh Shah88e4d272013-09-03 13:31:29 -07002147bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002148 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002149
Saurabh Shahc62f3982014-03-05 14:28:26 -08002150 const int lSplit = getLeftSplit(ctx, mDpy);
2151 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002152 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002153 pipe_info.lIndex = ovutils::OV_INVALID;
2154 pipe_info.rIndex = ovutils::OV_INVALID;
2155
Saurabh Shahc62f3982014-03-05 14:28:26 -08002156 Overlay::PipeSpecs pipeSpecs;
2157 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2158 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2159 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2160 pipeSpecs.dpy = mDpy;
2161 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2162 pipeSpecs.fb = false;
2163
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002164 // Acquire pipe only for the updating half
2165 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2166 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2167
2168 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002169 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002170 if(pipe_info.lIndex == ovutils::OV_INVALID)
2171 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002172 }
2173
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002174 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002175 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2176 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002177 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002178 return false;
2179 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002180
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002181 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002182}
2183
Saurabh Shah88e4d272013-09-03 13:31:29 -07002184bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002185 hwc_display_contents_1_t* list) {
2186 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002187
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002188 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002189
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002190 hwc_layer_1_t* layer = &list->hwLayers[index];
2191 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302192 hwc_rect_t dst = layer->displayFrame;
2193 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302194 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302195 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002196 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302197 continue;
2198 }
2199 }
2200 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002201 int mdpIndex = mCurrentFrame.layerToMDP[index];
2202 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002203 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002204 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002205 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002206
Saurabh Shahc62f3982014-03-05 14:28:26 -08002207 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2208 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2209 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002210 return false;
2211 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002212 }
2213 return true;
2214}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002215
radhakrishnac9a67412013-09-25 17:40:42 +05302216int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2217 PipeLayerPair& PipeLayerPair) {
2218 const int lSplit = getLeftSplit(ctx, mDpy);
2219 hwc_rect_t dst = layer->displayFrame;
2220 if((dst.left > lSplit)||(dst.right < lSplit)){
2221 MdpYUVPipeInfo& mdp_info =
2222 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2223 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302224 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2225 eDest lDest = mdp_info.lIndex;
2226 eDest rDest = mdp_info.rIndex;
2227
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002228 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302229 lDest, rDest, &PipeLayerPair.rot);
2230 }
2231 else{
2232 return configure(ctx, layer, PipeLayerPair);
2233 }
2234}
2235
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002236/*
2237 * Configures pipe(s) for MDP composition
2238 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002239int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002240 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002241 MdpPipeInfoSplit& mdp_info =
2242 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002243 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002244 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2245 eDest lDest = mdp_info.lIndex;
2246 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002247
2248 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2249 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2250
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002251 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002252 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002253}
2254
Saurabh Shah88e4d272013-09-03 13:31:29 -07002255bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002256
Raj Kamal4393eaa2014-06-06 13:45:20 +05302257 if(!isEnabled() or !mModeOn) {
2258 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302259 return true;
2260 }
2261
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002262 // Set the Handle timeout to true for MDP or MIXED composition.
2263 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2264 sHandleTimeout = true;
2265 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002266
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002267 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002268 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002269
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002270 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2271 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002272 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002273 if(mCurrentFrame.isFBComposed[i]) continue;
2274
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002275 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002276 private_handle_t *hnd = (private_handle_t *)layer->handle;
2277 if(!hnd) {
2278 ALOGE("%s handle null", __FUNCTION__);
2279 return false;
2280 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002281
2282 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2283 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002284 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002285
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002286 int mdpIndex = mCurrentFrame.layerToMDP[i];
2287
Raj Kamal389d6e32014-08-04 14:43:24 +05302288 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302289 {
2290 MdpYUVPipeInfo& pipe_info =
2291 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2292 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2293 ovutils::eDest indexL = pipe_info.lIndex;
2294 ovutils::eDest indexR = pipe_info.rIndex;
2295 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302296 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302297 if(rot) {
2298 rot->queueBuffer(fd, offset);
2299 fd = rot->getDstMemId();
2300 offset = rot->getDstOffset();
2301 }
2302 if(indexL != ovutils::OV_INVALID) {
2303 ovutils::eDest destL = (ovutils::eDest)indexL;
2304 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2305 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2306 if (!ov.queueBuffer(fd, offset, destL)) {
2307 ALOGE("%s: queueBuffer failed for display:%d",
2308 __FUNCTION__, mDpy);
2309 return false;
2310 }
2311 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002312
radhakrishnac9a67412013-09-25 17:40:42 +05302313 if(indexR != ovutils::OV_INVALID) {
2314 ovutils::eDest destR = (ovutils::eDest)indexR;
2315 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2316 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2317 if (!ov.queueBuffer(fd, offset, destR)) {
2318 ALOGE("%s: queueBuffer failed for display:%d",
2319 __FUNCTION__, mDpy);
2320 return false;
2321 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002322 }
2323 }
radhakrishnac9a67412013-09-25 17:40:42 +05302324 else{
2325 MdpPipeInfoSplit& pipe_info =
2326 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2327 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002328
radhakrishnac9a67412013-09-25 17:40:42 +05302329 ovutils::eDest indexL = pipe_info.lIndex;
2330 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002331
radhakrishnac9a67412013-09-25 17:40:42 +05302332 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002333 uint32_t offset = (uint32_t)hnd->offset;
2334 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2335 if (!mDpy && (index != -1)) {
2336 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2337 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002338 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002339 }
radhakrishnac9a67412013-09-25 17:40:42 +05302340
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002341 if(ctx->mAD->draw(ctx, fd, offset)) {
2342 fd = ctx->mAD->getDstFd();
2343 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002344 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002345
radhakrishnac9a67412013-09-25 17:40:42 +05302346 if(rot) {
2347 rot->queueBuffer(fd, offset);
2348 fd = rot->getDstMemId();
2349 offset = rot->getDstOffset();
2350 }
2351
2352 //************* play left mixer **********
2353 if(indexL != ovutils::OV_INVALID) {
2354 ovutils::eDest destL = (ovutils::eDest)indexL;
2355 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2356 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2357 if (!ov.queueBuffer(fd, offset, destL)) {
2358 ALOGE("%s: queueBuffer failed for left mixer",
2359 __FUNCTION__);
2360 return false;
2361 }
2362 }
2363
2364 //************* play right mixer **********
2365 if(indexR != ovutils::OV_INVALID) {
2366 ovutils::eDest destR = (ovutils::eDest)indexR;
2367 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2368 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2369 if (!ov.queueBuffer(fd, offset, destR)) {
2370 ALOGE("%s: queueBuffer failed for right mixer",
2371 __FUNCTION__);
2372 return false;
2373 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002374 }
2375 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002376
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002377 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2378 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002379
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002380 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002381}
Saurabh Shahab47c692014-02-12 18:45:57 -08002382
2383//================MDPCompSrcSplit==============================================
2384bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002385 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002386 private_handle_t *hnd = (private_handle_t *)layer->handle;
2387 hwc_rect_t dst = layer->displayFrame;
2388 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2389 pipe_info.lIndex = ovutils::OV_INVALID;
2390 pipe_info.rIndex = ovutils::OV_INVALID;
2391
2392 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2393 //should have a higher priority than the right one. Pipe priorities are
2394 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002395
Saurabh Shahc62f3982014-03-05 14:28:26 -08002396 Overlay::PipeSpecs pipeSpecs;
2397 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2398 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2399 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2400 pipeSpecs.dpy = mDpy;
2401 pipeSpecs.fb = false;
2402
Saurabh Shahab47c692014-02-12 18:45:57 -08002403 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002404 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002405 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002406 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002407 }
2408
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002409 /* Use 2 pipes IF
2410 a) Layer's crop width is > 2048 or
2411 b) Layer's dest width > 2048 or
2412 c) On primary, driver has indicated with caps to split always. This is
2413 based on an empirically derived value of panel height. Applied only
2414 if the layer's width is > mixer's width
2415 */
2416
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302417 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002418 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302419 mdpHw.isSrcSplitAlways();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002420 int lSplit = getLeftSplit(ctx, mDpy);
2421 int dstWidth = dst.right - dst.left;
2422 int cropWidth = crop.right - crop.left;
2423
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002424 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2425 //pipe line length, we are still using 2 pipes. This is fine just because
2426 //this is source split where destination doesn't matter. Evaluate later to
2427 //see if going through all the calcs to save a pipe is worth it
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302428 if(dstWidth > mdpHw.getMaxMixerWidth() or
2429 cropWidth > mdpHw.getMaxMixerWidth() or
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002430 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002431 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002432 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002433 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002434 }
2435
2436 // Return values
2437 // 1 Left pipe is higher priority, do nothing.
2438 // 0 Pipes of same priority.
2439 //-1 Right pipe is of higher priority, needs swap.
2440 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2441 pipe_info.rIndex) == -1) {
2442 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002443 }
2444 }
2445
2446 return true;
2447}
2448
Saurabh Shahab47c692014-02-12 18:45:57 -08002449int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2450 PipeLayerPair& PipeLayerPair) {
2451 private_handle_t *hnd = (private_handle_t *)layer->handle;
2452 if(!hnd) {
2453 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2454 return -1;
2455 }
2456 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2457 MdpPipeInfoSplit& mdp_info =
2458 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2459 Rotator **rot = &PipeLayerPair.rot;
2460 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002461 eDest lDest = mdp_info.lIndex;
2462 eDest rDest = mdp_info.rIndex;
2463 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2464 hwc_rect_t dst = layer->displayFrame;
2465 int transform = layer->transform;
2466 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002467 int rotFlags = ROT_FLAGS_NONE;
2468 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2469 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2470
2471 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2472 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2473
2474 // Handle R/B swap
2475 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2476 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2477 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2478 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2479 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2480 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002481 /* Calculate the external display position based on MDP downscale,
2482 ActionSafe, and extorientation features. */
2483 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002484
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002485 int downscale = getRotDownscale(ctx, layer);
Saurabh Shah97e2d802014-04-14 18:03:54 -07002486 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002487 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002488
2489 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2490 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002491 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002492 }
2493
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002494 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002495 (*rot) = ctx->mRotMgr->getNext();
2496 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002497 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002498 //If the video is using a single pipe, enable BWC
2499 if(rDest == OV_INVALID) {
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002500 BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002501 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002502 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002503 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002504 ALOGE("%s: configRotator failed!", __FUNCTION__);
2505 return -1;
2506 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002507 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002508 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002509 }
2510
2511 //If 2 pipes being used, divide layer into half, crop and dst
2512 hwc_rect_t cropL = crop;
2513 hwc_rect_t cropR = crop;
2514 hwc_rect_t dstL = dst;
2515 hwc_rect_t dstR = dst;
2516 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2517 cropL.right = (crop.right + crop.left) / 2;
2518 cropR.left = cropL.right;
2519 sanitizeSourceCrop(cropL, cropR, hnd);
2520
Saurabh Shahb729b192014-08-15 18:04:24 -07002521 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002522 //Swap crops on H flip since 2 pipes are being used
2523 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2524 hwc_rect_t tmp = cropL;
2525 cropL = cropR;
2526 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002527 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002528 }
2529
Saurabh Shahb729b192014-08-15 18:04:24 -07002530 //cropSwap trick: If the src and dst widths are both odd, let us say
2531 //2507, then splitting both into half would cause left width to be 1253
2532 //and right 1254. If crop is swapped because of H flip, this will cause
2533 //left crop width to be 1254, whereas left dst width remains 1253, thus
2534 //inducing a scaling that is unaccounted for. To overcome that we add 1
2535 //to the dst width if there is a cropSwap. So if the original width was
2536 //2507, the left dst width will be 1254. Even if the original width was
2537 //even for ex: 2508, the left dst width will still remain 1254.
2538 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002539 dstR.left = dstL.right;
2540 }
2541
2542 //For the mdp, since either we are pre-rotating or MDP does flips
2543 orient = OVERLAY_TRANSFORM_0;
2544 transform = 0;
2545
2546 //configure left pipe
2547 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002548 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002549 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2550 (ovutils::eBlending) getBlending(layer->blending));
2551
2552 if(configMdp(ctx->mOverlay, pargL, orient,
2553 cropL, dstL, metadata, lDest) < 0) {
2554 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2555 return -1;
2556 }
2557 }
2558
2559 //configure right pipe
2560 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002561 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002562 static_cast<eRotFlags>(rotFlags),
2563 layer->planeAlpha,
2564 (ovutils::eBlending) getBlending(layer->blending));
2565 if(configMdp(ctx->mOverlay, pargR, orient,
2566 cropR, dstR, metadata, rDest) < 0) {
2567 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2568 return -1;
2569 }
2570 }
2571
2572 return 0;
2573}
2574
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002575}; //namespace
2576