blob: 064158a3f1cdfadd49fc1321b14ee6c7fb92097d [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;
radhakrishnac9a67412013-09-25 17:40:42 +053048bool MDPComp::sEnable4k2kYUVSplit = 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
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800130 if(property_get("debug.mdpcomp.logs", property, NULL) > 0) {
131 if(atoi(property) != 0)
132 sDebugLogs = true;
133 }
134
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800135 sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Saurabh Shah85234ec2013-04-12 17:09:00 -0700136 if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
137 int val = atoi(property);
138 if(val >= 0)
139 sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800140 }
141
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400142 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
143 // Idle invalidation is not necessary on command mode panels
144 long idle_timeout = DEFAULT_IDLE_TIME;
145 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
146 if(atoi(property) != 0)
147 idle_timeout = atoi(property);
148 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800149
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400150 //create Idle Invalidator only when not disabled through property
151 if(idle_timeout != -1)
152 idleInvalidator = IdleInvalidator::getInstance();
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800153
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400154 if(idleInvalidator == NULL) {
155 ALOGE("%s: failed to instantiate idleInvalidator object",
156 __FUNCTION__);
157 } else {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530158 idleInvalidator->init(timeout_handler, ctx,
159 (unsigned int)idle_timeout);
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400160 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800161 }
radhakrishnac9a67412013-09-25 17:40:42 +0530162
163 if((property_get("debug.mdpcomp.4k2kSplit", property, "0") > 0) &&
164 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
165 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
166 sEnable4k2kYUVSplit = true;
167 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700168
169 if ((property_get("persist.hwc.ptor.enable", property, NULL) > 0) &&
170 ((!strncasecmp(property, "true", PROPERTY_VALUE_MAX )) ||
171 (!strncmp(property, "1", PROPERTY_VALUE_MAX )))) {
172 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
173 HWC_DISPLAY_PRIMARY);
174 }
175
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700176 return true;
177}
178
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800179void MDPComp::reset(hwc_context_t *ctx) {
180 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700181 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800182 ctx->mOverlay->clear(mDpy);
183 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700184}
185
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700186void MDPComp::timeout_handler(void *udata) {
187 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
188
189 if(!ctx) {
190 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
191 return;
192 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800193 Locker::Autolock _l(ctx->mDrawLock);
194 // Handle timeout event only if the previous composition is MDP or MIXED.
195 if(!sHandleTimeout) {
196 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
197 return;
198 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700199 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700200 ALOGE("%s: HWC proc not registered", __FUNCTION__);
201 return;
202 }
203 sIdleFallBack = true;
204 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700205 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700206}
207
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800208void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800209 hwc_display_contents_1_t* list) {
210 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800211
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800212 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800213 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800214 if(!mCurrentFrame.isFBComposed[index]) {
215 layerProp[index].mFlags |= HWC_MDPCOMP;
216 layer->compositionType = HWC_OVERLAY;
217 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800218 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700219 /* Drop the layer when its already present in FB OR when it lies
220 * outside frame's ROI */
221 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800222 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700223 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800224 }
225 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700226}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500227
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800228void MDPComp::setRedraw(hwc_context_t *ctx,
229 hwc_display_contents_1_t* list) {
230 mCurrentFrame.needsRedraw = false;
231 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
232 (list->flags & HWC_GEOMETRY_CHANGED) ||
233 isSkipPresent(ctx, mDpy)) {
234 mCurrentFrame.needsRedraw = true;
235 }
236}
237
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800238MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700239 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800240}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800241
Saurabh Shahaa236822013-04-24 18:07:26 -0700242void MDPComp::FrameInfo::reset(const int& numLayers) {
243 for(int i = 0 ; i < MAX_PIPES_PER_MIXER && numLayers; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800244 if(mdpToLayer[i].pipeInfo) {
245 delete mdpToLayer[i].pipeInfo;
246 mdpToLayer[i].pipeInfo = NULL;
247 //We dont own the rotator
248 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800249 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800250 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800251
252 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
253 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700254 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800255
Saurabh Shahaa236822013-04-24 18:07:26 -0700256 layerCount = numLayers;
257 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800258 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700259 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800260 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800261}
262
Saurabh Shahaa236822013-04-24 18:07:26 -0700263void MDPComp::FrameInfo::map() {
264 // populate layer and MDP maps
265 int mdpIdx = 0;
266 for(int idx = 0; idx < layerCount; idx++) {
267 if(!isFBComposed[idx]) {
268 mdpToLayer[mdpIdx].listIndex = idx;
269 layerToMDP[idx] = mdpIdx++;
270 }
271 }
272}
273
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800274MDPComp::LayerCache::LayerCache() {
275 reset();
276}
277
278void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700279 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530280 memset(&isFBComposed, true, sizeof(isFBComposed));
281 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800282 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700283}
284
285void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530286 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700287 for(int i = 0; i < numAppLayers; i++) {
288 hnd[i] = list->hwLayers[i].handle;
289 }
290}
291
292void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700293 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530294 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
295 memcpy(&drop, &curFrame.drop, sizeof(drop));
296}
297
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800298bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
299 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530300 if(layerCount != curFrame.layerCount)
301 return false;
302 for(int i = 0; i < curFrame.layerCount; i++) {
303 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
304 (curFrame.drop[i] != drop[i])) {
305 return false;
306 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800307 if(curFrame.isFBComposed[i] &&
308 (hnd[i] != list->hwLayers[i].handle)){
309 return false;
310 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530311 }
312 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800313}
314
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700315bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
316 private_handle_t *hnd = (private_handle_t *)layer->handle;
317 if((not isYuvBuffer(hnd) and has90Transform(layer)) or
318 (not isValidDimension(ctx,layer))
319 //More conditions here, SKIP, sRGB+Blend etc
320 ) {
321 return false;
322 }
323 return true;
324}
325
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530326bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800327 private_handle_t *hnd = (private_handle_t *)layer->handle;
328
329 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700330 if (layer->flags & HWC_COLOR_FILL) {
331 // Color layer
332 return true;
333 }
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800334 ALOGE("%s: layer handle is NULL", __FUNCTION__);
335 return false;
336 }
337
Naseer Ahmede850a802013-09-06 13:12:52 -0400338 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400339 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400340 return false;
341
Saurabh Shah62e1d732013-09-17 10:44:05 -0700342 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700343 hwc_rect_t dst = layer->displayFrame;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700344 int crop_w = crop.right - crop.left;
345 int crop_h = crop.bottom - crop.top;
346 int dst_w = dst.right - dst.left;
347 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800348 float w_scale = ((float)crop_w / (float)dst_w);
349 float h_scale = ((float)crop_h / (float)dst_h);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700350
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800351 /* Workaround for MDP HW limitation in DSI command mode panels where
352 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
353 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530354 * There also is a HW limilation in MDP, minimum block size is 2x2
355 * Fallback to GPU if height is less than 2.
356 */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800357 if((crop_w < 5)||(crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800358 return false;
359
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800360 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700361 const uint32_t maxMDPDownscale =
Saurabh Shah4fdde762013-04-30 18:47:33 -0700362 qdutils::MDPVersion::getInstance().getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800363 const float w_dscale = w_scale;
364 const float h_dscale = h_scale;
365
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800366 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700367
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800368 if(!qdutils::MDPVersion::getInstance().supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700369 /* On targets that doesnt support Decimation (eg.,8x26)
370 * maximum downscale support is overlay pipe downscale.
371 */
372 if(crop_w > MAX_DISPLAY_DIM || w_dscale > maxMDPDownscale ||
373 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800374 return false;
375 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700376 // Decimation on macrotile format layers is not supported.
377 if(isTileRendered(hnd)) {
378 /* MDP can read maximum MAX_DISPLAY_DIM width.
379 * Bail out if
380 * 1. Src crop > MAX_DISPLAY_DIM on nonsplit MDPComp
381 * 2. exceeds maximum downscale limit
382 */
383 if(((crop_w > MAX_DISPLAY_DIM) && !sSrcSplitEnabled) ||
384 w_dscale > maxMDPDownscale ||
385 h_dscale > maxMDPDownscale) {
386 return false;
387 }
388 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800389 return false;
390 }
391 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700392 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700393 return false;
394 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700395 }
396
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800397 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
398 const uint32_t upscale =
399 qdutils::MDPVersion::getInstance().getMaxMDPUpscale();
400 const float w_uscale = 1.0f / w_scale;
401 const float h_uscale = 1.0f / h_scale;
402
403 if(w_uscale > upscale || h_uscale > upscale)
404 return false;
405 }
406
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800407 return true;
408}
409
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800410bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700411 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800412
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800413 if(!isEnabled()) {
414 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700415 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530416 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530417 qdutils::MDPVersion::getInstance().is8x16() ||
418 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800419 ctx->mVideoTransFlag &&
420 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700421 //1 Padding round to shift pipes across mixers
422 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
423 __FUNCTION__);
424 ret = false;
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800425 } else if(isSecondaryConfiguring(ctx)) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800426 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800427 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700428 ret = false;
Saurabh Shahaa236822013-04-24 18:07:26 -0700429 } else if(ctx->isPaddingRound) {
Raj Kamal9ed3d6b2014-02-07 16:15:17 +0530430 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
431 __FUNCTION__,mDpy);
Saurabh Shahaa236822013-04-24 18:07:26 -0700432 ret = false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700433 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700434 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800435}
436
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800437void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
438 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
439 fbRect = getIntersection(fbRect, roi);
440}
441
442/* 1) Identify layers that are not visible or lying outside the updating ROI and
443 * drop them from composition.
444 * 2) If we have a scaling layer which needs cropping against generated
445 * ROI, reset ROI to full resolution. */
446bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
447 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700448 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800449 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800450
451 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800452 if(!isValidRect(visibleRect)) {
453 mCurrentFrame.drop[i] = true;
454 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800455 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800456 }
457
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700458 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700459 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800460 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700461
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700462 if(!isValidRect(res)) {
463 mCurrentFrame.drop[i] = true;
464 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800465 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700466 /* Reset frame ROI when any layer which needs scaling also needs ROI
467 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800468 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800469 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700470 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
471 mCurrentFrame.dropCount = 0;
472 return false;
473 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800474
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800475 /* deduct any opaque region from visibleRect */
476 if (layer->blending == HWC_BLENDING_NONE)
477 visibleRect = deductRect(visibleRect, res);
478 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700479 }
480 return true;
481}
482
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800483/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
484 * are updating. If DirtyRegion is applicable, calculate it by accounting all
485 * the changing layer's dirtyRegion. */
486void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
487 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700488 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800489 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700490 return;
491
492 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800493 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
494 (int)ctx->dpyAttr[mDpy].yres};
495
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700496 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800497 hwc_layer_1_t* layer = &list->hwLayers[index];
498 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800499 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700500 hwc_rect_t dst = layer->displayFrame;
501 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800502
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800503#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800504 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700505 {
506 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
507 int x_off = dst.left - src.left;
508 int y_off = dst.top - src.top;
509 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
510 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800511#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800512
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800513 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700514 }
515 }
516
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800517 /* No layer is updating. Still SF wants a refresh.*/
518 if(!isValidRect(roi))
519 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800520
521 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800522 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800523
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800524 ctx->listStats[mDpy].lRoi = roi;
525 if(!validateAndApplyROI(ctx, list))
526 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700527
528 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800529 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
530 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
531}
532
533void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
534 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
535 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
536
537 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
538 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
539 fbRect = getUnion(l_fbRect, r_fbRect);
540}
541/* 1) Identify layers that are not visible or lying outside BOTH the updating
542 * ROI's and drop them from composition. If a layer is spanning across both
543 * the halves of the screen but needed by only ROI, the non-contributing
544 * half will not be programmed for MDP.
545 * 2) If we have a scaling layer which needs cropping against generated
546 * ROI, reset ROI to full resolution. */
547bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
548 hwc_display_contents_1_t* list) {
549
550 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
551
552 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
553 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
554
555 for(int i = numAppLayers - 1; i >= 0; i--){
556 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
557 {
558 mCurrentFrame.drop[i] = true;
559 mCurrentFrame.dropCount++;
560 continue;
561 }
562
563 const hwc_layer_1_t* layer = &list->hwLayers[i];
564 hwc_rect_t dstRect = layer->displayFrame;
565
566 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
567 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
568 hwc_rect_t res = getUnion(l_res, r_res);
569
570 if(!isValidRect(l_res) && !isValidRect(r_res)) {
571 mCurrentFrame.drop[i] = true;
572 mCurrentFrame.dropCount++;
573 } else {
574 /* Reset frame ROI when any layer which needs scaling also needs ROI
575 * cropping */
576 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
577 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
578 mCurrentFrame.dropCount = 0;
579 return false;
580 }
581
582 if (layer->blending == HWC_BLENDING_NONE) {
583 visibleRectL = deductRect(visibleRectL, l_res);
584 visibleRectR = deductRect(visibleRectR, r_res);
585 }
586 }
587 }
588 return true;
589}
590/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
591 * are updating. If DirtyRegion is applicable, calculate it by accounting all
592 * the changing layer's dirtyRegion. */
593void MDPCompSplit::generateROI(hwc_context_t *ctx,
594 hwc_display_contents_1_t* list) {
595 if(!canPartialUpdate(ctx, list))
596 return;
597
598 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
599 int lSplit = getLeftSplit(ctx, mDpy);
600
601 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
602 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
603
604 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
605 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
606
607 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
608 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
609
610 for(int index = 0; index < numAppLayers; index++ ) {
611 hwc_layer_1_t* layer = &list->hwLayers[index];
612 if ((mCachedFrame.hnd[index] != layer->handle) ||
613 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700614 hwc_rect_t dst = layer->displayFrame;
615 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800616
617#ifdef QCOM_BSP
618 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700619 {
620 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
621 int x_off = dst.left - src.left;
622 int y_off = dst.top - src.top;
623 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
624 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800625#endif
626
627 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
628 if(isValidRect(l_dst))
629 l_roi = getUnion(l_roi, l_dst);
630
631 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
632 if(isValidRect(r_dst))
633 r_roi = getUnion(r_roi, r_dst);
634 }
635 }
636
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700637 /* For panels that cannot accept commands in both the interfaces, we cannot
638 * send two ROI's (for each half). We merge them into single ROI and split
639 * them across lSplit for MDP mixer use. The ROI's will be merged again
640 * finally before udpating the panel in the driver. */
641 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
642 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
643 l_roi = getIntersection(temp_roi, l_frame);
644 r_roi = getIntersection(temp_roi, r_frame);
645 }
646
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800647 /* No layer is updating. Still SF wants a refresh. */
648 if(!isValidRect(l_roi) && !isValidRect(r_roi))
649 return;
650
651 l_roi = getSanitizeROI(l_roi, l_frame);
652 r_roi = getSanitizeROI(r_roi, r_frame);
653
654 ctx->listStats[mDpy].lRoi = l_roi;
655 ctx->listStats[mDpy].rRoi = r_roi;
656
657 if(!validateAndApplyROI(ctx, list))
658 resetROI(ctx, mDpy);
659
660 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
661 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
662 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
663 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
664 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
665 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700666}
667
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800668/* Checks for conditions where all the layers marked for MDP comp cannot be
669 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800670bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800671 hwc_display_contents_1_t* list){
672
Saurabh Shahaa236822013-04-24 18:07:26 -0700673 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800674 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800675
Ramkumar Radhakrishnanba713382013-08-30 18:41:07 -0700676 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700677 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
678 return false;
679 }
680
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800681 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700682 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
683 __FUNCTION__,
684 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800685 return false;
686 }
687
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800688 if(mDpy > HWC_DISPLAY_PRIMARY && (priDispW > MAX_DISPLAY_DIM) &&
689 (ctx->dpyAttr[mDpy].xres < MAX_DISPLAY_DIM)) {
690 // Disable MDP comp on Secondary when the primary is highres panel and
691 // the secondary is a normal 1080p, because, MDP comp on secondary under
692 // in such usecase, decimation gets used for downscale and there will be
693 // a quality mismatch when there will be a fallback to GPU comp
694 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
695 __FUNCTION__);
696 return false;
697 }
698
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800699 // check for action safe flag and downscale mode which requires scaling.
700 if(ctx->dpyAttr[mDpy].mActionSafePresent
701 || ctx->dpyAttr[mDpy].mDownScaleMode) {
702 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
703 return false;
704 }
705
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800706 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800707 hwc_layer_1_t* layer = &list->hwLayers[i];
708 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800709
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700710 if(isYuvBuffer(hnd) && has90Transform(layer)) {
711 if(!canUseRotator(ctx, mDpy)) {
712 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
713 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700714 return false;
715 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800716 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530717
718 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
719 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700720 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530721 if(qdutils::MDPVersion::getInstance().is8x26() &&
722 (ctx->dpyAttr[mDpy].xres > 1024) &&
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700723 (transform & HWC_TRANSFORM_FLIP_H) &&
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530724 (!isYuvBuffer(hnd)))
725 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800726 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700727
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700728 if(ctx->mAD->isDoable()) {
729 return false;
730 }
731
Saurabh Shahaa236822013-04-24 18:07:26 -0700732 //If all above hard conditions are met we can do full or partial MDP comp.
733 bool ret = false;
734 if(fullMDPComp(ctx, list)) {
735 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700736 } else if(fullMDPCompWithPTOR(ctx, list)) {
737 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700738 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700739 ret = true;
740 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530741
Saurabh Shahaa236822013-04-24 18:07:26 -0700742 return ret;
743}
744
745bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700746
747 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
748 return false;
749
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700750 //Will benefit presentation / secondary-only layer.
751 if((mDpy > HWC_DISPLAY_PRIMARY) &&
752 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
753 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
754 return false;
755 }
756
757 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
758 for(int i = 0; i < numAppLayers; i++) {
759 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700760 if(not mCurrentFrame.drop[i] and
761 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700762 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
763 return false;
764 }
765 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800766
Saurabh Shahaa236822013-04-24 18:07:26 -0700767 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700768 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
769 sizeof(mCurrentFrame.isFBComposed));
770 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
771 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700772
radhakrishnac9a67412013-09-25 17:40:42 +0530773 if(sEnable4k2kYUVSplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800774 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530775 }
776
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800777 if(!postHeuristicsHandling(ctx, list)) {
778 ALOGD_IF(isDebug(), "post heuristic handling failed");
779 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700780 return false;
781 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700782 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
783 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700784 return true;
785}
786
Sushil Chauhandefd3522014-05-13 18:17:12 -0700787/* Full MDP Composition with Peripheral Tiny Overlap Removal.
788 * MDP bandwidth limitations can be avoided, if the overlap region
789 * covered by the smallest layer at a higher z-order, gets composed
790 * by Copybit on a render buffer, which can be queued to MDP.
791 */
792bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
793 hwc_display_contents_1_t* list) {
794
795 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
796 const int stagesForMDP = min(sMaxPipesPerMixer,
797 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
798
799 // Hard checks where we cannot use this mode
800 if (mDpy || !ctx->mCopyBit[mDpy] || isDisplaySplit(ctx, mDpy)) {
801 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
802 return false;
803 }
804
805 // Frame level checks
806 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
807 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
808 isSecurePresent(ctx, mDpy)) {
809 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
810 return false;
811 }
812
813 // Find overlap index
814 int overlapIdx = numAppLayers - 1;
815 uint32_t layerPixelCount, minPixelCount = 0;
816 for (int i = numAppLayers - 1; i >= 0; i--) {
817 hwc_layer_1_t* layer = &list->hwLayers[i];
818 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
819 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
820 if (!minPixelCount || (layerPixelCount < minPixelCount)) {
821 minPixelCount = layerPixelCount;
822 overlapIdx = i;
823 }
824 }
825
826 // No overlap
827 if (!overlapIdx)
828 return false;
829
830 /* We cannot use this composition mode, if:
831 1. A below layer needs scaling.
832 2. Overlap is not peripheral to display.
833 3. Overlap or a below layer has 90 degree transform.
834 4. Intersection of Overlap layer with a below layer is not valid.
835 5. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
836 */
837
838 hwc_rect_t overlap = list->hwLayers[overlapIdx].displayFrame;
839 if (!isPeripheral(overlap, ctx->mViewFrame[mDpy]))
840 return false;
841
842 if ((3 * (overlap.right - overlap.left) * (overlap.bottom - overlap.top)) >
843 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres))
844 return false;
845
846 for (int i = overlapIdx; i >= 0; i--) {
847 hwc_layer_1_t* layer = &list->hwLayers[i];
848 hwc_rect_t dispFrame = layer->displayFrame;
849
850 if (has90Transform(layer))
851 return false;
852
853 if (i < overlapIdx) {
854 if (needsScaling(layer) ||
855 !isValidRect(getIntersection(dispFrame, overlap)))
856 return false;
857 }
858 }
859
860 mOverlapIndex = overlapIdx;
861 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list, overlapIdx)) {
862 ALOGD_IF(isDebug(), "%s: Overlap prepare failed!",__FUNCTION__);
863 mOverlapIndex = -1;
864 return false;
865 }
866
867 hwc_rect_t sourceCrop[overlapIdx];
868 hwc_rect_t displayFrame[overlapIdx];
869
870 // Remove overlap from crop & displayFrame of below layers
871 for (int i = 0; i < overlapIdx; i++) {
872 hwc_layer_1_t* layer = &list->hwLayers[i];
873 displayFrame[i] = layer->displayFrame;
874 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
875
876 // Update layer attributes
877 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
878 hwc_rect_t destRect = deductRect(layer->displayFrame, overlap);
879 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
880 layer->transform);
881
882 layer->sourceCropf.left = (float)srcCrop.left;
883 layer->sourceCropf.top = (float)srcCrop.top;
884 layer->sourceCropf.right = (float)srcCrop.right;
885 layer->sourceCropf.bottom = (float)srcCrop.bottom;
886 }
887
888 mCurrentFrame.mdpCount = numAppLayers;
889 mCurrentFrame.fbCount = 0;
890 mCurrentFrame.fbZ = -1;
891
892 for (int j = 0; j < numAppLayers; j++)
893 mCurrentFrame.isFBComposed[j] = false;
894
895 bool result = postHeuristicsHandling(ctx, list);
896
897 // Restore layer attributes
898 for (int i = 0; i < overlapIdx; i++) {
899 hwc_layer_1_t* layer = &list->hwLayers[i];
900 layer->displayFrame = displayFrame[i];
901 layer->sourceCropf.left = (float)sourceCrop[i].left;
902 layer->sourceCropf.top = (float)sourceCrop[i].top;
903 layer->sourceCropf.right = (float)sourceCrop[i].right;
904 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
905 }
906
907 if (!result) {
908 mOverlapIndex = -1;
909 reset(ctx);
910 }
911
912 ALOGD_IF(isDebug(), "%s: Postheuristics %s!, Overlap index = %d",
913 __FUNCTION__, (result ? "successful" : "failed"), mOverlapIndex);
914 return result;
915}
916
Saurabh Shahaa236822013-04-24 18:07:26 -0700917bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
918{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700919 if(!sEnableMixedMode) {
920 //Mixed mode is disabled. No need to even try caching.
921 return false;
922 }
923
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700924 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800925 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800926 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800927 cacheBasedComp(ctx, list);
928 } else {
929 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800930 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700931 }
932
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700933 return ret;
934}
935
936bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
937 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700938 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
939 return false;
940
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700941 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -0700942 mCurrentFrame.reset(numAppLayers);
943 updateLayerCache(ctx, list);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700944
945 //If an MDP marked layer is unsupported cannot do partial MDP Comp
946 for(int i = 0; i < numAppLayers; i++) {
947 if(!mCurrentFrame.isFBComposed[i]) {
948 hwc_layer_1_t* layer = &list->hwLayers[i];
949 if(not isSupportedForMDPComp(ctx, layer)) {
950 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
951 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800952 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700953 return false;
954 }
955 }
956 }
957
Saurabh Shah90b7b9b2013-09-12 16:36:08 -0700958 updateYUV(ctx, list, false /*secure only*/);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +0530959 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700960 if(!ret) {
961 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800962 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700963 return false;
964 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700965
966 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700967
radhakrishnac9a67412013-09-25 17:40:42 +0530968 if(sEnable4k2kYUVSplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800969 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530970 }
971
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700972 //Will benefit cases where a video has non-updating background.
973 if((mDpy > HWC_DISPLAY_PRIMARY) and
974 (mdpCount > MAX_SEC_LAYERS)) {
975 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800976 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700977 return false;
978 }
979
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800980 if(!postHeuristicsHandling(ctx, list)) {
981 ALOGD_IF(isDebug(), "post heuristic handling failed");
982 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700983 return false;
984 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700985 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
986 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700987
Saurabh Shahaa236822013-04-24 18:07:26 -0700988 return true;
989}
990
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800991bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -0800992 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700993 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
994 return false;
995
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -0800996 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800997 return false;
998 }
999
Saurabh Shahb772ae32013-11-18 15:40:02 -08001000 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001001 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1002 const int stagesForMDP = min(sMaxPipesPerMixer,
1003 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001004
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001005 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1006 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1007 int lastMDPSupportedIndex = numAppLayers;
1008 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001009
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001010 //Find the minimum MDP batch size
1011 for(int i = 0; i < numAppLayers;i++) {
1012 if(mCurrentFrame.drop[i]) {
1013 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001014 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001015 }
1016 hwc_layer_1_t* layer = &list->hwLayers[i];
1017 if(not isSupportedForMDPComp(ctx, layer)) {
1018 lastMDPSupportedIndex = i;
1019 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1020 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001021 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001022 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001023 }
1024
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001025 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1026 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1027 mCurrentFrame.dropCount);
1028
1029 //Start at a point where the fb batch should at least have 2 layers, for
1030 //this mode to be justified.
1031 while(fbBatchSize < 2) {
1032 ++fbBatchSize;
1033 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001034 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001035
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001036 //If there are no layers for MDP, this mode doesnt make sense.
1037 if(mdpBatchSize < 1) {
1038 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1039 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001040 return false;
1041 }
1042
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001043 mCurrentFrame.reset(numAppLayers);
1044
1045 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1046 while(mdpBatchSize > 0) {
1047 //Mark layers for MDP comp
1048 int mdpBatchLeft = mdpBatchSize;
1049 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1050 if(mCurrentFrame.drop[i]) {
1051 continue;
1052 }
1053 mCurrentFrame.isFBComposed[i] = false;
1054 --mdpBatchLeft;
1055 }
1056
1057 mCurrentFrame.fbZ = mdpBatchSize;
1058 mCurrentFrame.fbCount = fbBatchSize;
1059 mCurrentFrame.mdpCount = mdpBatchSize;
1060
1061 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1062 __FUNCTION__, mdpBatchSize, fbBatchSize,
1063 mCurrentFrame.dropCount);
1064
1065 if(postHeuristicsHandling(ctx, list)) {
1066 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001067 __FUNCTION__);
1068 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1069 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001070 return true;
1071 }
1072
1073 reset(ctx);
1074 --mdpBatchSize;
1075 ++fbBatchSize;
1076 }
1077
1078 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001079}
1080
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001081bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301082 if(mDpy or isSecurePresent(ctx, mDpy) or
1083 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001084 return false;
1085 }
1086 return true;
1087}
1088
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001089bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1090 hwc_display_contents_1_t* list){
1091 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1092 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1093 mDpy ) {
1094 return false;
1095 }
1096 return true;
1097}
1098
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001099bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1100 hwc_display_contents_1_t* list) {
1101 const bool secureOnly = true;
1102 return videoOnlyComp(ctx, list, not secureOnly) or
1103 videoOnlyComp(ctx, list, secureOnly);
1104}
1105
1106bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001107 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001108 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1109 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001110 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001111
Saurabh Shahaa236822013-04-24 18:07:26 -07001112 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001113 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001114 updateYUV(ctx, list, secureOnly);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001115 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001116
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001117 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1118 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001119 return false;
1120 }
1121
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001122 /* Bail out if we are processing only secured video layers
1123 * and we dont have any */
1124 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001125 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001126 return false;
1127 }
1128
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001129 if(mCurrentFrame.fbCount)
1130 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001131
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001132 if(sEnable4k2kYUVSplit){
1133 adjustForSourceSplit(ctx, list);
1134 }
1135
1136 if(!postHeuristicsHandling(ctx, list)) {
1137 ALOGD_IF(isDebug(), "post heuristic handling failed");
1138 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001139 return false;
1140 }
1141
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001142 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1143 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001144 return true;
1145}
1146
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001147/* Checks for conditions where YUV layers cannot be bypassed */
1148bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001149 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001150 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001151 return false;
1152 }
1153
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001154 if(layer->transform & HWC_TRANSFORM_ROT_90 && !canUseRotator(ctx,mDpy)) {
1155 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1156 return false;
1157 }
1158
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001159 if(isSecuring(ctx, layer)) {
1160 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1161 return false;
1162 }
1163
Saurabh Shah4fdde762013-04-30 18:47:33 -07001164 if(!isValidDimension(ctx, layer)) {
1165 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1166 __FUNCTION__);
1167 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001168 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001169
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001170 if(layer->planeAlpha < 0xFF) {
1171 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1172 in video only mode",
1173 __FUNCTION__);
1174 return false;
1175 }
1176
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001177 return true;
1178}
1179
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301180/* starts at fromIndex and check for each layer to find
1181 * if it it has overlapping with any Updating layer above it in zorder
1182 * till the end of the batch. returns true if it finds any intersection */
1183bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1184 int fromIndex, int toIndex) {
1185 for(int i = fromIndex; i < toIndex; i++) {
1186 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1187 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1188 return false;
1189 }
1190 }
1191 }
1192 return true;
1193}
1194
1195/* Checks if given layer at targetLayerIndex has any
1196 * intersection with all the updating layers in beween
1197 * fromIndex and toIndex. Returns true if it finds intersectiion */
1198bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1199 int fromIndex, int toIndex, int targetLayerIndex) {
1200 for(int i = fromIndex; i <= toIndex; i++) {
1201 if(!mCurrentFrame.isFBComposed[i]) {
1202 if(areLayersIntersecting(&list->hwLayers[i],
1203 &list->hwLayers[targetLayerIndex])) {
1204 return true;
1205 }
1206 }
1207 }
1208 return false;
1209}
1210
1211int MDPComp::getBatch(hwc_display_contents_1_t* list,
1212 int& maxBatchStart, int& maxBatchEnd,
1213 int& maxBatchCount) {
1214 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301215 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001216 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301217 while (i < mCurrentFrame.layerCount) {
1218 int batchCount = 0;
1219 int batchStart = i;
1220 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001221 /* Adjust batch Z order with the dropped layers so far */
1222 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301223 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301224 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301225 while(i < mCurrentFrame.layerCount) {
1226 if(!mCurrentFrame.isFBComposed[i]) {
1227 if(!batchCount) {
1228 i++;
1229 break;
1230 }
1231 updatingLayersAbove++;
1232 i++;
1233 continue;
1234 } else {
1235 if(mCurrentFrame.drop[i]) {
1236 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001237 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301238 continue;
1239 } else if(updatingLayersAbove <= 0) {
1240 batchCount++;
1241 batchEnd = i;
1242 i++;
1243 continue;
1244 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1245
1246 // We have a valid updating layer already. If layer-i not
1247 // have overlapping with all updating layers in between
1248 // batch-start and i, then we can add layer i to batch.
1249 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1250 batchCount++;
1251 batchEnd = i;
1252 i++;
1253 continue;
1254 } else if(canPushBatchToTop(list, batchStart, i)) {
1255 //If All the non-updating layers with in this batch
1256 //does not have intersection with the updating layers
1257 //above in z-order, then we can safely move the batch to
1258 //higher z-order. Increment fbZ as it is moving up.
1259 if( firstZReverseIndex < 0) {
1260 firstZReverseIndex = i;
1261 }
1262 batchCount++;
1263 batchEnd = i;
1264 fbZ += updatingLayersAbove;
1265 i++;
1266 updatingLayersAbove = 0;
1267 continue;
1268 } else {
1269 //both failed.start the loop again from here.
1270 if(firstZReverseIndex >= 0) {
1271 i = firstZReverseIndex;
1272 }
1273 break;
1274 }
1275 }
1276 }
1277 }
1278 if(batchCount > maxBatchCount) {
1279 maxBatchCount = batchCount;
1280 maxBatchStart = batchStart;
1281 maxBatchEnd = batchEnd;
1282 fbZOrder = fbZ;
1283 }
1284 }
1285 return fbZOrder;
1286}
1287
1288bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1289 hwc_display_contents_1_t* list) {
1290 /* Idea is to keep as many non-updating(cached) layers in FB and
1291 * send rest of them through MDP. This is done in 2 steps.
1292 * 1. Find the maximum contiguous batch of non-updating layers.
1293 * 2. See if we can improve this batch size for caching by adding
1294 * opaque layers around the batch, if they don't have
1295 * any overlapping with the updating layers in between.
1296 * NEVER mark an updating layer for caching.
1297 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001298
1299 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001300 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001301 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301302 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001303
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001304 /* Nothing is cached. No batching needed */
1305 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001306 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001307 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001308
1309 /* No MDP comp layers, try to use other comp modes */
1310 if(mCurrentFrame.mdpCount == 0) {
1311 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001312 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001313
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301314 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001315
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301316 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001317 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001318 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001319 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301320 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001321 if(!mCurrentFrame.drop[i]){
1322 //If an unsupported layer is being attempted to
1323 //be pulled out we should fail
1324 if(not isSupportedForMDPComp(ctx, layer)) {
1325 return false;
1326 }
1327 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001328 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001329 }
1330 }
1331
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301332 // update the frame data
1333 mCurrentFrame.fbZ = fbZ;
1334 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001335 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001336 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001337
1338 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301339 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001340
1341 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001342}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001343
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001344void MDPComp::updateLayerCache(hwc_context_t* ctx,
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001345 hwc_display_contents_1_t* list) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001346 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001347 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001348
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001349 for(int i = 0; i < numAppLayers; i++) {
1350 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001351 if(!mCurrentFrame.drop[i])
1352 fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001353 mCurrentFrame.isFBComposed[i] = true;
1354 } else {
Saurabh Shahaa236822013-04-24 18:07:26 -07001355 mCurrentFrame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001356 }
1357 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001358
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001359 mCurrentFrame.fbCount = fbCount;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001360 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
1361 - mCurrentFrame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001362
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001363 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d"
1364 ,__FUNCTION__, mCurrentFrame.mdpCount, mCurrentFrame.fbCount,
1365 mCurrentFrame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001366}
1367
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001368void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
1369 bool secureOnly) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001370 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1371 for(int index = 0;index < nYuvCount; index++){
1372 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1373 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1374
1375 if(!isYUVDoable(ctx, layer)) {
1376 if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
1377 mCurrentFrame.isFBComposed[nYuvIndex] = true;
1378 mCurrentFrame.fbCount++;
1379 }
1380 } else {
1381 if(mCurrentFrame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001382 private_handle_t *hnd = (private_handle_t *)layer->handle;
1383 if(!secureOnly || isSecureBuffer(hnd)) {
1384 mCurrentFrame.isFBComposed[nYuvIndex] = false;
1385 mCurrentFrame.fbCount--;
1386 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001387 }
1388 }
1389 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001390
1391 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001392 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1393 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001394 mCurrentFrame.fbCount);
1395}
1396
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001397hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1398 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001399 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001400
1401 /* Update only the region of FB needed for composition */
1402 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1403 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1404 hwc_layer_1_t* layer = &list->hwLayers[i];
1405 hwc_rect_t dst = layer->displayFrame;
1406 fbRect = getUnion(fbRect, dst);
1407 }
1408 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001409 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001410 return fbRect;
1411}
1412
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001413bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1414 hwc_display_contents_1_t* list) {
1415
1416 //Capability checks
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301417 if(!resourceCheck()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001418 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1419 return false;
1420 }
1421
1422 //Limitations checks
1423 if(!hwLimitationsCheck(ctx, list)) {
1424 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1425 return false;
1426 }
1427
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001428 //Configure framebuffer first if applicable
1429 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001430 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001431 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1432 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001433 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1434 __FUNCTION__);
1435 return false;
1436 }
1437 }
1438
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001439 mCurrentFrame.map();
1440
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001441 if(!allocLayerPipes(ctx, list)) {
1442 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001443 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001444 }
1445
1446 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001447 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001448 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001449 int mdpIndex = mCurrentFrame.layerToMDP[index];
1450 hwc_layer_1_t* layer = &list->hwLayers[index];
1451
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301452 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1453 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1454 mdpNextZOrder++;
1455 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001456 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1457 cur_pipe->zOrder = mdpNextZOrder++;
1458
radhakrishnac9a67412013-09-25 17:40:42 +05301459 private_handle_t *hnd = (private_handle_t *)layer->handle;
1460 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
1461 if(configure4k2kYuv(ctx, layer,
1462 mCurrentFrame.mdpToLayer[mdpIndex])
1463 != 0 ){
1464 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1465 for layer %d",__FUNCTION__, index);
1466 return false;
1467 }
1468 else{
1469 mdpNextZOrder++;
1470 }
1471 continue;
1472 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001473 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1474 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301475 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001476 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001477 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001478 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001479 }
1480
Saurabh Shaha36be922013-12-16 18:18:39 -08001481 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1482 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1483 ,__FUNCTION__, mDpy);
1484 return false;
1485 }
1486
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001487 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001488 return true;
1489}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001490
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301491bool MDPComp::resourceCheck() {
Saurabh Shah173f4242013-11-20 09:50:12 -08001492 const bool fbUsed = mCurrentFrame.fbCount;
1493 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1494 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1495 return false;
1496 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001497 return true;
1498}
1499
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301500bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1501 hwc_display_contents_1_t* list) {
1502
1503 //A-family hw limitation:
1504 //If a layer need alpha scaling, MDP can not support.
1505 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1506 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1507 if(!mCurrentFrame.isFBComposed[i] &&
1508 isAlphaScaled( &list->hwLayers[i])) {
1509 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1510 return false;
1511 }
1512 }
1513 }
1514
1515 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1516 //If multiple layers requires downscaling and also they are overlapping
1517 //fall back to GPU since MDSS can not handle it.
1518 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1519 qdutils::MDPVersion::getInstance().is8x26()) {
1520 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1521 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1522 if(!mCurrentFrame.isFBComposed[i] &&
1523 isDownscaleRequired(botLayer)) {
1524 //if layer-i is marked for MDP and needs downscaling
1525 //check if any MDP layer on top of i & overlaps with layer-i
1526 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1527 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1528 if(!mCurrentFrame.isFBComposed[j] &&
1529 isDownscaleRequired(topLayer)) {
1530 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1531 topLayer->displayFrame);
1532 if(isValidRect(r))
1533 return false;
1534 }
1535 }
1536 }
1537 }
1538 }
1539 return true;
1540}
1541
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001542int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001543 int ret = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -07001544 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001545 char property[PROPERTY_VALUE_MAX];
1546
1547 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1548 int currentFlags = atoi(property);
1549 if(currentFlags != sSimulationFlags) {
1550 sSimulationFlags = currentFlags;
1551 ALOGE("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1552 sSimulationFlags, sSimulationFlags);
1553 }
1554 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001555 mOverlapIndex = -1;
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001556
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301557 //Do not cache the information for next draw cycle.
1558 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1559 ALOGI("%s: Unsupported layer count for mdp composition",
1560 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001561 mCachedFrame.reset();
1562 return -1;
1563 }
1564
Saurabh Shahb39f8152013-08-22 10:21:44 -07001565 //reset old data
1566 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001567 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1568 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301569
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001570 // Detect the start of animation and fall back to GPU only once to cache
1571 // all the layers in FB and display FB content untill animation completes.
1572 if(ctx->listStats[mDpy].isDisplayAnimating) {
1573 mCurrentFrame.needsRedraw = false;
1574 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1575 mCurrentFrame.needsRedraw = true;
1576 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1577 }
1578 setMDPCompLayerFlags(ctx, list);
1579 mCachedFrame.updateCounts(mCurrentFrame);
1580 ret = -1;
1581 return ret;
1582 } else {
1583 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1584 }
1585
Saurabh Shahb39f8152013-08-22 10:21:44 -07001586 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001587 if(isFrameDoable(ctx)) {
1588 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001589
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001590 if(tryFullFrame(ctx, list) || tryVideoOnly(ctx, list)) {
1591 setMDPCompLayerFlags(ctx, list);
1592 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001593 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001594 reset(ctx);
1595 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1596 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001597 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001598 }
1599 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001600 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1601 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001602 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001603 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001604
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001605 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001606 ALOGD("GEOMETRY change: %d",
1607 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001608 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001609 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001610 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001611 }
1612
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001613 mCachedFrame.cacheAll(list);
1614 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001615 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001616}
1617
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001618bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301619
1620 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301621 int mdpIndex = mCurrentFrame.layerToMDP[index];
1622 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1623 info.pipeInfo = new MdpYUVPipeInfo;
1624 info.rot = NULL;
1625 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301626
1627 pipe_info.lIndex = ovutils::OV_INVALID;
1628 pipe_info.rIndex = ovutils::OV_INVALID;
1629
Saurabh Shahc62f3982014-03-05 14:28:26 -08001630 Overlay::PipeSpecs pipeSpecs;
1631 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1632 pipeSpecs.needsScaling = true;
1633 pipeSpecs.dpy = mDpy;
1634 pipeSpecs.fb = false;
1635
1636 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301637 if(pipe_info.lIndex == ovutils::OV_INVALID){
1638 bRet = false;
1639 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1640 __FUNCTION__);
1641 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001642 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301643 if(pipe_info.rIndex == ovutils::OV_INVALID){
1644 bRet = false;
1645 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1646 __FUNCTION__);
1647 }
1648 return bRet;
1649}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001650
1651int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1652 int fd = -1;
1653 if (mOverlapIndex != -1) {
1654 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list, mOverlapIndex);
1655 if (fd < 0) {
1656 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
1657 mOverlapIndex = -1;
1658 }
1659 }
1660 return fd;
1661}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001662//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001663
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001664void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001665 hwc_display_contents_1_t*) {
radhakrishnac9a67412013-09-25 17:40:42 +05301666 //As we split 4kx2k yuv layer and program to 2 VG pipes
1667 //(if available) increase mdpcount accordingly
1668 mCurrentFrame.mdpCount += ctx->listStats[mDpy].yuv4k2kCount;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001669
1670 //If 4k2k Yuv layer split is possible, and if
1671 //fbz is above 4k2k layer, increment fb zorder by 1
1672 //as we split 4k2k layer and increment zorder for right half
1673 //of the layer
1674 if(mCurrentFrame.fbZ >= 0) {
1675 int n4k2kYuvCount = ctx->listStats[mDpy].yuv4k2kCount;
1676 for(int index = 0; index < n4k2kYuvCount; index++){
1677 int n4k2kYuvIndex =
1678 ctx->listStats[mDpy].yuv4k2kIndices[index];
Dileep Kumar Reddi4cff9282014-04-01 12:57:08 +05301679 if(mCurrentFrame.fbZ >= n4k2kYuvIndex){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001680 mCurrentFrame.fbZ += 1;
1681 }
1682 }
1683 }
radhakrishnac9a67412013-09-25 17:40:42 +05301684}
1685
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001686/*
1687 * Configures pipe(s) for MDP composition
1688 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001689int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001690 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001691 MdpPipeInfoNonSplit& mdp_info =
1692 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001693 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1694 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1695 eIsFg isFg = IS_FG_OFF;
1696 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001697
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001698 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1699 __FUNCTION__, layer, zOrder, dest);
1700
Saurabh Shah88e4d272013-09-03 13:31:29 -07001701 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001702 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001703}
1704
Saurabh Shah88e4d272013-09-03 13:31:29 -07001705bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001706 hwc_display_contents_1_t* list) {
1707 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001708
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001709 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001710
Jeykumar Sankarancf537002013-01-21 21:19:15 -08001711 hwc_layer_1_t* layer = &list->hwLayers[index];
1712 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05301713 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001714 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301715 continue;
1716 }
1717 }
1718
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001719 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001720 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001721 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08001722 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001723 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001724
Saurabh Shahc62f3982014-03-05 14:28:26 -08001725 Overlay::PipeSpecs pipeSpecs;
1726 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1727 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1728 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
1729 (qdutils::MDPVersion::getInstance().is8x26() and
1730 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
1731 pipeSpecs.dpy = mDpy;
1732 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08001733 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001734
Saurabh Shahc62f3982014-03-05 14:28:26 -08001735 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
1736
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001737 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001738 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001739 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001740 }
1741 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001742 return true;
1743}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001744
radhakrishnac9a67412013-09-25 17:40:42 +05301745int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1746 PipeLayerPair& PipeLayerPair) {
1747 MdpYUVPipeInfo& mdp_info =
1748 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
1749 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1750 eIsFg isFg = IS_FG_OFF;
1751 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1752 eDest lDest = mdp_info.lIndex;
1753 eDest rDest = mdp_info.rIndex;
1754
1755 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
1756 lDest, rDest, &PipeLayerPair.rot);
1757}
1758
Saurabh Shah88e4d272013-09-03 13:31:29 -07001759bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001760
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001761 if(!isEnabled()) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001762 ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
1763 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -08001764 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001765
1766 if(!ctx || !list) {
1767 ALOGE("%s: invalid contxt or list",__FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001768 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001769 }
1770
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05301771 if(ctx->listStats[mDpy].numAppLayers > MAX_NUM_APP_LAYERS) {
1772 ALOGD_IF(isDebug(),"%s: Exceeding max layer count", __FUNCTION__);
1773 return true;
1774 }
1775
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08001776 // Set the Handle timeout to true for MDP or MIXED composition.
1777 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
1778 sHandleTimeout = true;
1779 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001780
1781 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001782 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001783
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001784 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1785 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001786 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001787 if(mCurrentFrame.isFBComposed[i]) continue;
1788
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07001789 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08001790 private_handle_t *hnd = (private_handle_t *)layer->handle;
1791 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07001792 if (!(layer->flags & HWC_COLOR_FILL)) {
1793 ALOGE("%s handle null", __FUNCTION__);
1794 return false;
1795 }
1796 // No PLAY for Color layer
1797 layerProp[i].mFlags &= ~HWC_MDPCOMP;
1798 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001799 }
1800
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001801 int mdpIndex = mCurrentFrame.layerToMDP[i];
1802
radhakrishnac9a67412013-09-25 17:40:42 +05301803 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
1804 {
1805 MdpYUVPipeInfo& pipe_info =
1806 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1807 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1808 ovutils::eDest indexL = pipe_info.lIndex;
1809 ovutils::eDest indexR = pipe_info.rIndex;
1810 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301811 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05301812 if(rot) {
1813 rot->queueBuffer(fd, offset);
1814 fd = rot->getDstMemId();
1815 offset = rot->getDstOffset();
1816 }
1817 if(indexL != ovutils::OV_INVALID) {
1818 ovutils::eDest destL = (ovutils::eDest)indexL;
1819 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1820 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
1821 if (!ov.queueBuffer(fd, offset, destL)) {
1822 ALOGE("%s: queueBuffer failed for display:%d",
1823 __FUNCTION__, mDpy);
1824 return false;
1825 }
1826 }
1827
1828 if(indexR != ovutils::OV_INVALID) {
1829 ovutils::eDest destR = (ovutils::eDest)indexR;
1830 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1831 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
1832 if (!ov.queueBuffer(fd, offset, destR)) {
1833 ALOGE("%s: queueBuffer failed for display:%d",
1834 __FUNCTION__, mDpy);
1835 return false;
1836 }
1837 }
1838 }
1839 else{
1840 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07001841 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301842 ovutils::eDest dest = pipe_info.index;
1843 if(dest == ovutils::OV_INVALID) {
1844 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001845 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05301846 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001847
radhakrishnac9a67412013-09-25 17:40:42 +05301848 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1849 continue;
1850 }
1851
Sushil Chauhandefd3522014-05-13 18:17:12 -07001852 if (!mDpy && (i == mOverlapIndex)) {
1853 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1854 }
1855
radhakrishnac9a67412013-09-25 17:40:42 +05301856 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1857 using pipe: %d", __FUNCTION__, layer,
1858 hnd, dest );
1859
1860 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301861 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05301862
1863 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1864 if(rot) {
1865 if(!rot->queueBuffer(fd, offset))
1866 return false;
1867 fd = rot->getDstMemId();
1868 offset = rot->getDstOffset();
1869 }
1870
1871 if (!ov.queueBuffer(fd, offset, dest)) {
1872 ALOGE("%s: queueBuffer failed for display:%d ",
1873 __FUNCTION__, mDpy);
1874 return false;
1875 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001876 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001877
1878 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001879 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001880 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001881}
1882
Saurabh Shah88e4d272013-09-03 13:31:29 -07001883//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001884
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001885void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05301886 hwc_display_contents_1_t* list){
1887 //if 4kx2k yuv layer is totally present in either in left half
1888 //or right half then try splitting the yuv layer to avoid decimation
1889 int n4k2kYuvCount = ctx->listStats[mDpy].yuv4k2kCount;
1890 const int lSplit = getLeftSplit(ctx, mDpy);
1891 for(int index = 0; index < n4k2kYuvCount; index++){
1892 int n4k2kYuvIndex = ctx->listStats[mDpy].yuv4k2kIndices[index];
1893 hwc_layer_1_t* layer = &list->hwLayers[n4k2kYuvIndex];
1894 hwc_rect_t dst = layer->displayFrame;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001895 if((dst.left > lSplit) || (dst.right < lSplit)) {
radhakrishnac9a67412013-09-25 17:40:42 +05301896 mCurrentFrame.mdpCount += 1;
1897 }
Dileep Kumar Reddi4cff9282014-04-01 12:57:08 +05301898 if(mCurrentFrame.fbZ >= n4k2kYuvIndex){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001899 mCurrentFrame.fbZ += 1;
1900 }
radhakrishnac9a67412013-09-25 17:40:42 +05301901 }
1902}
1903
Saurabh Shah88e4d272013-09-03 13:31:29 -07001904bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08001905 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001906
Saurabh Shahc62f3982014-03-05 14:28:26 -08001907 const int lSplit = getLeftSplit(ctx, mDpy);
1908 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001909 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001910 pipe_info.lIndex = ovutils::OV_INVALID;
1911 pipe_info.rIndex = ovutils::OV_INVALID;
1912
Saurabh Shahc62f3982014-03-05 14:28:26 -08001913 Overlay::PipeSpecs pipeSpecs;
1914 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1915 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1916 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
1917 pipeSpecs.dpy = mDpy;
1918 pipeSpecs.mixer = Overlay::MIXER_LEFT;
1919 pipeSpecs.fb = false;
1920
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001921 // Acquire pipe only for the updating half
1922 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
1923 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
1924
1925 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001926 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001927 if(pipe_info.lIndex == ovutils::OV_INVALID)
1928 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001929 }
1930
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001931 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001932 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
1933 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001934 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001935 return false;
1936 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001937
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001938 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001939}
1940
Saurabh Shah88e4d272013-09-03 13:31:29 -07001941bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001942 hwc_display_contents_1_t* list) {
1943 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001944
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001945 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001946
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001947 hwc_layer_1_t* layer = &list->hwLayers[index];
1948 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05301949 hwc_rect_t dst = layer->displayFrame;
1950 const int lSplit = getLeftSplit(ctx, mDpy);
1951 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
1952 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001953 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301954 continue;
1955 }
1956 }
1957 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07001958 int mdpIndex = mCurrentFrame.layerToMDP[index];
1959 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001960 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07001961 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001962 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001963
Saurabh Shahc62f3982014-03-05 14:28:26 -08001964 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
1965 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
1966 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001967 return false;
1968 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001969 }
1970 return true;
1971}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001972
radhakrishnac9a67412013-09-25 17:40:42 +05301973int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1974 PipeLayerPair& PipeLayerPair) {
1975 const int lSplit = getLeftSplit(ctx, mDpy);
1976 hwc_rect_t dst = layer->displayFrame;
1977 if((dst.left > lSplit)||(dst.right < lSplit)){
1978 MdpYUVPipeInfo& mdp_info =
1979 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
1980 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1981 eIsFg isFg = IS_FG_OFF;
1982 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1983 eDest lDest = mdp_info.lIndex;
1984 eDest rDest = mdp_info.rIndex;
1985
1986 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
1987 lDest, rDest, &PipeLayerPair.rot);
1988 }
1989 else{
1990 return configure(ctx, layer, PipeLayerPair);
1991 }
1992}
1993
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001994/*
1995 * Configures pipe(s) for MDP composition
1996 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001997int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07001998 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001999 MdpPipeInfoSplit& mdp_info =
2000 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002001 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2002 eIsFg isFg = IS_FG_OFF;
2003 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2004 eDest lDest = mdp_info.lIndex;
2005 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002006
2007 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2008 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2009
Saurabh Shah88e4d272013-09-03 13:31:29 -07002010 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002011 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002012}
2013
Saurabh Shah88e4d272013-09-03 13:31:29 -07002014bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002015
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002016 if(!isEnabled()) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002017 ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
2018 return true;
2019 }
2020
2021 if(!ctx || !list) {
2022 ALOGE("%s: invalid contxt or list",__FUNCTION__);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002023 return false;
2024 }
2025
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302026 if(ctx->listStats[mDpy].numAppLayers > MAX_NUM_APP_LAYERS) {
2027 ALOGD_IF(isDebug(),"%s: Exceeding max layer count", __FUNCTION__);
2028 return true;
2029 }
2030
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002031 // Set the Handle timeout to true for MDP or MIXED composition.
2032 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2033 sHandleTimeout = true;
2034 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002035
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002036 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002037 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002038
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002039 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2040 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002041 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002042 if(mCurrentFrame.isFBComposed[i]) continue;
2043
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002044 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002045 private_handle_t *hnd = (private_handle_t *)layer->handle;
2046 if(!hnd) {
2047 ALOGE("%s handle null", __FUNCTION__);
2048 return false;
2049 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002050
2051 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2052 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002053 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002054
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002055 int mdpIndex = mCurrentFrame.layerToMDP[i];
2056
radhakrishnac9a67412013-09-25 17:40:42 +05302057 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
2058 {
2059 MdpYUVPipeInfo& pipe_info =
2060 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2061 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2062 ovutils::eDest indexL = pipe_info.lIndex;
2063 ovutils::eDest indexR = pipe_info.rIndex;
2064 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302065 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302066 if(rot) {
2067 rot->queueBuffer(fd, offset);
2068 fd = rot->getDstMemId();
2069 offset = rot->getDstOffset();
2070 }
2071 if(indexL != ovutils::OV_INVALID) {
2072 ovutils::eDest destL = (ovutils::eDest)indexL;
2073 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2074 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2075 if (!ov.queueBuffer(fd, offset, destL)) {
2076 ALOGE("%s: queueBuffer failed for display:%d",
2077 __FUNCTION__, mDpy);
2078 return false;
2079 }
2080 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002081
radhakrishnac9a67412013-09-25 17:40:42 +05302082 if(indexR != ovutils::OV_INVALID) {
2083 ovutils::eDest destR = (ovutils::eDest)indexR;
2084 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2085 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2086 if (!ov.queueBuffer(fd, offset, destR)) {
2087 ALOGE("%s: queueBuffer failed for display:%d",
2088 __FUNCTION__, mDpy);
2089 return false;
2090 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002091 }
2092 }
radhakrishnac9a67412013-09-25 17:40:42 +05302093 else{
2094 MdpPipeInfoSplit& pipe_info =
2095 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2096 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002097
radhakrishnac9a67412013-09-25 17:40:42 +05302098 ovutils::eDest indexL = pipe_info.lIndex;
2099 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002100
Sushil Chauhandefd3522014-05-13 18:17:12 -07002101 if (!mDpy && (i == mOverlapIndex)) {
2102 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2103 }
2104
radhakrishnac9a67412013-09-25 17:40:42 +05302105 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302106 int offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302107
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002108 if(ctx->mAD->draw(ctx, fd, offset)) {
2109 fd = ctx->mAD->getDstFd();
2110 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002111 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002112
radhakrishnac9a67412013-09-25 17:40:42 +05302113 if(rot) {
2114 rot->queueBuffer(fd, offset);
2115 fd = rot->getDstMemId();
2116 offset = rot->getDstOffset();
2117 }
2118
2119 //************* play left mixer **********
2120 if(indexL != ovutils::OV_INVALID) {
2121 ovutils::eDest destL = (ovutils::eDest)indexL;
2122 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2123 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2124 if (!ov.queueBuffer(fd, offset, destL)) {
2125 ALOGE("%s: queueBuffer failed for left mixer",
2126 __FUNCTION__);
2127 return false;
2128 }
2129 }
2130
2131 //************* play right mixer **********
2132 if(indexR != ovutils::OV_INVALID) {
2133 ovutils::eDest destR = (ovutils::eDest)indexR;
2134 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2135 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2136 if (!ov.queueBuffer(fd, offset, destR)) {
2137 ALOGE("%s: queueBuffer failed for right mixer",
2138 __FUNCTION__);
2139 return false;
2140 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002141 }
2142 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002143
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002144 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2145 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002146
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002147 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002148}
Saurabh Shahab47c692014-02-12 18:45:57 -08002149
2150//================MDPCompSrcSplit==============================================
2151bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002152 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002153 private_handle_t *hnd = (private_handle_t *)layer->handle;
2154 hwc_rect_t dst = layer->displayFrame;
2155 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2156 pipe_info.lIndex = ovutils::OV_INVALID;
2157 pipe_info.rIndex = ovutils::OV_INVALID;
2158
2159 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2160 //should have a higher priority than the right one. Pipe priorities are
2161 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002162
Saurabh Shahc62f3982014-03-05 14:28:26 -08002163 Overlay::PipeSpecs pipeSpecs;
2164 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2165 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2166 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2167 pipeSpecs.dpy = mDpy;
2168 pipeSpecs.fb = false;
2169
Saurabh Shahab47c692014-02-12 18:45:57 -08002170 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002171 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002172 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002173 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002174 }
2175
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002176 /* Use 2 pipes IF
2177 a) Layer's crop width is > 2048 or
2178 b) Layer's dest width > 2048 or
2179 c) On primary, driver has indicated with caps to split always. This is
2180 based on an empirically derived value of panel height. Applied only
2181 if the layer's width is > mixer's width
2182 */
2183
2184 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
2185 qdutils::MDPVersion::getInstance().isSrcSplitAlways();
2186 int lSplit = getLeftSplit(ctx, mDpy);
2187 int dstWidth = dst.right - dst.left;
2188 int cropWidth = crop.right - crop.left;
2189
2190 if(dstWidth > qdutils::MAX_DISPLAY_DIM or
2191 cropWidth > qdutils::MAX_DISPLAY_DIM or
2192 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002193 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002194 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002195 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002196 }
2197
2198 // Return values
2199 // 1 Left pipe is higher priority, do nothing.
2200 // 0 Pipes of same priority.
2201 //-1 Right pipe is of higher priority, needs swap.
2202 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2203 pipe_info.rIndex) == -1) {
2204 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002205 }
2206 }
2207
2208 return true;
2209}
2210
Saurabh Shahab47c692014-02-12 18:45:57 -08002211int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2212 PipeLayerPair& PipeLayerPair) {
2213 private_handle_t *hnd = (private_handle_t *)layer->handle;
2214 if(!hnd) {
2215 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2216 return -1;
2217 }
2218 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2219 MdpPipeInfoSplit& mdp_info =
2220 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2221 Rotator **rot = &PipeLayerPair.rot;
2222 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
2223 eIsFg isFg = IS_FG_OFF;
2224 eDest lDest = mdp_info.lIndex;
2225 eDest rDest = mdp_info.rIndex;
2226 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2227 hwc_rect_t dst = layer->displayFrame;
2228 int transform = layer->transform;
2229 eTransform orient = static_cast<eTransform>(transform);
2230 const int downscale = 0;
2231 int rotFlags = ROT_FLAGS_NONE;
2232 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2233 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2234
2235 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2236 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2237
2238 // Handle R/B swap
2239 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2240 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2241 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2242 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2243 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2244 }
2245
Saurabh Shah97e2d802014-04-14 18:03:54 -07002246 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
2247 setMdpFlags(layer, mdpFlags, 0, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002248
2249 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2250 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002251 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002252 }
2253
2254 if(isYuvBuffer(hnd) && (transform & HWC_TRANSFORM_ROT_90)) {
2255 (*rot) = ctx->mRotMgr->getNext();
2256 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002257 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002258 //If the video is using a single pipe, enable BWC
2259 if(rDest == OV_INVALID) {
2260 BwcPM::setBwc(crop, dst, transform, mdpFlags);
2261 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002262 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002263 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002264 ALOGE("%s: configRotator failed!", __FUNCTION__);
2265 return -1;
2266 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002267 whf.format = (*rot)->getDstFormat();
2268 updateSource(orient, whf, crop);
2269 rotFlags |= ROT_PREROTATED;
2270 }
2271
2272 //If 2 pipes being used, divide layer into half, crop and dst
2273 hwc_rect_t cropL = crop;
2274 hwc_rect_t cropR = crop;
2275 hwc_rect_t dstL = dst;
2276 hwc_rect_t dstR = dst;
2277 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2278 cropL.right = (crop.right + crop.left) / 2;
2279 cropR.left = cropL.right;
2280 sanitizeSourceCrop(cropL, cropR, hnd);
2281
2282 //Swap crops on H flip since 2 pipes are being used
2283 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2284 hwc_rect_t tmp = cropL;
2285 cropL = cropR;
2286 cropR = tmp;
2287 }
2288
2289 dstL.right = (dst.right + dst.left) / 2;
2290 dstR.left = dstL.right;
2291 }
2292
2293 //For the mdp, since either we are pre-rotating or MDP does flips
2294 orient = OVERLAY_TRANSFORM_0;
2295 transform = 0;
2296
2297 //configure left pipe
2298 if(lDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002299 PipeArgs pargL(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002300 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2301 (ovutils::eBlending) getBlending(layer->blending));
2302
2303 if(configMdp(ctx->mOverlay, pargL, orient,
2304 cropL, dstL, metadata, lDest) < 0) {
2305 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2306 return -1;
2307 }
2308 }
2309
2310 //configure right pipe
2311 if(rDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002312 PipeArgs pargR(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002313 static_cast<eRotFlags>(rotFlags),
2314 layer->planeAlpha,
2315 (ovutils::eBlending) getBlending(layer->blending));
2316 if(configMdp(ctx->mOverlay, pargR, orient,
2317 cropR, dstR, metadata, rDest) < 0) {
2318 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2319 return -1;
2320 }
2321 }
2322
2323 return 0;
2324}
2325
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002326}; //namespace
2327