blob: 5bd339241e4f48045186fb79afbe8b21feb20ddb [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002 * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003 * Not a Contribution, Apache license notifications and license are retained
4 * for attribution purposes only.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
Saurabh Shah4fdde762013-04-30 18:47:33 -070019#include <math.h>
Naseer Ahmed7c958d42012-07-31 18:57:03 -070020#include "hwc_mdpcomp.h"
Naseer Ahmed54821fe2012-11-28 18:44:38 -050021#include <sys/ioctl.h>
Tatenda Chipeperekwaaf2c0042014-09-17 12:55:01 -070022#include "hdmi.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080023#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080024#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070025#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070026#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080027#include <overlayRotator.h>
Sushil Chauhandefd3522014-05-13 18:17:12 -070028#include "hwc_copybit.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080029
Saurabh Shah85234ec2013-04-12 17:09:00 -070030using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070031using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080032using namespace overlay::utils;
33namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070034
Naseer Ahmed7c958d42012-07-31 18:57:03 -070035namespace qhwc {
36
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080037//==============MDPComp========================================================
38
Saurabh Shah59562ff2014-09-30 16:13:12 -070039IdleInvalidator *MDPComp::sIdleInvalidator = NULL;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070040bool MDPComp::sIdleFallBack = false;
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -080041bool MDPComp::sHandleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070042bool 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 Sankaran0ad97c42014-03-09 23:00:53 -070045int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080046int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Raj Kamal389d6e32014-08-04 14:43:24 +053047bool MDPComp::sEnableYUVsplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070048bool MDPComp::sSrcSplitEnabled = false;
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +053049bool MDPComp::enablePartialUpdateForMDP3 = false;
Saurabh Shah88e4d272013-09-03 13:31:29 -070050MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070051 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
52 sSrcSplitEnabled = true;
53 return new MDPCompSrcSplit(dpy);
54 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070055 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080056 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070057 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080058}
59
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080060MDPComp::MDPComp(int dpy):mDpy(dpy){};
61
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070062void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080063{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070064 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
65 return;
66
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080067 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070068 (mDpy == 0) ? "\"PRIMARY\"" :
69 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070070 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
71 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080072 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
73 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
74 (mCurrentFrame.needsRedraw? "YES" : "NO"),
75 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070076 if(isDisplaySplit(ctx, mDpy)) {
77 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
78 "Right: [%d, %d, %d, %d] \n",
79 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
80 ctx->listStats[mDpy].lRoi.right,
81 ctx->listStats[mDpy].lRoi.bottom,
82 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
83 ctx->listStats[mDpy].rRoi.right,
84 ctx->listStats[mDpy].rRoi.bottom);
85 } else {
86 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
87 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
88 ctx->listStats[mDpy].lRoi.right,
89 ctx->listStats[mDpy].lRoi.bottom);
90 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080091 dumpsys_log(buf," --------------------------------------------- \n");
92 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
93 dumpsys_log(buf," --------------------------------------------- \n");
94 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
95 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
96 index,
97 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070098 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080099 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700100 (mCurrentFrame.drop[index] ? "DROP" :
101 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800102 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
103 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
104 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800105}
106
107bool MDPComp::init(hwc_context_t *ctx) {
108
109 if(!ctx) {
110 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
111 return false;
112 }
113
Saurabh Shah59562ff2014-09-30 16:13:12 -0700114 char property[PROPERTY_VALUE_MAX] = {0};
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800115
116 sEnabled = false;
117 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800118 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
119 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800120 sEnabled = true;
121 }
122
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700123 sEnableMixedMode = true;
124 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
125 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
126 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
127 sEnableMixedMode = false;
128 }
129
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800130 sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Saurabh Shah85234ec2013-04-12 17:09:00 -0700131 if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
132 int val = atoi(property);
133 if(val >= 0)
134 sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800135 }
136
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400137 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
Saurabh Shah59562ff2014-09-30 16:13:12 -0700138 sIdleInvalidator = IdleInvalidator::getInstance();
139 if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
140 delete sIdleInvalidator;
141 sIdleInvalidator = NULL;
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400142 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800143 }
radhakrishnac9a67412013-09-25 17:40:42 +0530144
Saurabh Shah7c727642014-06-02 15:47:14 -0700145 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700146 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700147 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
148 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
149 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530150 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530151 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700152
Dileep Kumar Reddic6ef3472014-09-24 19:07:08 +0530153 bool defaultPTOR = false;
154 //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
155 //8x16 and 8x39 targets by default
156 if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
157 (qdutils::MDPVersion::getInstance().is8x16() ||
158 qdutils::MDPVersion::getInstance().is8x39())) {
159 defaultPTOR = true;
160 }
161
162 if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
163 (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700164 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
165 HWC_DISPLAY_PRIMARY);
166 }
167
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +0530168 if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
169 (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
170 enablePartialUpdateForMDP3 = true;
171 }
172
173 if(!enablePartialUpdateForMDP3 &&
174 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
175 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
176 enablePartialUpdateForMDP3 = true;
177 }
178
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700179 return true;
180}
181
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800182void MDPComp::reset(hwc_context_t *ctx) {
183 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700184 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800185 ctx->mOverlay->clear(mDpy);
186 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700187}
188
Raj Kamal4393eaa2014-06-06 13:45:20 +0530189void MDPComp::reset() {
190 sHandleTimeout = false;
191 mModeOn = false;
192}
193
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700194void MDPComp::timeout_handler(void *udata) {
195 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
196
197 if(!ctx) {
198 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
199 return;
200 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800201 Locker::Autolock _l(ctx->mDrawLock);
202 // Handle timeout event only if the previous composition is MDP or MIXED.
203 if(!sHandleTimeout) {
204 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
205 return;
206 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700207 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700208 ALOGE("%s: HWC proc not registered", __FUNCTION__);
209 return;
210 }
211 sIdleFallBack = true;
212 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700213 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700214}
215
Saurabh Shah59562ff2014-09-30 16:13:12 -0700216void MDPComp::setIdleTimeout(const uint32_t& timeout) {
217 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
218
219 if(sIdleInvalidator) {
220 if(timeout <= ONE_REFRESH_PERIOD_MS) {
221 //If the specified timeout is < 1 draw cycle worth, "virtually"
222 //disable idle timeout. The ideal way for clients to disable
223 //timeout is to set it to 0
224 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
225 ALOGI("Disabled idle timeout");
226 return;
227 }
228 sIdleInvalidator->setIdleTimeout(timeout);
229 ALOGI("Idle timeout set to %u", timeout);
230 } else {
231 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
232 }
233}
234
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800235void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800236 hwc_display_contents_1_t* list) {
237 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800238
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800239 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800240 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800241 if(!mCurrentFrame.isFBComposed[index]) {
242 layerProp[index].mFlags |= HWC_MDPCOMP;
243 layer->compositionType = HWC_OVERLAY;
244 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800245 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700246 /* Drop the layer when its already present in FB OR when it lies
247 * outside frame's ROI */
248 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800249 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700250 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800251 }
252 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700253}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500254
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800255void MDPComp::setRedraw(hwc_context_t *ctx,
256 hwc_display_contents_1_t* list) {
257 mCurrentFrame.needsRedraw = false;
258 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
259 (list->flags & HWC_GEOMETRY_CHANGED) ||
260 isSkipPresent(ctx, mDpy)) {
261 mCurrentFrame.needsRedraw = true;
262 }
263}
264
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800265MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700266 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700267 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800268}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800269
Saurabh Shahaa236822013-04-24 18:07:26 -0700270void MDPComp::FrameInfo::reset(const int& numLayers) {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700271 for(int i = 0; i < MAX_PIPES_PER_MIXER; i++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800272 if(mdpToLayer[i].pipeInfo) {
273 delete mdpToLayer[i].pipeInfo;
274 mdpToLayer[i].pipeInfo = NULL;
275 //We dont own the rotator
276 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800277 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800278 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800279
280 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
281 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700282 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800283
Saurabh Shahaa236822013-04-24 18:07:26 -0700284 layerCount = numLayers;
285 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800286 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700287 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800288 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800289}
290
Saurabh Shahaa236822013-04-24 18:07:26 -0700291void MDPComp::FrameInfo::map() {
292 // populate layer and MDP maps
293 int mdpIdx = 0;
294 for(int idx = 0; idx < layerCount; idx++) {
295 if(!isFBComposed[idx]) {
296 mdpToLayer[mdpIdx].listIndex = idx;
297 layerToMDP[idx] = mdpIdx++;
298 }
299 }
300}
301
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800302MDPComp::LayerCache::LayerCache() {
303 reset();
304}
305
306void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700307 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530308 memset(&isFBComposed, true, sizeof(isFBComposed));
309 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800310 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700311}
312
313void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530314 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700315 for(int i = 0; i < numAppLayers; i++) {
316 hnd[i] = list->hwLayers[i].handle;
317 }
318}
319
320void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700321 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530322 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
323 memcpy(&drop, &curFrame.drop, sizeof(drop));
324}
325
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800326bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
327 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530328 if(layerCount != curFrame.layerCount)
329 return false;
330 for(int i = 0; i < curFrame.layerCount; i++) {
331 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
332 (curFrame.drop[i] != drop[i])) {
333 return false;
334 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800335 if(curFrame.isFBComposed[i] &&
336 (hnd[i] != list->hwLayers[i].handle)){
337 return false;
338 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530339 }
340 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800341}
342
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700343bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
344 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800345 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700346 (not isValidDimension(ctx,layer))
347 //More conditions here, SKIP, sRGB+Blend etc
348 ) {
349 return false;
350 }
351 return true;
352}
353
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530354bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800355 private_handle_t *hnd = (private_handle_t *)layer->handle;
356
357 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700358 if (layer->flags & HWC_COLOR_FILL) {
359 // Color layer
360 return true;
361 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700362 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800363 return false;
364 }
365
Naseer Ahmede850a802013-09-06 13:12:52 -0400366 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400367 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400368 return false;
369
Saurabh Shah62e1d732013-09-17 10:44:05 -0700370 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700371 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700372 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700373 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
374 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700375 int dst_w = dst.right - dst.left;
376 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800377 float w_scale = ((float)crop_w / (float)dst_w);
378 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530379 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700380
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800381 /* Workaround for MDP HW limitation in DSI command mode panels where
382 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
383 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530384 * There also is a HW limilation in MDP, minimum block size is 2x2
385 * Fallback to GPU if height is less than 2.
386 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700387 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800388 return false;
389
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800390 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530391 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800392 const float w_dscale = w_scale;
393 const float h_dscale = h_scale;
394
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800395 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700396
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530397 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700398 /* On targets that doesnt support Decimation (eg.,8x26)
399 * maximum downscale support is overlay pipe downscale.
400 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400401 if(crop_w > (int) mdpHw.getMaxMixerWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530402 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700403 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800404 return false;
405 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700406 // Decimation on macrotile format layers is not supported.
407 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530408 /* Bail out if
409 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700410 * 2. exceeds maximum downscale limit
411 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400412 if(((crop_w > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530413 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700414 w_dscale > maxMDPDownscale ||
415 h_dscale > maxMDPDownscale) {
416 return false;
417 }
418 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800419 return false;
420 }
421 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700422 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700423 return false;
424 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700425 }
426
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800427 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530428 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800429 const float w_uscale = 1.0f / w_scale;
430 const float h_uscale = 1.0f / h_scale;
431
432 if(w_uscale > upscale || h_uscale > upscale)
433 return false;
434 }
435
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800436 return true;
437}
438
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800439bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700440 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800441
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800442 if(!isEnabled()) {
443 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700444 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530445 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530446 qdutils::MDPVersion::getInstance().is8x16() ||
447 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800448 ctx->mVideoTransFlag &&
449 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700450 //1 Padding round to shift pipes across mixers
451 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
452 __FUNCTION__);
453 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700454 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
455 /* TODO: freeing up all the resources only for the targets having total
456 number of pipes < 8. Need to analyze number of VIG pipes used
457 for primary in previous draw cycle and accordingly decide
458 whether to fall back to full GPU comp or video only comp
459 */
460 if(isSecondaryConfiguring(ctx)) {
461 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
462 __FUNCTION__);
463 ret = false;
464 } else if(ctx->isPaddingRound) {
465 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
466 __FUNCTION__,mDpy);
467 ret = false;
468 }
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700469 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700470 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800471}
472
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800473void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
474 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
475 fbRect = getIntersection(fbRect, roi);
476}
477
478/* 1) Identify layers that are not visible or lying outside the updating ROI and
479 * drop them from composition.
480 * 2) If we have a scaling layer which needs cropping against generated
481 * ROI, reset ROI to full resolution. */
482bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
483 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700484 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800485 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800486
487 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800488 if(!isValidRect(visibleRect)) {
489 mCurrentFrame.drop[i] = true;
490 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800491 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800492 }
493
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700494 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700495 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800496 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700497
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700498 if(!isValidRect(res)) {
499 mCurrentFrame.drop[i] = true;
500 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800501 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700502 /* Reset frame ROI when any layer which needs scaling also needs ROI
503 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800504 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800505 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700506 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
507 mCurrentFrame.dropCount = 0;
508 return false;
509 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800510
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800511 /* deduct any opaque region from visibleRect */
512 if (layer->blending == HWC_BLENDING_NONE)
513 visibleRect = deductRect(visibleRect, res);
514 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700515 }
516 return true;
517}
518
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800519/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
520 * are updating. If DirtyRegion is applicable, calculate it by accounting all
521 * the changing layer's dirtyRegion. */
522void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
523 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700524 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800525 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700526 return;
527
528 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800529 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
530 (int)ctx->dpyAttr[mDpy].yres};
531
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700532 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800533 hwc_layer_1_t* layer = &list->hwLayers[index];
534 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800535 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700536 hwc_rect_t dst = layer->displayFrame;
537 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800538
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800539#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800540 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700541 {
542 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
543 int x_off = dst.left - src.left;
544 int y_off = dst.top - src.top;
545 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
546 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800547#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800548
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800549 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700550 }
551 }
552
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800553 /* No layer is updating. Still SF wants a refresh.*/
554 if(!isValidRect(roi))
555 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800556
557 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800558 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800559
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800560 ctx->listStats[mDpy].lRoi = roi;
561 if(!validateAndApplyROI(ctx, list))
562 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700563
564 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800565 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
566 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
567}
568
569void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
570 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
571 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
572
573 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
574 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
575 fbRect = getUnion(l_fbRect, r_fbRect);
576}
577/* 1) Identify layers that are not visible or lying outside BOTH the updating
578 * ROI's and drop them from composition. If a layer is spanning across both
579 * the halves of the screen but needed by only ROI, the non-contributing
580 * half will not be programmed for MDP.
581 * 2) If we have a scaling layer which needs cropping against generated
582 * ROI, reset ROI to full resolution. */
583bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
584 hwc_display_contents_1_t* list) {
585
586 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
587
588 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
589 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
590
591 for(int i = numAppLayers - 1; i >= 0; i--){
592 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
593 {
594 mCurrentFrame.drop[i] = true;
595 mCurrentFrame.dropCount++;
596 continue;
597 }
598
599 const hwc_layer_1_t* layer = &list->hwLayers[i];
600 hwc_rect_t dstRect = layer->displayFrame;
601
602 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
603 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
604 hwc_rect_t res = getUnion(l_res, r_res);
605
606 if(!isValidRect(l_res) && !isValidRect(r_res)) {
607 mCurrentFrame.drop[i] = true;
608 mCurrentFrame.dropCount++;
609 } else {
610 /* Reset frame ROI when any layer which needs scaling also needs ROI
611 * cropping */
612 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
613 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
614 mCurrentFrame.dropCount = 0;
615 return false;
616 }
617
618 if (layer->blending == HWC_BLENDING_NONE) {
619 visibleRectL = deductRect(visibleRectL, l_res);
620 visibleRectR = deductRect(visibleRectR, r_res);
621 }
622 }
623 }
624 return true;
625}
626/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
627 * are updating. If DirtyRegion is applicable, calculate it by accounting all
628 * the changing layer's dirtyRegion. */
629void MDPCompSplit::generateROI(hwc_context_t *ctx,
630 hwc_display_contents_1_t* list) {
631 if(!canPartialUpdate(ctx, list))
632 return;
633
634 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
635 int lSplit = getLeftSplit(ctx, mDpy);
636
637 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
638 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
639
640 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
641 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
642
643 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
644 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
645
646 for(int index = 0; index < numAppLayers; index++ ) {
647 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800648 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800649 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800650 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700651 hwc_rect_t dst = layer->displayFrame;
652 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800653
654#ifdef QCOM_BSP
655 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700656 {
657 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
658 int x_off = dst.left - src.left;
659 int y_off = dst.top - src.top;
660 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
661 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800662#endif
663
664 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
665 if(isValidRect(l_dst))
666 l_roi = getUnion(l_roi, l_dst);
667
668 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
669 if(isValidRect(r_dst))
670 r_roi = getUnion(r_roi, r_dst);
671 }
672 }
673
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700674 /* For panels that cannot accept commands in both the interfaces, we cannot
675 * send two ROI's (for each half). We merge them into single ROI and split
676 * them across lSplit for MDP mixer use. The ROI's will be merged again
677 * finally before udpating the panel in the driver. */
678 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
679 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
680 l_roi = getIntersection(temp_roi, l_frame);
681 r_roi = getIntersection(temp_roi, r_frame);
682 }
683
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800684 /* No layer is updating. Still SF wants a refresh. */
685 if(!isValidRect(l_roi) && !isValidRect(r_roi))
686 return;
687
688 l_roi = getSanitizeROI(l_roi, l_frame);
689 r_roi = getSanitizeROI(r_roi, r_frame);
690
691 ctx->listStats[mDpy].lRoi = l_roi;
692 ctx->listStats[mDpy].rRoi = r_roi;
693
694 if(!validateAndApplyROI(ctx, list))
695 resetROI(ctx, mDpy);
696
697 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
698 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
699 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
700 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
701 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
702 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700703}
704
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800705/* Checks for conditions where all the layers marked for MDP comp cannot be
706 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800707bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800708 hwc_display_contents_1_t* list){
709
Saurabh Shahaa236822013-04-24 18:07:26 -0700710 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800711 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800712
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700713 // This is a special mode which needs to be handled separately.
714 // Only AIV tagged layers will be displayed on external in this mode.
715 // This is applicable only for external display , Return false, so that
716 // this will be handled separately
717 if(ctx->mAIVVideoMode[mDpy]) {
718 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
719 __FUNCTION__, mDpy);
720 return false;
721 }
722
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400723 // No Idle fall back, if secure display or secure RGB layers are present or
724 // if there's only a single layer being composed
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -0700725 if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400726 !ctx->listStats[mDpy].secureRGBCount) &&
727 (ctx->listStats[mDpy].numAppLayers != 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700728 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
729 return false;
730 }
731
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800732 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700733 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
734 __FUNCTION__,
735 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800736 return false;
737 }
738
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700739 // if secondary is configuring or Padding round, fall back to video only
740 // composition and release all assigned non VIG pipes from primary.
741 if(isSecondaryConfiguring(ctx)) {
742 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
743 __FUNCTION__);
744 return false;
745 } else if(ctx->isPaddingRound) {
746 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
747 __FUNCTION__,mDpy);
748 return false;
749 }
750
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530751 MDPVersion& mdpHw = MDPVersion::getInstance();
752 if(mDpy > HWC_DISPLAY_PRIMARY &&
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400753 (priDispW > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530754 (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800755 // Disable MDP comp on Secondary when the primary is highres panel and
756 // the secondary is a normal 1080p, because, MDP comp on secondary under
757 // in such usecase, decimation gets used for downscale and there will be
758 // a quality mismatch when there will be a fallback to GPU comp
759 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
760 __FUNCTION__);
761 return false;
762 }
763
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700764 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800765 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700766 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800767 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
768 return false;
769 }
770
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800771 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800772 hwc_layer_1_t* layer = &list->hwLayers[i];
773 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800774
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800775 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700776 if(!canUseRotator(ctx, mDpy)) {
777 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
778 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700779 return false;
780 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800781 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530782
783 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
784 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700785 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530786 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
787 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
788 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800789 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700790
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700791 if(ctx->mAD->isDoable()) {
792 return false;
793 }
794
Saurabh Shahaa236822013-04-24 18:07:26 -0700795 //If all above hard conditions are met we can do full or partial MDP comp.
796 bool ret = false;
797 if(fullMDPComp(ctx, list)) {
798 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700799 } else if(fullMDPCompWithPTOR(ctx, list)) {
800 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700801 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700802 ret = true;
803 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530804
Saurabh Shahaa236822013-04-24 18:07:26 -0700805 return ret;
806}
807
808bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700809
810 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
811 return false;
812
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700813 //Will benefit presentation / secondary-only layer.
814 if((mDpy > HWC_DISPLAY_PRIMARY) &&
815 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
816 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
817 return false;
818 }
819
820 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
821 for(int i = 0; i < numAppLayers; i++) {
822 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700823 if(not mCurrentFrame.drop[i] and
824 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700825 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
826 return false;
827 }
828 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800829
Saurabh Shahaa236822013-04-24 18:07:26 -0700830 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700831 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
832 sizeof(mCurrentFrame.isFBComposed));
833 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
834 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700835
Raj Kamal389d6e32014-08-04 14:43:24 +0530836 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800837 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530838 }
839
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800840 if(!postHeuristicsHandling(ctx, list)) {
841 ALOGD_IF(isDebug(), "post heuristic handling failed");
842 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700843 return false;
844 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700845 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
846 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700847 return true;
848}
849
Sushil Chauhandefd3522014-05-13 18:17:12 -0700850/* Full MDP Composition with Peripheral Tiny Overlap Removal.
851 * MDP bandwidth limitations can be avoided, if the overlap region
852 * covered by the smallest layer at a higher z-order, gets composed
853 * by Copybit on a render buffer, which can be queued to MDP.
854 */
855bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
856 hwc_display_contents_1_t* list) {
857
858 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
859 const int stagesForMDP = min(sMaxPipesPerMixer,
860 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
861
862 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700863 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700864 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
865 return false;
866 }
867
868 // Frame level checks
869 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
870 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
871 isSecurePresent(ctx, mDpy)) {
872 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
873 return false;
874 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700875 // MDP comp checks
876 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700877 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700878 if(not isSupportedForMDPComp(ctx, layer)) {
879 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
880 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700881 }
882 }
883
Sushil Chauhandefd3522014-05-13 18:17:12 -0700884 /* We cannot use this composition mode, if:
885 1. A below layer needs scaling.
886 2. Overlap is not peripheral to display.
887 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700888 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700889 */
890
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700891 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
892 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
893 memset(overlapRect, 0, sizeof(overlapRect));
894 int layerPixelCount, minPixelCount = 0;
895 int numPTORLayersFound = 0;
896 for (int i = numAppLayers-1; (i >= 0 &&
897 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700898 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700899 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700900 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700901 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
902 // PTOR layer should be peripheral and cannot have transform
903 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
904 has90Transform(layer)) {
905 continue;
906 }
907 if((3 * (layerPixelCount + minPixelCount)) >
908 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
909 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
910 continue;
911 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700912 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700913 for (int j = i-1; j >= 0; j--) {
914 // Check if the layers below this layer qualifies for PTOR comp
915 hwc_layer_1_t* layer = &list->hwLayers[j];
916 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700917 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700918 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700919 if (isValidRect(getIntersection(dispFrame, disFrame))) {
920 if (has90Transform(layer) || needsScaling(layer)) {
921 found = false;
922 break;
923 }
924 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700925 }
926 }
927 // Store the minLayer Index
928 if(found) {
929 minLayerIndex[numPTORLayersFound] = i;
930 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
931 minPixelCount += layerPixelCount;
932 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700933 }
934 }
935
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700936 // No overlap layers
937 if (!numPTORLayersFound)
938 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700939
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700940 // Store the displayFrame and the sourceCrops of the layers
941 hwc_rect_t displayFrame[numAppLayers];
942 hwc_rect_t sourceCrop[numAppLayers];
943 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700944 hwc_layer_1_t* layer = &list->hwLayers[i];
945 displayFrame[i] = layer->displayFrame;
946 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700947 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700948
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530949 /**
950 * It's possible that 2 PTOR layers might have overlapping.
951 * In such case, remove the intersection(again if peripheral)
952 * from the lower PTOR layer to avoid overlapping.
953 * If intersection is not on peripheral then compromise
954 * by reducing number of PTOR layers.
955 **/
956 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
957 if(isValidRect(commonRect)) {
958 overlapRect[1] = deductRect(overlapRect[1], commonRect);
959 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
960 }
961
962 ctx->mPtorInfo.count = numPTORLayersFound;
963 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
964 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
965 }
966
967 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
968 // reset PTOR
969 ctx->mPtorInfo.count = 0;
970 if(isValidRect(commonRect)) {
971 // If PTORs are intersecting restore displayframe of PTOR[1]
972 // before returning, as we have modified it above.
973 list->hwLayers[minLayerIndex[1]].displayFrame =
974 displayFrame[minLayerIndex[1]];
975 }
976 return false;
977 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700978 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
979 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
980
Xu Yangcda012c2014-07-30 21:57:21 +0800981 // Store the blending mode, planeAlpha, and transform of PTOR layers
982 int32_t blending[numPTORLayersFound];
983 uint8_t planeAlpha[numPTORLayersFound];
984 uint32_t transform[numPTORLayersFound];
985
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700986 for(int j = 0; j < numPTORLayersFound; j++) {
987 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700988
989 // Update src crop of PTOR layer
990 hwc_layer_1_t* layer = &list->hwLayers[index];
991 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
992 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
993 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
994 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
995
996 // Store & update w, h, format of PTOR layer
997 private_handle_t *hnd = (private_handle_t *)layer->handle;
998 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
999 layerWhf[j] = whf;
1000 hnd->width = renderBuf->width;
1001 hnd->height = renderBuf->height;
1002 hnd->format = renderBuf->format;
1003
Xu Yangcda012c2014-07-30 21:57:21 +08001004 // Store & update blending mode, planeAlpha and transform of PTOR layer
1005 blending[j] = layer->blending;
1006 planeAlpha[j] = layer->planeAlpha;
1007 transform[j] = layer->transform;
1008 layer->blending = HWC_BLENDING_NONE;
1009 layer->planeAlpha = 0xFF;
1010 layer->transform = 0;
1011
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001012 // Remove overlap from crop & displayFrame of below layers
1013 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001014 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001015 if(!isValidRect(getIntersection(layer->displayFrame,
1016 overlapRect[j]))) {
1017 continue;
1018 }
1019 // Update layer attributes
1020 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1021 hwc_rect_t destRect = deductRect(layer->displayFrame,
1022 overlapRect[j]);
1023 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1024 layer->transform);
1025 layer->sourceCropf.left = (float)srcCrop.left;
1026 layer->sourceCropf.top = (float)srcCrop.top;
1027 layer->sourceCropf.right = (float)srcCrop.right;
1028 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1029 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001030 }
1031
1032 mCurrentFrame.mdpCount = numAppLayers;
1033 mCurrentFrame.fbCount = 0;
1034 mCurrentFrame.fbZ = -1;
1035
1036 for (int j = 0; j < numAppLayers; j++)
1037 mCurrentFrame.isFBComposed[j] = false;
1038
1039 bool result = postHeuristicsHandling(ctx, list);
1040
1041 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001042 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001043 hwc_layer_1_t* layer = &list->hwLayers[i];
1044 layer->displayFrame = displayFrame[i];
1045 layer->sourceCropf.left = (float)sourceCrop[i].left;
1046 layer->sourceCropf.top = (float)sourceCrop[i].top;
1047 layer->sourceCropf.right = (float)sourceCrop[i].right;
1048 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1049 }
1050
Xu Yangcda012c2014-07-30 21:57:21 +08001051 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001052 for (int i = 0; i < numPTORLayersFound; i++) {
1053 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001054 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001055 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1056 hnd->width = layerWhf[i].w;
1057 hnd->height = layerWhf[i].h;
1058 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001059 layer->blending = blending[i];
1060 layer->planeAlpha = planeAlpha[i];
1061 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001062 }
1063
Sushil Chauhandefd3522014-05-13 18:17:12 -07001064 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001065 // reset PTOR
1066 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001067 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001068 } else {
1069 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1070 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001071 }
1072
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001073 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1074 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001075 return result;
1076}
1077
Saurabh Shahaa236822013-04-24 18:07:26 -07001078bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1079{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001080 if(!sEnableMixedMode) {
1081 //Mixed mode is disabled. No need to even try caching.
1082 return false;
1083 }
1084
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001085 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001086 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001087 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001088 cacheBasedComp(ctx, list);
1089 } else {
1090 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001091 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001092 }
1093
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001094 return ret;
1095}
1096
1097bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1098 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001099 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1100 return false;
1101
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001102 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001103 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001104 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001105
1106 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1107 for(int i = 0; i < numAppLayers; i++) {
1108 if(!mCurrentFrame.isFBComposed[i]) {
1109 hwc_layer_1_t* layer = &list->hwLayers[i];
1110 if(not isSupportedForMDPComp(ctx, layer)) {
1111 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1112 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001113 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001114 return false;
1115 }
1116 }
1117 }
1118
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001119 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001120 /* mark secure RGB layers for MDP comp */
1121 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301122 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001123 if(!ret) {
1124 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001125 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001126 return false;
1127 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001128
1129 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001130
Raj Kamal389d6e32014-08-04 14:43:24 +05301131 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001132 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301133 }
1134
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001135 //Will benefit cases where a video has non-updating background.
1136 if((mDpy > HWC_DISPLAY_PRIMARY) and
1137 (mdpCount > MAX_SEC_LAYERS)) {
1138 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001139 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001140 return false;
1141 }
1142
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001143 if(!postHeuristicsHandling(ctx, list)) {
1144 ALOGD_IF(isDebug(), "post heuristic handling failed");
1145 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001146 return false;
1147 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001148 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1149 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001150
Saurabh Shahaa236822013-04-24 18:07:26 -07001151 return true;
1152}
1153
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001154bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001155 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001156 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1157 return false;
1158
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001159 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001160 return false;
1161 }
1162
Saurabh Shahb772ae32013-11-18 15:40:02 -08001163 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001164 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1165 const int stagesForMDP = min(sMaxPipesPerMixer,
1166 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001167
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001168 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1169 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1170 int lastMDPSupportedIndex = numAppLayers;
1171 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001172
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001173 //Find the minimum MDP batch size
1174 for(int i = 0; i < numAppLayers;i++) {
1175 if(mCurrentFrame.drop[i]) {
1176 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001177 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001178 }
1179 hwc_layer_1_t* layer = &list->hwLayers[i];
1180 if(not isSupportedForMDPComp(ctx, layer)) {
1181 lastMDPSupportedIndex = i;
1182 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1183 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001184 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001185 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001186 }
1187
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001188 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1189 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1190 mCurrentFrame.dropCount);
1191
1192 //Start at a point where the fb batch should at least have 2 layers, for
1193 //this mode to be justified.
1194 while(fbBatchSize < 2) {
1195 ++fbBatchSize;
1196 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001197 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001198
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001199 //If there are no layers for MDP, this mode doesnt make sense.
1200 if(mdpBatchSize < 1) {
1201 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1202 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001203 return false;
1204 }
1205
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001206 mCurrentFrame.reset(numAppLayers);
1207
1208 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1209 while(mdpBatchSize > 0) {
1210 //Mark layers for MDP comp
1211 int mdpBatchLeft = mdpBatchSize;
1212 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1213 if(mCurrentFrame.drop[i]) {
1214 continue;
1215 }
1216 mCurrentFrame.isFBComposed[i] = false;
1217 --mdpBatchLeft;
1218 }
1219
1220 mCurrentFrame.fbZ = mdpBatchSize;
1221 mCurrentFrame.fbCount = fbBatchSize;
1222 mCurrentFrame.mdpCount = mdpBatchSize;
1223
1224 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1225 __FUNCTION__, mdpBatchSize, fbBatchSize,
1226 mCurrentFrame.dropCount);
1227
1228 if(postHeuristicsHandling(ctx, list)) {
1229 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001230 __FUNCTION__);
1231 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1232 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001233 return true;
1234 }
1235
1236 reset(ctx);
1237 --mdpBatchSize;
1238 ++fbBatchSize;
1239 }
1240
1241 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001242}
1243
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001244bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301245 if(mDpy or isSecurePresent(ctx, mDpy) or
1246 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001247 return false;
1248 }
1249 return true;
1250}
1251
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001252bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1253 hwc_display_contents_1_t* list){
1254 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1255 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1256 mDpy ) {
1257 return false;
1258 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001259 if(ctx->listStats[mDpy].secureUI)
1260 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001261 return true;
1262}
1263
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001264bool MDPComp::tryAIVVideoMode(hwc_context_t *ctx,
1265 hwc_display_contents_1_t* list) {
1266 if(sSimulationFlags & MDPCOMP_AVOID_AIV_VIDEO_MODE)
1267 return false;
1268 if(!ctx->mAIVVideoMode[mDpy]) {
1269 return false;
1270 }
1271 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1272
1273 mCurrentFrame.reset(numAppLayers);
1274 updateAIVLayers(ctx, list);
1275 int mdpCount = mCurrentFrame.mdpCount;
1276
1277 if(mdpCount == 0) {
1278 reset(ctx);
1279 return false;
1280 }
1281
1282 if(mCurrentFrame.fbCount) {
1283 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
1284 }
1285
1286 if(sEnableYUVsplit){
1287 adjustForSourceSplit(ctx, list);
1288 }
1289
1290 if(!postHeuristicsHandling(ctx, list)) {
1291 ALOGD_IF(isDebug(), "post heuristic handling failed");
1292 reset(ctx);
1293 return false;
1294 }
1295
1296 ALOGD_IF(sSimulationFlags,"%s: AIV_VIDEO_MODE_COMP SUCCEEDED",
1297 __FUNCTION__);
1298 return true;
1299}
1300
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001301bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1302 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001303 // This is a special mode which needs to be handled separately.
1304 // Only AIV tagged layers will be displayed on external in this mode.
1305 // This is applicable only for external display , Return false, so that
1306 // this will be handled separately
1307 if(ctx->mAIVVideoMode[mDpy]) {
1308 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1309 __FUNCTION__, mDpy);
1310 return false;
1311 }
1312
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001313 const bool secureOnly = true;
1314 return videoOnlyComp(ctx, list, not secureOnly) or
1315 videoOnlyComp(ctx, list, secureOnly);
1316}
1317
1318bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001319 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001320 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1321 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001322 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001323
Saurabh Shahaa236822013-04-24 18:07:26 -07001324 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001325 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001326 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001327 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001328
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001329 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1330 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001331 return false;
1332 }
1333
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001334 /* Bail out if we are processing only secured video layers
1335 * and we dont have any */
1336 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001337 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001338 return false;
1339 }
1340
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001341 if(mCurrentFrame.fbCount)
1342 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001343
Raj Kamal389d6e32014-08-04 14:43:24 +05301344 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001345 adjustForSourceSplit(ctx, list);
1346 }
1347
1348 if(!postHeuristicsHandling(ctx, list)) {
1349 ALOGD_IF(isDebug(), "post heuristic handling failed");
1350 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001351 return false;
1352 }
1353
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001354 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1355 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001356 return true;
1357}
1358
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001359/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1360bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1361 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001362 // This is a special mode which needs to be handled separately.
1363 // Only AIV tagged layers will be displayed on external in this mode.
1364 // This is applicable only for external display , Return false, so that
1365 // this will be handled separately
1366 if(ctx->mAIVVideoMode[mDpy]) {
1367 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1368 __FUNCTION__, mDpy);
1369 return false;
1370 }
1371
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001372 const bool secureOnly = true;
1373 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1374 mdpOnlyLayersComp(ctx, list, secureOnly);
1375
1376}
1377
1378bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1379 hwc_display_contents_1_t* list, bool secureOnly) {
1380
1381 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1382 return false;
1383
1384 /* Bail out if we are processing only secured video layers
1385 * and we dont have any */
1386 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1387 reset(ctx);
1388 return false;
1389 }
1390
1391 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1392 mCurrentFrame.reset(numAppLayers);
1393 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1394
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001395 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001396 /* mark secure RGB layers for MDP comp */
1397 updateSecureRGB(ctx, list);
1398
1399 if(mCurrentFrame.mdpCount == 0) {
1400 reset(ctx);
1401 return false;
1402 }
1403
1404 /* find the maximum batch of layers to be marked for framebuffer */
1405 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1406 if(!ret) {
1407 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1408 reset(ctx);
1409 return false;
1410 }
1411
1412 if(sEnableYUVsplit){
1413 adjustForSourceSplit(ctx, list);
1414 }
1415
1416 if(!postHeuristicsHandling(ctx, list)) {
1417 ALOGD_IF(isDebug(), "post heuristic handling failed");
1418 reset(ctx);
1419 return false;
1420 }
1421
1422 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1423 __FUNCTION__);
1424 return true;
1425}
1426
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001427/* Checks for conditions where YUV layers cannot be bypassed */
1428bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001429 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001430 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001431 return false;
1432 }
1433
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001434 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001435 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1436 return false;
1437 }
1438
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001439 if(isSecuring(ctx, layer)) {
1440 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1441 return false;
1442 }
1443
Saurabh Shah4fdde762013-04-30 18:47:33 -07001444 if(!isValidDimension(ctx, layer)) {
1445 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1446 __FUNCTION__);
1447 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001448 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001449
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001450 if(layer->planeAlpha < 0xFF) {
1451 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1452 in video only mode",
1453 __FUNCTION__);
1454 return false;
1455 }
1456
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001457 return true;
1458}
1459
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001460/* Checks for conditions where Secure RGB layers cannot be bypassed */
1461bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1462 if(isSkipLayer(layer)) {
1463 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1464 __FUNCTION__, mDpy);
1465 return false;
1466 }
1467
1468 if(isSecuring(ctx, layer)) {
1469 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1470 return false;
1471 }
1472
1473 if(not isSupportedForMDPComp(ctx, layer)) {
1474 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1475 __FUNCTION__);
1476 return false;
1477 }
1478 return true;
1479}
1480
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301481/* starts at fromIndex and check for each layer to find
1482 * if it it has overlapping with any Updating layer above it in zorder
1483 * till the end of the batch. returns true if it finds any intersection */
1484bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1485 int fromIndex, int toIndex) {
1486 for(int i = fromIndex; i < toIndex; i++) {
1487 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1488 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1489 return false;
1490 }
1491 }
1492 }
1493 return true;
1494}
1495
1496/* Checks if given layer at targetLayerIndex has any
1497 * intersection with all the updating layers in beween
1498 * fromIndex and toIndex. Returns true if it finds intersectiion */
1499bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1500 int fromIndex, int toIndex, int targetLayerIndex) {
1501 for(int i = fromIndex; i <= toIndex; i++) {
1502 if(!mCurrentFrame.isFBComposed[i]) {
1503 if(areLayersIntersecting(&list->hwLayers[i],
1504 &list->hwLayers[targetLayerIndex])) {
1505 return true;
1506 }
1507 }
1508 }
1509 return false;
1510}
1511
1512int MDPComp::getBatch(hwc_display_contents_1_t* list,
1513 int& maxBatchStart, int& maxBatchEnd,
1514 int& maxBatchCount) {
1515 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301516 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001517 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301518 while (i < mCurrentFrame.layerCount) {
1519 int batchCount = 0;
1520 int batchStart = i;
1521 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001522 /* Adjust batch Z order with the dropped layers so far */
1523 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301524 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301525 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301526 while(i < mCurrentFrame.layerCount) {
1527 if(!mCurrentFrame.isFBComposed[i]) {
1528 if(!batchCount) {
1529 i++;
1530 break;
1531 }
1532 updatingLayersAbove++;
1533 i++;
1534 continue;
1535 } else {
1536 if(mCurrentFrame.drop[i]) {
1537 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001538 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301539 continue;
1540 } else if(updatingLayersAbove <= 0) {
1541 batchCount++;
1542 batchEnd = i;
1543 i++;
1544 continue;
1545 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1546
1547 // We have a valid updating layer already. If layer-i not
1548 // have overlapping with all updating layers in between
1549 // batch-start and i, then we can add layer i to batch.
1550 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1551 batchCount++;
1552 batchEnd = i;
1553 i++;
1554 continue;
1555 } else if(canPushBatchToTop(list, batchStart, i)) {
1556 //If All the non-updating layers with in this batch
1557 //does not have intersection with the updating layers
1558 //above in z-order, then we can safely move the batch to
1559 //higher z-order. Increment fbZ as it is moving up.
1560 if( firstZReverseIndex < 0) {
1561 firstZReverseIndex = i;
1562 }
1563 batchCount++;
1564 batchEnd = i;
1565 fbZ += updatingLayersAbove;
1566 i++;
1567 updatingLayersAbove = 0;
1568 continue;
1569 } else {
1570 //both failed.start the loop again from here.
1571 if(firstZReverseIndex >= 0) {
1572 i = firstZReverseIndex;
1573 }
1574 break;
1575 }
1576 }
1577 }
1578 }
1579 if(batchCount > maxBatchCount) {
1580 maxBatchCount = batchCount;
1581 maxBatchStart = batchStart;
1582 maxBatchEnd = batchEnd;
1583 fbZOrder = fbZ;
1584 }
1585 }
1586 return fbZOrder;
1587}
1588
1589bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1590 hwc_display_contents_1_t* list) {
1591 /* Idea is to keep as many non-updating(cached) layers in FB and
1592 * send rest of them through MDP. This is done in 2 steps.
1593 * 1. Find the maximum contiguous batch of non-updating layers.
1594 * 2. See if we can improve this batch size for caching by adding
1595 * opaque layers around the batch, if they don't have
1596 * any overlapping with the updating layers in between.
1597 * NEVER mark an updating layer for caching.
1598 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001599
1600 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001601 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001602 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301603 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001604
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001605 /* Nothing is cached. No batching needed */
1606 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001607 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001608 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001609
1610 /* No MDP comp layers, try to use other comp modes */
1611 if(mCurrentFrame.mdpCount == 0) {
1612 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001613 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001614
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301615 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001616
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301617 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001618 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001619 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001620 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301621 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001622 if(!mCurrentFrame.drop[i]){
1623 //If an unsupported layer is being attempted to
1624 //be pulled out we should fail
1625 if(not isSupportedForMDPComp(ctx, layer)) {
1626 return false;
1627 }
1628 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001629 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001630 }
1631 }
1632
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301633 // update the frame data
1634 mCurrentFrame.fbZ = fbZ;
1635 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001636 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001637 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001638
1639 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301640 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001641
1642 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001643}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001644
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001645void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001646 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001647 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001648 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001649
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001650 for(int i = 0; i < numAppLayers; i++) {
1651 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001652 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001653 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001654 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001655 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001656 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001657 }
1658 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001659
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001660 frame.fbCount = fbCount;
1661 frame.mdpCount = frame.layerCount - frame.fbCount
1662 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001663
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001664 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1665 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001666}
1667
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001668// Mark AIV layers for composition and drop other non-AIV layers.
1669void MDPComp::updateAIVLayers(hwc_context_t* ctx,
1670 hwc_display_contents_1_t* list) {
1671 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1672 hwc_layer_1_t * layer = &list->hwLayers[i];
1673 if(isAIVVideoLayer(layer)) {
1674 if(isYUVDoable(ctx, layer)) {
1675 mCurrentFrame.isFBComposed[i] = false;
1676 mCurrentFrame.fbCount--;
1677 }
1678 } else if(!isAIVCCLayer(layer)) {
1679 mCurrentFrame.dropCount++;
1680 mCurrentFrame.drop[i] = true;
1681 }
1682 }
1683 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1684 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1685 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1686 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1687 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1688 mCurrentFrame.dropCount);
1689}
1690
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001691void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001692 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001693 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1694 for(int index = 0;index < nYuvCount; index++){
1695 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1696 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1697
1698 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001699 if(!frame.isFBComposed[nYuvIndex]) {
1700 frame.isFBComposed[nYuvIndex] = true;
1701 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001702 }
1703 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001704 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001705 private_handle_t *hnd = (private_handle_t *)layer->handle;
1706 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001707 frame.isFBComposed[nYuvIndex] = false;
1708 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001709 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001710 }
1711 }
1712 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001713
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001714 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1715 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001716}
1717
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001718void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1719 hwc_display_contents_1_t* list) {
1720 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1721 for(int index = 0;index < nSecureRGBCount; index++){
1722 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1723 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1724
1725 if(!isSecureRGBDoable(ctx, layer)) {
1726 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1727 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1728 mCurrentFrame.fbCount++;
1729 }
1730 } else {
1731 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1732 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1733 mCurrentFrame.fbCount--;
1734 }
1735 }
1736 }
1737
1738 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1739 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1740 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1741 mCurrentFrame.fbCount);
1742}
1743
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001744hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1745 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001746 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001747
1748 /* Update only the region of FB needed for composition */
1749 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1750 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1751 hwc_layer_1_t* layer = &list->hwLayers[i];
1752 hwc_rect_t dst = layer->displayFrame;
1753 fbRect = getUnion(fbRect, dst);
1754 }
1755 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001756 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001757 return fbRect;
1758}
1759
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001760bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1761 hwc_display_contents_1_t* list) {
1762
1763 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001764 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001765 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1766 return false;
1767 }
1768
1769 //Limitations checks
1770 if(!hwLimitationsCheck(ctx, list)) {
1771 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1772 return false;
1773 }
1774
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001775 //Configure framebuffer first if applicable
1776 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001777 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001778 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1779 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001780 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1781 __FUNCTION__);
1782 return false;
1783 }
1784 }
1785
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001786 mCurrentFrame.map();
1787
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001788 if(!allocLayerPipes(ctx, list)) {
1789 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001790 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001791 }
1792
1793 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001794 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001795 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001796 int mdpIndex = mCurrentFrame.layerToMDP[index];
1797 hwc_layer_1_t* layer = &list->hwLayers[index];
1798
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301799 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1800 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1801 mdpNextZOrder++;
1802 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001803 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1804 cur_pipe->zOrder = mdpNextZOrder++;
1805
radhakrishnac9a67412013-09-25 17:40:42 +05301806 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301807 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301808 if(configure4k2kYuv(ctx, layer,
1809 mCurrentFrame.mdpToLayer[mdpIndex])
1810 != 0 ){
1811 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1812 for layer %d",__FUNCTION__, index);
1813 return false;
1814 }
1815 else{
1816 mdpNextZOrder++;
1817 }
1818 continue;
1819 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001820 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1821 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301822 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001823 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001824 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001825 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001826 }
1827
Saurabh Shaha36be922013-12-16 18:18:39 -08001828 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1829 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1830 ,__FUNCTION__, mDpy);
1831 return false;
1832 }
1833
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001834 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001835 return true;
1836}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001837
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001838bool MDPComp::resourceCheck(hwc_context_t* ctx,
1839 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001840 const bool fbUsed = mCurrentFrame.fbCount;
1841 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1842 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1843 return false;
1844 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001845 // Init rotCount to number of rotate sessions used by other displays
1846 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1847 // Count the number of rotator sessions required for current display
1848 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1849 if(!mCurrentFrame.isFBComposed[index]) {
1850 hwc_layer_1_t* layer = &list->hwLayers[index];
1851 private_handle_t *hnd = (private_handle_t *)layer->handle;
1852 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1853 rotCount++;
1854 }
1855 }
1856 }
1857 // if number of layers to rotate exceeds max rotator sessions, bail out.
1858 if(rotCount > RotMgr::MAX_ROT_SESS) {
1859 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1860 __FUNCTION__, mDpy);
1861 return false;
1862 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001863 return true;
1864}
1865
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301866bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1867 hwc_display_contents_1_t* list) {
1868
1869 //A-family hw limitation:
1870 //If a layer need alpha scaling, MDP can not support.
1871 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1872 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1873 if(!mCurrentFrame.isFBComposed[i] &&
1874 isAlphaScaled( &list->hwLayers[i])) {
1875 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1876 return false;
1877 }
1878 }
1879 }
1880
1881 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1882 //If multiple layers requires downscaling and also they are overlapping
1883 //fall back to GPU since MDSS can not handle it.
1884 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1885 qdutils::MDPVersion::getInstance().is8x26()) {
1886 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1887 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1888 if(!mCurrentFrame.isFBComposed[i] &&
1889 isDownscaleRequired(botLayer)) {
1890 //if layer-i is marked for MDP and needs downscaling
1891 //check if any MDP layer on top of i & overlaps with layer-i
1892 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1893 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1894 if(!mCurrentFrame.isFBComposed[j] &&
1895 isDownscaleRequired(topLayer)) {
1896 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1897 topLayer->displayFrame);
1898 if(isValidRect(r))
1899 return false;
1900 }
1901 }
1902 }
1903 }
1904 }
1905 return true;
1906}
1907
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001908int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001909 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001910 char property[PROPERTY_VALUE_MAX];
1911
Raj Kamal4393eaa2014-06-06 13:45:20 +05301912 if(!ctx || !list) {
1913 ALOGE("%s: Invalid context or list",__FUNCTION__);
1914 mCachedFrame.reset();
1915 return -1;
1916 }
1917
1918 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001919 if(mDpy == HWC_DISPLAY_PRIMARY) {
1920 sSimulationFlags = 0;
1921 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1922 int currentFlags = atoi(property);
1923 if(currentFlags != sSimulationFlags) {
1924 sSimulationFlags = currentFlags;
1925 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1926 sSimulationFlags, sSimulationFlags);
1927 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001928 }
1929 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001930 // reset PTOR
1931 if(!mDpy)
1932 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001933
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301934 //Do not cache the information for next draw cycle.
1935 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1936 ALOGI("%s: Unsupported layer count for mdp composition",
1937 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001938 mCachedFrame.reset();
1939 return -1;
1940 }
1941
Saurabh Shahb39f8152013-08-22 10:21:44 -07001942 //reset old data
1943 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001944 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1945 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301946
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001947 // Detect the start of animation and fall back to GPU only once to cache
1948 // all the layers in FB and display FB content untill animation completes.
1949 if(ctx->listStats[mDpy].isDisplayAnimating) {
1950 mCurrentFrame.needsRedraw = false;
1951 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1952 mCurrentFrame.needsRedraw = true;
1953 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1954 }
1955 setMDPCompLayerFlags(ctx, list);
1956 mCachedFrame.updateCounts(mCurrentFrame);
1957 ret = -1;
1958 return ret;
1959 } else {
1960 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1961 }
1962
Saurabh Shahb39f8152013-08-22 10:21:44 -07001963 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001964 if(isFrameDoable(ctx)) {
1965 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001966
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001967 // if tryFullFrame fails, try to push all video and secure RGB layers
1968 // to MDP for composition.
1969 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001970 tryVideoOnly(ctx, list) || tryAIVVideoMode(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301971 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001972 setMDPCompLayerFlags(ctx, list);
1973 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001974 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001975 reset(ctx);
1976 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1977 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001978 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001979 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1980 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001981 }
1982 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05301983 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
1984 enablePartialUpdateForMDP3) {
1985 generateROI(ctx, list);
1986 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
1987 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
1988 }
1989 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001990 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1991 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001992 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001993 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001994
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001995 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001996 ALOGD("GEOMETRY change: %d",
1997 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001998 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001999 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002000 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002001 }
2002
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002003#ifdef DYNAMIC_FPS
2004 //For primary display, set the dynamic refreshrate
2005 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported()) {
2006 FrameInfo frame;
2007 frame.reset(mCurrentFrame.layerCount);
2008 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
2009 __FUNCTION__);
2010 updateLayerCache(ctx, list, frame);
2011 updateYUV(ctx, list, false /*secure only*/, frame);
2012 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
2013 //Set the new fresh rate, if there is only one updating YUV layer
2014 //or there is one single RGB layer with this request
2015 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
2016 (frame.layerCount == 1)) {
2017 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
2018 }
2019 setRefreshRate(ctx, mDpy, refreshRate);
2020 }
2021#endif
2022
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002023 mCachedFrame.cacheAll(list);
2024 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002025 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002026}
2027
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002028bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302029
2030 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302031 int mdpIndex = mCurrentFrame.layerToMDP[index];
2032 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2033 info.pipeInfo = new MdpYUVPipeInfo;
2034 info.rot = NULL;
2035 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302036
2037 pipe_info.lIndex = ovutils::OV_INVALID;
2038 pipe_info.rIndex = ovutils::OV_INVALID;
2039
Saurabh Shahc62f3982014-03-05 14:28:26 -08002040 Overlay::PipeSpecs pipeSpecs;
2041 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2042 pipeSpecs.needsScaling = true;
2043 pipeSpecs.dpy = mDpy;
2044 pipeSpecs.fb = false;
2045
2046 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302047 if(pipe_info.lIndex == ovutils::OV_INVALID){
2048 bRet = false;
2049 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2050 __FUNCTION__);
2051 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002052 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302053 if(pipe_info.rIndex == ovutils::OV_INVALID){
2054 bRet = false;
2055 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2056 __FUNCTION__);
2057 }
2058 return bRet;
2059}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002060
2061int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2062 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002063 if (ctx->mPtorInfo.isActive()) {
2064 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002065 if (fd < 0) {
2066 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002067 }
2068 }
2069 return fd;
2070}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002071//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002072
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002073void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302074 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002075 //If 4k2k Yuv layer split is possible, and if
2076 //fbz is above 4k2k layer, increment fb zorder by 1
2077 //as we split 4k2k layer and increment zorder for right half
2078 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002079 if(!ctx)
2080 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002081 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302082 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2083 index++) {
2084 if(!mCurrentFrame.isFBComposed[index]) {
2085 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2086 mdpNextZOrder++;
2087 }
2088 mdpNextZOrder++;
2089 hwc_layer_1_t* layer = &list->hwLayers[index];
2090 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302091 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302092 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2093 mCurrentFrame.fbZ += 1;
2094 mdpNextZOrder++;
2095 //As we split 4kx2k yuv layer and program to 2 VG pipes
2096 //(if available) increase mdpcount by 1.
2097 mCurrentFrame.mdpCount++;
2098 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002099 }
2100 }
2101 }
radhakrishnac9a67412013-09-25 17:40:42 +05302102}
2103
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002104/*
2105 * Configures pipe(s) for MDP composition
2106 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002107int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002108 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002109 MdpPipeInfoNonSplit& mdp_info =
2110 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002111 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
2112 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002113 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002114
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002115 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2116 __FUNCTION__, layer, zOrder, dest);
2117
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002118 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002119 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002120}
2121
Saurabh Shah88e4d272013-09-03 13:31:29 -07002122bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002123 hwc_display_contents_1_t* list) {
2124 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002125
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002126 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002127
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002128 hwc_layer_1_t* layer = &list->hwLayers[index];
2129 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302130 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002131 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302132 continue;
2133 }
2134 }
2135
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002136 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002137 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002138 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002139 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002140 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002141
Saurabh Shahc62f3982014-03-05 14:28:26 -08002142 Overlay::PipeSpecs pipeSpecs;
2143 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2144 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2145 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2146 (qdutils::MDPVersion::getInstance().is8x26() and
2147 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2148 pipeSpecs.dpy = mDpy;
2149 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002150 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002151
Saurabh Shahc62f3982014-03-05 14:28:26 -08002152 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2153
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002154 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002155 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002156 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002157 }
2158 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002159 return true;
2160}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002161
radhakrishnac9a67412013-09-25 17:40:42 +05302162int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2163 PipeLayerPair& PipeLayerPair) {
2164 MdpYUVPipeInfo& mdp_info =
2165 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2166 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302167 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2168 eDest lDest = mdp_info.lIndex;
2169 eDest rDest = mdp_info.rIndex;
2170
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002171 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302172 lDest, rDest, &PipeLayerPair.rot);
2173}
2174
Saurabh Shah88e4d272013-09-03 13:31:29 -07002175bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002176
Raj Kamal4393eaa2014-06-06 13:45:20 +05302177 if(!isEnabled() or !mModeOn) {
2178 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302179 return true;
2180 }
2181
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002182 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002183 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002184 sHandleTimeout = true;
2185 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002186
2187 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002188 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002189
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002190 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2191 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002192 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002193 if(mCurrentFrame.isFBComposed[i]) continue;
2194
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002195 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002196 private_handle_t *hnd = (private_handle_t *)layer->handle;
2197 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002198 if (!(layer->flags & HWC_COLOR_FILL)) {
2199 ALOGE("%s handle null", __FUNCTION__);
2200 return false;
2201 }
2202 // No PLAY for Color layer
2203 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2204 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002205 }
2206
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002207 int mdpIndex = mCurrentFrame.layerToMDP[i];
2208
Raj Kamal389d6e32014-08-04 14:43:24 +05302209 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302210 {
2211 MdpYUVPipeInfo& pipe_info =
2212 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2213 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2214 ovutils::eDest indexL = pipe_info.lIndex;
2215 ovutils::eDest indexR = pipe_info.rIndex;
2216 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302217 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302218 if(rot) {
2219 rot->queueBuffer(fd, offset);
2220 fd = rot->getDstMemId();
2221 offset = rot->getDstOffset();
2222 }
2223 if(indexL != ovutils::OV_INVALID) {
2224 ovutils::eDest destL = (ovutils::eDest)indexL;
2225 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2226 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2227 if (!ov.queueBuffer(fd, offset, destL)) {
2228 ALOGE("%s: queueBuffer failed for display:%d",
2229 __FUNCTION__, mDpy);
2230 return false;
2231 }
2232 }
2233
2234 if(indexR != ovutils::OV_INVALID) {
2235 ovutils::eDest destR = (ovutils::eDest)indexR;
2236 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2237 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2238 if (!ov.queueBuffer(fd, offset, destR)) {
2239 ALOGE("%s: queueBuffer failed for display:%d",
2240 __FUNCTION__, mDpy);
2241 return false;
2242 }
2243 }
2244 }
2245 else{
2246 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002247 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302248 ovutils::eDest dest = pipe_info.index;
2249 if(dest == ovutils::OV_INVALID) {
2250 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002251 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302252 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002253
radhakrishnac9a67412013-09-25 17:40:42 +05302254 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2255 continue;
2256 }
2257
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002258 int fd = hnd->fd;
2259 uint32_t offset = (uint32_t)hnd->offset;
2260 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2261 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002262 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002263 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002264 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002265 }
2266
radhakrishnac9a67412013-09-25 17:40:42 +05302267 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2268 using pipe: %d", __FUNCTION__, layer,
2269 hnd, dest );
2270
radhakrishnac9a67412013-09-25 17:40:42 +05302271 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2272 if(rot) {
2273 if(!rot->queueBuffer(fd, offset))
2274 return false;
2275 fd = rot->getDstMemId();
2276 offset = rot->getDstOffset();
2277 }
2278
2279 if (!ov.queueBuffer(fd, offset, dest)) {
2280 ALOGE("%s: queueBuffer failed for display:%d ",
2281 __FUNCTION__, mDpy);
2282 return false;
2283 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002284 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002285
2286 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002287 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002288 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002289}
2290
Saurabh Shah88e4d272013-09-03 13:31:29 -07002291//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002292
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002293void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302294 hwc_display_contents_1_t* list){
2295 //if 4kx2k yuv layer is totally present in either in left half
2296 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302297 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302298 if(mCurrentFrame.fbZ >= 0) {
2299 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2300 index++) {
2301 if(!mCurrentFrame.isFBComposed[index]) {
2302 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2303 mdpNextZOrder++;
2304 }
2305 mdpNextZOrder++;
2306 hwc_layer_1_t* layer = &list->hwLayers[index];
2307 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302308 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302309 hwc_rect_t dst = layer->displayFrame;
2310 if((dst.left > lSplit) || (dst.right < lSplit)) {
2311 mCurrentFrame.mdpCount += 1;
2312 }
2313 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2314 mCurrentFrame.fbZ += 1;
2315 mdpNextZOrder++;
2316 }
2317 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002318 }
radhakrishnac9a67412013-09-25 17:40:42 +05302319 }
2320}
2321
Saurabh Shah88e4d272013-09-03 13:31:29 -07002322bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002323 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002324
Saurabh Shahc62f3982014-03-05 14:28:26 -08002325 const int lSplit = getLeftSplit(ctx, mDpy);
2326 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002327 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002328 pipe_info.lIndex = ovutils::OV_INVALID;
2329 pipe_info.rIndex = ovutils::OV_INVALID;
2330
Saurabh Shahc62f3982014-03-05 14:28:26 -08002331 Overlay::PipeSpecs pipeSpecs;
2332 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2333 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2334 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2335 pipeSpecs.dpy = mDpy;
2336 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2337 pipeSpecs.fb = false;
2338
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002339 // Acquire pipe only for the updating half
2340 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2341 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2342
2343 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002344 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002345 if(pipe_info.lIndex == ovutils::OV_INVALID)
2346 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002347 }
2348
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002349 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002350 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2351 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002352 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002353 return false;
2354 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002355
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002356 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002357}
2358
Saurabh Shah88e4d272013-09-03 13:31:29 -07002359bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002360 hwc_display_contents_1_t* list) {
2361 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002362
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002363 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002364
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002365 hwc_layer_1_t* layer = &list->hwLayers[index];
2366 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302367 hwc_rect_t dst = layer->displayFrame;
2368 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302369 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302370 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002371 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302372 continue;
2373 }
2374 }
2375 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002376 int mdpIndex = mCurrentFrame.layerToMDP[index];
2377 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002378 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002379 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002380 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002381
Saurabh Shahc62f3982014-03-05 14:28:26 -08002382 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2383 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2384 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002385 return false;
2386 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002387 }
2388 return true;
2389}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002390
radhakrishnac9a67412013-09-25 17:40:42 +05302391int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2392 PipeLayerPair& PipeLayerPair) {
2393 const int lSplit = getLeftSplit(ctx, mDpy);
2394 hwc_rect_t dst = layer->displayFrame;
2395 if((dst.left > lSplit)||(dst.right < lSplit)){
2396 MdpYUVPipeInfo& mdp_info =
2397 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2398 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302399 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2400 eDest lDest = mdp_info.lIndex;
2401 eDest rDest = mdp_info.rIndex;
2402
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002403 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302404 lDest, rDest, &PipeLayerPair.rot);
2405 }
2406 else{
2407 return configure(ctx, layer, PipeLayerPair);
2408 }
2409}
2410
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002411/*
2412 * Configures pipe(s) for MDP composition
2413 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002414int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002415 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002416 MdpPipeInfoSplit& mdp_info =
2417 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002418 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002419 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2420 eDest lDest = mdp_info.lIndex;
2421 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002422
2423 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2424 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2425
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002426 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002427 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002428}
2429
Saurabh Shah88e4d272013-09-03 13:31:29 -07002430bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002431
Raj Kamal4393eaa2014-06-06 13:45:20 +05302432 if(!isEnabled() or !mModeOn) {
2433 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302434 return true;
2435 }
2436
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002437 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002438 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002439 sHandleTimeout = true;
2440 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002441
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002442 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002443 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002444
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002445 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2446 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002447 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002448 if(mCurrentFrame.isFBComposed[i]) continue;
2449
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002450 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002451 private_handle_t *hnd = (private_handle_t *)layer->handle;
2452 if(!hnd) {
2453 ALOGE("%s handle null", __FUNCTION__);
2454 return false;
2455 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002456
2457 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2458 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002459 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002460
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002461 int mdpIndex = mCurrentFrame.layerToMDP[i];
2462
Raj Kamal389d6e32014-08-04 14:43:24 +05302463 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302464 {
2465 MdpYUVPipeInfo& pipe_info =
2466 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2467 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2468 ovutils::eDest indexL = pipe_info.lIndex;
2469 ovutils::eDest indexR = pipe_info.rIndex;
2470 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302471 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302472 if(rot) {
2473 rot->queueBuffer(fd, offset);
2474 fd = rot->getDstMemId();
2475 offset = rot->getDstOffset();
2476 }
2477 if(indexL != ovutils::OV_INVALID) {
2478 ovutils::eDest destL = (ovutils::eDest)indexL;
2479 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2480 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2481 if (!ov.queueBuffer(fd, offset, destL)) {
2482 ALOGE("%s: queueBuffer failed for display:%d",
2483 __FUNCTION__, mDpy);
2484 return false;
2485 }
2486 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002487
radhakrishnac9a67412013-09-25 17:40:42 +05302488 if(indexR != ovutils::OV_INVALID) {
2489 ovutils::eDest destR = (ovutils::eDest)indexR;
2490 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2491 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2492 if (!ov.queueBuffer(fd, offset, destR)) {
2493 ALOGE("%s: queueBuffer failed for display:%d",
2494 __FUNCTION__, mDpy);
2495 return false;
2496 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002497 }
2498 }
radhakrishnac9a67412013-09-25 17:40:42 +05302499 else{
2500 MdpPipeInfoSplit& pipe_info =
2501 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2502 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002503
radhakrishnac9a67412013-09-25 17:40:42 +05302504 ovutils::eDest indexL = pipe_info.lIndex;
2505 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002506
radhakrishnac9a67412013-09-25 17:40:42 +05302507 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002508 uint32_t offset = (uint32_t)hnd->offset;
2509 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2510 if (!mDpy && (index != -1)) {
2511 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2512 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002513 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002514 }
radhakrishnac9a67412013-09-25 17:40:42 +05302515
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002516 if(ctx->mAD->draw(ctx, fd, offset)) {
2517 fd = ctx->mAD->getDstFd();
2518 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002519 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002520
radhakrishnac9a67412013-09-25 17:40:42 +05302521 if(rot) {
2522 rot->queueBuffer(fd, offset);
2523 fd = rot->getDstMemId();
2524 offset = rot->getDstOffset();
2525 }
2526
2527 //************* play left mixer **********
2528 if(indexL != ovutils::OV_INVALID) {
2529 ovutils::eDest destL = (ovutils::eDest)indexL;
2530 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2531 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2532 if (!ov.queueBuffer(fd, offset, destL)) {
2533 ALOGE("%s: queueBuffer failed for left mixer",
2534 __FUNCTION__);
2535 return false;
2536 }
2537 }
2538
2539 //************* play right mixer **********
2540 if(indexR != ovutils::OV_INVALID) {
2541 ovutils::eDest destR = (ovutils::eDest)indexR;
2542 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2543 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2544 if (!ov.queueBuffer(fd, offset, destR)) {
2545 ALOGE("%s: queueBuffer failed for right mixer",
2546 __FUNCTION__);
2547 return false;
2548 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002549 }
2550 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002551
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002552 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2553 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002554
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002555 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002556}
Saurabh Shahab47c692014-02-12 18:45:57 -08002557
2558//================MDPCompSrcSplit==============================================
2559bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002560 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002561 private_handle_t *hnd = (private_handle_t *)layer->handle;
2562 hwc_rect_t dst = layer->displayFrame;
2563 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2564 pipe_info.lIndex = ovutils::OV_INVALID;
2565 pipe_info.rIndex = ovutils::OV_INVALID;
2566
2567 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2568 //should have a higher priority than the right one. Pipe priorities are
2569 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002570
Saurabh Shahc62f3982014-03-05 14:28:26 -08002571 Overlay::PipeSpecs pipeSpecs;
2572 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2573 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2574 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2575 pipeSpecs.dpy = mDpy;
2576 pipeSpecs.fb = false;
2577
Saurabh Shahab47c692014-02-12 18:45:57 -08002578 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002579 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002580 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002581 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002582 }
2583
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002584 /* Use 2 pipes IF
2585 a) Layer's crop width is > 2048 or
2586 b) Layer's dest width > 2048 or
2587 c) On primary, driver has indicated with caps to split always. This is
2588 based on an empirically derived value of panel height. Applied only
2589 if the layer's width is > mixer's width
2590 */
2591
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302592 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002593 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302594 mdpHw.isSrcSplitAlways();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002595 int lSplit = getLeftSplit(ctx, mDpy);
2596 int dstWidth = dst.right - dst.left;
Saurabh Shah189f23d2014-09-26 17:21:00 -07002597 int cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
2598 crop.right - crop.left;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002599
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002600 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2601 //pipe line length, we are still using 2 pipes. This is fine just because
2602 //this is source split where destination doesn't matter. Evaluate later to
2603 //see if going through all the calcs to save a pipe is worth it
Naseer Ahmed9eb5e092014-09-25 13:24:44 -04002604 if(dstWidth > (int) mdpHw.getMaxMixerWidth() or
2605 cropWidth > (int) mdpHw.getMaxMixerWidth() or
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002606 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002607 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002608 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002609 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002610 }
2611
2612 // Return values
2613 // 1 Left pipe is higher priority, do nothing.
2614 // 0 Pipes of same priority.
2615 //-1 Right pipe is of higher priority, needs swap.
2616 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2617 pipe_info.rIndex) == -1) {
2618 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002619 }
2620 }
2621
2622 return true;
2623}
2624
Saurabh Shahab47c692014-02-12 18:45:57 -08002625int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2626 PipeLayerPair& PipeLayerPair) {
2627 private_handle_t *hnd = (private_handle_t *)layer->handle;
2628 if(!hnd) {
2629 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2630 return -1;
2631 }
2632 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2633 MdpPipeInfoSplit& mdp_info =
2634 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2635 Rotator **rot = &PipeLayerPair.rot;
2636 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002637 eDest lDest = mdp_info.lIndex;
2638 eDest rDest = mdp_info.rIndex;
2639 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2640 hwc_rect_t dst = layer->displayFrame;
2641 int transform = layer->transform;
2642 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002643 int rotFlags = ROT_FLAGS_NONE;
2644 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2645 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2646
2647 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2648 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2649
2650 // Handle R/B swap
2651 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2652 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2653 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2654 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2655 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2656 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002657 // update source crop and destination position of AIV video layer.
2658 if(ctx->mAIVVideoMode[mDpy] &&isYuvBuffer(hnd)) {
2659 updateExtDisplayCoordinates(ctx, crop, dst, mDpy);
2660 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002661 /* Calculate the external display position based on MDP downscale,
2662 ActionSafe, and extorientation features. */
2663 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002664
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002665 int downscale = getRotDownscale(ctx, layer);
Saurabh Shah97e2d802014-04-14 18:03:54 -07002666 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002667 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002668
2669 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2670 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002671 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002672 }
2673
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002674 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002675 (*rot) = ctx->mRotMgr->getNext();
2676 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002677 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002678 //If the video is using a single pipe, enable BWC
2679 if(rDest == OV_INVALID) {
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002680 BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002681 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002682 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002683 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002684 ALOGE("%s: configRotator failed!", __FUNCTION__);
2685 return -1;
2686 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002687 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002688 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002689 }
2690
2691 //If 2 pipes being used, divide layer into half, crop and dst
2692 hwc_rect_t cropL = crop;
2693 hwc_rect_t cropR = crop;
2694 hwc_rect_t dstL = dst;
2695 hwc_rect_t dstR = dst;
2696 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2697 cropL.right = (crop.right + crop.left) / 2;
2698 cropR.left = cropL.right;
2699 sanitizeSourceCrop(cropL, cropR, hnd);
2700
Saurabh Shahb729b192014-08-15 18:04:24 -07002701 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002702 //Swap crops on H flip since 2 pipes are being used
2703 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2704 hwc_rect_t tmp = cropL;
2705 cropL = cropR;
2706 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002707 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002708 }
2709
Saurabh Shahb729b192014-08-15 18:04:24 -07002710 //cropSwap trick: If the src and dst widths are both odd, let us say
2711 //2507, then splitting both into half would cause left width to be 1253
2712 //and right 1254. If crop is swapped because of H flip, this will cause
2713 //left crop width to be 1254, whereas left dst width remains 1253, thus
2714 //inducing a scaling that is unaccounted for. To overcome that we add 1
2715 //to the dst width if there is a cropSwap. So if the original width was
2716 //2507, the left dst width will be 1254. Even if the original width was
2717 //even for ex: 2508, the left dst width will still remain 1254.
2718 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002719 dstR.left = dstL.right;
2720 }
2721
2722 //For the mdp, since either we are pre-rotating or MDP does flips
2723 orient = OVERLAY_TRANSFORM_0;
2724 transform = 0;
2725
2726 //configure left pipe
2727 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002728 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002729 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2730 (ovutils::eBlending) getBlending(layer->blending));
2731
2732 if(configMdp(ctx->mOverlay, pargL, orient,
2733 cropL, dstL, metadata, lDest) < 0) {
2734 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2735 return -1;
2736 }
2737 }
2738
2739 //configure right pipe
2740 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002741 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002742 static_cast<eRotFlags>(rotFlags),
2743 layer->planeAlpha,
2744 (ovutils::eBlending) getBlending(layer->blending));
2745 if(configMdp(ctx->mOverlay, pargR, orient,
2746 cropR, dstR, metadata, rDest) < 0) {
2747 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2748 return -1;
2749 }
2750 }
2751
2752 return 0;
2753}
2754
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002755}; //namespace
2756