blob: 2904e6fe937e4f2e67c1a4662c5b87565b4f0fe1 [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 Radhakrishnanb33f4902014-10-03 16:46:35 -0700713 // Fall back to video only composition, if AIV video mode is enabled
714 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700715 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
716 __FUNCTION__, mDpy);
717 return false;
718 }
719
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400720 // No Idle fall back, if secure display or secure RGB layers are present or
721 // if there's only a single layer being composed
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -0700722 if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400723 !ctx->listStats[mDpy].secureRGBCount) &&
724 (ctx->listStats[mDpy].numAppLayers != 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700725 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
726 return false;
727 }
728
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800729 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700730 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
731 __FUNCTION__,
732 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800733 return false;
734 }
735
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700736 // if secondary is configuring or Padding round, fall back to video only
737 // composition and release all assigned non VIG pipes from primary.
738 if(isSecondaryConfiguring(ctx)) {
739 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
740 __FUNCTION__);
741 return false;
742 } else if(ctx->isPaddingRound) {
743 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
744 __FUNCTION__,mDpy);
745 return false;
746 }
747
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530748 MDPVersion& mdpHw = MDPVersion::getInstance();
749 if(mDpy > HWC_DISPLAY_PRIMARY &&
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400750 (priDispW > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530751 (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800752 // Disable MDP comp on Secondary when the primary is highres panel and
753 // the secondary is a normal 1080p, because, MDP comp on secondary under
754 // in such usecase, decimation gets used for downscale and there will be
755 // a quality mismatch when there will be a fallback to GPU comp
756 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
757 __FUNCTION__);
758 return false;
759 }
760
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700761 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800762 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700763 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800764 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
765 return false;
766 }
767
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800768 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800769 hwc_layer_1_t* layer = &list->hwLayers[i];
770 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800771
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800772 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700773 if(!canUseRotator(ctx, mDpy)) {
774 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
775 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700776 return false;
777 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800778 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530779
780 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
781 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700782 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530783 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
784 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
785 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800786 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700787
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700788 if(ctx->mAD->isDoable()) {
789 return false;
790 }
791
Saurabh Shahaa236822013-04-24 18:07:26 -0700792 //If all above hard conditions are met we can do full or partial MDP comp.
793 bool ret = false;
794 if(fullMDPComp(ctx, list)) {
795 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700796 } else if(fullMDPCompWithPTOR(ctx, list)) {
797 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700798 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700799 ret = true;
800 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530801
Saurabh Shahaa236822013-04-24 18:07:26 -0700802 return ret;
803}
804
805bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700806
807 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
808 return false;
809
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700810 //Will benefit presentation / secondary-only layer.
811 if((mDpy > HWC_DISPLAY_PRIMARY) &&
812 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
813 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
814 return false;
815 }
816
817 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
818 for(int i = 0; i < numAppLayers; i++) {
819 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700820 if(not mCurrentFrame.drop[i] and
821 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700822 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
823 return false;
824 }
825 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800826
Saurabh Shahaa236822013-04-24 18:07:26 -0700827 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700828 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
829 sizeof(mCurrentFrame.isFBComposed));
830 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
831 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700832
Raj Kamal389d6e32014-08-04 14:43:24 +0530833 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800834 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530835 }
836
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800837 if(!postHeuristicsHandling(ctx, list)) {
838 ALOGD_IF(isDebug(), "post heuristic handling failed");
839 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700840 return false;
841 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700842 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
843 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700844 return true;
845}
846
Sushil Chauhandefd3522014-05-13 18:17:12 -0700847/* Full MDP Composition with Peripheral Tiny Overlap Removal.
848 * MDP bandwidth limitations can be avoided, if the overlap region
849 * covered by the smallest layer at a higher z-order, gets composed
850 * by Copybit on a render buffer, which can be queued to MDP.
851 */
852bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
853 hwc_display_contents_1_t* list) {
854
855 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
856 const int stagesForMDP = min(sMaxPipesPerMixer,
857 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
858
859 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700860 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700861 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
862 return false;
863 }
864
865 // Frame level checks
866 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
867 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
868 isSecurePresent(ctx, mDpy)) {
869 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
870 return false;
871 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700872 // MDP comp checks
873 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700874 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700875 if(not isSupportedForMDPComp(ctx, layer)) {
876 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
877 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700878 }
879 }
880
Sushil Chauhandefd3522014-05-13 18:17:12 -0700881 /* We cannot use this composition mode, if:
882 1. A below layer needs scaling.
883 2. Overlap is not peripheral to display.
884 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700885 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700886 */
887
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700888 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
889 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
890 memset(overlapRect, 0, sizeof(overlapRect));
891 int layerPixelCount, minPixelCount = 0;
892 int numPTORLayersFound = 0;
893 for (int i = numAppLayers-1; (i >= 0 &&
894 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700895 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700896 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700897 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700898 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
899 // PTOR layer should be peripheral and cannot have transform
900 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
901 has90Transform(layer)) {
902 continue;
903 }
904 if((3 * (layerPixelCount + minPixelCount)) >
905 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
906 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
907 continue;
908 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700909 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700910 for (int j = i-1; j >= 0; j--) {
911 // Check if the layers below this layer qualifies for PTOR comp
912 hwc_layer_1_t* layer = &list->hwLayers[j];
913 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700914 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700915 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700916 if (isValidRect(getIntersection(dispFrame, disFrame))) {
917 if (has90Transform(layer) || needsScaling(layer)) {
918 found = false;
919 break;
920 }
921 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700922 }
923 }
924 // Store the minLayer Index
925 if(found) {
926 minLayerIndex[numPTORLayersFound] = i;
927 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
928 minPixelCount += layerPixelCount;
929 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700930 }
931 }
932
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700933 // No overlap layers
934 if (!numPTORLayersFound)
935 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700936
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700937 // Store the displayFrame and the sourceCrops of the layers
938 hwc_rect_t displayFrame[numAppLayers];
939 hwc_rect_t sourceCrop[numAppLayers];
940 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700941 hwc_layer_1_t* layer = &list->hwLayers[i];
942 displayFrame[i] = layer->displayFrame;
943 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700944 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700945
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530946 /**
947 * It's possible that 2 PTOR layers might have overlapping.
948 * In such case, remove the intersection(again if peripheral)
949 * from the lower PTOR layer to avoid overlapping.
950 * If intersection is not on peripheral then compromise
951 * by reducing number of PTOR layers.
952 **/
953 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
954 if(isValidRect(commonRect)) {
955 overlapRect[1] = deductRect(overlapRect[1], commonRect);
956 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
957 }
958
959 ctx->mPtorInfo.count = numPTORLayersFound;
960 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
961 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
962 }
963
964 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
965 // reset PTOR
966 ctx->mPtorInfo.count = 0;
967 if(isValidRect(commonRect)) {
968 // If PTORs are intersecting restore displayframe of PTOR[1]
969 // before returning, as we have modified it above.
970 list->hwLayers[minLayerIndex[1]].displayFrame =
971 displayFrame[minLayerIndex[1]];
972 }
973 return false;
974 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700975 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
976 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
977
Xu Yangcda012c2014-07-30 21:57:21 +0800978 // Store the blending mode, planeAlpha, and transform of PTOR layers
979 int32_t blending[numPTORLayersFound];
980 uint8_t planeAlpha[numPTORLayersFound];
981 uint32_t transform[numPTORLayersFound];
982
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700983 for(int j = 0; j < numPTORLayersFound; j++) {
984 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700985
986 // Update src crop of PTOR layer
987 hwc_layer_1_t* layer = &list->hwLayers[index];
988 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
989 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
990 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
991 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
992
993 // Store & update w, h, format of PTOR layer
994 private_handle_t *hnd = (private_handle_t *)layer->handle;
995 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
996 layerWhf[j] = whf;
997 hnd->width = renderBuf->width;
998 hnd->height = renderBuf->height;
999 hnd->format = renderBuf->format;
1000
Xu Yangcda012c2014-07-30 21:57:21 +08001001 // Store & update blending mode, planeAlpha and transform of PTOR layer
1002 blending[j] = layer->blending;
1003 planeAlpha[j] = layer->planeAlpha;
1004 transform[j] = layer->transform;
1005 layer->blending = HWC_BLENDING_NONE;
1006 layer->planeAlpha = 0xFF;
1007 layer->transform = 0;
1008
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001009 // Remove overlap from crop & displayFrame of below layers
1010 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001011 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001012 if(!isValidRect(getIntersection(layer->displayFrame,
1013 overlapRect[j]))) {
1014 continue;
1015 }
1016 // Update layer attributes
1017 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1018 hwc_rect_t destRect = deductRect(layer->displayFrame,
1019 overlapRect[j]);
1020 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1021 layer->transform);
1022 layer->sourceCropf.left = (float)srcCrop.left;
1023 layer->sourceCropf.top = (float)srcCrop.top;
1024 layer->sourceCropf.right = (float)srcCrop.right;
1025 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1026 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001027 }
1028
1029 mCurrentFrame.mdpCount = numAppLayers;
1030 mCurrentFrame.fbCount = 0;
1031 mCurrentFrame.fbZ = -1;
1032
1033 for (int j = 0; j < numAppLayers; j++)
1034 mCurrentFrame.isFBComposed[j] = false;
1035
1036 bool result = postHeuristicsHandling(ctx, list);
1037
1038 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001039 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001040 hwc_layer_1_t* layer = &list->hwLayers[i];
1041 layer->displayFrame = displayFrame[i];
1042 layer->sourceCropf.left = (float)sourceCrop[i].left;
1043 layer->sourceCropf.top = (float)sourceCrop[i].top;
1044 layer->sourceCropf.right = (float)sourceCrop[i].right;
1045 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1046 }
1047
Xu Yangcda012c2014-07-30 21:57:21 +08001048 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001049 for (int i = 0; i < numPTORLayersFound; i++) {
1050 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001051 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001052 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1053 hnd->width = layerWhf[i].w;
1054 hnd->height = layerWhf[i].h;
1055 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001056 layer->blending = blending[i];
1057 layer->planeAlpha = planeAlpha[i];
1058 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001059 }
1060
Sushil Chauhandefd3522014-05-13 18:17:12 -07001061 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001062 // reset PTOR
1063 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001064 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001065 } else {
1066 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1067 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001068 }
1069
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001070 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1071 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001072 return result;
1073}
1074
Saurabh Shahaa236822013-04-24 18:07:26 -07001075bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1076{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001077 if(!sEnableMixedMode) {
1078 //Mixed mode is disabled. No need to even try caching.
1079 return false;
1080 }
1081
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001082 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001083 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001084 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001085 cacheBasedComp(ctx, list);
1086 } else {
1087 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001088 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001089 }
1090
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001091 return ret;
1092}
1093
1094bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1095 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001096 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1097 return false;
1098
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001099 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001100 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001101 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001102
1103 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1104 for(int i = 0; i < numAppLayers; i++) {
1105 if(!mCurrentFrame.isFBComposed[i]) {
1106 hwc_layer_1_t* layer = &list->hwLayers[i];
1107 if(not isSupportedForMDPComp(ctx, layer)) {
1108 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1109 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001110 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001111 return false;
1112 }
1113 }
1114 }
1115
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001116 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001117 /* mark secure RGB layers for MDP comp */
1118 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301119 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001120 if(!ret) {
1121 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001122 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001123 return false;
1124 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001125
1126 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001127
Raj Kamal389d6e32014-08-04 14:43:24 +05301128 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001129 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301130 }
1131
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001132 //Will benefit cases where a video has non-updating background.
1133 if((mDpy > HWC_DISPLAY_PRIMARY) and
1134 (mdpCount > MAX_SEC_LAYERS)) {
1135 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001136 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001137 return false;
1138 }
1139
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001140 if(!postHeuristicsHandling(ctx, list)) {
1141 ALOGD_IF(isDebug(), "post heuristic handling failed");
1142 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001143 return false;
1144 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001145 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1146 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001147
Saurabh Shahaa236822013-04-24 18:07:26 -07001148 return true;
1149}
1150
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001151bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001152 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001153 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1154 return false;
1155
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001156 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001157 return false;
1158 }
1159
Saurabh Shahb772ae32013-11-18 15:40:02 -08001160 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001161 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1162 const int stagesForMDP = min(sMaxPipesPerMixer,
1163 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001164
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001165 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1166 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1167 int lastMDPSupportedIndex = numAppLayers;
1168 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001169
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001170 //Find the minimum MDP batch size
1171 for(int i = 0; i < numAppLayers;i++) {
1172 if(mCurrentFrame.drop[i]) {
1173 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001174 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001175 }
1176 hwc_layer_1_t* layer = &list->hwLayers[i];
1177 if(not isSupportedForMDPComp(ctx, layer)) {
1178 lastMDPSupportedIndex = i;
1179 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1180 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001181 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001182 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001183 }
1184
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001185 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1186 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1187 mCurrentFrame.dropCount);
1188
1189 //Start at a point where the fb batch should at least have 2 layers, for
1190 //this mode to be justified.
1191 while(fbBatchSize < 2) {
1192 ++fbBatchSize;
1193 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001194 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001195
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001196 //If there are no layers for MDP, this mode doesnt make sense.
1197 if(mdpBatchSize < 1) {
1198 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1199 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001200 return false;
1201 }
1202
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001203 mCurrentFrame.reset(numAppLayers);
1204
1205 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1206 while(mdpBatchSize > 0) {
1207 //Mark layers for MDP comp
1208 int mdpBatchLeft = mdpBatchSize;
1209 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1210 if(mCurrentFrame.drop[i]) {
1211 continue;
1212 }
1213 mCurrentFrame.isFBComposed[i] = false;
1214 --mdpBatchLeft;
1215 }
1216
1217 mCurrentFrame.fbZ = mdpBatchSize;
1218 mCurrentFrame.fbCount = fbBatchSize;
1219 mCurrentFrame.mdpCount = mdpBatchSize;
1220
1221 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1222 __FUNCTION__, mdpBatchSize, fbBatchSize,
1223 mCurrentFrame.dropCount);
1224
1225 if(postHeuristicsHandling(ctx, list)) {
1226 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001227 __FUNCTION__);
1228 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1229 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001230 return true;
1231 }
1232
1233 reset(ctx);
1234 --mdpBatchSize;
1235 ++fbBatchSize;
1236 }
1237
1238 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001239}
1240
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001241bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301242 if(mDpy or isSecurePresent(ctx, mDpy) or
1243 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001244 return false;
1245 }
1246 return true;
1247}
1248
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001249bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1250 hwc_display_contents_1_t* list){
1251 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1252 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1253 mDpy ) {
1254 return false;
1255 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001256 if(ctx->listStats[mDpy].secureUI)
1257 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001258 return true;
1259}
1260
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001261bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1262 hwc_display_contents_1_t* list) {
1263 const bool secureOnly = true;
1264 return videoOnlyComp(ctx, list, not secureOnly) or
1265 videoOnlyComp(ctx, list, secureOnly);
1266}
1267
1268bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001269 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001270 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1271 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001272 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001273
Saurabh Shahaa236822013-04-24 18:07:26 -07001274 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001275 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001276 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001277 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001278
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001279 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1280 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001281 return false;
1282 }
1283
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001284 /* Bail out if we are processing only secured video layers
1285 * and we dont have any */
1286 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001287 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001288 return false;
1289 }
1290
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001291 if(mCurrentFrame.fbCount)
1292 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001293
Raj Kamal389d6e32014-08-04 14:43:24 +05301294 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001295 adjustForSourceSplit(ctx, list);
1296 }
1297
1298 if(!postHeuristicsHandling(ctx, list)) {
1299 ALOGD_IF(isDebug(), "post heuristic handling failed");
1300 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001301 return false;
1302 }
1303
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001304 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1305 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001306 return true;
1307}
1308
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001309/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1310bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1311 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001312 // Fall back to video only composition, if AIV video mode is enabled
1313 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001314 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1315 __FUNCTION__, mDpy);
1316 return false;
1317 }
1318
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001319 const bool secureOnly = true;
1320 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1321 mdpOnlyLayersComp(ctx, list, secureOnly);
1322
1323}
1324
1325bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1326 hwc_display_contents_1_t* list, bool secureOnly) {
1327
1328 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1329 return false;
1330
1331 /* Bail out if we are processing only secured video layers
1332 * and we dont have any */
1333 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1334 reset(ctx);
1335 return false;
1336 }
1337
1338 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1339 mCurrentFrame.reset(numAppLayers);
1340 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1341
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001342 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001343 /* mark secure RGB layers for MDP comp */
1344 updateSecureRGB(ctx, list);
1345
1346 if(mCurrentFrame.mdpCount == 0) {
1347 reset(ctx);
1348 return false;
1349 }
1350
1351 /* find the maximum batch of layers to be marked for framebuffer */
1352 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1353 if(!ret) {
1354 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1355 reset(ctx);
1356 return false;
1357 }
1358
1359 if(sEnableYUVsplit){
1360 adjustForSourceSplit(ctx, list);
1361 }
1362
1363 if(!postHeuristicsHandling(ctx, list)) {
1364 ALOGD_IF(isDebug(), "post heuristic handling failed");
1365 reset(ctx);
1366 return false;
1367 }
1368
1369 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1370 __FUNCTION__);
1371 return true;
1372}
1373
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001374/* Checks for conditions where YUV layers cannot be bypassed */
1375bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001376 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001377 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001378 return false;
1379 }
1380
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001381 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001382 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1383 return false;
1384 }
1385
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001386 if(isSecuring(ctx, layer)) {
1387 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1388 return false;
1389 }
1390
Saurabh Shah4fdde762013-04-30 18:47:33 -07001391 if(!isValidDimension(ctx, layer)) {
1392 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1393 __FUNCTION__);
1394 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001395 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001396
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001397 if(layer->planeAlpha < 0xFF) {
1398 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1399 in video only mode",
1400 __FUNCTION__);
1401 return false;
1402 }
1403
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001404 return true;
1405}
1406
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001407/* Checks for conditions where Secure RGB layers cannot be bypassed */
1408bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1409 if(isSkipLayer(layer)) {
1410 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1411 __FUNCTION__, mDpy);
1412 return false;
1413 }
1414
1415 if(isSecuring(ctx, layer)) {
1416 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1417 return false;
1418 }
1419
1420 if(not isSupportedForMDPComp(ctx, layer)) {
1421 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1422 __FUNCTION__);
1423 return false;
1424 }
1425 return true;
1426}
1427
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301428/* starts at fromIndex and check for each layer to find
1429 * if it it has overlapping with any Updating layer above it in zorder
1430 * till the end of the batch. returns true if it finds any intersection */
1431bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1432 int fromIndex, int toIndex) {
1433 for(int i = fromIndex; i < toIndex; i++) {
1434 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1435 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1436 return false;
1437 }
1438 }
1439 }
1440 return true;
1441}
1442
1443/* Checks if given layer at targetLayerIndex has any
1444 * intersection with all the updating layers in beween
1445 * fromIndex and toIndex. Returns true if it finds intersectiion */
1446bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1447 int fromIndex, int toIndex, int targetLayerIndex) {
1448 for(int i = fromIndex; i <= toIndex; i++) {
1449 if(!mCurrentFrame.isFBComposed[i]) {
1450 if(areLayersIntersecting(&list->hwLayers[i],
1451 &list->hwLayers[targetLayerIndex])) {
1452 return true;
1453 }
1454 }
1455 }
1456 return false;
1457}
1458
1459int MDPComp::getBatch(hwc_display_contents_1_t* list,
1460 int& maxBatchStart, int& maxBatchEnd,
1461 int& maxBatchCount) {
1462 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301463 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001464 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301465 while (i < mCurrentFrame.layerCount) {
1466 int batchCount = 0;
1467 int batchStart = i;
1468 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001469 /* Adjust batch Z order with the dropped layers so far */
1470 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301471 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301472 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301473 while(i < mCurrentFrame.layerCount) {
1474 if(!mCurrentFrame.isFBComposed[i]) {
1475 if(!batchCount) {
1476 i++;
1477 break;
1478 }
1479 updatingLayersAbove++;
1480 i++;
1481 continue;
1482 } else {
1483 if(mCurrentFrame.drop[i]) {
1484 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001485 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301486 continue;
1487 } else if(updatingLayersAbove <= 0) {
1488 batchCount++;
1489 batchEnd = i;
1490 i++;
1491 continue;
1492 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1493
1494 // We have a valid updating layer already. If layer-i not
1495 // have overlapping with all updating layers in between
1496 // batch-start and i, then we can add layer i to batch.
1497 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1498 batchCount++;
1499 batchEnd = i;
1500 i++;
1501 continue;
1502 } else if(canPushBatchToTop(list, batchStart, i)) {
1503 //If All the non-updating layers with in this batch
1504 //does not have intersection with the updating layers
1505 //above in z-order, then we can safely move the batch to
1506 //higher z-order. Increment fbZ as it is moving up.
1507 if( firstZReverseIndex < 0) {
1508 firstZReverseIndex = i;
1509 }
1510 batchCount++;
1511 batchEnd = i;
1512 fbZ += updatingLayersAbove;
1513 i++;
1514 updatingLayersAbove = 0;
1515 continue;
1516 } else {
1517 //both failed.start the loop again from here.
1518 if(firstZReverseIndex >= 0) {
1519 i = firstZReverseIndex;
1520 }
1521 break;
1522 }
1523 }
1524 }
1525 }
1526 if(batchCount > maxBatchCount) {
1527 maxBatchCount = batchCount;
1528 maxBatchStart = batchStart;
1529 maxBatchEnd = batchEnd;
1530 fbZOrder = fbZ;
1531 }
1532 }
1533 return fbZOrder;
1534}
1535
1536bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1537 hwc_display_contents_1_t* list) {
1538 /* Idea is to keep as many non-updating(cached) layers in FB and
1539 * send rest of them through MDP. This is done in 2 steps.
1540 * 1. Find the maximum contiguous batch of non-updating layers.
1541 * 2. See if we can improve this batch size for caching by adding
1542 * opaque layers around the batch, if they don't have
1543 * any overlapping with the updating layers in between.
1544 * NEVER mark an updating layer for caching.
1545 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001546
1547 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001548 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001549 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301550 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001551
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001552 /* Nothing is cached. No batching needed */
1553 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001554 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001555 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001556
1557 /* No MDP comp layers, try to use other comp modes */
1558 if(mCurrentFrame.mdpCount == 0) {
1559 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001560 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001561
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301562 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001563
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301564 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001565 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001566 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001567 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301568 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001569 if(!mCurrentFrame.drop[i]){
1570 //If an unsupported layer is being attempted to
1571 //be pulled out we should fail
1572 if(not isSupportedForMDPComp(ctx, layer)) {
1573 return false;
1574 }
1575 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001576 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001577 }
1578 }
1579
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301580 // update the frame data
1581 mCurrentFrame.fbZ = fbZ;
1582 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001583 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001584 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001585
1586 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301587 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001588
1589 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001590}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001591
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001592void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001593 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001594 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001595 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001596
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001597 for(int i = 0; i < numAppLayers; i++) {
1598 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001599 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001600 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001601 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001602 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001603 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001604 }
1605 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001606
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001607 frame.fbCount = fbCount;
1608 frame.mdpCount = frame.layerCount - frame.fbCount
1609 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001610
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001611 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1612 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001613}
1614
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001615// drop other non-AIV layers from external display list.
1616void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001617 hwc_display_contents_1_t* list) {
1618 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1619 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001620 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001621 mCurrentFrame.dropCount++;
1622 mCurrentFrame.drop[i] = true;
1623 }
1624 }
1625 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1626 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1627 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1628 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1629 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1630 mCurrentFrame.dropCount);
1631}
1632
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001633void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001634 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001635 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1636 for(int index = 0;index < nYuvCount; index++){
1637 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1638 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1639
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001640 if(mCurrentFrame.drop[nYuvIndex]) {
1641 continue;
1642 }
1643
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001644 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001645 if(!frame.isFBComposed[nYuvIndex]) {
1646 frame.isFBComposed[nYuvIndex] = true;
1647 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001648 }
1649 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001650 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001651 private_handle_t *hnd = (private_handle_t *)layer->handle;
1652 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001653 frame.isFBComposed[nYuvIndex] = false;
1654 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001655 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001656 }
1657 }
1658 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001659
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001660 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1661 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001662}
1663
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001664void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1665 hwc_display_contents_1_t* list) {
1666 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1667 for(int index = 0;index < nSecureRGBCount; index++){
1668 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1669 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1670
1671 if(!isSecureRGBDoable(ctx, layer)) {
1672 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1673 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1674 mCurrentFrame.fbCount++;
1675 }
1676 } else {
1677 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1678 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1679 mCurrentFrame.fbCount--;
1680 }
1681 }
1682 }
1683
1684 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1685 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1686 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1687 mCurrentFrame.fbCount);
1688}
1689
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001690hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1691 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001692 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001693
1694 /* Update only the region of FB needed for composition */
1695 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1696 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1697 hwc_layer_1_t* layer = &list->hwLayers[i];
1698 hwc_rect_t dst = layer->displayFrame;
1699 fbRect = getUnion(fbRect, dst);
1700 }
1701 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001702 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001703 return fbRect;
1704}
1705
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001706bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1707 hwc_display_contents_1_t* list) {
1708
1709 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001710 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001711 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1712 return false;
1713 }
1714
1715 //Limitations checks
1716 if(!hwLimitationsCheck(ctx, list)) {
1717 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1718 return false;
1719 }
1720
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001721 //Configure framebuffer first if applicable
1722 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001723 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001724 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1725 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001726 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1727 __FUNCTION__);
1728 return false;
1729 }
1730 }
1731
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001732 mCurrentFrame.map();
1733
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001734 if(!allocLayerPipes(ctx, list)) {
1735 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001736 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001737 }
1738
1739 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001740 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001741 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001742 int mdpIndex = mCurrentFrame.layerToMDP[index];
1743 hwc_layer_1_t* layer = &list->hwLayers[index];
1744
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301745 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1746 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1747 mdpNextZOrder++;
1748 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001749 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1750 cur_pipe->zOrder = mdpNextZOrder++;
1751
radhakrishnac9a67412013-09-25 17:40:42 +05301752 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301753 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301754 if(configure4k2kYuv(ctx, layer,
1755 mCurrentFrame.mdpToLayer[mdpIndex])
1756 != 0 ){
1757 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1758 for layer %d",__FUNCTION__, index);
1759 return false;
1760 }
1761 else{
1762 mdpNextZOrder++;
1763 }
1764 continue;
1765 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001766 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1767 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301768 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001769 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001770 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001771 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001772 }
1773
Saurabh Shaha36be922013-12-16 18:18:39 -08001774 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1775 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1776 ,__FUNCTION__, mDpy);
1777 return false;
1778 }
1779
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001780 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001781 return true;
1782}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001783
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001784bool MDPComp::resourceCheck(hwc_context_t* ctx,
1785 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001786 const bool fbUsed = mCurrentFrame.fbCount;
1787 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1788 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1789 return false;
1790 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001791 // Init rotCount to number of rotate sessions used by other displays
1792 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1793 // Count the number of rotator sessions required for current display
1794 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1795 if(!mCurrentFrame.isFBComposed[index]) {
1796 hwc_layer_1_t* layer = &list->hwLayers[index];
1797 private_handle_t *hnd = (private_handle_t *)layer->handle;
1798 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1799 rotCount++;
1800 }
1801 }
1802 }
1803 // if number of layers to rotate exceeds max rotator sessions, bail out.
1804 if(rotCount > RotMgr::MAX_ROT_SESS) {
1805 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1806 __FUNCTION__, mDpy);
1807 return false;
1808 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001809 return true;
1810}
1811
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301812bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1813 hwc_display_contents_1_t* list) {
1814
1815 //A-family hw limitation:
1816 //If a layer need alpha scaling, MDP can not support.
1817 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1818 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1819 if(!mCurrentFrame.isFBComposed[i] &&
1820 isAlphaScaled( &list->hwLayers[i])) {
1821 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1822 return false;
1823 }
1824 }
1825 }
1826
1827 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1828 //If multiple layers requires downscaling and also they are overlapping
1829 //fall back to GPU since MDSS can not handle it.
1830 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1831 qdutils::MDPVersion::getInstance().is8x26()) {
1832 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1833 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1834 if(!mCurrentFrame.isFBComposed[i] &&
1835 isDownscaleRequired(botLayer)) {
1836 //if layer-i is marked for MDP and needs downscaling
1837 //check if any MDP layer on top of i & overlaps with layer-i
1838 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1839 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1840 if(!mCurrentFrame.isFBComposed[j] &&
1841 isDownscaleRequired(topLayer)) {
1842 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1843 topLayer->displayFrame);
1844 if(isValidRect(r))
1845 return false;
1846 }
1847 }
1848 }
1849 }
1850 }
1851 return true;
1852}
1853
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001854int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001855 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001856 char property[PROPERTY_VALUE_MAX];
1857
Raj Kamal4393eaa2014-06-06 13:45:20 +05301858 if(!ctx || !list) {
1859 ALOGE("%s: Invalid context or list",__FUNCTION__);
1860 mCachedFrame.reset();
1861 return -1;
1862 }
1863
1864 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001865 if(mDpy == HWC_DISPLAY_PRIMARY) {
1866 sSimulationFlags = 0;
1867 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1868 int currentFlags = atoi(property);
1869 if(currentFlags != sSimulationFlags) {
1870 sSimulationFlags = currentFlags;
1871 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1872 sSimulationFlags, sSimulationFlags);
1873 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001874 }
1875 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001876 // reset PTOR
1877 if(!mDpy)
1878 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001879
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301880 //Do not cache the information for next draw cycle.
1881 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1882 ALOGI("%s: Unsupported layer count for mdp composition",
1883 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001884 mCachedFrame.reset();
1885 return -1;
1886 }
1887
Saurabh Shahb39f8152013-08-22 10:21:44 -07001888 //reset old data
1889 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001890 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1891 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301892
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001893 // Detect the start of animation and fall back to GPU only once to cache
1894 // all the layers in FB and display FB content untill animation completes.
1895 if(ctx->listStats[mDpy].isDisplayAnimating) {
1896 mCurrentFrame.needsRedraw = false;
1897 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1898 mCurrentFrame.needsRedraw = true;
1899 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1900 }
1901 setMDPCompLayerFlags(ctx, list);
1902 mCachedFrame.updateCounts(mCurrentFrame);
1903 ret = -1;
1904 return ret;
1905 } else {
1906 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1907 }
1908
Saurabh Shahb39f8152013-08-22 10:21:44 -07001909 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001910 if(isFrameDoable(ctx)) {
1911 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001912 // if AIV Video mode is enabled, drop all non AIV layers from the
1913 // external display list.
1914 if(ctx->listStats[mDpy].mAIVVideoMode) {
1915 dropNonAIVLayers(ctx, list);
1916 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001917
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001918 // if tryFullFrame fails, try to push all video and secure RGB layers
1919 // to MDP for composition.
1920 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001921 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301922 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001923 setMDPCompLayerFlags(ctx, list);
1924 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001925 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001926 reset(ctx);
1927 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1928 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001929 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001930 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1931 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001932 }
1933 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05301934 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
1935 enablePartialUpdateForMDP3) {
1936 generateROI(ctx, list);
1937 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
1938 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
1939 }
1940 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001941 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1942 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001943 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001944 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001945
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001946 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001947 ALOGD("GEOMETRY change: %d",
1948 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001949 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001950 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001951 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001952 }
1953
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001954#ifdef DYNAMIC_FPS
1955 //For primary display, set the dynamic refreshrate
1956 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported()) {
1957 FrameInfo frame;
1958 frame.reset(mCurrentFrame.layerCount);
Raj Kamal18e946e2014-10-10 14:23:47 +05301959 memset(&frame.drop, 0, sizeof(frame.drop));
1960 frame.dropCount = 0;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001961 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
1962 __FUNCTION__);
1963 updateLayerCache(ctx, list, frame);
1964 updateYUV(ctx, list, false /*secure only*/, frame);
1965 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1966 //Set the new fresh rate, if there is only one updating YUV layer
1967 //or there is one single RGB layer with this request
1968 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1969 (frame.layerCount == 1)) {
1970 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1971 }
1972 setRefreshRate(ctx, mDpy, refreshRate);
1973 }
1974#endif
1975
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001976 mCachedFrame.cacheAll(list);
1977 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001978 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001979}
1980
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001981bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301982
1983 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301984 int mdpIndex = mCurrentFrame.layerToMDP[index];
1985 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1986 info.pipeInfo = new MdpYUVPipeInfo;
1987 info.rot = NULL;
1988 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301989
1990 pipe_info.lIndex = ovutils::OV_INVALID;
1991 pipe_info.rIndex = ovutils::OV_INVALID;
1992
Saurabh Shahc62f3982014-03-05 14:28:26 -08001993 Overlay::PipeSpecs pipeSpecs;
1994 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1995 pipeSpecs.needsScaling = true;
1996 pipeSpecs.dpy = mDpy;
1997 pipeSpecs.fb = false;
1998
1999 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302000 if(pipe_info.lIndex == ovutils::OV_INVALID){
2001 bRet = false;
2002 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2003 __FUNCTION__);
2004 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002005 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302006 if(pipe_info.rIndex == ovutils::OV_INVALID){
2007 bRet = false;
2008 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2009 __FUNCTION__);
2010 }
2011 return bRet;
2012}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002013
2014int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2015 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002016 if (ctx->mPtorInfo.isActive()) {
2017 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002018 if (fd < 0) {
2019 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002020 }
2021 }
2022 return fd;
2023}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002024//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002025
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002026void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302027 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002028 //If 4k2k Yuv layer split is possible, and if
2029 //fbz is above 4k2k layer, increment fb zorder by 1
2030 //as we split 4k2k layer and increment zorder for right half
2031 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002032 if(!ctx)
2033 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002034 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302035 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2036 index++) {
2037 if(!mCurrentFrame.isFBComposed[index]) {
2038 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2039 mdpNextZOrder++;
2040 }
2041 mdpNextZOrder++;
2042 hwc_layer_1_t* layer = &list->hwLayers[index];
2043 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302044 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302045 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2046 mCurrentFrame.fbZ += 1;
2047 mdpNextZOrder++;
2048 //As we split 4kx2k yuv layer and program to 2 VG pipes
2049 //(if available) increase mdpcount by 1.
2050 mCurrentFrame.mdpCount++;
2051 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002052 }
2053 }
2054 }
radhakrishnac9a67412013-09-25 17:40:42 +05302055}
2056
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002057/*
2058 * Configures pipe(s) for MDP composition
2059 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002060int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002061 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002062 MdpPipeInfoNonSplit& mdp_info =
2063 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002064 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
2065 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002066 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002067
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002068 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2069 __FUNCTION__, layer, zOrder, dest);
2070
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002071 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002072 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002073}
2074
Saurabh Shah88e4d272013-09-03 13:31:29 -07002075bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002076 hwc_display_contents_1_t* list) {
2077 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002078
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002079 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002080
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002081 hwc_layer_1_t* layer = &list->hwLayers[index];
2082 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302083 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002084 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302085 continue;
2086 }
2087 }
2088
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002089 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002090 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002091 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002092 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002093 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002094
Saurabh Shahc62f3982014-03-05 14:28:26 -08002095 Overlay::PipeSpecs pipeSpecs;
2096 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2097 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2098 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2099 (qdutils::MDPVersion::getInstance().is8x26() and
2100 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2101 pipeSpecs.dpy = mDpy;
2102 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002103 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002104
Saurabh Shahc62f3982014-03-05 14:28:26 -08002105 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2106
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002107 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002108 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002109 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002110 }
2111 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002112 return true;
2113}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002114
radhakrishnac9a67412013-09-25 17:40:42 +05302115int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2116 PipeLayerPair& PipeLayerPair) {
2117 MdpYUVPipeInfo& mdp_info =
2118 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2119 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302120 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2121 eDest lDest = mdp_info.lIndex;
2122 eDest rDest = mdp_info.rIndex;
2123
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002124 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302125 lDest, rDest, &PipeLayerPair.rot);
2126}
2127
Saurabh Shah88e4d272013-09-03 13:31:29 -07002128bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002129
Raj Kamal4393eaa2014-06-06 13:45:20 +05302130 if(!isEnabled() or !mModeOn) {
2131 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302132 return true;
2133 }
2134
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002135 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002136 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002137 sHandleTimeout = true;
2138 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002139
2140 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002141 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002142
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002143 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2144 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002145 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002146 if(mCurrentFrame.isFBComposed[i]) continue;
2147
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002148 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002149 private_handle_t *hnd = (private_handle_t *)layer->handle;
2150 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002151 if (!(layer->flags & HWC_COLOR_FILL)) {
2152 ALOGE("%s handle null", __FUNCTION__);
2153 return false;
2154 }
2155 // No PLAY for Color layer
2156 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2157 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002158 }
2159
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002160 int mdpIndex = mCurrentFrame.layerToMDP[i];
2161
Raj Kamal389d6e32014-08-04 14:43:24 +05302162 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302163 {
2164 MdpYUVPipeInfo& pipe_info =
2165 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2166 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2167 ovutils::eDest indexL = pipe_info.lIndex;
2168 ovutils::eDest indexR = pipe_info.rIndex;
2169 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302170 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302171 if(rot) {
2172 rot->queueBuffer(fd, offset);
2173 fd = rot->getDstMemId();
2174 offset = rot->getDstOffset();
2175 }
2176 if(indexL != ovutils::OV_INVALID) {
2177 ovutils::eDest destL = (ovutils::eDest)indexL;
2178 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2179 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2180 if (!ov.queueBuffer(fd, offset, destL)) {
2181 ALOGE("%s: queueBuffer failed for display:%d",
2182 __FUNCTION__, mDpy);
2183 return false;
2184 }
2185 }
2186
2187 if(indexR != ovutils::OV_INVALID) {
2188 ovutils::eDest destR = (ovutils::eDest)indexR;
2189 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2190 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2191 if (!ov.queueBuffer(fd, offset, destR)) {
2192 ALOGE("%s: queueBuffer failed for display:%d",
2193 __FUNCTION__, mDpy);
2194 return false;
2195 }
2196 }
2197 }
2198 else{
2199 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002200 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302201 ovutils::eDest dest = pipe_info.index;
2202 if(dest == ovutils::OV_INVALID) {
2203 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002204 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302205 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002206
radhakrishnac9a67412013-09-25 17:40:42 +05302207 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2208 continue;
2209 }
2210
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002211 int fd = hnd->fd;
2212 uint32_t offset = (uint32_t)hnd->offset;
2213 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2214 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002215 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002216 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002217 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002218 }
2219
radhakrishnac9a67412013-09-25 17:40:42 +05302220 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2221 using pipe: %d", __FUNCTION__, layer,
2222 hnd, dest );
2223
radhakrishnac9a67412013-09-25 17:40:42 +05302224 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2225 if(rot) {
2226 if(!rot->queueBuffer(fd, offset))
2227 return false;
2228 fd = rot->getDstMemId();
2229 offset = rot->getDstOffset();
2230 }
2231
2232 if (!ov.queueBuffer(fd, offset, dest)) {
2233 ALOGE("%s: queueBuffer failed for display:%d ",
2234 __FUNCTION__, mDpy);
2235 return false;
2236 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002237 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002238
2239 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002240 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002241 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002242}
2243
Saurabh Shah88e4d272013-09-03 13:31:29 -07002244//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002245
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002246void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302247 hwc_display_contents_1_t* list){
2248 //if 4kx2k yuv layer is totally present in either in left half
2249 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302250 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302251 if(mCurrentFrame.fbZ >= 0) {
2252 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2253 index++) {
2254 if(!mCurrentFrame.isFBComposed[index]) {
2255 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2256 mdpNextZOrder++;
2257 }
2258 mdpNextZOrder++;
2259 hwc_layer_1_t* layer = &list->hwLayers[index];
2260 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302261 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302262 hwc_rect_t dst = layer->displayFrame;
2263 if((dst.left > lSplit) || (dst.right < lSplit)) {
2264 mCurrentFrame.mdpCount += 1;
2265 }
2266 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2267 mCurrentFrame.fbZ += 1;
2268 mdpNextZOrder++;
2269 }
2270 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002271 }
radhakrishnac9a67412013-09-25 17:40:42 +05302272 }
2273}
2274
Saurabh Shah88e4d272013-09-03 13:31:29 -07002275bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002276 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002277
Saurabh Shahc62f3982014-03-05 14:28:26 -08002278 const int lSplit = getLeftSplit(ctx, mDpy);
2279 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002280 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002281 pipe_info.lIndex = ovutils::OV_INVALID;
2282 pipe_info.rIndex = ovutils::OV_INVALID;
2283
Saurabh Shahc62f3982014-03-05 14:28:26 -08002284 Overlay::PipeSpecs pipeSpecs;
2285 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2286 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2287 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2288 pipeSpecs.dpy = mDpy;
2289 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2290 pipeSpecs.fb = false;
2291
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002292 // Acquire pipe only for the updating half
2293 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2294 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2295
2296 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002297 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002298 if(pipe_info.lIndex == ovutils::OV_INVALID)
2299 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002300 }
2301
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002302 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002303 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2304 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002305 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002306 return false;
2307 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002308
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002309 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002310}
2311
Saurabh Shah88e4d272013-09-03 13:31:29 -07002312bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002313 hwc_display_contents_1_t* list) {
2314 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002315
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002316 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002317
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002318 hwc_layer_1_t* layer = &list->hwLayers[index];
2319 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302320 hwc_rect_t dst = layer->displayFrame;
2321 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302322 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302323 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002324 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302325 continue;
2326 }
2327 }
2328 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002329 int mdpIndex = mCurrentFrame.layerToMDP[index];
2330 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002331 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002332 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002333 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002334
Saurabh Shahc62f3982014-03-05 14:28:26 -08002335 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2336 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2337 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002338 return false;
2339 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002340 }
2341 return true;
2342}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002343
radhakrishnac9a67412013-09-25 17:40:42 +05302344int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2345 PipeLayerPair& PipeLayerPair) {
2346 const int lSplit = getLeftSplit(ctx, mDpy);
2347 hwc_rect_t dst = layer->displayFrame;
2348 if((dst.left > lSplit)||(dst.right < lSplit)){
2349 MdpYUVPipeInfo& mdp_info =
2350 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2351 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302352 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2353 eDest lDest = mdp_info.lIndex;
2354 eDest rDest = mdp_info.rIndex;
2355
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002356 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302357 lDest, rDest, &PipeLayerPair.rot);
2358 }
2359 else{
2360 return configure(ctx, layer, PipeLayerPair);
2361 }
2362}
2363
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002364/*
2365 * Configures pipe(s) for MDP composition
2366 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002367int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002368 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002369 MdpPipeInfoSplit& mdp_info =
2370 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002371 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002372 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2373 eDest lDest = mdp_info.lIndex;
2374 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002375
2376 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2377 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2378
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002379 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002380 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002381}
2382
Saurabh Shah88e4d272013-09-03 13:31:29 -07002383bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002384
Raj Kamal4393eaa2014-06-06 13:45:20 +05302385 if(!isEnabled() or !mModeOn) {
2386 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302387 return true;
2388 }
2389
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002390 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002391 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002392 sHandleTimeout = true;
2393 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002394
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002395 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002396 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002397
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002398 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2399 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002400 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002401 if(mCurrentFrame.isFBComposed[i]) continue;
2402
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002403 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002404 private_handle_t *hnd = (private_handle_t *)layer->handle;
2405 if(!hnd) {
2406 ALOGE("%s handle null", __FUNCTION__);
2407 return false;
2408 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002409
2410 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2411 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002412 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002413
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002414 int mdpIndex = mCurrentFrame.layerToMDP[i];
2415
Raj Kamal389d6e32014-08-04 14:43:24 +05302416 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302417 {
2418 MdpYUVPipeInfo& pipe_info =
2419 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2420 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2421 ovutils::eDest indexL = pipe_info.lIndex;
2422 ovutils::eDest indexR = pipe_info.rIndex;
2423 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302424 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302425 if(rot) {
2426 rot->queueBuffer(fd, offset);
2427 fd = rot->getDstMemId();
2428 offset = rot->getDstOffset();
2429 }
2430 if(indexL != ovutils::OV_INVALID) {
2431 ovutils::eDest destL = (ovutils::eDest)indexL;
2432 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2433 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2434 if (!ov.queueBuffer(fd, offset, destL)) {
2435 ALOGE("%s: queueBuffer failed for display:%d",
2436 __FUNCTION__, mDpy);
2437 return false;
2438 }
2439 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002440
radhakrishnac9a67412013-09-25 17:40:42 +05302441 if(indexR != ovutils::OV_INVALID) {
2442 ovutils::eDest destR = (ovutils::eDest)indexR;
2443 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2444 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2445 if (!ov.queueBuffer(fd, offset, destR)) {
2446 ALOGE("%s: queueBuffer failed for display:%d",
2447 __FUNCTION__, mDpy);
2448 return false;
2449 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002450 }
2451 }
radhakrishnac9a67412013-09-25 17:40:42 +05302452 else{
2453 MdpPipeInfoSplit& pipe_info =
2454 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2455 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002456
radhakrishnac9a67412013-09-25 17:40:42 +05302457 ovutils::eDest indexL = pipe_info.lIndex;
2458 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002459
radhakrishnac9a67412013-09-25 17:40:42 +05302460 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002461 uint32_t offset = (uint32_t)hnd->offset;
2462 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2463 if (!mDpy && (index != -1)) {
2464 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2465 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002466 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002467 }
radhakrishnac9a67412013-09-25 17:40:42 +05302468
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002469 if(ctx->mAD->draw(ctx, fd, offset)) {
2470 fd = ctx->mAD->getDstFd();
2471 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002472 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002473
radhakrishnac9a67412013-09-25 17:40:42 +05302474 if(rot) {
2475 rot->queueBuffer(fd, offset);
2476 fd = rot->getDstMemId();
2477 offset = rot->getDstOffset();
2478 }
2479
2480 //************* play left mixer **********
2481 if(indexL != ovutils::OV_INVALID) {
2482 ovutils::eDest destL = (ovutils::eDest)indexL;
2483 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2484 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2485 if (!ov.queueBuffer(fd, offset, destL)) {
2486 ALOGE("%s: queueBuffer failed for left mixer",
2487 __FUNCTION__);
2488 return false;
2489 }
2490 }
2491
2492 //************* play right mixer **********
2493 if(indexR != ovutils::OV_INVALID) {
2494 ovutils::eDest destR = (ovutils::eDest)indexR;
2495 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2496 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2497 if (!ov.queueBuffer(fd, offset, destR)) {
2498 ALOGE("%s: queueBuffer failed for right mixer",
2499 __FUNCTION__);
2500 return false;
2501 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002502 }
2503 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002504
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002505 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2506 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002507
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002508 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002509}
Saurabh Shahab47c692014-02-12 18:45:57 -08002510
2511//================MDPCompSrcSplit==============================================
2512bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002513 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002514 private_handle_t *hnd = (private_handle_t *)layer->handle;
2515 hwc_rect_t dst = layer->displayFrame;
2516 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2517 pipe_info.lIndex = ovutils::OV_INVALID;
2518 pipe_info.rIndex = ovutils::OV_INVALID;
2519
2520 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2521 //should have a higher priority than the right one. Pipe priorities are
2522 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002523
Saurabh Shahc62f3982014-03-05 14:28:26 -08002524 Overlay::PipeSpecs pipeSpecs;
2525 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2526 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2527 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2528 pipeSpecs.dpy = mDpy;
2529 pipeSpecs.fb = false;
2530
Saurabh Shahab47c692014-02-12 18:45:57 -08002531 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002532 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002533 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002534 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002535 }
2536
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002537 /* Use 2 pipes IF
2538 a) Layer's crop width is > 2048 or
2539 b) Layer's dest width > 2048 or
2540 c) On primary, driver has indicated with caps to split always. This is
2541 based on an empirically derived value of panel height. Applied only
2542 if the layer's width is > mixer's width
2543 */
2544
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302545 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002546 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302547 mdpHw.isSrcSplitAlways();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002548 int lSplit = getLeftSplit(ctx, mDpy);
2549 int dstWidth = dst.right - dst.left;
Saurabh Shah189f23d2014-09-26 17:21:00 -07002550 int cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
2551 crop.right - crop.left;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002552
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002553 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2554 //pipe line length, we are still using 2 pipes. This is fine just because
2555 //this is source split where destination doesn't matter. Evaluate later to
2556 //see if going through all the calcs to save a pipe is worth it
Naseer Ahmed9eb5e092014-09-25 13:24:44 -04002557 if(dstWidth > (int) mdpHw.getMaxMixerWidth() or
2558 cropWidth > (int) mdpHw.getMaxMixerWidth() or
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002559 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002560 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002561 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002562 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002563 }
2564
2565 // Return values
2566 // 1 Left pipe is higher priority, do nothing.
2567 // 0 Pipes of same priority.
2568 //-1 Right pipe is of higher priority, needs swap.
2569 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2570 pipe_info.rIndex) == -1) {
2571 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002572 }
2573 }
2574
2575 return true;
2576}
2577
Saurabh Shahab47c692014-02-12 18:45:57 -08002578int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2579 PipeLayerPair& PipeLayerPair) {
2580 private_handle_t *hnd = (private_handle_t *)layer->handle;
2581 if(!hnd) {
2582 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2583 return -1;
2584 }
2585 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2586 MdpPipeInfoSplit& mdp_info =
2587 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2588 Rotator **rot = &PipeLayerPair.rot;
2589 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002590 eDest lDest = mdp_info.lIndex;
2591 eDest rDest = mdp_info.rIndex;
2592 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2593 hwc_rect_t dst = layer->displayFrame;
2594 int transform = layer->transform;
2595 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002596 int rotFlags = ROT_FLAGS_NONE;
2597 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2598 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2599
2600 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2601 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2602
2603 // Handle R/B swap
2604 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2605 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2606 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2607 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2608 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2609 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002610 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002611 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2612 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002613 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002614 /* Calculate the external display position based on MDP downscale,
2615 ActionSafe, and extorientation features. */
2616 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002617
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002618 int downscale = getRotDownscale(ctx, layer);
Saurabh Shah97e2d802014-04-14 18:03:54 -07002619 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002620 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002621
2622 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2623 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002624 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002625 }
2626
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002627 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002628 (*rot) = ctx->mRotMgr->getNext();
2629 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002630 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002631 //If the video is using a single pipe, enable BWC
2632 if(rDest == OV_INVALID) {
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002633 BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002634 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002635 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002636 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002637 ALOGE("%s: configRotator failed!", __FUNCTION__);
2638 return -1;
2639 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002640 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002641 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002642 }
2643
2644 //If 2 pipes being used, divide layer into half, crop and dst
2645 hwc_rect_t cropL = crop;
2646 hwc_rect_t cropR = crop;
2647 hwc_rect_t dstL = dst;
2648 hwc_rect_t dstR = dst;
2649 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2650 cropL.right = (crop.right + crop.left) / 2;
2651 cropR.left = cropL.right;
2652 sanitizeSourceCrop(cropL, cropR, hnd);
2653
Saurabh Shahb729b192014-08-15 18:04:24 -07002654 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002655 //Swap crops on H flip since 2 pipes are being used
2656 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2657 hwc_rect_t tmp = cropL;
2658 cropL = cropR;
2659 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002660 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002661 }
2662
Saurabh Shahb729b192014-08-15 18:04:24 -07002663 //cropSwap trick: If the src and dst widths are both odd, let us say
2664 //2507, then splitting both into half would cause left width to be 1253
2665 //and right 1254. If crop is swapped because of H flip, this will cause
2666 //left crop width to be 1254, whereas left dst width remains 1253, thus
2667 //inducing a scaling that is unaccounted for. To overcome that we add 1
2668 //to the dst width if there is a cropSwap. So if the original width was
2669 //2507, the left dst width will be 1254. Even if the original width was
2670 //even for ex: 2508, the left dst width will still remain 1254.
2671 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002672 dstR.left = dstL.right;
2673 }
2674
2675 //For the mdp, since either we are pre-rotating or MDP does flips
2676 orient = OVERLAY_TRANSFORM_0;
2677 transform = 0;
2678
2679 //configure left pipe
2680 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002681 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002682 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2683 (ovutils::eBlending) getBlending(layer->blending));
2684
2685 if(configMdp(ctx->mOverlay, pargL, orient,
2686 cropL, dstL, metadata, lDest) < 0) {
2687 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2688 return -1;
2689 }
2690 }
2691
2692 //configure right pipe
2693 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002694 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002695 static_cast<eRotFlags>(rotFlags),
2696 layer->planeAlpha,
2697 (ovutils::eBlending) getBlending(layer->blending));
2698 if(configMdp(ctx->mOverlay, pargR, orient,
2699 cropR, dstR, metadata, rDest) < 0) {
2700 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2701 return -1;
2702 }
2703 }
2704
2705 return 0;
2706}
2707
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002708}; //namespace
2709