blob: 8ab29ea24654fe2bcb741b84287c0bb29f842eb3 [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
Prabhanjan Kandula30696ee2014-04-21 12:12:38 +0530116 // We read from drivers if panel supports partial updating
117 // and we enable partial update computations if supported.
118 // Keeping this property to disable partial update for
119 // debugging by setting below property to 0 & only 0.
120 property_get("persist.hwc.partialupdate", property, "-1");
121 if((atoi(property) != 0) &&
122 qdutils::MDPVersion::getInstance().isPartialUpdateEnabled()) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700123 sEnablePartialFrameUpdate = true;
124 }
125 ALOGE_IF(isDebug(), "%s: Partial Update applicable?: %d",__FUNCTION__,
126 sEnablePartialFrameUpdate);
127
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800128 sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Saurabh Shah85234ec2013-04-12 17:09:00 -0700129 if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
130 int val = atoi(property);
131 if(val >= 0)
132 sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800133 }
134
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400135 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
136 // Idle invalidation is not necessary on command mode panels
137 long idle_timeout = DEFAULT_IDLE_TIME;
138 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
139 if(atoi(property) != 0)
140 idle_timeout = atoi(property);
141 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800142
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400143 //create Idle Invalidator only when not disabled through property
144 if(idle_timeout != -1)
145 idleInvalidator = IdleInvalidator::getInstance();
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800146
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400147 if(idleInvalidator == NULL) {
148 ALOGE("%s: failed to instantiate idleInvalidator object",
149 __FUNCTION__);
150 } else {
151 idleInvalidator->init(timeout_handler, ctx, idle_timeout);
152 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800153 }
radhakrishnac9a67412013-09-25 17:40:42 +0530154
155 if((property_get("debug.mdpcomp.4k2kSplit", property, "0") > 0) &&
156 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
157 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
158 sEnable4k2kYUVSplit = true;
159 }
Sushil Chauhan4259d872014-05-13 18:17:12 -0700160
161 if ((property_get("persist.hwc.ptor.enable", property, NULL) > 0) &&
162 ((!strncasecmp(property, "true", PROPERTY_VALUE_MAX )) ||
163 (!strncmp(property, "1", PROPERTY_VALUE_MAX )))) {
164 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
165 HWC_DISPLAY_PRIMARY);
166 }
167
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700168 return true;
169}
170
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800171void MDPComp::reset(hwc_context_t *ctx) {
172 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700173 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800174 ctx->mOverlay->clear(mDpy);
175 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700176}
177
Raj Kamal5166b312014-06-06 13:45:20 +0530178void MDPComp::reset() {
Raj Kamal46dc44f2015-03-16 21:59:25 +0530179 mPrevModeOn = mModeOn;
Raj Kamal5166b312014-06-06 13:45:20 +0530180 mModeOn = false;
181}
182
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700183void MDPComp::timeout_handler(void *udata) {
184 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
Raj Kamal46dc44f2015-03-16 21:59:25 +0530185 bool handleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700186
187 if(!ctx) {
188 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
189 return;
190 }
Raj Kamal46dc44f2015-03-16 21:59:25 +0530191
Ramkumar Radhakrishnand8595ae2014-02-06 21:31:29 -0800192 Locker::Autolock _l(ctx->mDrawLock);
Raj Kamal46dc44f2015-03-16 21:59:25 +0530193
194 /* Handle timeout event only if the previous composition
195 on any display is MDP or MIXED*/
196 for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
197 if(ctx->mMDPComp[i])
198 handleTimeout =
199 ctx->mMDPComp[i]->isMDPComp() || handleTimeout;
200 }
201
202 if(!handleTimeout) {
Ramkumar Radhakrishnand8595ae2014-02-06 21:31:29 -0800203 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
204 return;
205 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700206 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700207 ALOGE("%s: HWC proc not registered", __FUNCTION__);
208 return;
209 }
210 sIdleFallBack = true;
211 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700212 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700213}
214
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800215void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800216 hwc_display_contents_1_t* list) {
217 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800218
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800219 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800220 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800221 if(!mCurrentFrame.isFBComposed[index]) {
222 layerProp[index].mFlags |= HWC_MDPCOMP;
223 layer->compositionType = HWC_OVERLAY;
224 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800225 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700226 /* Drop the layer when its already present in FB OR when it lies
227 * outside frame's ROI */
228 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800229 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700230 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800231 }
232 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700233}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500234
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800235void MDPComp::setRedraw(hwc_context_t *ctx,
236 hwc_display_contents_1_t* list) {
237 mCurrentFrame.needsRedraw = false;
238 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
239 (list->flags & HWC_GEOMETRY_CHANGED) ||
240 isSkipPresent(ctx, mDpy)) {
241 mCurrentFrame.needsRedraw = true;
242 }
243}
244
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800245MDPComp::FrameInfo::FrameInfo() {
Saurabh Shah8d09ba32014-08-14 10:11:36 -0700246 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700247 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800248}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800249
Saurabh Shahaa236822013-04-24 18:07:26 -0700250void MDPComp::FrameInfo::reset(const int& numLayers) {
Saurabh Shah8d09ba32014-08-14 10:11:36 -0700251 for(int i = 0; i < MAX_PIPES_PER_MIXER; i++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800252 if(mdpToLayer[i].pipeInfo) {
253 delete mdpToLayer[i].pipeInfo;
254 mdpToLayer[i].pipeInfo = NULL;
255 //We dont own the rotator
256 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800257 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800258 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800259
260 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
261 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700262 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800263
Saurabh Shahaa236822013-04-24 18:07:26 -0700264 layerCount = numLayers;
265 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800266 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700267 needsRedraw = true;
Saurabh Shahce188452014-02-05 10:17:43 -0800268 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800269}
270
Saurabh Shahaa236822013-04-24 18:07:26 -0700271void MDPComp::FrameInfo::map() {
272 // populate layer and MDP maps
273 int mdpIdx = 0;
274 for(int idx = 0; idx < layerCount; idx++) {
275 if(!isFBComposed[idx]) {
276 mdpToLayer[mdpIdx].listIndex = idx;
277 layerToMDP[idx] = mdpIdx++;
278 }
279 }
280}
281
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800282MDPComp::LayerCache::LayerCache() {
283 reset();
284}
285
286void MDPComp::LayerCache::reset() {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530287 memset(&isFBComposed, true, sizeof(isFBComposed));
288 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800289 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700290}
291
Saurabh Shahaa236822013-04-24 18:07:26 -0700292void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700293 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530294 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
295 memcpy(&drop, &curFrame.drop, sizeof(drop));
296}
297
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800298bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
299 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530300 if(layerCount != curFrame.layerCount)
301 return false;
302 for(int i = 0; i < curFrame.layerCount; i++) {
303 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
304 (curFrame.drop[i] != drop[i])) {
305 return false;
306 }
Arun Kumar K.Rdff18b82015-07-27 16:00:02 +0530307 hwc_layer_1_t const* layer = &list->hwLayers[i];
308 if(curFrame.isFBComposed[i] && layerUpdating(layer)) {
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800309 return false;
310 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530311 }
312 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800313}
314
Raj Kamal46dc44f2015-03-16 21:59:25 +0530315bool MDPComp::LayerCache::isSameFrame(hwc_context_t *ctx, int dpy,
316 hwc_display_contents_1_t* list) {
317
318 if(layerCount != ctx->listStats[dpy].numAppLayers)
319 return false;
320
321 if((list->flags & HWC_GEOMETRY_CHANGED) ||
322 isSkipPresent(ctx, dpy)) {
323 return false;
324 }
325
326 for(int i = 0; i < layerCount; i++) {
Arun Kumar K.Rdff18b82015-07-27 16:00:02 +0530327 hwc_layer_1_t const* layer = &list->hwLayers[i];
328 if(layerUpdating(layer))
Raj Kamal46dc44f2015-03-16 21:59:25 +0530329 return false;
330 }
331
332 return true;
333}
334
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700335bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
336 private_handle_t *hnd = (private_handle_t *)layer->handle;
337 if((not isYuvBuffer(hnd) and has90Transform(layer)) or
Raj Kamal81cab692014-10-28 15:31:35 +0530338 (not isValidDimension(ctx,layer)) ||
339 isSkipLayer(layer)) {
340 //More conditions here, sRGB+Blend etc
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700341 return false;
342 }
343 return true;
344}
345
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530346bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Saurabh Shah4fdde762013-04-30 18:47:33 -0700347 const int dpy = HWC_DISPLAY_PRIMARY;
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800348 private_handle_t *hnd = (private_handle_t *)layer->handle;
349
350 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700351 if (layer->flags & HWC_COLOR_FILL) {
352 // Color layer
353 return true;
354 }
Steve Kondikc44491f2015-04-14 23:31:16 -0700355 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800356 return false;
357 }
358
Naseer Ahmede850a802013-09-06 13:12:52 -0400359 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400360 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400361 return false;
362
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800363 int hw_w = ctx->dpyAttr[mDpy].xres;
364 int hw_h = ctx->dpyAttr[mDpy].yres;
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800365
Saurabh Shah62e1d732013-09-17 10:44:05 -0700366 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700367 hwc_rect_t dst = layer->displayFrame;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700368 int crop_w = crop.right - crop.left;
369 int crop_h = crop.bottom - crop.top;
370 int dst_w = dst.right - dst.left;
371 int dst_h = dst.bottom - dst.top;
372 float w_dscale = ceilf((float)crop_w / (float)dst_w);
373 float h_dscale = ceilf((float)crop_h / (float)dst_h);
374
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800375 /* Workaround for MDP HW limitation in DSI command mode panels where
376 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
377 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530378 * There also is a HW limilation in MDP, minimum block size is 2x2
379 * Fallback to GPU if height is less than 2.
380 */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800381 if((crop_w < 5)||(crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800382 return false;
383
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800384 if((w_dscale > 1.0f) || (h_dscale > 1.0f)) {
385 const uint32_t downscale =
Saurabh Shah4fdde762013-04-30 18:47:33 -0700386 qdutils::MDPVersion::getInstance().getMaxMDPDownscale();
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800387 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
388 /* Workaround for downscales larger than 4x.
389 * Will be removed once decimator block is enabled for MDSS
390 */
391 if(!qdutils::MDPVersion::getInstance().supportsDecimation()) {
392 if(crop_w > MAX_DISPLAY_DIM || w_dscale > downscale ||
393 h_dscale > downscale)
394 return false;
395 } else {
396 if(w_dscale > 64 || h_dscale > 64)
397 return false;
398 }
399 } else { //A-family
400 if(w_dscale > downscale || h_dscale > downscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700401 return false;
402 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700403 }
404
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800405 return true;
406}
407
Saurabh Shahaf5f5972013-07-30 13:56:35 -0700408ovutils::eDest MDPComp::getMdpPipe(hwc_context_t *ctx, ePipeType type,
409 int mixer) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800410 overlay::Overlay& ov = *ctx->mOverlay;
411 ovutils::eDest mdp_pipe = ovutils::OV_INVALID;
412
413 switch(type) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800414 case MDPCOMP_OV_DMA:
Baldev Sahu5cbb5462014-11-12 15:35:13 +0530415 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_DMA, mDpy, mixer,
416 Overlay::FORMAT_RGB);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800417 if(mdp_pipe != ovutils::OV_INVALID) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800418 return mdp_pipe;
419 }
420 case MDPCOMP_OV_ANY:
421 case MDPCOMP_OV_RGB:
Baldev Sahu5cbb5462014-11-12 15:35:13 +0530422 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy, mixer,
423 Overlay::FORMAT_RGB);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800424 if(mdp_pipe != ovutils::OV_INVALID) {
425 return mdp_pipe;
426 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800427
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800428 if(type == MDPCOMP_OV_RGB) {
429 //Requested only for RGB pipe
430 break;
431 }
432 case MDPCOMP_OV_VG:
Baldev Sahu5cbb5462014-11-12 15:35:13 +0530433 return ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy, mixer,
434 Overlay::FORMAT_YUV);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800435 default:
436 ALOGE("%s: Invalid pipe type",__FUNCTION__);
437 return ovutils::OV_INVALID;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800438 };
439 return ovutils::OV_INVALID;
440}
441
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800442bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700443 bool ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700444 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800445
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800446 if(!isEnabled()) {
447 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700448 ret = false;
Saurabh Shahd4e65852013-06-17 11:33:53 -0700449 } else if(qdutils::MDPVersion::getInstance().is8x26() &&
Tatenda Chipeperekwa75a41812014-04-01 12:54:13 -0700450 ctx->mVideoTransFlag &&
451 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700452 //1 Padding round to shift pipes across mixers
453 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
454 __FUNCTION__);
455 ret = false;
Raj Kamal2a18d6d2015-03-17 20:53:14 +0530456 } else if(qdutils::MDPVersion::getInstance().is8x26() &&
457 !mDpy && isSecondaryAnimating(ctx) &&
458 (isYuvPresent(ctx,HWC_DISPLAY_EXTERNAL) ||
459 isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL))) {
460 ALOGD_IF(isDebug(),"%s: Display animation in progress",
461 __FUNCTION__);
462 ret = false;
Ramkumar Radhakrishnan0f952612013-12-30 23:11:27 -0800463 } else if(isSecondaryConfiguring(ctx)) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800464 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800465 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700466 ret = false;
Saurabh Shahaa236822013-04-24 18:07:26 -0700467 } else if(ctx->isPaddingRound) {
Raj Kamalfc5b9222014-02-07 16:15:17 +0530468 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
469 __FUNCTION__,mDpy);
Saurabh Shahaa236822013-04-24 18:07:26 -0700470 ret = false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700471 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700472 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800473}
474
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800475/*
476 * 1) Identify layers that are not visible in the updating ROI and drop them
477 * from composition.
478 * 2) If we have a scaling layers which needs cropping against generated ROI.
479 * Reset ROI to full resolution.
480 */
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700481bool MDPComp::validateAndApplyROI(hwc_context_t *ctx,
482 hwc_display_contents_1_t* list, hwc_rect_t roi) {
483 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
484
485 if(!isValidRect(roi))
486 return false;
487
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800488 hwc_rect_t visibleRect = roi;
489
490 for(int i = numAppLayers - 1; i >= 0; i--){
491
492 if(!isValidRect(visibleRect)) {
493 mCurrentFrame.drop[i] = true;
494 mCurrentFrame.dropCount++;
Jeykumar Sankaran65bc8022014-01-21 17:26:12 -0800495 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800496 }
497
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700498 const hwc_layer_1_t* layer = &list->hwLayers[i];
499
500 hwc_rect_t dstRect = layer->displayFrame;
Arun Kumar K.R91090c72013-10-28 19:40:18 -0700501 hwc_rect_t srcRect = integerizeSourceCrop(layer->sourceCropf);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700502 int transform = layer->transform;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700503
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800504 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700505
506 int res_w = res.right - res.left;
507 int res_h = res.bottom - res.top;
508 int dst_w = dstRect.right - dstRect.left;
509 int dst_h = dstRect.bottom - dstRect.top;
510
511 if(!isValidRect(res)) {
512 mCurrentFrame.drop[i] = true;
513 mCurrentFrame.dropCount++;
514 }else {
515 /* Reset frame ROI when any layer which needs scaling also needs ROI
516 * cropping */
Jeykumar Sankaran65bc8022014-01-21 17:26:12 -0800517 if((res_w != dst_w || res_h != dst_h) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800518 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700519 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
520 mCurrentFrame.dropCount = 0;
521 return false;
522 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800523
Jeykumar Sankaran65bc8022014-01-21 17:26:12 -0800524 /* deduct any opaque region from visibleRect */
radhakrishna31858932014-11-03 13:19:27 +0530525 if (layer->blending == HWC_BLENDING_NONE &&
526 layer->planeAlpha == 0xFF)
Jeykumar Sankaran65bc8022014-01-21 17:26:12 -0800527 visibleRect = deductRect(visibleRect, res);
528 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700529 }
530 return true;
531}
532
Jeykumar Sankaran4d76a382014-02-26 18:26:58 -0800533bool MDPComp::canDoPartialUpdate(hwc_context_t *ctx,
534 hwc_display_contents_1_t* list){
535 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() || mDpy ||
536 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED)||
537 isDisplaySplit(ctx, mDpy)) {
538 return false;
539 }
Jeykumar Sankaranb582a0e2014-07-02 12:23:09 -0700540
541 if(ctx->listStats[mDpy].secureUI)
542 return false;
543
Jeykumar Sankaran4d76a382014-02-26 18:26:58 -0800544 return true;
545}
546
Arun Kumar K.Rdff18b82015-07-27 16:00:02 +0530547/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
548 * are updating. If DirtyRegion is applicable, calculate it by accounting all
549 * the changing layer's dirtyRegion. */
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700550void MDPComp::generateROI(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
551 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
552
Jeykumar Sankaran4d76a382014-02-26 18:26:58 -0800553 if(!canDoPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700554 return;
555
556 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Arun Kumar K.Rdff18b82015-07-27 16:00:02 +0530557 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
558 (int)ctx->dpyAttr[mDpy].yres};
559
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700560 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran4d76a382014-02-26 18:26:58 -0800561 hwc_layer_1_t* layer = &list->hwLayers[index];
Arun Kumar K.Rdff18b82015-07-27 16:00:02 +0530562 if (layerUpdating(layer) ||
Jeykumar Sankaran78893422014-05-07 16:23:14 -0700563 isYuvBuffer((private_handle_t *)layer->handle)) {
Arun Kumar K.Rdff18b82015-07-27 16:00:02 +0530564 hwc_rect_t updatingRect = layer->displayFrame;
565 if(!needsScaling(layer) && !layer->transform &&
566 (!isYuvBuffer((private_handle_t *)layer->handle)))
Jeykumar Sankaran78893422014-05-07 16:23:14 -0700567 {
Arun Kumar K.Rdff18b82015-07-27 16:00:02 +0530568 updatingRect = calculateDirtyRect(layer, fullFrame);
Jeykumar Sankaran78893422014-05-07 16:23:14 -0700569 }
Arun Kumar K.Rdff18b82015-07-27 16:00:02 +0530570
Jeykumar Sankaran4d76a382014-02-26 18:26:58 -0800571 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700572 }
573 }
574
Jeykumar Sankaran4d76a382014-02-26 18:26:58 -0800575 // 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
Raj Kamal2a18d6d2015-03-17 20:53:14 +0530602 if(!mDpy && isSecondaryAnimating(ctx) &&
603 (isYuvPresent(ctx,HWC_DISPLAY_EXTERNAL) ||
604 isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL)) ) {
605 ALOGD_IF(isDebug(),"%s: Display animation in progress",
606 __FUNCTION__);
607 return false;
608 }
609
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800610 // check for action safe flag and downscale mode which requires scaling.
611 if(ctx->dpyAttr[mDpy].mActionSafePresent
612 || ctx->dpyAttr[mDpy].mDownScaleMode) {
613 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
614 return false;
615 }
616
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800617 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800618 hwc_layer_1_t* layer = &list->hwLayers[i];
619 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800620
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700621 if(isYuvBuffer(hnd) && has90Transform(layer)) {
622 if(!canUseRotator(ctx, mDpy)) {
623 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
624 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700625 return false;
626 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800627 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530628
629 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
630 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhand8ef93f2014-03-20 11:08:41 -0700631 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530632 if(qdutils::MDPVersion::getInstance().is8x26() &&
633 (ctx->dpyAttr[mDpy].xres > 1024) &&
Sushil Chauhand8ef93f2014-03-20 11:08:41 -0700634 (transform & HWC_TRANSFORM_FLIP_H) &&
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530635 (!isYuvBuffer(hnd)))
636 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800637 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700638
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700639 if(ctx->mAD->isDoable()) {
640 return false;
641 }
642
Saurabh Shahaa236822013-04-24 18:07:26 -0700643 //If all above hard conditions are met we can do full or partial MDP comp.
644 bool ret = false;
645 if(fullMDPComp(ctx, list)) {
646 ret = true;
Sushil Chauhan4259d872014-05-13 18:17:12 -0700647 } else if(fullMDPCompWithPTOR(ctx, list)) {
648 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700649 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700650 ret = true;
651 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530652
Saurabh Shahaa236822013-04-24 18:07:26 -0700653 return ret;
654}
655
656bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700657 //Will benefit presentation / secondary-only layer.
658 if((mDpy > HWC_DISPLAY_PRIMARY) &&
659 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
660 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
661 return false;
662 }
663
664 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
665 for(int i = 0; i < numAppLayers; i++) {
666 hwc_layer_1_t* layer = &list->hwLayers[i];
667 if(not isSupportedForMDPComp(ctx, layer)) {
668 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
669 return false;
670 }
671 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800672
Saurabh Shahaa236822013-04-24 18:07:26 -0700673 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700674 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
675 sizeof(mCurrentFrame.isFBComposed));
676 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
677 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700678
radhakrishnac9a67412013-09-25 17:40:42 +0530679 if(sEnable4k2kYUVSplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800680 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530681 }
682
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800683 if(!postHeuristicsHandling(ctx, list)) {
684 ALOGD_IF(isDebug(), "post heuristic handling failed");
685 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700686 return false;
687 }
688
Saurabh Shahaa236822013-04-24 18:07:26 -0700689 return true;
690}
691
Sushil Chauhan4259d872014-05-13 18:17:12 -0700692/* Full MDP Composition with Peripheral Tiny Overlap Removal.
693 * MDP bandwidth limitations can be avoided, if the overlap region
694 * covered by the smallest layer at a higher z-order, gets composed
695 * by Copybit on a render buffer, which can be queued to MDP.
696 */
697bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
698 hwc_display_contents_1_t* list) {
699
700 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
701 const int stagesForMDP = min(sMaxPipesPerMixer,
702 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
703
704 // Hard checks where we cannot use this mode
Justin Philipb1906f72014-10-30 14:14:19 +0530705 if (mDpy || !ctx->mCopyBit[mDpy] || !ctx->mIsPTOREnabled) {
Sushil Chauhan4259d872014-05-13 18:17:12 -0700706 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
707 return false;
708 }
709
710 // Frame level checks
711 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
712 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
713 isSecurePresent(ctx, mDpy)) {
714 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
715 return false;
716 }
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700717 // MDP comp checks
718 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhan4259d872014-05-13 18:17:12 -0700719 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700720 if(not isSupportedForMDPComp(ctx, layer)) {
721 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
722 return false;
Sushil Chauhan4259d872014-05-13 18:17:12 -0700723 }
724 }
725
Sushil Chauhan4259d872014-05-13 18:17:12 -0700726 /* We cannot use this composition mode, if:
727 1. A below layer needs scaling.
728 2. Overlap is not peripheral to display.
729 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700730 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhan4259d872014-05-13 18:17:12 -0700731 */
732
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700733 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
734 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
735 memset(overlapRect, 0, sizeof(overlapRect));
736 int layerPixelCount, minPixelCount = 0;
737 int numPTORLayersFound = 0;
738 for (int i = numAppLayers-1; (i >= 0 &&
739 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhan4259d872014-05-13 18:17:12 -0700740 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700741 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhan4259d872014-05-13 18:17:12 -0700742 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700743 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
744 // PTOR layer should be peripheral and cannot have transform
745 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
746 has90Transform(layer)) {
747 continue;
748 }
749 if((3 * (layerPixelCount + minPixelCount)) >
750 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
751 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
752 continue;
753 }
Sushil Chauhane1474bf2014-07-25 12:20:23 -0700754 bool found = false;
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700755 for (int j = i-1; j >= 0; j--) {
756 // Check if the layers below this layer qualifies for PTOR comp
757 hwc_layer_1_t* layer = &list->hwLayers[j];
758 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhane1474bf2014-07-25 12:20:23 -0700759 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700760 // needs scaling cannot be supported.
Sushil Chauhane1474bf2014-07-25 12:20:23 -0700761 if (isValidRect(getIntersection(dispFrame, disFrame))) {
762 if (has90Transform(layer) || needsScaling(layer)) {
763 found = false;
764 break;
765 }
766 found = true;
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700767 }
768 }
769 // Store the minLayer Index
770 if(found) {
771 minLayerIndex[numPTORLayersFound] = i;
772 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
773 minPixelCount += layerPixelCount;
774 numPTORLayersFound++;
Sushil Chauhan4259d872014-05-13 18:17:12 -0700775 }
776 }
777
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700778 // No overlap layers
779 if (!numPTORLayersFound)
780 return false;
Sushil Chauhan4259d872014-05-13 18:17:12 -0700781
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700782 // Store the displayFrame and the sourceCrops of the layers
783 hwc_rect_t displayFrame[numAppLayers];
784 hwc_rect_t sourceCrop[numAppLayers];
785 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhan4259d872014-05-13 18:17:12 -0700786 hwc_layer_1_t* layer = &list->hwLayers[i];
787 displayFrame[i] = layer->displayFrame;
788 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700789 }
Sushil Chauhan4259d872014-05-13 18:17:12 -0700790
Prabhanjan Kandulabb1f6be2014-09-04 21:50:35 +0530791 /**
792 * It's possible that 2 PTOR layers might have overlapping.
793 * In such case, remove the intersection(again if peripheral)
794 * from the lower PTOR layer to avoid overlapping.
795 * If intersection is not on peripheral then compromise
796 * by reducing number of PTOR layers.
797 **/
798 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
799 if(isValidRect(commonRect)) {
800 overlapRect[1] = deductRect(overlapRect[1], commonRect);
801 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
802 }
803
804 ctx->mPtorInfo.count = numPTORLayersFound;
805 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
806 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
807 }
808
809 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
810 // reset PTOR
811 ctx->mPtorInfo.count = 0;
812 if(isValidRect(commonRect)) {
813 // If PTORs are intersecting restore displayframe of PTOR[1]
814 // before returning, as we have modified it above.
815 list->hwLayers[minLayerIndex[1]].displayFrame =
816 displayFrame[minLayerIndex[1]];
817 }
818 return false;
819 }
Sushil Chauhane1474bf2014-07-25 12:20:23 -0700820 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
821 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
822
Xu Yang645cb1f2014-07-30 21:57:21 +0800823 // Store the blending mode, planeAlpha, and transform of PTOR layers
824 int32_t blending[numPTORLayersFound];
825 uint8_t planeAlpha[numPTORLayersFound];
826 uint32_t transform[numPTORLayersFound];
827
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700828 for(int j = 0; j < numPTORLayersFound; j++) {
829 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhane1474bf2014-07-25 12:20:23 -0700830
831 // Update src crop of PTOR layer
832 hwc_layer_1_t* layer = &list->hwLayers[index];
833 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
834 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
835 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
836 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
837
838 // Store & update w, h, format of PTOR layer
839 private_handle_t *hnd = (private_handle_t *)layer->handle;
840 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
841 layerWhf[j] = whf;
842 hnd->width = renderBuf->width;
843 hnd->height = renderBuf->height;
844 hnd->format = renderBuf->format;
845
Xu Yang645cb1f2014-07-30 21:57:21 +0800846 // Store & update blending mode, planeAlpha and transform of PTOR layer
847 blending[j] = layer->blending;
848 planeAlpha[j] = layer->planeAlpha;
849 transform[j] = layer->transform;
850 layer->blending = HWC_BLENDING_NONE;
851 layer->planeAlpha = 0xFF;
852 layer->transform = 0;
853
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700854 // Remove overlap from crop & displayFrame of below layers
855 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhane1474bf2014-07-25 12:20:23 -0700856 layer = &list->hwLayers[i];
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700857 if(!isValidRect(getIntersection(layer->displayFrame,
858 overlapRect[j]))) {
859 continue;
860 }
861 // Update layer attributes
862 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
863 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddicc32af02014-11-11 16:03:03 +0530864 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700865 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
866 layer->transform);
867 layer->sourceCropf.left = (float)srcCrop.left;
868 layer->sourceCropf.top = (float)srcCrop.top;
869 layer->sourceCropf.right = (float)srcCrop.right;
870 layer->sourceCropf.bottom = (float)srcCrop.bottom;
871 }
Sushil Chauhan4259d872014-05-13 18:17:12 -0700872 }
873
874 mCurrentFrame.mdpCount = numAppLayers;
875 mCurrentFrame.fbCount = 0;
876 mCurrentFrame.fbZ = -1;
877
Dileep Kumar Reddicc32af02014-11-11 16:03:03 +0530878 for (int j = 0; j < numAppLayers; j++) {
879 if(isValidRect(list->hwLayers[j].displayFrame)) {
880 mCurrentFrame.isFBComposed[j] = false;
881 } else {
882 mCurrentFrame.mdpCount--;
883 mCurrentFrame.drop[j] = true;
884 }
885 }
Sushil Chauhan4259d872014-05-13 18:17:12 -0700886
887 bool result = postHeuristicsHandling(ctx, list);
888
889 // Restore layer attributes
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700890 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhan4259d872014-05-13 18:17:12 -0700891 hwc_layer_1_t* layer = &list->hwLayers[i];
892 layer->displayFrame = displayFrame[i];
893 layer->sourceCropf.left = (float)sourceCrop[i].left;
894 layer->sourceCropf.top = (float)sourceCrop[i].top;
895 layer->sourceCropf.right = (float)sourceCrop[i].right;
896 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
897 }
898
Xu Yang645cb1f2014-07-30 21:57:21 +0800899 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhane1474bf2014-07-25 12:20:23 -0700900 for (int i = 0; i < numPTORLayersFound; i++) {
901 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yang645cb1f2014-07-30 21:57:21 +0800902 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhane1474bf2014-07-25 12:20:23 -0700903 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
904 hnd->width = layerWhf[i].w;
905 hnd->height = layerWhf[i].h;
906 hnd->format = layerWhf[i].format;
Xu Yang645cb1f2014-07-30 21:57:21 +0800907 layer->blending = blending[i];
908 layer->planeAlpha = planeAlpha[i];
909 layer->transform = transform[i];
Sushil Chauhane1474bf2014-07-25 12:20:23 -0700910 }
911
Sushil Chauhan4259d872014-05-13 18:17:12 -0700912 if (!result) {
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700913 // reset PTOR
914 ctx->mPtorInfo.count = 0;
Sushil Chauhan4259d872014-05-13 18:17:12 -0700915 reset(ctx);
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700916 } else {
917 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
918 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhan4259d872014-05-13 18:17:12 -0700919 }
920
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -0700921 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
922 (result ? "successful" : "failed"));
Sushil Chauhan4259d872014-05-13 18:17:12 -0700923 return result;
924}
925
Saurabh Shahaa236822013-04-24 18:07:26 -0700926bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
927{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700928 if(!sEnableMixedMode) {
929 //Mixed mode is disabled. No need to even try caching.
930 return false;
931 }
932
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700933 bool ret = false;
Raj Kamal81cab692014-10-28 15:31:35 +0530934 if(isSkipPresent(ctx, mDpy) or list->flags & HWC_GEOMETRY_CHANGED) {
935 //Try load based first
Saurabh Shah6e8ab772014-02-20 16:18:45 -0800936 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800937 cacheBasedComp(ctx, list);
938 } else {
939 ret = cacheBasedComp(ctx, list) or
Saurabh Shah6e8ab772014-02-20 16:18:45 -0800940 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700941 }
942
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700943 return ret;
944}
945
946bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
947 hwc_display_contents_1_t* list) {
948 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -0700949 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.R1d4bbd22014-08-20 17:14:26 -0700950 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700951
952 //If an MDP marked layer is unsupported cannot do partial MDP Comp
953 for(int i = 0; i < numAppLayers; i++) {
954 if(!mCurrentFrame.isFBComposed[i]) {
955 hwc_layer_1_t* layer = &list->hwLayers[i];
956 if(not isSupportedForMDPComp(ctx, layer)) {
957 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
958 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800959 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700960 return false;
961 }
962 }
963 }
964
Arun Kumar K.R1d4bbd22014-08-20 17:14:26 -0700965 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
966
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +0530967 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700968 if(!ret) {
969 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800970 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700971 return false;
972 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700973
974 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700975
radhakrishnac9a67412013-09-25 17:40:42 +0530976 if(sEnable4k2kYUVSplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800977 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530978 }
979
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700980 //Will benefit cases where a video has non-updating background.
981 if((mDpy > HWC_DISPLAY_PRIMARY) and
982 (mdpCount > MAX_SEC_LAYERS)) {
983 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800984 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700985 return false;
986 }
987
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800988 if(!postHeuristicsHandling(ctx, list)) {
989 ALOGD_IF(isDebug(), "post heuristic handling failed");
990 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700991 return false;
992 }
993
Saurabh Shahaa236822013-04-24 18:07:26 -0700994 return true;
995}
996
Saurabh Shah6e8ab772014-02-20 16:18:45 -0800997bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -0800998 hwc_display_contents_1_t* list) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800999 if(not isLoadBasedCompDoable(ctx, list)) {
1000 return false;
1001 }
1002
Saurabh Shahb772ae32013-11-18 15:40:02 -08001003 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah6e8ab772014-02-20 16:18:45 -08001004 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1005 const int stagesForMDP = min(sMaxPipesPerMixer,
1006 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001007
Saurabh Shah6e8ab772014-02-20 16:18:45 -08001008 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1009 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1010 int lastMDPSupportedIndex = numAppLayers;
1011 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001012
Saurabh Shah6e8ab772014-02-20 16:18:45 -08001013 //Find the minimum MDP batch size
1014 for(int i = 0; i < numAppLayers;i++) {
1015 if(mCurrentFrame.drop[i]) {
1016 dropCount++;
Jeykumar Sankaran6279bc32014-01-23 21:59:58 -08001017 continue;
Saurabh Shah6e8ab772014-02-20 16:18:45 -08001018 }
1019 hwc_layer_1_t* layer = &list->hwLayers[i];
1020 if(not isSupportedForMDPComp(ctx, layer)) {
1021 lastMDPSupportedIndex = i;
1022 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1023 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran6279bc32014-01-23 21:59:58 -08001024 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001025 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001026 }
1027
Saurabh Shah6e8ab772014-02-20 16:18:45 -08001028 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1029 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1030 mCurrentFrame.dropCount);
1031
1032 //Start at a point where the fb batch should at least have 2 layers, for
1033 //this mode to be justified.
1034 while(fbBatchSize < 2) {
1035 ++fbBatchSize;
1036 --mdpBatchSize;
Jeykumar Sankaran6279bc32014-01-23 21:59:58 -08001037 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001038
Saurabh Shah6e8ab772014-02-20 16:18:45 -08001039 //If there are no layers for MDP, this mode doesnt make sense.
1040 if(mdpBatchSize < 1) {
1041 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1042 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001043 return false;
1044 }
1045
Saurabh Shah6e8ab772014-02-20 16:18:45 -08001046 mCurrentFrame.reset(numAppLayers);
1047
1048 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1049 while(mdpBatchSize > 0) {
1050 //Mark layers for MDP comp
1051 int mdpBatchLeft = mdpBatchSize;
1052 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1053 if(mCurrentFrame.drop[i]) {
1054 continue;
1055 }
1056 mCurrentFrame.isFBComposed[i] = false;
1057 --mdpBatchLeft;
1058 }
1059
1060 mCurrentFrame.fbZ = mdpBatchSize;
1061 mCurrentFrame.fbCount = fbBatchSize;
1062 mCurrentFrame.mdpCount = mdpBatchSize;
1063
1064 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1065 __FUNCTION__, mdpBatchSize, fbBatchSize,
1066 mCurrentFrame.dropCount);
1067
1068 if(postHeuristicsHandling(ctx, list)) {
1069 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
1070 __FUNCTION__);
1071 return true;
1072 }
1073
1074 reset(ctx);
1075 --mdpBatchSize;
1076 ++fbBatchSize;
1077 }
1078
1079 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001080}
1081
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001082bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx,
1083 hwc_display_contents_1_t* list) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301084 if(mDpy or isSecurePresent(ctx, mDpy) or
1085 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001086 return false;
1087 }
1088 return true;
1089}
1090
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001091bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1092 hwc_display_contents_1_t* list) {
1093 const bool secureOnly = true;
1094 return videoOnlyComp(ctx, list, not secureOnly) or
1095 videoOnlyComp(ctx, list, secureOnly);
1096}
1097
1098bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001099 hwc_display_contents_1_t* list, bool secureOnly) {
Saurabh Shahaa236822013-04-24 18:07:26 -07001100 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001101
Saurabh Shahaa236822013-04-24 18:07:26 -07001102 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.R1d4bbd22014-08-20 17:14:26 -07001103 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001104 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001105
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001106 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1107 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001108 return false;
1109 }
1110
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001111 /* Bail out if we are processing only secured video layers
1112 * and we dont have any */
1113 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001114 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001115 return false;
1116 }
1117
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001118 if(mCurrentFrame.fbCount)
1119 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001120
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001121 if(sEnable4k2kYUVSplit){
1122 adjustForSourceSplit(ctx, list);
1123 }
1124
1125 if(!postHeuristicsHandling(ctx, list)) {
1126 ALOGD_IF(isDebug(), "post heuristic handling failed");
Justin Philipc9907322015-01-06 11:55:12 +05301127 if(errno == ENOBUFS) {
1128 ALOGD_IF(isDebug(), "SMP Allocation failed");
1129 //On SMP allocation failure in video only comp add padding round
1130 ctx->isPaddingRound = true;
1131 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001132 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001133 return false;
1134 }
1135
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001136 return true;
1137}
1138
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001139/* Checks for conditions where YUV layers cannot be bypassed */
1140bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001141 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001142 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001143 return false;
1144 }
1145
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001146 if(layer->transform & HWC_TRANSFORM_ROT_90 && !canUseRotator(ctx,mDpy)) {
1147 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1148 return false;
1149 }
1150
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001151 if(isSecuring(ctx, layer)) {
1152 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1153 return false;
1154 }
1155
Saurabh Shah4fdde762013-04-30 18:47:33 -07001156 if(!isValidDimension(ctx, layer)) {
1157 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1158 __FUNCTION__);
1159 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001160 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001161
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001162 if(layer->planeAlpha < 0xFF) {
1163 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1164 in video only mode",
1165 __FUNCTION__);
1166 return false;
1167 }
1168
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001169 return true;
1170}
1171
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301172/* starts at fromIndex and check for each layer to find
1173 * if it it has overlapping with any Updating layer above it in zorder
1174 * till the end of the batch. returns true if it finds any intersection */
1175bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1176 int fromIndex, int toIndex) {
1177 for(int i = fromIndex; i < toIndex; i++) {
1178 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1179 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1180 return false;
1181 }
1182 }
1183 }
1184 return true;
1185}
1186
1187/* Checks if given layer at targetLayerIndex has any
1188 * intersection with all the updating layers in beween
1189 * fromIndex and toIndex. Returns true if it finds intersectiion */
1190bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1191 int fromIndex, int toIndex, int targetLayerIndex) {
1192 for(int i = fromIndex; i <= toIndex; i++) {
1193 if(!mCurrentFrame.isFBComposed[i]) {
1194 if(areLayersIntersecting(&list->hwLayers[i],
1195 &list->hwLayers[targetLayerIndex])) {
1196 return true;
1197 }
1198 }
1199 }
1200 return false;
1201}
1202
1203int MDPComp::getBatch(hwc_display_contents_1_t* list,
1204 int& maxBatchStart, int& maxBatchEnd,
1205 int& maxBatchCount) {
1206 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301207 int fbZOrder =-1;
Jeykumar Sankaran5a495da2014-01-20 12:25:32 -08001208 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301209 while (i < mCurrentFrame.layerCount) {
1210 int batchCount = 0;
1211 int batchStart = i;
1212 int batchEnd = i;
Jeykumar Sankaran5a495da2014-01-20 12:25:32 -08001213 /* Adjust batch Z order with the dropped layers so far */
1214 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301215 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301216 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301217 while(i < mCurrentFrame.layerCount) {
1218 if(!mCurrentFrame.isFBComposed[i]) {
1219 if(!batchCount) {
1220 i++;
1221 break;
1222 }
1223 updatingLayersAbove++;
1224 i++;
1225 continue;
1226 } else {
1227 if(mCurrentFrame.drop[i]) {
1228 i++;
Jeykumar Sankaran5a495da2014-01-20 12:25:32 -08001229 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301230 continue;
1231 } else if(updatingLayersAbove <= 0) {
1232 batchCount++;
1233 batchEnd = i;
1234 i++;
1235 continue;
1236 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1237
1238 // We have a valid updating layer already. If layer-i not
1239 // have overlapping with all updating layers in between
1240 // batch-start and i, then we can add layer i to batch.
1241 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1242 batchCount++;
1243 batchEnd = i;
1244 i++;
1245 continue;
1246 } else if(canPushBatchToTop(list, batchStart, i)) {
1247 //If All the non-updating layers with in this batch
1248 //does not have intersection with the updating layers
1249 //above in z-order, then we can safely move the batch to
1250 //higher z-order. Increment fbZ as it is moving up.
1251 if( firstZReverseIndex < 0) {
1252 firstZReverseIndex = i;
1253 }
1254 batchCount++;
1255 batchEnd = i;
1256 fbZ += updatingLayersAbove;
1257 i++;
1258 updatingLayersAbove = 0;
1259 continue;
1260 } else {
1261 //both failed.start the loop again from here.
1262 if(firstZReverseIndex >= 0) {
1263 i = firstZReverseIndex;
1264 }
1265 break;
1266 }
1267 }
1268 }
1269 }
1270 if(batchCount > maxBatchCount) {
1271 maxBatchCount = batchCount;
1272 maxBatchStart = batchStart;
1273 maxBatchEnd = batchEnd;
1274 fbZOrder = fbZ;
1275 }
1276 }
1277 return fbZOrder;
1278}
1279
1280bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1281 hwc_display_contents_1_t* list) {
1282 /* Idea is to keep as many non-updating(cached) layers in FB and
1283 * send rest of them through MDP. This is done in 2 steps.
1284 * 1. Find the maximum contiguous batch of non-updating layers.
1285 * 2. See if we can improve this batch size for caching by adding
1286 * opaque layers around the batch, if they don't have
1287 * any overlapping with the updating layers in between.
1288 * NEVER mark an updating layer for caching.
1289 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001290
1291 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001292 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001293 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301294 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001295
Saurabh Shahce188452014-02-05 10:17:43 -08001296 /* Nothing is cached. No batching needed */
1297 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001298 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001299 }
Saurabh Shahce188452014-02-05 10:17:43 -08001300
1301 /* No MDP comp layers, try to use other comp modes */
1302 if(mCurrentFrame.mdpCount == 0) {
1303 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001304 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001305
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301306 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001307
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301308 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001309 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001310 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001311 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301312 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001313 if(!mCurrentFrame.drop[i]){
1314 //If an unsupported layer is being attempted to
1315 //be pulled out we should fail
1316 if(not isSupportedForMDPComp(ctx, layer)) {
1317 return false;
1318 }
1319 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001320 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001321 }
1322 }
1323
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301324 // update the frame data
1325 mCurrentFrame.fbZ = fbZ;
1326 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001327 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001328 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001329
1330 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301331 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001332
1333 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001334}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001335
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001336void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.R1d4bbd22014-08-20 17:14:26 -07001337 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001338 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001339 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001340
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001341 for(int i = 0; i < numAppLayers; i++) {
Arun Kumar K.Rdff18b82015-07-27 16:00:02 +05301342 hwc_layer_1_t * layer = &list->hwLayers[i];
1343 if (!layerUpdating(layer)) {
Arun Kumar K.R1d4bbd22014-08-20 17:14:26 -07001344 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001345 fbCount++;
Arun Kumar K.R1d4bbd22014-08-20 17:14:26 -07001346 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001347 } else {
Arun Kumar K.R1d4bbd22014-08-20 17:14:26 -07001348 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001349 }
1350 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001351
Arun Kumar K.R1d4bbd22014-08-20 17:14:26 -07001352 frame.fbCount = fbCount;
1353 frame.mdpCount = frame.layerCount - frame.fbCount
1354 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001355
Arun Kumar K.R1d4bbd22014-08-20 17:14:26 -07001356 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1357 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001358}
1359
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001360void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.R1d4bbd22014-08-20 17:14:26 -07001361 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001362 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1363 for(int index = 0;index < nYuvCount; index++){
1364 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1365 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1366
1367 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.R1d4bbd22014-08-20 17:14:26 -07001368 if(!frame.isFBComposed[nYuvIndex]) {
1369 frame.isFBComposed[nYuvIndex] = true;
1370 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001371 }
1372 } else {
Arun Kumar K.R1d4bbd22014-08-20 17:14:26 -07001373 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001374 private_handle_t *hnd = (private_handle_t *)layer->handle;
1375 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.R1d4bbd22014-08-20 17:14:26 -07001376 frame.isFBComposed[nYuvIndex] = false;
1377 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001378 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001379 }
1380 }
1381 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001382
Arun Kumar K.R1d4bbd22014-08-20 17:14:26 -07001383 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1384 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001385}
1386
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001387bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1388 hwc_display_contents_1_t* list) {
1389
1390 //Capability checks
1391 if(!resourceCheck(ctx, list)) {
1392 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1393 return false;
1394 }
1395
1396 //Limitations checks
1397 if(!hwLimitationsCheck(ctx, list)) {
1398 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1399 return false;
1400 }
1401
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001402 //Configure framebuffer first if applicable
1403 if(mCurrentFrame.fbZ >= 0) {
1404 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, mCurrentFrame.fbZ)) {
1405 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1406 __FUNCTION__);
1407 return false;
1408 }
1409 }
1410
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001411 mCurrentFrame.map();
1412
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001413 if(!allocLayerPipes(ctx, list)) {
1414 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001415 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001416 }
1417
1418 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001419 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001420 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001421 int mdpIndex = mCurrentFrame.layerToMDP[index];
1422 hwc_layer_1_t* layer = &list->hwLayers[index];
1423
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301424 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1425 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1426 mdpNextZOrder++;
1427 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001428 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1429 cur_pipe->zOrder = mdpNextZOrder++;
1430
radhakrishnac9a67412013-09-25 17:40:42 +05301431 private_handle_t *hnd = (private_handle_t *)layer->handle;
1432 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
1433 if(configure4k2kYuv(ctx, layer,
1434 mCurrentFrame.mdpToLayer[mdpIndex])
1435 != 0 ){
1436 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1437 for layer %d",__FUNCTION__, index);
1438 return false;
1439 }
1440 else{
1441 mdpNextZOrder++;
1442 }
1443 continue;
1444 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001445 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1446 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301447 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001448 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001449 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001450 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001451 }
1452
Saurabh Shah450ac972013-12-16 18:18:39 -08001453 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1454 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1455 ,__FUNCTION__, mDpy);
1456 return false;
1457 }
1458
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001459 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001460 return true;
1461}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001462
Saurabh Shah173f4242013-11-20 09:50:12 -08001463bool MDPComp::resourceCheck(hwc_context_t *ctx,
1464 hwc_display_contents_1_t *list) {
1465 const bool fbUsed = mCurrentFrame.fbCount;
1466 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1467 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1468 return false;
1469 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001470 return true;
1471}
1472
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301473bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1474 hwc_display_contents_1_t* list) {
1475
1476 //A-family hw limitation:
1477 //If a layer need alpha scaling, MDP can not support.
1478 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1479 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1480 if(!mCurrentFrame.isFBComposed[i] &&
1481 isAlphaScaled( &list->hwLayers[i])) {
1482 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1483 return false;
1484 }
1485 }
1486 }
1487
1488 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1489 //If multiple layers requires downscaling and also they are overlapping
1490 //fall back to GPU since MDSS can not handle it.
1491 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1492 qdutils::MDPVersion::getInstance().is8x26()) {
1493 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1494 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1495 if(!mCurrentFrame.isFBComposed[i] &&
1496 isDownscaleRequired(botLayer)) {
1497 //if layer-i is marked for MDP and needs downscaling
1498 //check if any MDP layer on top of i & overlaps with layer-i
1499 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1500 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1501 if(!mCurrentFrame.isFBComposed[j] &&
1502 isDownscaleRequired(topLayer)) {
1503 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1504 topLayer->displayFrame);
1505 if(isValidRect(r))
1506 return false;
1507 }
1508 }
1509 }
1510 }
1511 }
1512 return true;
1513}
1514
Praveena Pachipulusuab89fcf2014-11-25 18:47:54 +05301515void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1516 //For primary display, set the dynamic refreshrate
1517 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
1518 ctx->mUseMetaDataRefreshRate) {
1519 FrameInfo frame;
1520 frame.reset(mCurrentFrame.layerCount);
1521 memset(&frame.drop, 0, sizeof(frame.drop));
1522 frame.dropCount = 0;
1523 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
1524 __FUNCTION__);
1525 updateLayerCache(ctx, list, frame);
1526 updateYUV(ctx, list, false /*secure only*/, frame);
1527 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1528 MDPVersion& mdpHw = MDPVersion::getInstance();
1529 if(sIdleFallBack) {
1530 //Set minimum panel refresh rate during idle timeout
1531 refreshRate = mdpHw.getMinFpsSupported();
1532 } else if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1533 (frame.layerCount == 1)) {
1534 //Set the new fresh rate, if there is only one updating YUV layer
1535 //or there is one single RGB layer with this request
1536 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1537 }
1538 setRefreshRate(ctx, mDpy, refreshRate);
1539 }
1540}
1541
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001542int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001543 int ret = 0;
Raj Kamal5166b312014-06-06 13:45:20 +05301544
1545 if(!ctx || !list) {
1546 ALOGE("%s: Invalid context or list",__FUNCTION__);
1547 mCachedFrame.reset();
1548 return -1;
1549 }
1550
Saurabh Shahaa236822013-04-24 18:07:26 -07001551 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahf5f2b132013-11-25 12:08:35 -08001552 MDPVersion& mdpVersion = qdutils::MDPVersion::getInstance();
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -07001553
1554 // reset PTOR
1555 if(!mDpy)
1556 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001557
Saurabh Shahb39f8152013-08-22 10:21:44 -07001558 //reset old data
1559 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001560 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1561 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301562
Praveena Pachipulusuab89fcf2014-11-25 18:47:54 +05301563 //Do not cache the information for next draw cycle.
1564 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1565 ALOGI("%s: Unsupported layer count for mdp composition",
1566 __FUNCTION__);
1567 mCachedFrame.reset();
1568#ifdef DYNAMIC_FPS
1569 setDynRefreshRate(ctx, list);
1570#endif
1571 return -1;
1572 }
1573
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001574 // Detect the start of animation and fall back to GPU only once to cache
1575 // all the layers in FB and display FB content untill animation completes.
1576 if(ctx->listStats[mDpy].isDisplayAnimating) {
1577 mCurrentFrame.needsRedraw = false;
1578 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1579 mCurrentFrame.needsRedraw = true;
1580 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1581 }
1582 setMDPCompLayerFlags(ctx, list);
1583 mCachedFrame.updateCounts(mCurrentFrame);
Praveena Pachipulusuab89fcf2014-11-25 18:47:54 +05301584#ifdef DYNAMIC_FPS
1585 setDynRefreshRate(ctx, list);
1586#endif
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001587 ret = -1;
1588 return ret;
1589 } else {
1590 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1591 }
1592
Raj Kamal46dc44f2015-03-16 21:59:25 +05301593 if(!mDpy and !isSecondaryConnected(ctx) and !mPrevModeOn and
1594 mCachedFrame.isSameFrame(ctx,mDpy,list)) {
1595 ALOGD_IF(isDebug(),"%s: Avoid new composition",__FUNCTION__);
1596 mCurrentFrame.needsRedraw = false;
1597 setMDPCompLayerFlags(ctx, list);
1598 mCachedFrame.updateCounts(mCurrentFrame);
1599 return -1;
1600
1601 }
1602
Saurabh Shahb39f8152013-08-22 10:21:44 -07001603 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001604 if(isFrameDoable(ctx)) {
1605 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001606
Raj Kamal5166b312014-06-06 13:45:20 +05301607 mModeOn = tryFullFrame(ctx, list) || tryVideoOnly(ctx, list);
1608 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001609 setMDPCompLayerFlags(ctx, list);
1610 } else {
1611 reset(ctx);
1612 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1613 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001614 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001615 }
1616 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001617 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1618 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001619 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001620 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001621
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001622 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001623 ALOGD("GEOMETRY change: %d",
1624 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001625 android::String8 sDump("");
1626 dump(sDump);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001627 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001628 }
1629
Arun Kumar K.R1d4bbd22014-08-20 17:14:26 -07001630#ifdef DYNAMIC_FPS
Praveena Pachipulusuab89fcf2014-11-25 18:47:54 +05301631 setDynRefreshRate(ctx, list);
Arun Kumar K.R1d4bbd22014-08-20 17:14:26 -07001632#endif
1633
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001634 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001635 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001636}
1637
radhakrishnac9a67412013-09-25 17:40:42 +05301638bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx,
1639 hwc_display_contents_1_t* list, int index) {
1640
1641 bool bRet = true;
1642 hwc_layer_1_t* layer = &list->hwLayers[index];
1643 private_handle_t *hnd = (private_handle_t *)layer->handle;
1644 int mdpIndex = mCurrentFrame.layerToMDP[index];
1645 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1646 info.pipeInfo = new MdpYUVPipeInfo;
1647 info.rot = NULL;
1648 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
1649 ePipeType type = MDPCOMP_OV_VG;
1650
1651 pipe_info.lIndex = ovutils::OV_INVALID;
1652 pipe_info.rIndex = ovutils::OV_INVALID;
1653
1654 pipe_info.lIndex = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
1655 if(pipe_info.lIndex == ovutils::OV_INVALID){
1656 bRet = false;
1657 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1658 __FUNCTION__);
1659 }
1660 pipe_info.rIndex = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
1661 if(pipe_info.rIndex == ovutils::OV_INVALID){
1662 bRet = false;
1663 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1664 __FUNCTION__);
1665 }
1666 return bRet;
1667}
Sushil Chauhan4259d872014-05-13 18:17:12 -07001668
1669int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1670 int fd = -1;
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -07001671 if (ctx->mPtorInfo.isActive()) {
1672 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhan4259d872014-05-13 18:17:12 -07001673 if (fd < 0) {
1674 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhan4259d872014-05-13 18:17:12 -07001675 }
1676 }
1677 return fd;
1678}
1679
Saurabh Shah88e4d272013-09-03 13:31:29 -07001680//=============MDPCompNonSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001681
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001682void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05301683 hwc_display_contents_1_t* list){
1684 //As we split 4kx2k yuv layer and program to 2 VG pipes
1685 //(if available) increase mdpcount accordingly
1686 mCurrentFrame.mdpCount += ctx->listStats[mDpy].yuv4k2kCount;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001687
1688 //If 4k2k Yuv layer split is possible, and if
1689 //fbz is above 4k2k layer, increment fb zorder by 1
1690 //as we split 4k2k layer and increment zorder for right half
1691 //of the layer
1692 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi2268dd72014-05-22 22:24:53 +05301693 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1694 index++) {
1695 if(!mCurrentFrame.isFBComposed[index]) {
1696 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1697 mdpNextZOrder++;
1698 }
1699 mdpNextZOrder++;
1700 hwc_layer_1_t* layer = &list->hwLayers[index];
1701 private_handle_t *hnd = (private_handle_t *)layer->handle;
1702 if(is4kx2kYuvBuffer(hnd)) {
1703 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1704 mCurrentFrame.fbZ += 1;
1705 mdpNextZOrder++;
1706 //As we split 4kx2k yuv layer and program to 2 VG pipes
1707 //(if available) increase mdpcount by 1.
1708 mCurrentFrame.mdpCount++;
1709 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001710 }
1711 }
1712 }
radhakrishnac9a67412013-09-25 17:40:42 +05301713}
1714
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001715/*
1716 * Configures pipe(s) for MDP composition
1717 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001718int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001719 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001720 MdpPipeInfoNonSplit& mdp_info =
1721 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philip23200512014-08-12 13:42:21 +05301722 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08001723 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1724 eIsFg isFg = IS_FG_OFF;
1725 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001726
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001727 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1728 __FUNCTION__, layer, zOrder, dest);
1729
Saurabh Shah88e4d272013-09-03 13:31:29 -07001730 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001731 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001732}
1733
Saurabh Shah88e4d272013-09-03 13:31:29 -07001734bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001735 hwc_display_contents_1_t* list) {
1736 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001737
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001738 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001739
Jeykumar Sankarancf537002013-01-21 21:19:15 -08001740 hwc_layer_1_t* layer = &list->hwLayers[index];
1741 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05301742 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
1743 if(allocSplitVGPipesfor4k2k(ctx, list, index)){
1744 continue;
1745 }
1746 }
1747
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001748 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001749 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001750 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08001751 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001752 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001753 ePipeType type = MDPCOMP_OV_ANY;
1754
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001755 if(isYuvBuffer(hnd)) {
1756 type = MDPCOMP_OV_VG;
Prabhanjan Kandula5b8913e2014-01-22 23:01:45 +05301757 } else if(qdutils::MDPVersion::getInstance().is8x26() &&
1758 (ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024)) {
1759 if(qhwc::needsScaling(layer))
1760 type = MDPCOMP_OV_RGB;
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301761 } else if(!qhwc::needsScaling(layer)
Saurabh Shah85234ec2013-04-12 17:09:00 -07001762 && Overlay::getDMAMode() != Overlay::DMA_BLOCK_MODE
1763 && ctx->mMDP.version >= qdutils::MDSS_V5) {
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001764 type = MDPCOMP_OV_DMA;
1765 }
1766
Xu Yang5c2b3af2014-04-08 13:56:47 +08001767 // for 8x26, never allow primary display occupy DMA pipe
1768 // when external display is connected
1769 if(qdutils::MDPVersion::getInstance().is8x26()
1770 && ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive
1771 && ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected
1772 && !ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isPause
1773 && mDpy == HWC_DISPLAY_PRIMARY
1774 && type == MDPCOMP_OV_DMA) {
1775 type = MDPCOMP_OV_RGB;
1776 }
1777
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001778 pipe_info.index = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001779 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001780 ALOGD_IF(isDebug(), "%s: Unable to get pipe type = %d",
1781 __FUNCTION__, (int) type);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001782 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001783 }
1784 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001785 return true;
1786}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001787
radhakrishnac9a67412013-09-25 17:40:42 +05301788int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1789 PipeLayerPair& PipeLayerPair) {
1790 MdpYUVPipeInfo& mdp_info =
1791 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
1792 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1793 eIsFg isFg = IS_FG_OFF;
Justin Philip23200512014-08-12 13:42:21 +05301794 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05301795 eDest lDest = mdp_info.lIndex;
1796 eDest rDest = mdp_info.rIndex;
1797
1798 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
1799 lDest, rDest, &PipeLayerPair.rot);
1800}
1801
Saurabh Shah88e4d272013-09-03 13:31:29 -07001802bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001803
Raj Kamal5166b312014-06-06 13:45:20 +05301804 if(!isEnabled() or !mModeOn) {
1805 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05301806 return true;
1807 }
1808
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001809 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001810 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001811
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001812 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1813 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001814 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001815 if(mCurrentFrame.isFBComposed[i]) continue;
1816
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07001817 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08001818 private_handle_t *hnd = (private_handle_t *)layer->handle;
1819 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07001820 if (!(layer->flags & HWC_COLOR_FILL)) {
1821 ALOGE("%s handle null", __FUNCTION__);
1822 return false;
1823 }
1824 // No PLAY for Color layer
1825 layerProp[i].mFlags &= ~HWC_MDPCOMP;
1826 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001827 }
1828
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001829 int mdpIndex = mCurrentFrame.layerToMDP[i];
1830
radhakrishnac9a67412013-09-25 17:40:42 +05301831 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
1832 {
1833 MdpYUVPipeInfo& pipe_info =
1834 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1835 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1836 ovutils::eDest indexL = pipe_info.lIndex;
1837 ovutils::eDest indexR = pipe_info.rIndex;
1838 int fd = hnd->fd;
1839 uint32_t offset = hnd->offset;
1840 if(rot) {
1841 rot->queueBuffer(fd, offset);
1842 fd = rot->getDstMemId();
1843 offset = rot->getDstOffset();
1844 }
1845 if(indexL != ovutils::OV_INVALID) {
1846 ovutils::eDest destL = (ovutils::eDest)indexL;
1847 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1848 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
1849 if (!ov.queueBuffer(fd, offset, destL)) {
1850 ALOGE("%s: queueBuffer failed for display:%d",
1851 __FUNCTION__, mDpy);
1852 return false;
1853 }
1854 }
1855
1856 if(indexR != ovutils::OV_INVALID) {
1857 ovutils::eDest destR = (ovutils::eDest)indexR;
1858 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1859 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
1860 if (!ov.queueBuffer(fd, offset, destR)) {
1861 ALOGE("%s: queueBuffer failed for display:%d",
1862 __FUNCTION__, mDpy);
1863 return false;
1864 }
1865 }
1866 }
1867 else{
1868 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07001869 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301870 ovutils::eDest dest = pipe_info.index;
1871 if(dest == ovutils::OV_INVALID) {
1872 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001873 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05301874 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001875
radhakrishnac9a67412013-09-25 17:40:42 +05301876 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1877 continue;
1878 }
1879
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -07001880 int fd = hnd->fd;
1881 uint32_t offset = (uint32_t)hnd->offset;
1882 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
1883 if (!mDpy && (index != -1)) {
Sushil Chauhan4259d872014-05-13 18:17:12 -07001884 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -07001885 fd = hnd->fd;
Sushil Chauhane1474bf2014-07-25 12:20:23 -07001886 offset = 0;
Sushil Chauhan4259d872014-05-13 18:17:12 -07001887 }
1888
radhakrishnac9a67412013-09-25 17:40:42 +05301889 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1890 using pipe: %d", __FUNCTION__, layer,
1891 hnd, dest );
1892
radhakrishnac9a67412013-09-25 17:40:42 +05301893 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1894 if(rot) {
1895 if(!rot->queueBuffer(fd, offset))
1896 return false;
1897 fd = rot->getDstMemId();
1898 offset = rot->getDstOffset();
1899 }
1900
1901 if (!ov.queueBuffer(fd, offset, dest)) {
1902 ALOGE("%s: queueBuffer failed for display:%d ",
1903 __FUNCTION__, mDpy);
1904 return false;
1905 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001906 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001907
1908 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001909 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001910 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001911}
1912
Saurabh Shah88e4d272013-09-03 13:31:29 -07001913//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001914
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001915void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05301916 hwc_display_contents_1_t* list){
1917 //if 4kx2k yuv layer is totally present in either in left half
1918 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05301919 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi2268dd72014-05-22 22:24:53 +05301920 if(mCurrentFrame.fbZ >= 0) {
1921 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1922 index++) {
1923 if(!mCurrentFrame.isFBComposed[index]) {
1924 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1925 mdpNextZOrder++;
1926 }
1927 mdpNextZOrder++;
1928 hwc_layer_1_t* layer = &list->hwLayers[index];
1929 private_handle_t *hnd = (private_handle_t *)layer->handle;
1930 if(is4kx2kYuvBuffer(hnd)) {
1931 hwc_rect_t dst = layer->displayFrame;
1932 if((dst.left > lSplit) || (dst.right < lSplit)) {
1933 mCurrentFrame.mdpCount += 1;
1934 }
1935 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1936 mCurrentFrame.fbZ += 1;
1937 mdpNextZOrder++;
1938 }
1939 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001940 }
radhakrishnac9a67412013-09-25 17:40:42 +05301941 }
1942}
1943
Saurabh Shah88e4d272013-09-03 13:31:29 -07001944bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
1945 MdpPipeInfoSplit& pipe_info,
Saurabh Shah67a38c32013-06-10 16:23:15 -07001946 ePipeType type) {
1947 const int xres = ctx->dpyAttr[mDpy].xres;
Saurabh Shah07a8ca82013-08-06 18:45:42 -07001948 const int lSplit = getLeftSplit(ctx, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001949
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001950 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001951 pipe_info.lIndex = ovutils::OV_INVALID;
1952 pipe_info.rIndex = ovutils::OV_INVALID;
1953
1954 if (dst.left < lSplit) {
1955 pipe_info.lIndex = getMdpPipe(ctx, type, Overlay::MIXER_LEFT);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001956 if(pipe_info.lIndex == ovutils::OV_INVALID)
1957 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001958 }
1959
1960 if(dst.right > lSplit) {
1961 pipe_info.rIndex = getMdpPipe(ctx, type, Overlay::MIXER_RIGHT);
1962 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001963 return false;
1964 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001965
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001966 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001967}
1968
Saurabh Shah88e4d272013-09-03 13:31:29 -07001969bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001970 hwc_display_contents_1_t* list) {
1971 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001972
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001973 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001974
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001975 hwc_layer_1_t* layer = &list->hwLayers[index];
1976 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05301977 hwc_rect_t dst = layer->displayFrame;
1978 const int lSplit = getLeftSplit(ctx, mDpy);
1979 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
1980 if((dst.left > lSplit)||(dst.right < lSplit)){
1981 if(allocSplitVGPipesfor4k2k(ctx, list, index)){
1982 continue;
1983 }
1984 }
1985 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07001986 int mdpIndex = mCurrentFrame.layerToMDP[index];
1987 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001988 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07001989 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001990 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001991 ePipeType type = MDPCOMP_OV_ANY;
1992
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001993 if(isYuvBuffer(hnd)) {
1994 type = MDPCOMP_OV_VG;
Sushil Chauhan15a2ea62013-09-04 18:28:36 -07001995 } else if(!qhwc::needsScalingWithSplit(ctx, layer, mDpy)
Saurabh Shah85234ec2013-04-12 17:09:00 -07001996 && Overlay::getDMAMode() != Overlay::DMA_BLOCK_MODE
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001997 && ctx->mMDP.version >= qdutils::MDSS_V5) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001998 type = MDPCOMP_OV_DMA;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001999 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002000
2001 if(!acquireMDPPipes(ctx, layer, pipe_info, type)) {
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002002 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type = %d",
2003 __FUNCTION__, (int) type);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002004 return false;
2005 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002006 }
2007 return true;
2008}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002009
radhakrishnac9a67412013-09-25 17:40:42 +05302010int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2011 PipeLayerPair& PipeLayerPair) {
2012 const int lSplit = getLeftSplit(ctx, mDpy);
2013 hwc_rect_t dst = layer->displayFrame;
2014 if((dst.left > lSplit)||(dst.right < lSplit)){
2015 MdpYUVPipeInfo& mdp_info =
2016 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2017 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2018 eIsFg isFg = IS_FG_OFF;
Justin Philip23200512014-08-12 13:42:21 +05302019 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302020 eDest lDest = mdp_info.lIndex;
2021 eDest rDest = mdp_info.rIndex;
2022
2023 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
2024 lDest, rDest, &PipeLayerPair.rot);
2025 }
2026 else{
2027 return configure(ctx, layer, PipeLayerPair);
2028 }
2029}
2030
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002031/*
2032 * Configures pipe(s) for MDP composition
2033 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002034int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002035 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002036 MdpPipeInfoSplit& mdp_info =
2037 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002038 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2039 eIsFg isFg = IS_FG_OFF;
Justin Philip23200512014-08-12 13:42:21 +05302040 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002041 eDest lDest = mdp_info.lIndex;
2042 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002043
2044 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2045 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2046
Saurabh Shah88e4d272013-09-03 13:31:29 -07002047 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002048 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002049}
2050
Saurabh Shah88e4d272013-09-03 13:31:29 -07002051bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002052
Raj Kamal5166b312014-06-06 13:45:20 +05302053 if(!isEnabled() or !mModeOn) {
2054 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302055 return true;
2056 }
2057
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002058 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002059 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002060
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002061 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2062 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002063 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002064 if(mCurrentFrame.isFBComposed[i]) continue;
2065
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002066 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002067 private_handle_t *hnd = (private_handle_t *)layer->handle;
2068 if(!hnd) {
2069 ALOGE("%s handle null", __FUNCTION__);
2070 return false;
2071 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002072
2073 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2074 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002075 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002076
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002077 int mdpIndex = mCurrentFrame.layerToMDP[i];
2078
radhakrishnac9a67412013-09-25 17:40:42 +05302079 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
2080 {
2081 MdpYUVPipeInfo& pipe_info =
2082 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2083 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2084 ovutils::eDest indexL = pipe_info.lIndex;
2085 ovutils::eDest indexR = pipe_info.rIndex;
2086 int fd = hnd->fd;
2087 uint32_t offset = hnd->offset;
2088 if(rot) {
2089 rot->queueBuffer(fd, offset);
2090 fd = rot->getDstMemId();
2091 offset = rot->getDstOffset();
2092 }
2093 if(indexL != ovutils::OV_INVALID) {
2094 ovutils::eDest destL = (ovutils::eDest)indexL;
2095 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2096 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2097 if (!ov.queueBuffer(fd, offset, destL)) {
2098 ALOGE("%s: queueBuffer failed for display:%d",
2099 __FUNCTION__, mDpy);
2100 return false;
2101 }
2102 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002103
radhakrishnac9a67412013-09-25 17:40:42 +05302104 if(indexR != ovutils::OV_INVALID) {
2105 ovutils::eDest destR = (ovutils::eDest)indexR;
2106 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2107 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2108 if (!ov.queueBuffer(fd, offset, destR)) {
2109 ALOGE("%s: queueBuffer failed for display:%d",
2110 __FUNCTION__, mDpy);
2111 return false;
2112 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002113 }
2114 }
radhakrishnac9a67412013-09-25 17:40:42 +05302115 else{
2116 MdpPipeInfoSplit& pipe_info =
2117 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2118 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002119
radhakrishnac9a67412013-09-25 17:40:42 +05302120 ovutils::eDest indexL = pipe_info.lIndex;
2121 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002122
radhakrishnac9a67412013-09-25 17:40:42 +05302123 int fd = hnd->fd;
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -07002124 uint32_t offset = (uint32_t)hnd->offset;
2125 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2126 if (!mDpy && (index != -1)) {
2127 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2128 fd = hnd->fd;
Sushil Chauhane1474bf2014-07-25 12:20:23 -07002129 offset = 0;
Arun Kumar K.Rbad65ab2014-06-03 11:54:10 -07002130 }
radhakrishnac9a67412013-09-25 17:40:42 +05302131
Tatenda Chipeperekwa2f8cd2b2014-04-14 10:36:06 -07002132 if(ctx->mAD->draw(ctx, fd, offset)) {
2133 fd = ctx->mAD->getDstFd(ctx);
2134 offset = ctx->mAD->getDstOffset(ctx);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002135 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002136
radhakrishnac9a67412013-09-25 17:40:42 +05302137 if(rot) {
2138 rot->queueBuffer(fd, offset);
2139 fd = rot->getDstMemId();
2140 offset = rot->getDstOffset();
2141 }
2142
2143 //************* play left mixer **********
2144 if(indexL != ovutils::OV_INVALID) {
2145 ovutils::eDest destL = (ovutils::eDest)indexL;
2146 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2147 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2148 if (!ov.queueBuffer(fd, offset, destL)) {
2149 ALOGE("%s: queueBuffer failed for left mixer",
2150 __FUNCTION__);
2151 return false;
2152 }
2153 }
2154
2155 //************* play right mixer **********
2156 if(indexR != ovutils::OV_INVALID) {
2157 ovutils::eDest destR = (ovutils::eDest)indexR;
2158 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2159 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2160 if (!ov.queueBuffer(fd, offset, destR)) {
2161 ALOGE("%s: queueBuffer failed for right mixer",
2162 __FUNCTION__);
2163 return false;
2164 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002165 }
2166 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002167
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002168 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2169 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002170
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002171 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002172}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002173}; //namespace
2174