blob: 2ecd339d2e10080cbcf74c594828ccb409f85a38 [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002 * Copyright (C) 2012-2013, 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>
Tatenda Chipeperekwa12f41c92014-09-17 12:55:01 -070022#include "hdmi.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 Chauhan4259d872014-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;
42bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050043bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070044bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070045bool MDPComp::sEnablePartialFrameUpdate = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080046int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
radhakrishnac9a67412013-09-25 17:40:42 +053047bool MDPComp::sEnable4k2kYUVSplit = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070048
Saurabh Shah88e4d272013-09-03 13:31:29 -070049MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
50 if(isDisplaySplit(ctx, dpy)) {
51 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080052 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070053 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080054}
55
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080056MDPComp::MDPComp(int dpy):mDpy(dpy){};
57
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080058void MDPComp::dump(android::String8& buf)
59{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070060 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
61 return;
62
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080063 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070064 (mDpy == 0) ? "\"PRIMARY\"" :
65 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070066 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
67 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080068 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
69 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
70 (mCurrentFrame.needsRedraw? "YES" : "NO"),
71 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
72 dumpsys_log(buf," --------------------------------------------- \n");
73 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
74 dumpsys_log(buf," --------------------------------------------- \n");
75 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
76 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
77 index,
78 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070079 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080080 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070081 (mCurrentFrame.drop[index] ? "DROP" :
82 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080083 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
84 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
85 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080086}
87
88bool MDPComp::init(hwc_context_t *ctx) {
89
90 if(!ctx) {
91 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
92 return false;
93 }
94
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080095 char property[PROPERTY_VALUE_MAX];
96
97 sEnabled = false;
98 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080099 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
100 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800101 sEnabled = true;
102 }
103
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700104 sEnableMixedMode = true;
105 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
106 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
107 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
108 sEnableMixedMode = false;
109 }
110
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800111 if(property_get("debug.mdpcomp.logs", property, NULL) > 0) {
112 if(atoi(property) != 0)
113 sDebugLogs = true;
114 }
115
Jeykumar Sankaran18469742014-02-19 12:40:57 -0800116 if(property_get("persist.hwc.partialupdate", property, NULL) > 0) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700117 if((atoi(property) != 0) && ctx->mMDP.panel == MIPI_CMD_PANEL &&
118 qdutils::MDPVersion::getInstance().is8x74v2())
119 sEnablePartialFrameUpdate = true;
120 }
121 ALOGE_IF(isDebug(), "%s: Partial Update applicable?: %d",__FUNCTION__,
122 sEnablePartialFrameUpdate);
123
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800124 sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Saurabh Shah85234ec2013-04-12 17:09:00 -0700125 if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
126 int val = atoi(property);
127 if(val >= 0)
128 sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800129 }
130
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400131 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
132 // Idle invalidation is not necessary on command mode panels
133 long idle_timeout = DEFAULT_IDLE_TIME;
134 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
135 if(atoi(property) != 0)
136 idle_timeout = atoi(property);
137 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800138
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400139 //create Idle Invalidator only when not disabled through property
140 if(idle_timeout != -1)
141 idleInvalidator = IdleInvalidator::getInstance();
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800142
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400143 if(idleInvalidator == NULL) {
144 ALOGE("%s: failed to instantiate idleInvalidator object",
145 __FUNCTION__);
146 } else {
147 idleInvalidator->init(timeout_handler, ctx, idle_timeout);
148 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800149 }
radhakrishnac9a67412013-09-25 17:40:42 +0530150
151 if((property_get("debug.mdpcomp.4k2kSplit", property, "0") > 0) &&
152 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
153 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
154 sEnable4k2kYUVSplit = true;
155 }
Sushil Chauhan4259d872014-05-13 18:17:12 -0700156
157 if ((property_get("persist.hwc.ptor.enable", property, NULL) > 0) &&
158 ((!strncasecmp(property, "true", PROPERTY_VALUE_MAX )) ||
159 (!strncmp(property, "1", PROPERTY_VALUE_MAX )))) {
160 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
161 HWC_DISPLAY_PRIMARY);
162 }
163
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700164 return true;
165}
166
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800167void MDPComp::reset(hwc_context_t *ctx) {
168 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700169 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800170 ctx->mOverlay->clear(mDpy);
171 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700172}
173
Raj Kamal5166b312014-06-06 13:45:20 +0530174void MDPComp::reset() {
Raj Kamal46dc44f2015-03-16 21:59:25 +0530175 mPrevModeOn = mModeOn;
Raj Kamal5166b312014-06-06 13:45:20 +0530176 mModeOn = false;
177}
178
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700179void MDPComp::timeout_handler(void *udata) {
180 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
Raj Kamal46dc44f2015-03-16 21:59:25 +0530181 bool handleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700182
183 if(!ctx) {
184 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
185 return;
186 }
Raj Kamal46dc44f2015-03-16 21:59:25 +0530187
Ramkumar Radhakrishnand8595ae2014-02-06 21:31:29 -0800188 Locker::Autolock _l(ctx->mDrawLock);
Raj Kamal46dc44f2015-03-16 21:59:25 +0530189
190 /* Handle timeout event only if the previous composition
191 on any display is MDP or MIXED*/
192 for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
193 if(ctx->mMDPComp[i])
194 handleTimeout =
195 ctx->mMDPComp[i]->isMDPComp() || handleTimeout;
196 }
197
198 if(!handleTimeout) {
Ramkumar Radhakrishnand8595ae2014-02-06 21:31:29 -0800199 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
200 return;
201 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700202 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700203 ALOGE("%s: HWC proc not registered", __FUNCTION__);
204 return;
205 }
206 sIdleFallBack = true;
207 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700208 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700209}
210
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800211void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800212 hwc_display_contents_1_t* list) {
213 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800214
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800215 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800216 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800217 if(!mCurrentFrame.isFBComposed[index]) {
218 layerProp[index].mFlags |= HWC_MDPCOMP;
219 layer->compositionType = HWC_OVERLAY;
220 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800221 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700222 /* Drop the layer when its already present in FB OR when it lies
223 * outside frame's ROI */
224 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800225 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700226 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800227 }
228 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700229}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500230
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800231void MDPComp::setRedraw(hwc_context_t *ctx,
232 hwc_display_contents_1_t* list) {
233 mCurrentFrame.needsRedraw = false;
234 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
235 (list->flags & HWC_GEOMETRY_CHANGED) ||
236 isSkipPresent(ctx, mDpy)) {
237 mCurrentFrame.needsRedraw = true;
238 }
239}
240
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800241MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700242 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800243}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800244
Saurabh Shahaa236822013-04-24 18:07:26 -0700245void MDPComp::FrameInfo::reset(const int& numLayers) {
246 for(int i = 0 ; i < MAX_PIPES_PER_MIXER && numLayers; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800247 if(mdpToLayer[i].pipeInfo) {
248 delete mdpToLayer[i].pipeInfo;
249 mdpToLayer[i].pipeInfo = NULL;
250 //We dont own the rotator
251 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800252 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800253 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800254
255 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
256 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700257 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800258
Saurabh Shahaa236822013-04-24 18:07:26 -0700259 layerCount = numLayers;
260 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800261 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700262 needsRedraw = true;
Saurabh Shahce188452014-02-05 10:17:43 -0800263 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800264}
265
Saurabh Shahaa236822013-04-24 18:07:26 -0700266void MDPComp::FrameInfo::map() {
267 // populate layer and MDP maps
268 int mdpIdx = 0;
269 for(int idx = 0; idx < layerCount; idx++) {
270 if(!isFBComposed[idx]) {
271 mdpToLayer[mdpIdx].listIndex = idx;
272 layerToMDP[idx] = mdpIdx++;
273 }
274 }
275}
276
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800277MDPComp::LayerCache::LayerCache() {
278 reset();
279}
280
281void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700282 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530283 memset(&isFBComposed, true, sizeof(isFBComposed));
284 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800285 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700286}
287
288void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
289 const int numAppLayers = list->numHwLayers - 1;
290 for(int i = 0; i < numAppLayers; i++) {
291 hnd[i] = list->hwLayers[i].handle;
292 }
293}
294
295void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700296 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530297 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
298 memcpy(&drop, &curFrame.drop, sizeof(drop));
299}
300
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800301bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
302 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530303 if(layerCount != curFrame.layerCount)
304 return false;
305 for(int i = 0; i < curFrame.layerCount; i++) {
306 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
307 (curFrame.drop[i] != drop[i])) {
308 return false;
309 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800310 if(curFrame.isFBComposed[i] &&
311 (hnd[i] != list->hwLayers[i].handle)){
312 return false;
313 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530314 }
315 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800316}
317
Raj Kamal46dc44f2015-03-16 21:59:25 +0530318bool MDPComp::LayerCache::isSameFrame(hwc_context_t *ctx, int dpy,
319 hwc_display_contents_1_t* list) {
320
321 if(layerCount != ctx->listStats[dpy].numAppLayers)
322 return false;
323
324 if((list->flags & HWC_GEOMETRY_CHANGED) ||
325 isSkipPresent(ctx, dpy)) {
326 return false;
327 }
328
329 for(int i = 0; i < layerCount; i++) {
330 if(hnd[i] != list->hwLayers[i].handle)
331 return false;
332 }
333
334 return true;
335}
336
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700337bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
338 private_handle_t *hnd = (private_handle_t *)layer->handle;
339 if((not isYuvBuffer(hnd) and has90Transform(layer)) or
340 (not isValidDimension(ctx,layer))
341 //More conditions here, SKIP, sRGB+Blend etc
342 ) {
343 return false;
344 }
345 return true;
346}
347
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530348bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Saurabh Shah4fdde762013-04-30 18:47:33 -0700349 const int dpy = HWC_DISPLAY_PRIMARY;
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800350 private_handle_t *hnd = (private_handle_t *)layer->handle;
351
352 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700353 if (layer->flags & HWC_COLOR_FILL) {
354 // Color layer
355 return true;
356 }
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800357 ALOGE("%s: layer handle is NULL", __FUNCTION__);
358 return false;
359 }
360
Naseer Ahmede850a802013-09-06 13:12:52 -0400361 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400362 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400363 return false;
364
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800365 int hw_w = ctx->dpyAttr[mDpy].xres;
366 int hw_h = ctx->dpyAttr[mDpy].yres;
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800367
Saurabh Shah62e1d732013-09-17 10:44:05 -0700368 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700369 hwc_rect_t dst = layer->displayFrame;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700370 int crop_w = crop.right - crop.left;
371 int crop_h = crop.bottom - crop.top;
372 int dst_w = dst.right - dst.left;
373 int dst_h = dst.bottom - dst.top;
374 float w_dscale = ceilf((float)crop_w / (float)dst_w);
375 float h_dscale = ceilf((float)crop_h / (float)dst_h);
376
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800377 /* Workaround for MDP HW limitation in DSI command mode panels where
378 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
379 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530380 * There also is a HW limilation in MDP, minimum block size is 2x2
381 * Fallback to GPU if height is less than 2.
382 */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800383 if((crop_w < 5)||(crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800384 return false;
385
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800386 if((w_dscale > 1.0f) || (h_dscale > 1.0f)) {
387 const uint32_t downscale =
Saurabh Shah4fdde762013-04-30 18:47:33 -0700388 qdutils::MDPVersion::getInstance().getMaxMDPDownscale();
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800389 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
390 /* Workaround for downscales larger than 4x.
391 * Will be removed once decimator block is enabled for MDSS
392 */
393 if(!qdutils::MDPVersion::getInstance().supportsDecimation()) {
394 if(crop_w > MAX_DISPLAY_DIM || w_dscale > downscale ||
395 h_dscale > downscale)
396 return false;
397 } else {
398 if(w_dscale > 64 || h_dscale > 64)
399 return false;
400 }
401 } else { //A-family
402 if(w_dscale > downscale || h_dscale > downscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700403 return false;
404 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700405 }
406
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800407 return true;
408}
409
Saurabh Shahaf5f5972013-07-30 13:56:35 -0700410ovutils::eDest MDPComp::getMdpPipe(hwc_context_t *ctx, ePipeType type,
411 int mixer) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800412 overlay::Overlay& ov = *ctx->mOverlay;
413 ovutils::eDest mdp_pipe = ovutils::OV_INVALID;
414
415 switch(type) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800416 case MDPCOMP_OV_DMA:
Baldev Sahu5cbb5462014-11-12 15:35:13 +0530417 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_DMA, mDpy, mixer,
418 Overlay::FORMAT_RGB);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800419 if(mdp_pipe != ovutils::OV_INVALID) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800420 return mdp_pipe;
421 }
422 case MDPCOMP_OV_ANY:
423 case MDPCOMP_OV_RGB:
Baldev Sahu5cbb5462014-11-12 15:35:13 +0530424 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy, mixer,
425 Overlay::FORMAT_RGB);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800426 if(mdp_pipe != ovutils::OV_INVALID) {
427 return mdp_pipe;
428 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800429
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800430 if(type == MDPCOMP_OV_RGB) {
431 //Requested only for RGB pipe
432 break;
433 }
434 case MDPCOMP_OV_VG:
Baldev Sahu5cbb5462014-11-12 15:35:13 +0530435 return ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy, mixer,
436 Overlay::FORMAT_YUV);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800437 default:
438 ALOGE("%s: Invalid pipe type",__FUNCTION__);
439 return ovutils::OV_INVALID;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800440 };
441 return ovutils::OV_INVALID;
442}
443
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800444bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700445 bool ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700446 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800447
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800448 if(!isEnabled()) {
449 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700450 ret = false;
Saurabh Shahd4e65852013-06-17 11:33:53 -0700451 } else if(qdutils::MDPVersion::getInstance().is8x26() &&
Tatenda Chipeperekwa75a41812014-04-01 12:54:13 -0700452 ctx->mVideoTransFlag &&
453 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700454 //1 Padding round to shift pipes across mixers
455 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
456 __FUNCTION__);
457 ret = false;
Raj Kamal2a18d6d2015-03-17 20:53:14 +0530458 } else if(qdutils::MDPVersion::getInstance().is8x26() &&
459 !mDpy && isSecondaryAnimating(ctx) &&
460 (isYuvPresent(ctx,HWC_DISPLAY_EXTERNAL) ||
461 isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL))) {
462 ALOGD_IF(isDebug(),"%s: Display animation in progress",
463 __FUNCTION__);
464 ret = false;
Ramkumar Radhakrishnan0f952612013-12-30 23:11:27 -0800465 } else if(isSecondaryConfiguring(ctx)) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800466 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800467 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700468 ret = false;
Saurabh Shahaa236822013-04-24 18:07:26 -0700469 } else if(ctx->isPaddingRound) {
Raj Kamalfc5b9222014-02-07 16:15:17 +0530470 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
471 __FUNCTION__,mDpy);
Saurabh Shahaa236822013-04-24 18:07:26 -0700472 ret = false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700473 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700474 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800475}
476
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800477/*
478 * 1) Identify layers that are not visible in the updating ROI and drop them
479 * from composition.
480 * 2) If we have a scaling layers which needs cropping against generated ROI.
481 * Reset ROI to full resolution.
482 */
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700483bool MDPComp::validateAndApplyROI(hwc_context_t *ctx,
484 hwc_display_contents_1_t* list, hwc_rect_t roi) {
485 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
486
487 if(!isValidRect(roi))
488 return false;
489
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800490 hwc_rect_t visibleRect = roi;
491
492 for(int i = numAppLayers - 1; i >= 0; i--){
493
494 if(!isValidRect(visibleRect)) {
495 mCurrentFrame.drop[i] = true;
496 mCurrentFrame.dropCount++;
Jeykumar Sankaran65bc8022014-01-21 17:26:12 -0800497 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800498 }
499
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700500 const hwc_layer_1_t* layer = &list->hwLayers[i];
501
502 hwc_rect_t dstRect = layer->displayFrame;
Arun Kumar K.R91090c72013-10-28 19:40:18 -0700503 hwc_rect_t srcRect = integerizeSourceCrop(layer->sourceCropf);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700504 int transform = layer->transform;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700505
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800506 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700507
508 int res_w = res.right - res.left;
509 int res_h = res.bottom - res.top;
510 int dst_w = dstRect.right - dstRect.left;
511 int dst_h = dstRect.bottom - dstRect.top;
512
513 if(!isValidRect(res)) {
514 mCurrentFrame.drop[i] = true;
515 mCurrentFrame.dropCount++;
516 }else {
517 /* Reset frame ROI when any layer which needs scaling also needs ROI
518 * cropping */
Jeykumar Sankaran65bc8022014-01-21 17:26:12 -0800519 if((res_w != dst_w || res_h != dst_h) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800520 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700521 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
522 mCurrentFrame.dropCount = 0;
523 return false;
524 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800525
Jeykumar Sankaran65bc8022014-01-21 17:26:12 -0800526 /* deduct any opaque region from visibleRect */
radhakrishna31858932014-11-03 13:19:27 +0530527 if (layer->blending == HWC_BLENDING_NONE &&
528 layer->planeAlpha == 0xFF)
Jeykumar Sankaran65bc8022014-01-21 17:26:12 -0800529 visibleRect = deductRect(visibleRect, res);
530 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700531 }
532 return true;
533}
534
Jeykumar Sankaran4d76a382014-02-26 18:26:58 -0800535bool MDPComp::canDoPartialUpdate(hwc_context_t *ctx,
536 hwc_display_contents_1_t* list){
537 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() || mDpy ||
538 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED)||
539 isDisplaySplit(ctx, mDpy)) {
540 return false;
541 }
542 return true;
543}
544
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700545void MDPComp::generateROI(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
546 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
547
Jeykumar Sankaran4d76a382014-02-26 18:26:58 -0800548 if(!canDoPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700549 return;
550
551 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
552 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran4d76a382014-02-26 18:26:58 -0800553 hwc_layer_1_t* layer = &list->hwLayers[index];
554 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran78893422014-05-07 16:23:14 -0700555 isYuvBuffer((private_handle_t *)layer->handle)) {
556 hwc_rect_t dst = layer->displayFrame;
557 hwc_rect_t updatingRect = dst;
558
Jeykumar Sankaran4d76a382014-02-26 18:26:58 -0800559#ifdef QCOM_BSP
Jeykumar Sankaran78893422014-05-07 16:23:14 -0700560 if(!needsScaling(layer) && !layer->transform)
561 {
562 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
563 int x_off = dst.left - src.left;
564 int y_off = dst.top - src.top;
565 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
566 }
Jeykumar Sankaran4d76a382014-02-26 18:26:58 -0800567#endif
568 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700569 }
570 }
571
Jeykumar Sankaran4d76a382014-02-26 18:26:58 -0800572 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
573 (int)ctx->dpyAttr[mDpy].yres};
574
575 // Align ROI coordinates to panel restrictions
576 roi = sanitizeROI(roi, fullFrame);
577
578 if(!validateAndApplyROI(ctx, list, roi))
579 roi = fullFrame;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700580
581 ctx->listStats[mDpy].roi.x = roi.left;
582 ctx->listStats[mDpy].roi.y = roi.top;
583 ctx->listStats[mDpy].roi.w = roi.right - roi.left;
584 ctx->listStats[mDpy].roi.h = roi.bottom - roi.top;
585
586 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
587 roi.left, roi.top, roi.right, roi.bottom);
588}
589
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800590/* Checks for conditions where all the layers marked for MDP comp cannot be
591 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800592bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800593 hwc_display_contents_1_t* list){
594
Saurabh Shahaa236822013-04-24 18:07:26 -0700595 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800596
Ramkumar Radhakrishnanba713382013-08-30 18:41:07 -0700597 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700598 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
599 return false;
600 }
601
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800602 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700603 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
604 __FUNCTION__,
605 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800606 return false;
607 }
608
Raj Kamal2a18d6d2015-03-17 20:53:14 +0530609 if(!mDpy && isSecondaryAnimating(ctx) &&
610 (isYuvPresent(ctx,HWC_DISPLAY_EXTERNAL) ||
611 isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL)) ) {
612 ALOGD_IF(isDebug(),"%s: Display animation in progress",
613 __FUNCTION__);
614 return false;
615 }
616
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800617 // check for action safe flag and downscale mode which requires scaling.
618 if(ctx->dpyAttr[mDpy].mActionSafePresent
619 || ctx->dpyAttr[mDpy].mDownScaleMode) {
620 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
621 return false;
622 }
623
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800624 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800625 hwc_layer_1_t* layer = &list->hwLayers[i];
626 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800627
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700628 if(isYuvBuffer(hnd) && has90Transform(layer)) {
629 if(!canUseRotator(ctx, mDpy)) {
630 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
631 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700632 return false;
633 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800634 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530635
636 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
637 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhand8ef93f2014-03-20 11:08:41 -0700638 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530639 if(qdutils::MDPVersion::getInstance().is8x26() &&
640 (ctx->dpyAttr[mDpy].xres > 1024) &&
Sushil Chauhand8ef93f2014-03-20 11:08:41 -0700641 (transform & HWC_TRANSFORM_FLIP_H) &&
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530642 (!isYuvBuffer(hnd)))
643 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800644 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700645
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700646 if(ctx->mAD->isDoable()) {
647 return false;
648 }
649
Saurabh Shahaa236822013-04-24 18:07:26 -0700650 //If all above hard conditions are met we can do full or partial MDP comp.
651 bool ret = false;
652 if(fullMDPComp(ctx, list)) {
653 ret = true;
Sushil Chauhan4259d872014-05-13 18:17:12 -0700654 } else if(fullMDPCompWithPTOR(ctx, list)) {
655 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700656 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700657 ret = true;
658 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530659
Saurabh Shahaa236822013-04-24 18:07:26 -0700660 return ret;
661}
662
663bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700664 //Will benefit presentation / secondary-only layer.
665 if((mDpy > HWC_DISPLAY_PRIMARY) &&
666 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
667 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
668 return false;
669 }
670
671 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
672 for(int i = 0; i < numAppLayers; i++) {
673 hwc_layer_1_t* layer = &list->hwLayers[i];
674 if(not isSupportedForMDPComp(ctx, layer)) {
675 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
676 return false;
677 }
678 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800679
Saurabh Shahaa236822013-04-24 18:07:26 -0700680 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700681 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
682 sizeof(mCurrentFrame.isFBComposed));
683 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
684 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700685
radhakrishnac9a67412013-09-25 17:40:42 +0530686 if(sEnable4k2kYUVSplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800687 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530688 }
689
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800690 if(!postHeuristicsHandling(ctx, list)) {
691 ALOGD_IF(isDebug(), "post heuristic handling failed");
692 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700693 return false;
694 }
695
Saurabh Shahaa236822013-04-24 18:07:26 -0700696 return true;
697}
698
Sushil Chauhan4259d872014-05-13 18:17:12 -0700699/* Full MDP Composition with Peripheral Tiny Overlap Removal.
700 * MDP bandwidth limitations can be avoided, if the overlap region
701 * covered by the smallest layer at a higher z-order, gets composed
702 * by Copybit on a render buffer, which can be queued to MDP.
703 */
704bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
705 hwc_display_contents_1_t* list) {
706
707 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
708 const int stagesForMDP = min(sMaxPipesPerMixer,
709 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
710
711 // Hard checks where we cannot use this mode
Justin Philipb1906f72014-10-30 14:14:19 +0530712 if (mDpy || !ctx->mCopyBit[mDpy] || !ctx->mIsPTOREnabled) {
Sushil Chauhan4259d872014-05-13 18:17:12 -0700713 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
714 return false;
715 }
716
717 // Frame level checks
718 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
719 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
720 isSecurePresent(ctx, mDpy)) {
721 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
722 return false;
723 }
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700724 // MDP comp checks
725 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhan4259d872014-05-13 18:17:12 -0700726 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700727 if(not isSupportedForMDPComp(ctx, layer)) {
728 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
729 return false;
Sushil Chauhan4259d872014-05-13 18:17:12 -0700730 }
731 }
732
Sushil Chauhan4259d872014-05-13 18:17:12 -0700733 /* We cannot use this composition mode, if:
734 1. A below layer needs scaling.
735 2. Overlap is not peripheral to display.
736 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700737 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhan4259d872014-05-13 18:17:12 -0700738 */
739
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700740 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
741 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
742 memset(overlapRect, 0, sizeof(overlapRect));
743 int layerPixelCount, minPixelCount = 0;
744 int numPTORLayersFound = 0;
745 for (int i = numAppLayers-1; (i >= 0 &&
746 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhan4259d872014-05-13 18:17:12 -0700747 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700748 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhan4259d872014-05-13 18:17:12 -0700749 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700750 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
751 // PTOR layer should be peripheral and cannot have transform
752 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
753 has90Transform(layer)) {
754 continue;
755 }
756 if((3 * (layerPixelCount + minPixelCount)) >
757 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
758 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
759 continue;
760 }
Sushil Chauhane1474bf2014-07-25 12:20:23 -0700761 bool found = false;
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700762 for (int j = i-1; j >= 0; j--) {
763 // Check if the layers below this layer qualifies for PTOR comp
764 hwc_layer_1_t* layer = &list->hwLayers[j];
765 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhane1474bf2014-07-25 12:20:23 -0700766 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700767 // needs scaling cannot be supported.
Sushil Chauhane1474bf2014-07-25 12:20:23 -0700768 if (isValidRect(getIntersection(dispFrame, disFrame))) {
769 if (has90Transform(layer) || needsScaling(layer)) {
770 found = false;
771 break;
772 }
773 found = true;
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700774 }
775 }
776 // Store the minLayer Index
777 if(found) {
778 minLayerIndex[numPTORLayersFound] = i;
779 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
780 minPixelCount += layerPixelCount;
781 numPTORLayersFound++;
Sushil Chauhan4259d872014-05-13 18:17:12 -0700782 }
783 }
784
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700785 // No overlap layers
786 if (!numPTORLayersFound)
787 return false;
Sushil Chauhan4259d872014-05-13 18:17:12 -0700788
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700789 // Store the displayFrame and the sourceCrops of the layers
790 hwc_rect_t displayFrame[numAppLayers];
791 hwc_rect_t sourceCrop[numAppLayers];
792 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhan4259d872014-05-13 18:17:12 -0700793 hwc_layer_1_t* layer = &list->hwLayers[i];
794 displayFrame[i] = layer->displayFrame;
795 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700796 }
Sushil Chauhan4259d872014-05-13 18:17:12 -0700797
Prabhanjan Kandulabb1f6be2014-09-04 21:50:35 +0530798 /**
799 * It's possible that 2 PTOR layers might have overlapping.
800 * In such case, remove the intersection(again if peripheral)
801 * from the lower PTOR layer to avoid overlapping.
802 * If intersection is not on peripheral then compromise
803 * by reducing number of PTOR layers.
804 **/
805 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
806 if(isValidRect(commonRect)) {
807 overlapRect[1] = deductRect(overlapRect[1], commonRect);
808 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
809 }
810
811 ctx->mPtorInfo.count = numPTORLayersFound;
812 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
813 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
814 }
815
816 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
817 // reset PTOR
818 ctx->mPtorInfo.count = 0;
819 if(isValidRect(commonRect)) {
820 // If PTORs are intersecting restore displayframe of PTOR[1]
821 // before returning, as we have modified it above.
822 list->hwLayers[minLayerIndex[1]].displayFrame =
823 displayFrame[minLayerIndex[1]];
824 }
825 return false;
826 }
Sushil Chauhane1474bf2014-07-25 12:20:23 -0700827 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
828 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
829
Xu Yang645cb1f2014-07-30 21:57:21 +0800830 // Store the blending mode, planeAlpha, and transform of PTOR layers
831 int32_t blending[numPTORLayersFound];
832 uint8_t planeAlpha[numPTORLayersFound];
833 uint32_t transform[numPTORLayersFound];
834
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700835 for(int j = 0; j < numPTORLayersFound; j++) {
836 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhane1474bf2014-07-25 12:20:23 -0700837
838 // Update src crop of PTOR layer
839 hwc_layer_1_t* layer = &list->hwLayers[index];
840 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
841 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
842 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
843 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
844
845 // Store & update w, h, format of PTOR layer
846 private_handle_t *hnd = (private_handle_t *)layer->handle;
847 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
848 layerWhf[j] = whf;
849 hnd->width = renderBuf->width;
850 hnd->height = renderBuf->height;
851 hnd->format = renderBuf->format;
852
Xu Yang645cb1f2014-07-30 21:57:21 +0800853 // Store & update blending mode, planeAlpha and transform of PTOR layer
854 blending[j] = layer->blending;
855 planeAlpha[j] = layer->planeAlpha;
856 transform[j] = layer->transform;
857 layer->blending = HWC_BLENDING_NONE;
858 layer->planeAlpha = 0xFF;
859 layer->transform = 0;
860
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700861 // Remove overlap from crop & displayFrame of below layers
862 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhane1474bf2014-07-25 12:20:23 -0700863 layer = &list->hwLayers[i];
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700864 if(!isValidRect(getIntersection(layer->displayFrame,
865 overlapRect[j]))) {
866 continue;
867 }
868 // Update layer attributes
869 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
870 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddicc32af02014-11-11 16:03:03 +0530871 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700872 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
873 layer->transform);
874 layer->sourceCropf.left = (float)srcCrop.left;
875 layer->sourceCropf.top = (float)srcCrop.top;
876 layer->sourceCropf.right = (float)srcCrop.right;
877 layer->sourceCropf.bottom = (float)srcCrop.bottom;
878 }
Sushil Chauhan4259d872014-05-13 18:17:12 -0700879 }
880
881 mCurrentFrame.mdpCount = numAppLayers;
882 mCurrentFrame.fbCount = 0;
883 mCurrentFrame.fbZ = -1;
884
Dileep Kumar Reddicc32af02014-11-11 16:03:03 +0530885 for (int j = 0; j < numAppLayers; j++) {
886 if(isValidRect(list->hwLayers[j].displayFrame)) {
887 mCurrentFrame.isFBComposed[j] = false;
888 } else {
889 mCurrentFrame.mdpCount--;
890 mCurrentFrame.drop[j] = true;
891 }
892 }
Sushil Chauhan4259d872014-05-13 18:17:12 -0700893
894 bool result = postHeuristicsHandling(ctx, list);
895
896 // Restore layer attributes
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700897 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhan4259d872014-05-13 18:17:12 -0700898 hwc_layer_1_t* layer = &list->hwLayers[i];
899 layer->displayFrame = displayFrame[i];
900 layer->sourceCropf.left = (float)sourceCrop[i].left;
901 layer->sourceCropf.top = (float)sourceCrop[i].top;
902 layer->sourceCropf.right = (float)sourceCrop[i].right;
903 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
904 }
905
Xu Yang645cb1f2014-07-30 21:57:21 +0800906 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhane1474bf2014-07-25 12:20:23 -0700907 for (int i = 0; i < numPTORLayersFound; i++) {
908 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yang645cb1f2014-07-30 21:57:21 +0800909 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhane1474bf2014-07-25 12:20:23 -0700910 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
911 hnd->width = layerWhf[i].w;
912 hnd->height = layerWhf[i].h;
913 hnd->format = layerWhf[i].format;
Xu Yang645cb1f2014-07-30 21:57:21 +0800914 layer->blending = blending[i];
915 layer->planeAlpha = planeAlpha[i];
916 layer->transform = transform[i];
Sushil Chauhane1474bf2014-07-25 12:20:23 -0700917 }
918
Sushil Chauhan4259d872014-05-13 18:17:12 -0700919 if (!result) {
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700920 // reset PTOR
921 ctx->mPtorInfo.count = 0;
Sushil Chauhan4259d872014-05-13 18:17:12 -0700922 reset(ctx);
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700923 } else {
924 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
925 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhan4259d872014-05-13 18:17:12 -0700926 }
927
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700928 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
929 (result ? "successful" : "failed"));
Sushil Chauhan4259d872014-05-13 18:17:12 -0700930 return result;
931}
932
Saurabh Shahaa236822013-04-24 18:07:26 -0700933bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
934{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700935 if(!sEnableMixedMode) {
936 //Mixed mode is disabled. No need to even try caching.
937 return false;
938 }
939
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700940 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800941 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shah6e8ab772014-02-20 16:18:45 -0800942 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800943 cacheBasedComp(ctx, list);
944 } else {
945 ret = cacheBasedComp(ctx, list) or
Saurabh Shah6e8ab772014-02-20 16:18:45 -0800946 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700947 }
948
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700949 return ret;
950}
951
952bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
953 hwc_display_contents_1_t* list) {
954 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -0700955 mCurrentFrame.reset(numAppLayers);
956 updateLayerCache(ctx, list);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700957
958 //If an MDP marked layer is unsupported cannot do partial MDP Comp
959 for(int i = 0; i < numAppLayers; i++) {
960 if(!mCurrentFrame.isFBComposed[i]) {
961 hwc_layer_1_t* layer = &list->hwLayers[i];
962 if(not isSupportedForMDPComp(ctx, layer)) {
963 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
964 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800965 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700966 return false;
967 }
968 }
969 }
970
Saurabh Shah90b7b9b2013-09-12 16:36:08 -0700971 updateYUV(ctx, list, false /*secure only*/);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +0530972 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700973 if(!ret) {
974 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800975 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700976 return false;
977 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700978
979 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700980
radhakrishnac9a67412013-09-25 17:40:42 +0530981 if(sEnable4k2kYUVSplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800982 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530983 }
984
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700985 //Will benefit cases where a video has non-updating background.
986 if((mDpy > HWC_DISPLAY_PRIMARY) and
987 (mdpCount > MAX_SEC_LAYERS)) {
988 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800989 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700990 return false;
991 }
992
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800993 if(!postHeuristicsHandling(ctx, list)) {
994 ALOGD_IF(isDebug(), "post heuristic handling failed");
995 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700996 return false;
997 }
998
Saurabh Shahaa236822013-04-24 18:07:26 -0700999 return true;
1000}
1001
Saurabh Shah6e8ab772014-02-20 16:18:45 -08001002bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001003 hwc_display_contents_1_t* list) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001004 if(not isLoadBasedCompDoable(ctx, list)) {
1005 return false;
1006 }
1007
Saurabh Shahb772ae32013-11-18 15:40:02 -08001008 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah6e8ab772014-02-20 16:18:45 -08001009 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1010 const int stagesForMDP = min(sMaxPipesPerMixer,
1011 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001012
Saurabh Shah6e8ab772014-02-20 16:18:45 -08001013 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1014 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1015 int lastMDPSupportedIndex = numAppLayers;
1016 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001017
Saurabh Shah6e8ab772014-02-20 16:18:45 -08001018 //Find the minimum MDP batch size
1019 for(int i = 0; i < numAppLayers;i++) {
1020 if(mCurrentFrame.drop[i]) {
1021 dropCount++;
Jeykumar Sankaran6279bc32014-01-23 21:59:58 -08001022 continue;
Saurabh Shah6e8ab772014-02-20 16:18:45 -08001023 }
1024 hwc_layer_1_t* layer = &list->hwLayers[i];
1025 if(not isSupportedForMDPComp(ctx, layer)) {
1026 lastMDPSupportedIndex = i;
1027 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1028 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran6279bc32014-01-23 21:59:58 -08001029 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001030 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001031 }
1032
Saurabh Shah6e8ab772014-02-20 16:18:45 -08001033 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1034 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1035 mCurrentFrame.dropCount);
1036
1037 //Start at a point where the fb batch should at least have 2 layers, for
1038 //this mode to be justified.
1039 while(fbBatchSize < 2) {
1040 ++fbBatchSize;
1041 --mdpBatchSize;
Jeykumar Sankaran6279bc32014-01-23 21:59:58 -08001042 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001043
Saurabh Shah6e8ab772014-02-20 16:18:45 -08001044 //If there are no layers for MDP, this mode doesnt make sense.
1045 if(mdpBatchSize < 1) {
1046 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1047 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001048 return false;
1049 }
1050
Saurabh Shah6e8ab772014-02-20 16:18:45 -08001051 mCurrentFrame.reset(numAppLayers);
1052
1053 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1054 while(mdpBatchSize > 0) {
1055 //Mark layers for MDP comp
1056 int mdpBatchLeft = mdpBatchSize;
1057 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1058 if(mCurrentFrame.drop[i]) {
1059 continue;
1060 }
1061 mCurrentFrame.isFBComposed[i] = false;
1062 --mdpBatchLeft;
1063 }
1064
1065 mCurrentFrame.fbZ = mdpBatchSize;
1066 mCurrentFrame.fbCount = fbBatchSize;
1067 mCurrentFrame.mdpCount = mdpBatchSize;
1068
1069 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1070 __FUNCTION__, mdpBatchSize, fbBatchSize,
1071 mCurrentFrame.dropCount);
1072
1073 if(postHeuristicsHandling(ctx, list)) {
1074 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
1075 __FUNCTION__);
1076 return true;
1077 }
1078
1079 reset(ctx);
1080 --mdpBatchSize;
1081 ++fbBatchSize;
1082 }
1083
1084 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001085}
1086
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001087bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx,
1088 hwc_display_contents_1_t* list) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301089 if(mDpy or isSecurePresent(ctx, mDpy) or
1090 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001091 return false;
1092 }
1093 return true;
1094}
1095
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001096bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1097 hwc_display_contents_1_t* list) {
1098 const bool secureOnly = true;
1099 return videoOnlyComp(ctx, list, not secureOnly) or
1100 videoOnlyComp(ctx, list, secureOnly);
1101}
1102
1103bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001104 hwc_display_contents_1_t* list, bool secureOnly) {
Saurabh Shahaa236822013-04-24 18:07:26 -07001105 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001106
Saurabh Shahaa236822013-04-24 18:07:26 -07001107 mCurrentFrame.reset(numAppLayers);
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001108 updateYUV(ctx, list, secureOnly);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001109 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001110
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001111 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1112 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001113 return false;
1114 }
1115
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001116 /* Bail out if we are processing only secured video layers
1117 * and we dont have any */
1118 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001119 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001120 return false;
1121 }
1122
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001123 if(mCurrentFrame.fbCount)
1124 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001125
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001126 if(sEnable4k2kYUVSplit){
1127 adjustForSourceSplit(ctx, list);
1128 }
1129
1130 if(!postHeuristicsHandling(ctx, list)) {
1131 ALOGD_IF(isDebug(), "post heuristic handling failed");
Justin Philipc9907322015-01-06 11:55:12 +05301132 if(errno == ENOBUFS) {
1133 ALOGD_IF(isDebug(), "SMP Allocation failed");
1134 //On SMP allocation failure in video only comp add padding round
1135 ctx->isPaddingRound = true;
1136 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001137 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001138 return false;
1139 }
1140
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001141 return true;
1142}
1143
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001144/* Checks for conditions where YUV layers cannot be bypassed */
1145bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001146 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001147 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001148 return false;
1149 }
1150
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001151 if(layer->transform & HWC_TRANSFORM_ROT_90 && !canUseRotator(ctx,mDpy)) {
1152 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1153 return false;
1154 }
1155
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001156 if(isSecuring(ctx, layer)) {
1157 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1158 return false;
1159 }
1160
Saurabh Shah4fdde762013-04-30 18:47:33 -07001161 if(!isValidDimension(ctx, layer)) {
1162 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1163 __FUNCTION__);
1164 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001165 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001166
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001167 if(layer->planeAlpha < 0xFF) {
1168 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1169 in video only mode",
1170 __FUNCTION__);
1171 return false;
1172 }
1173
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001174 return true;
1175}
1176
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301177/* starts at fromIndex and check for each layer to find
1178 * if it it has overlapping with any Updating layer above it in zorder
1179 * till the end of the batch. returns true if it finds any intersection */
1180bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1181 int fromIndex, int toIndex) {
1182 for(int i = fromIndex; i < toIndex; i++) {
1183 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1184 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1185 return false;
1186 }
1187 }
1188 }
1189 return true;
1190}
1191
1192/* Checks if given layer at targetLayerIndex has any
1193 * intersection with all the updating layers in beween
1194 * fromIndex and toIndex. Returns true if it finds intersectiion */
1195bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1196 int fromIndex, int toIndex, int targetLayerIndex) {
1197 for(int i = fromIndex; i <= toIndex; i++) {
1198 if(!mCurrentFrame.isFBComposed[i]) {
1199 if(areLayersIntersecting(&list->hwLayers[i],
1200 &list->hwLayers[targetLayerIndex])) {
1201 return true;
1202 }
1203 }
1204 }
1205 return false;
1206}
1207
1208int MDPComp::getBatch(hwc_display_contents_1_t* list,
1209 int& maxBatchStart, int& maxBatchEnd,
1210 int& maxBatchCount) {
1211 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301212 int fbZOrder =-1;
Jeykumar Sankaran5a495da2014-01-20 12:25:32 -08001213 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301214 while (i < mCurrentFrame.layerCount) {
1215 int batchCount = 0;
1216 int batchStart = i;
1217 int batchEnd = i;
Jeykumar Sankaran5a495da2014-01-20 12:25:32 -08001218 /* Adjust batch Z order with the dropped layers so far */
1219 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301220 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301221 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301222 while(i < mCurrentFrame.layerCount) {
1223 if(!mCurrentFrame.isFBComposed[i]) {
1224 if(!batchCount) {
1225 i++;
1226 break;
1227 }
1228 updatingLayersAbove++;
1229 i++;
1230 continue;
1231 } else {
1232 if(mCurrentFrame.drop[i]) {
1233 i++;
Jeykumar Sankaran5a495da2014-01-20 12:25:32 -08001234 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301235 continue;
1236 } else if(updatingLayersAbove <= 0) {
1237 batchCount++;
1238 batchEnd = i;
1239 i++;
1240 continue;
1241 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1242
1243 // We have a valid updating layer already. If layer-i not
1244 // have overlapping with all updating layers in between
1245 // batch-start and i, then we can add layer i to batch.
1246 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1247 batchCount++;
1248 batchEnd = i;
1249 i++;
1250 continue;
1251 } else if(canPushBatchToTop(list, batchStart, i)) {
1252 //If All the non-updating layers with in this batch
1253 //does not have intersection with the updating layers
1254 //above in z-order, then we can safely move the batch to
1255 //higher z-order. Increment fbZ as it is moving up.
1256 if( firstZReverseIndex < 0) {
1257 firstZReverseIndex = i;
1258 }
1259 batchCount++;
1260 batchEnd = i;
1261 fbZ += updatingLayersAbove;
1262 i++;
1263 updatingLayersAbove = 0;
1264 continue;
1265 } else {
1266 //both failed.start the loop again from here.
1267 if(firstZReverseIndex >= 0) {
1268 i = firstZReverseIndex;
1269 }
1270 break;
1271 }
1272 }
1273 }
1274 }
1275 if(batchCount > maxBatchCount) {
1276 maxBatchCount = batchCount;
1277 maxBatchStart = batchStart;
1278 maxBatchEnd = batchEnd;
1279 fbZOrder = fbZ;
1280 }
1281 }
1282 return fbZOrder;
1283}
1284
1285bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1286 hwc_display_contents_1_t* list) {
1287 /* Idea is to keep as many non-updating(cached) layers in FB and
1288 * send rest of them through MDP. This is done in 2 steps.
1289 * 1. Find the maximum contiguous batch of non-updating layers.
1290 * 2. See if we can improve this batch size for caching by adding
1291 * opaque layers around the batch, if they don't have
1292 * any overlapping with the updating layers in between.
1293 * NEVER mark an updating layer for caching.
1294 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001295
1296 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001297 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001298 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301299 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001300
Saurabh Shahce188452014-02-05 10:17:43 -08001301 /* Nothing is cached. No batching needed */
1302 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001303 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001304 }
Saurabh Shahce188452014-02-05 10:17:43 -08001305
1306 /* No MDP comp layers, try to use other comp modes */
1307 if(mCurrentFrame.mdpCount == 0) {
1308 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001309 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001310
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301311 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001312
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301313 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001314 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001315 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001316 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301317 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001318 if(!mCurrentFrame.drop[i]){
1319 //If an unsupported layer is being attempted to
1320 //be pulled out we should fail
1321 if(not isSupportedForMDPComp(ctx, layer)) {
1322 return false;
1323 }
1324 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001325 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001326 }
1327 }
1328
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301329 // update the frame data
1330 mCurrentFrame.fbZ = fbZ;
1331 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001332 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001333 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001334
1335 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301336 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001337
1338 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001339}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001340
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001341void MDPComp::updateLayerCache(hwc_context_t* ctx,
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001342 hwc_display_contents_1_t* list) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001343 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001344 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001345
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001346 for(int i = 0; i < numAppLayers; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001347 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001348 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001349 if(!mCurrentFrame.drop[i])
1350 fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001351 mCurrentFrame.isFBComposed[i] = true;
1352 } else {
Saurabh Shahaa236822013-04-24 18:07:26 -07001353 mCurrentFrame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001354 }
1355 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001356
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001357 mCurrentFrame.fbCount = fbCount;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001358 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
1359 - mCurrentFrame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001360
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001361 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d"
1362 ,__FUNCTION__, mCurrentFrame.mdpCount, mCurrentFrame.fbCount,
1363 mCurrentFrame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001364}
1365
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001366void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
1367 bool secureOnly) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001368 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1369 for(int index = 0;index < nYuvCount; index++){
1370 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1371 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1372
1373 if(!isYUVDoable(ctx, layer)) {
1374 if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
1375 mCurrentFrame.isFBComposed[nYuvIndex] = true;
1376 mCurrentFrame.fbCount++;
1377 }
1378 } else {
1379 if(mCurrentFrame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001380 private_handle_t *hnd = (private_handle_t *)layer->handle;
1381 if(!secureOnly || isSecureBuffer(hnd)) {
1382 mCurrentFrame.isFBComposed[nYuvIndex] = false;
1383 mCurrentFrame.fbCount--;
1384 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001385 }
1386 }
1387 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001388
1389 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001390 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1391 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001392 mCurrentFrame.fbCount);
1393}
1394
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001395bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1396 hwc_display_contents_1_t* list) {
1397
1398 //Capability checks
1399 if(!resourceCheck(ctx, list)) {
1400 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1401 return false;
1402 }
1403
1404 //Limitations checks
1405 if(!hwLimitationsCheck(ctx, list)) {
1406 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1407 return false;
1408 }
1409
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001410 //Configure framebuffer first if applicable
1411 if(mCurrentFrame.fbZ >= 0) {
1412 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, mCurrentFrame.fbZ)) {
1413 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1414 __FUNCTION__);
1415 return false;
1416 }
1417 }
1418
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001419 mCurrentFrame.map();
1420
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001421 if(!allocLayerPipes(ctx, list)) {
1422 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001423 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001424 }
1425
1426 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001427 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001428 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001429 int mdpIndex = mCurrentFrame.layerToMDP[index];
1430 hwc_layer_1_t* layer = &list->hwLayers[index];
1431
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301432 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1433 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1434 mdpNextZOrder++;
1435 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001436 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1437 cur_pipe->zOrder = mdpNextZOrder++;
1438
radhakrishnac9a67412013-09-25 17:40:42 +05301439 private_handle_t *hnd = (private_handle_t *)layer->handle;
1440 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
1441 if(configure4k2kYuv(ctx, layer,
1442 mCurrentFrame.mdpToLayer[mdpIndex])
1443 != 0 ){
1444 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1445 for layer %d",__FUNCTION__, index);
1446 return false;
1447 }
1448 else{
1449 mdpNextZOrder++;
1450 }
1451 continue;
1452 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001453 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1454 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301455 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001456 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001457 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001458 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001459 }
1460
Saurabh Shah450ac972013-12-16 18:18:39 -08001461 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1462 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1463 ,__FUNCTION__, mDpy);
1464 return false;
1465 }
1466
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001467 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001468 return true;
1469}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001470
Saurabh Shah173f4242013-11-20 09:50:12 -08001471bool MDPComp::resourceCheck(hwc_context_t *ctx,
1472 hwc_display_contents_1_t *list) {
1473 const bool fbUsed = mCurrentFrame.fbCount;
1474 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1475 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1476 return false;
1477 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001478 return true;
1479}
1480
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301481bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1482 hwc_display_contents_1_t* list) {
1483
1484 //A-family hw limitation:
1485 //If a layer need alpha scaling, MDP can not support.
1486 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1487 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1488 if(!mCurrentFrame.isFBComposed[i] &&
1489 isAlphaScaled( &list->hwLayers[i])) {
1490 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1491 return false;
1492 }
1493 }
1494 }
1495
1496 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1497 //If multiple layers requires downscaling and also they are overlapping
1498 //fall back to GPU since MDSS can not handle it.
1499 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1500 qdutils::MDPVersion::getInstance().is8x26()) {
1501 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1502 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1503 if(!mCurrentFrame.isFBComposed[i] &&
1504 isDownscaleRequired(botLayer)) {
1505 //if layer-i is marked for MDP and needs downscaling
1506 //check if any MDP layer on top of i & overlaps with layer-i
1507 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1508 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1509 if(!mCurrentFrame.isFBComposed[j] &&
1510 isDownscaleRequired(topLayer)) {
1511 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1512 topLayer->displayFrame);
1513 if(isValidRect(r))
1514 return false;
1515 }
1516 }
1517 }
1518 }
1519 }
1520 return true;
1521}
1522
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001523int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001524 int ret = 0;
Raj Kamal5166b312014-06-06 13:45:20 +05301525
1526 if(!ctx || !list) {
1527 ALOGE("%s: Invalid context or list",__FUNCTION__);
1528 mCachedFrame.reset();
1529 return -1;
1530 }
1531
Saurabh Shahaa236822013-04-24 18:07:26 -07001532 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahf5f2b132013-11-25 12:08:35 -08001533 MDPVersion& mdpVersion = qdutils::MDPVersion::getInstance();
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -07001534
1535 // reset PTOR
1536 if(!mDpy)
1537 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Raj Kamalfc5b9222014-02-07 16:15:17 +05301538 //Do not cache the information for next draw cycle.
1539 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1540 ALOGI("%s: Unsupported layer count for mdp composition",
1541 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001542 mCachedFrame.reset();
1543 return -1;
1544 }
1545
Saurabh Shahb39f8152013-08-22 10:21:44 -07001546 //reset old data
1547 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001548 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1549 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301550
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001551 // Detect the start of animation and fall back to GPU only once to cache
1552 // all the layers in FB and display FB content untill animation completes.
1553 if(ctx->listStats[mDpy].isDisplayAnimating) {
1554 mCurrentFrame.needsRedraw = false;
1555 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1556 mCurrentFrame.needsRedraw = true;
1557 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1558 }
1559 setMDPCompLayerFlags(ctx, list);
1560 mCachedFrame.updateCounts(mCurrentFrame);
1561 ret = -1;
1562 return ret;
1563 } else {
1564 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1565 }
1566
Raj Kamal46dc44f2015-03-16 21:59:25 +05301567 if(!mDpy and !isSecondaryConnected(ctx) and !mPrevModeOn and
1568 mCachedFrame.isSameFrame(ctx,mDpy,list)) {
1569 ALOGD_IF(isDebug(),"%s: Avoid new composition",__FUNCTION__);
1570 mCurrentFrame.needsRedraw = false;
1571 setMDPCompLayerFlags(ctx, list);
1572 mCachedFrame.updateCounts(mCurrentFrame);
1573 return -1;
1574
1575 }
1576
Saurabh Shahb39f8152013-08-22 10:21:44 -07001577 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001578 if(isFrameDoable(ctx)) {
1579 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001580
Raj Kamal5166b312014-06-06 13:45:20 +05301581 mModeOn = tryFullFrame(ctx, list) || tryVideoOnly(ctx, list);
1582 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001583 setMDPCompLayerFlags(ctx, list);
1584 } else {
1585 reset(ctx);
1586 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1587 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001588 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001589 }
1590 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001591 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1592 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001593 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001594 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001595
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001596 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001597 ALOGD("GEOMETRY change: %d",
1598 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001599 android::String8 sDump("");
1600 dump(sDump);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001601 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001602 }
1603
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001604 mCachedFrame.cacheAll(list);
1605 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001606 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001607}
1608
radhakrishnac9a67412013-09-25 17:40:42 +05301609bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx,
1610 hwc_display_contents_1_t* list, int index) {
1611
1612 bool bRet = true;
1613 hwc_layer_1_t* layer = &list->hwLayers[index];
1614 private_handle_t *hnd = (private_handle_t *)layer->handle;
1615 int mdpIndex = mCurrentFrame.layerToMDP[index];
1616 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1617 info.pipeInfo = new MdpYUVPipeInfo;
1618 info.rot = NULL;
1619 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
1620 ePipeType type = MDPCOMP_OV_VG;
1621
1622 pipe_info.lIndex = ovutils::OV_INVALID;
1623 pipe_info.rIndex = ovutils::OV_INVALID;
1624
1625 pipe_info.lIndex = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
1626 if(pipe_info.lIndex == ovutils::OV_INVALID){
1627 bRet = false;
1628 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1629 __FUNCTION__);
1630 }
1631 pipe_info.rIndex = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
1632 if(pipe_info.rIndex == ovutils::OV_INVALID){
1633 bRet = false;
1634 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1635 __FUNCTION__);
1636 }
1637 return bRet;
1638}
Sushil Chauhan4259d872014-05-13 18:17:12 -07001639
1640int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1641 int fd = -1;
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -07001642 if (ctx->mPtorInfo.isActive()) {
1643 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhan4259d872014-05-13 18:17:12 -07001644 if (fd < 0) {
1645 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhan4259d872014-05-13 18:17:12 -07001646 }
1647 }
1648 return fd;
1649}
1650
Saurabh Shah88e4d272013-09-03 13:31:29 -07001651//=============MDPCompNonSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001652
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001653void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05301654 hwc_display_contents_1_t* list){
1655 //As we split 4kx2k yuv layer and program to 2 VG pipes
1656 //(if available) increase mdpcount accordingly
1657 mCurrentFrame.mdpCount += ctx->listStats[mDpy].yuv4k2kCount;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001658
1659 //If 4k2k Yuv layer split is possible, and if
1660 //fbz is above 4k2k layer, increment fb zorder by 1
1661 //as we split 4k2k layer and increment zorder for right half
1662 //of the layer
1663 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi2268dd72014-05-22 22:24:53 +05301664 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1665 index++) {
1666 if(!mCurrentFrame.isFBComposed[index]) {
1667 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1668 mdpNextZOrder++;
1669 }
1670 mdpNextZOrder++;
1671 hwc_layer_1_t* layer = &list->hwLayers[index];
1672 private_handle_t *hnd = (private_handle_t *)layer->handle;
1673 if(is4kx2kYuvBuffer(hnd)) {
1674 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1675 mCurrentFrame.fbZ += 1;
1676 mdpNextZOrder++;
1677 //As we split 4kx2k yuv layer and program to 2 VG pipes
1678 //(if available) increase mdpcount by 1.
1679 mCurrentFrame.mdpCount++;
1680 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001681 }
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));
Justin Philip23200512014-08-12 13:42:21 +05301693 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08001694 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){
1714 if(allocSplitVGPipesfor4k2k(ctx, list, index)){
1715 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 ePipeType type = MDPCOMP_OV_ANY;
1725
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001726 if(isYuvBuffer(hnd)) {
1727 type = MDPCOMP_OV_VG;
Prabhanjan Kandula5b8913e2014-01-22 23:01:45 +05301728 } else if(qdutils::MDPVersion::getInstance().is8x26() &&
1729 (ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024)) {
1730 if(qhwc::needsScaling(layer))
1731 type = MDPCOMP_OV_RGB;
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301732 } else if(!qhwc::needsScaling(layer)
Saurabh Shah85234ec2013-04-12 17:09:00 -07001733 && Overlay::getDMAMode() != Overlay::DMA_BLOCK_MODE
1734 && ctx->mMDP.version >= qdutils::MDSS_V5) {
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001735 type = MDPCOMP_OV_DMA;
1736 }
1737
Xu Yang5c2b3af2014-04-08 13:56:47 +08001738 // for 8x26, never allow primary display occupy DMA pipe
1739 // when external display is connected
1740 if(qdutils::MDPVersion::getInstance().is8x26()
1741 && ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive
1742 && ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected
1743 && !ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isPause
1744 && mDpy == HWC_DISPLAY_PRIMARY
1745 && type == MDPCOMP_OV_DMA) {
1746 type = MDPCOMP_OV_RGB;
1747 }
1748
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001749 pipe_info.index = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001750 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001751 ALOGD_IF(isDebug(), "%s: Unable to get pipe type = %d",
1752 __FUNCTION__, (int) type);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001753 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001754 }
1755 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001756 return true;
1757}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001758
radhakrishnac9a67412013-09-25 17:40:42 +05301759int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1760 PipeLayerPair& PipeLayerPair) {
1761 MdpYUVPipeInfo& mdp_info =
1762 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
1763 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1764 eIsFg isFg = IS_FG_OFF;
Justin Philip23200512014-08-12 13:42:21 +05301765 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05301766 eDest lDest = mdp_info.lIndex;
1767 eDest rDest = mdp_info.rIndex;
1768
1769 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
1770 lDest, rDest, &PipeLayerPair.rot);
1771}
1772
Saurabh Shah88e4d272013-09-03 13:31:29 -07001773bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001774
Raj Kamal5166b312014-06-06 13:45:20 +05301775 if(!isEnabled() or !mModeOn) {
1776 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05301777 return true;
1778 }
1779
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001780 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001781 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001782
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001783 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1784 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001785 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001786 if(mCurrentFrame.isFBComposed[i]) continue;
1787
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07001788 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08001789 private_handle_t *hnd = (private_handle_t *)layer->handle;
1790 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07001791 if (!(layer->flags & HWC_COLOR_FILL)) {
1792 ALOGE("%s handle null", __FUNCTION__);
1793 return false;
1794 }
1795 // No PLAY for Color layer
1796 layerProp[i].mFlags &= ~HWC_MDPCOMP;
1797 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001798 }
1799
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001800 int mdpIndex = mCurrentFrame.layerToMDP[i];
1801
radhakrishnac9a67412013-09-25 17:40:42 +05301802 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
1803 {
1804 MdpYUVPipeInfo& pipe_info =
1805 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1806 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1807 ovutils::eDest indexL = pipe_info.lIndex;
1808 ovutils::eDest indexR = pipe_info.rIndex;
1809 int fd = hnd->fd;
1810 uint32_t offset = hnd->offset;
1811 if(rot) {
1812 rot->queueBuffer(fd, offset);
1813 fd = rot->getDstMemId();
1814 offset = rot->getDstOffset();
1815 }
1816 if(indexL != ovutils::OV_INVALID) {
1817 ovutils::eDest destL = (ovutils::eDest)indexL;
1818 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1819 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
1820 if (!ov.queueBuffer(fd, offset, destL)) {
1821 ALOGE("%s: queueBuffer failed for display:%d",
1822 __FUNCTION__, mDpy);
1823 return false;
1824 }
1825 }
1826
1827 if(indexR != ovutils::OV_INVALID) {
1828 ovutils::eDest destR = (ovutils::eDest)indexR;
1829 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1830 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
1831 if (!ov.queueBuffer(fd, offset, destR)) {
1832 ALOGE("%s: queueBuffer failed for display:%d",
1833 __FUNCTION__, mDpy);
1834 return false;
1835 }
1836 }
1837 }
1838 else{
1839 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07001840 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301841 ovutils::eDest dest = pipe_info.index;
1842 if(dest == ovutils::OV_INVALID) {
1843 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001844 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05301845 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001846
radhakrishnac9a67412013-09-25 17:40:42 +05301847 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1848 continue;
1849 }
1850
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -07001851 int fd = hnd->fd;
1852 uint32_t offset = (uint32_t)hnd->offset;
1853 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
1854 if (!mDpy && (index != -1)) {
Sushil Chauhan4259d872014-05-13 18:17:12 -07001855 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -07001856 fd = hnd->fd;
Sushil Chauhane1474bf2014-07-25 12:20:23 -07001857 offset = 0;
Sushil Chauhan4259d872014-05-13 18:17:12 -07001858 }
1859
radhakrishnac9a67412013-09-25 17:40:42 +05301860 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1861 using pipe: %d", __FUNCTION__, layer,
1862 hnd, dest );
1863
radhakrishnac9a67412013-09-25 17:40:42 +05301864 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1865 if(rot) {
1866 if(!rot->queueBuffer(fd, offset))
1867 return false;
1868 fd = rot->getDstMemId();
1869 offset = rot->getDstOffset();
1870 }
1871
1872 if (!ov.queueBuffer(fd, offset, dest)) {
1873 ALOGE("%s: queueBuffer failed for display:%d ",
1874 __FUNCTION__, mDpy);
1875 return false;
1876 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001877 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001878
1879 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001880 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001881 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001882}
1883
Saurabh Shah88e4d272013-09-03 13:31:29 -07001884//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001885
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001886void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05301887 hwc_display_contents_1_t* list){
1888 //if 4kx2k yuv layer is totally present in either in left half
1889 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05301890 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi2268dd72014-05-22 22:24:53 +05301891 if(mCurrentFrame.fbZ >= 0) {
1892 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1893 index++) {
1894 if(!mCurrentFrame.isFBComposed[index]) {
1895 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1896 mdpNextZOrder++;
1897 }
1898 mdpNextZOrder++;
1899 hwc_layer_1_t* layer = &list->hwLayers[index];
1900 private_handle_t *hnd = (private_handle_t *)layer->handle;
1901 if(is4kx2kYuvBuffer(hnd)) {
1902 hwc_rect_t dst = layer->displayFrame;
1903 if((dst.left > lSplit) || (dst.right < lSplit)) {
1904 mCurrentFrame.mdpCount += 1;
1905 }
1906 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1907 mCurrentFrame.fbZ += 1;
1908 mdpNextZOrder++;
1909 }
1910 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001911 }
radhakrishnac9a67412013-09-25 17:40:42 +05301912 }
1913}
1914
Saurabh Shah88e4d272013-09-03 13:31:29 -07001915bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
1916 MdpPipeInfoSplit& pipe_info,
Saurabh Shah67a38c32013-06-10 16:23:15 -07001917 ePipeType type) {
1918 const int xres = ctx->dpyAttr[mDpy].xres;
Saurabh Shah07a8ca82013-08-06 18:45:42 -07001919 const int lSplit = getLeftSplit(ctx, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001920
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001921 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001922 pipe_info.lIndex = ovutils::OV_INVALID;
1923 pipe_info.rIndex = ovutils::OV_INVALID;
1924
1925 if (dst.left < lSplit) {
1926 pipe_info.lIndex = getMdpPipe(ctx, type, Overlay::MIXER_LEFT);
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
1931 if(dst.right > lSplit) {
1932 pipe_info.rIndex = getMdpPipe(ctx, type, Overlay::MIXER_RIGHT);
1933 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001934 return false;
1935 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001936
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001937 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001938}
1939
Saurabh Shah88e4d272013-09-03 13:31:29 -07001940bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001941 hwc_display_contents_1_t* list) {
1942 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001943
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001944 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001945
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001946 hwc_layer_1_t* layer = &list->hwLayers[index];
1947 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05301948 hwc_rect_t dst = layer->displayFrame;
1949 const int lSplit = getLeftSplit(ctx, mDpy);
1950 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
1951 if((dst.left > lSplit)||(dst.right < lSplit)){
1952 if(allocSplitVGPipesfor4k2k(ctx, list, index)){
1953 continue;
1954 }
1955 }
1956 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07001957 int mdpIndex = mCurrentFrame.layerToMDP[index];
1958 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001959 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07001960 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001961 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001962 ePipeType type = MDPCOMP_OV_ANY;
1963
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001964 if(isYuvBuffer(hnd)) {
1965 type = MDPCOMP_OV_VG;
Sushil Chauhan15a2ea62013-09-04 18:28:36 -07001966 } else if(!qhwc::needsScalingWithSplit(ctx, layer, mDpy)
Saurabh Shah85234ec2013-04-12 17:09:00 -07001967 && Overlay::getDMAMode() != Overlay::DMA_BLOCK_MODE
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001968 && ctx->mMDP.version >= qdutils::MDSS_V5) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001969 type = MDPCOMP_OV_DMA;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001970 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001971
1972 if(!acquireMDPPipes(ctx, layer, pipe_info, type)) {
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001973 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type = %d",
1974 __FUNCTION__, (int) type);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001975 return false;
1976 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001977 }
1978 return true;
1979}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001980
radhakrishnac9a67412013-09-25 17:40:42 +05301981int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1982 PipeLayerPair& PipeLayerPair) {
1983 const int lSplit = getLeftSplit(ctx, mDpy);
1984 hwc_rect_t dst = layer->displayFrame;
1985 if((dst.left > lSplit)||(dst.right < lSplit)){
1986 MdpYUVPipeInfo& mdp_info =
1987 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
1988 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1989 eIsFg isFg = IS_FG_OFF;
Justin Philip23200512014-08-12 13:42:21 +05301990 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05301991 eDest lDest = mdp_info.lIndex;
1992 eDest rDest = mdp_info.rIndex;
1993
1994 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
1995 lDest, rDest, &PipeLayerPair.rot);
1996 }
1997 else{
1998 return configure(ctx, layer, PipeLayerPair);
1999 }
2000}
2001
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002002/*
2003 * Configures pipe(s) for MDP composition
2004 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002005int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002006 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002007 MdpPipeInfoSplit& mdp_info =
2008 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002009 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2010 eIsFg isFg = IS_FG_OFF;
Justin Philip23200512014-08-12 13:42:21 +05302011 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002012 eDest lDest = mdp_info.lIndex;
2013 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002014
2015 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2016 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2017
Saurabh Shah88e4d272013-09-03 13:31:29 -07002018 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002019 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002020}
2021
Saurabh Shah88e4d272013-09-03 13:31:29 -07002022bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002023
Raj Kamal5166b312014-06-06 13:45:20 +05302024 if(!isEnabled() or !mModeOn) {
2025 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302026 return true;
2027 }
2028
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002029 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002030 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002031
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002032 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2033 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002034 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002035 if(mCurrentFrame.isFBComposed[i]) continue;
2036
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002037 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002038 private_handle_t *hnd = (private_handle_t *)layer->handle;
2039 if(!hnd) {
2040 ALOGE("%s handle null", __FUNCTION__);
2041 return false;
2042 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002043
2044 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2045 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002046 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002047
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002048 int mdpIndex = mCurrentFrame.layerToMDP[i];
2049
radhakrishnac9a67412013-09-25 17:40:42 +05302050 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
2051 {
2052 MdpYUVPipeInfo& pipe_info =
2053 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2054 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2055 ovutils::eDest indexL = pipe_info.lIndex;
2056 ovutils::eDest indexR = pipe_info.rIndex;
2057 int fd = hnd->fd;
2058 uint32_t offset = hnd->offset;
2059 if(rot) {
2060 rot->queueBuffer(fd, offset);
2061 fd = rot->getDstMemId();
2062 offset = rot->getDstOffset();
2063 }
2064 if(indexL != ovutils::OV_INVALID) {
2065 ovutils::eDest destL = (ovutils::eDest)indexL;
2066 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2067 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2068 if (!ov.queueBuffer(fd, offset, destL)) {
2069 ALOGE("%s: queueBuffer failed for display:%d",
2070 __FUNCTION__, mDpy);
2071 return false;
2072 }
2073 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002074
radhakrishnac9a67412013-09-25 17:40:42 +05302075 if(indexR != ovutils::OV_INVALID) {
2076 ovutils::eDest destR = (ovutils::eDest)indexR;
2077 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2078 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2079 if (!ov.queueBuffer(fd, offset, destR)) {
2080 ALOGE("%s: queueBuffer failed for display:%d",
2081 __FUNCTION__, mDpy);
2082 return false;
2083 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002084 }
2085 }
radhakrishnac9a67412013-09-25 17:40:42 +05302086 else{
2087 MdpPipeInfoSplit& pipe_info =
2088 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2089 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002090
radhakrishnac9a67412013-09-25 17:40:42 +05302091 ovutils::eDest indexL = pipe_info.lIndex;
2092 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002093
radhakrishnac9a67412013-09-25 17:40:42 +05302094 int fd = hnd->fd;
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -07002095 uint32_t offset = (uint32_t)hnd->offset;
2096 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2097 if (!mDpy && (index != -1)) {
2098 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2099 fd = hnd->fd;
Sushil Chauhane1474bf2014-07-25 12:20:23 -07002100 offset = 0;
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -07002101 }
radhakrishnac9a67412013-09-25 17:40:42 +05302102
Tatenda Chipeperekwa2f8cd2b2014-04-14 10:36:06 -07002103 if(ctx->mAD->draw(ctx, fd, offset)) {
2104 fd = ctx->mAD->getDstFd(ctx);
2105 offset = ctx->mAD->getDstOffset(ctx);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002106 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002107
radhakrishnac9a67412013-09-25 17:40:42 +05302108 if(rot) {
2109 rot->queueBuffer(fd, offset);
2110 fd = rot->getDstMemId();
2111 offset = rot->getDstOffset();
2112 }
2113
2114 //************* play left mixer **********
2115 if(indexL != ovutils::OV_INVALID) {
2116 ovutils::eDest destL = (ovutils::eDest)indexL;
2117 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2118 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2119 if (!ov.queueBuffer(fd, offset, destL)) {
2120 ALOGE("%s: queueBuffer failed for left mixer",
2121 __FUNCTION__);
2122 return false;
2123 }
2124 }
2125
2126 //************* play right mixer **********
2127 if(indexR != ovutils::OV_INVALID) {
2128 ovutils::eDest destR = (ovutils::eDest)indexR;
2129 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2130 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2131 if (!ov.queueBuffer(fd, offset, destR)) {
2132 ALOGE("%s: queueBuffer failed for right mixer",
2133 __FUNCTION__);
2134 return false;
2135 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002136 }
2137 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002138
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002139 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2140 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002141
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002142 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002143}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002144}; //namespace
2145