blob: baeb1b9c1f77a56e097a24c49027e4f1c33482bd [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 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800469 } else if (ctx->isDMAStateChanging) {
470 // Bail out if a padding round has been invoked in order to switch DMA
471 // state to block mode. We need this to cater for the case when a layer
472 // requires rotation in the current frame.
473 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
474 __FUNCTION__);
475 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700476 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800477
Saurabh Shahaa236822013-04-24 18:07:26 -0700478 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800479}
480
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800481void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
482 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
483 fbRect = getIntersection(fbRect, roi);
484}
485
486/* 1) Identify layers that are not visible or lying outside the updating ROI and
487 * drop them from composition.
488 * 2) If we have a scaling layer which needs cropping against generated
489 * ROI, reset ROI to full resolution. */
490bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
491 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700492 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800493 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800494
495 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800496 if(!isValidRect(visibleRect)) {
497 mCurrentFrame.drop[i] = true;
498 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800499 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800500 }
501
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700502 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700503 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800504 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700505
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700506 if(!isValidRect(res)) {
507 mCurrentFrame.drop[i] = true;
508 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800509 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700510 /* Reset frame ROI when any layer which needs scaling also needs ROI
511 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800512 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800513 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700514 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
515 mCurrentFrame.dropCount = 0;
516 return false;
517 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800518
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800519 /* deduct any opaque region from visibleRect */
520 if (layer->blending == HWC_BLENDING_NONE)
521 visibleRect = deductRect(visibleRect, res);
522 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700523 }
524 return true;
525}
526
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800527/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
528 * are updating. If DirtyRegion is applicable, calculate it by accounting all
529 * the changing layer's dirtyRegion. */
530void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
531 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700532 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800533 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700534 return;
535
536 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800537 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
538 (int)ctx->dpyAttr[mDpy].yres};
539
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700540 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800541 hwc_layer_1_t* layer = &list->hwLayers[index];
542 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800543 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700544 hwc_rect_t dst = layer->displayFrame;
545 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800546
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800547#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800548 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700549 {
550 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
551 int x_off = dst.left - src.left;
552 int y_off = dst.top - src.top;
553 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
554 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800555#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800556
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800557 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700558 }
559 }
560
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800561 /* No layer is updating. Still SF wants a refresh.*/
562 if(!isValidRect(roi))
563 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800564
565 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800566 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800567
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800568 ctx->listStats[mDpy].lRoi = roi;
569 if(!validateAndApplyROI(ctx, list))
570 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700571
572 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800573 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
574 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
575}
576
577void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
578 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
579 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
580
581 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
582 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
583 fbRect = getUnion(l_fbRect, r_fbRect);
584}
585/* 1) Identify layers that are not visible or lying outside BOTH the updating
586 * ROI's and drop them from composition. If a layer is spanning across both
587 * the halves of the screen but needed by only ROI, the non-contributing
588 * half will not be programmed for MDP.
589 * 2) If we have a scaling layer which needs cropping against generated
590 * ROI, reset ROI to full resolution. */
591bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
592 hwc_display_contents_1_t* list) {
593
594 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
595
596 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
597 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
598
599 for(int i = numAppLayers - 1; i >= 0; i--){
600 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
601 {
602 mCurrentFrame.drop[i] = true;
603 mCurrentFrame.dropCount++;
604 continue;
605 }
606
607 const hwc_layer_1_t* layer = &list->hwLayers[i];
608 hwc_rect_t dstRect = layer->displayFrame;
609
610 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
611 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
612 hwc_rect_t res = getUnion(l_res, r_res);
613
614 if(!isValidRect(l_res) && !isValidRect(r_res)) {
615 mCurrentFrame.drop[i] = true;
616 mCurrentFrame.dropCount++;
617 } else {
618 /* Reset frame ROI when any layer which needs scaling also needs ROI
619 * cropping */
620 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
621 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
622 mCurrentFrame.dropCount = 0;
623 return false;
624 }
625
626 if (layer->blending == HWC_BLENDING_NONE) {
627 visibleRectL = deductRect(visibleRectL, l_res);
628 visibleRectR = deductRect(visibleRectR, r_res);
629 }
630 }
631 }
632 return true;
633}
634/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
635 * are updating. If DirtyRegion is applicable, calculate it by accounting all
636 * the changing layer's dirtyRegion. */
637void MDPCompSplit::generateROI(hwc_context_t *ctx,
638 hwc_display_contents_1_t* list) {
639 if(!canPartialUpdate(ctx, list))
640 return;
641
642 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
643 int lSplit = getLeftSplit(ctx, mDpy);
644
645 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
646 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
647
648 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
649 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
650
651 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
652 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
653
654 for(int index = 0; index < numAppLayers; index++ ) {
655 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800656 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800657 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800658 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700659 hwc_rect_t dst = layer->displayFrame;
660 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800661
662#ifdef QCOM_BSP
663 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700664 {
665 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
666 int x_off = dst.left - src.left;
667 int y_off = dst.top - src.top;
668 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
669 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800670#endif
671
672 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
673 if(isValidRect(l_dst))
674 l_roi = getUnion(l_roi, l_dst);
675
676 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
677 if(isValidRect(r_dst))
678 r_roi = getUnion(r_roi, r_dst);
679 }
680 }
681
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700682 /* For panels that cannot accept commands in both the interfaces, we cannot
683 * send two ROI's (for each half). We merge them into single ROI and split
684 * them across lSplit for MDP mixer use. The ROI's will be merged again
685 * finally before udpating the panel in the driver. */
686 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
687 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
688 l_roi = getIntersection(temp_roi, l_frame);
689 r_roi = getIntersection(temp_roi, r_frame);
690 }
691
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800692 /* No layer is updating. Still SF wants a refresh. */
693 if(!isValidRect(l_roi) && !isValidRect(r_roi))
694 return;
695
696 l_roi = getSanitizeROI(l_roi, l_frame);
697 r_roi = getSanitizeROI(r_roi, r_frame);
698
699 ctx->listStats[mDpy].lRoi = l_roi;
700 ctx->listStats[mDpy].rRoi = r_roi;
701
702 if(!validateAndApplyROI(ctx, list))
703 resetROI(ctx, mDpy);
704
705 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
706 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
707 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
708 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
709 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
710 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700711}
712
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800713/* Checks for conditions where all the layers marked for MDP comp cannot be
714 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800715bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800716 hwc_display_contents_1_t* list){
717
Saurabh Shahaa236822013-04-24 18:07:26 -0700718 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800719 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800720
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700721 // Fall back to video only composition, if AIV video mode is enabled
722 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700723 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
724 __FUNCTION__, mDpy);
725 return false;
726 }
727
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400728 // No Idle fall back, if secure display or secure RGB layers are present or
729 // if there's only a single layer being composed
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -0700730 if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400731 !ctx->listStats[mDpy].secureRGBCount) &&
732 (ctx->listStats[mDpy].numAppLayers != 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700733 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
734 return false;
735 }
736
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800737 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700738 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
739 __FUNCTION__,
740 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800741 return false;
742 }
743
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700744 // if secondary is configuring or Padding round, fall back to video only
745 // composition and release all assigned non VIG pipes from primary.
746 if(isSecondaryConfiguring(ctx)) {
747 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
748 __FUNCTION__);
749 return false;
750 } else if(ctx->isPaddingRound) {
751 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
752 __FUNCTION__,mDpy);
753 return false;
754 }
755
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530756 MDPVersion& mdpHw = MDPVersion::getInstance();
757 if(mDpy > HWC_DISPLAY_PRIMARY &&
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400758 (priDispW > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530759 (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800760 // Disable MDP comp on Secondary when the primary is highres panel and
761 // the secondary is a normal 1080p, because, MDP comp on secondary under
762 // in such usecase, decimation gets used for downscale and there will be
763 // a quality mismatch when there will be a fallback to GPU comp
764 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
765 __FUNCTION__);
766 return false;
767 }
768
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700769 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800770 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700771 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800772 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
773 return false;
774 }
775
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800776 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800777 hwc_layer_1_t* layer = &list->hwLayers[i];
778 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800779
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800780 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700781 if(!canUseRotator(ctx, mDpy)) {
782 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
783 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700784 return false;
785 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800786 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530787
788 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
789 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700790 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530791 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
792 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
793 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800794 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700795
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700796 if(ctx->mAD->isDoable()) {
797 return false;
798 }
799
Saurabh Shahaa236822013-04-24 18:07:26 -0700800 //If all above hard conditions are met we can do full or partial MDP comp.
801 bool ret = false;
802 if(fullMDPComp(ctx, list)) {
803 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700804 } else if(fullMDPCompWithPTOR(ctx, list)) {
805 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700806 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700807 ret = true;
808 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530809
Saurabh Shahaa236822013-04-24 18:07:26 -0700810 return ret;
811}
812
813bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700814
815 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
816 return false;
817
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700818 //Will benefit presentation / secondary-only layer.
819 if((mDpy > HWC_DISPLAY_PRIMARY) &&
820 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
821 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
822 return false;
823 }
824
825 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
826 for(int i = 0; i < numAppLayers; i++) {
827 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700828 if(not mCurrentFrame.drop[i] and
829 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700830 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
831 return false;
832 }
833 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800834
Saurabh Shahaa236822013-04-24 18:07:26 -0700835 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700836 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
837 sizeof(mCurrentFrame.isFBComposed));
838 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
839 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700840
Raj Kamal389d6e32014-08-04 14:43:24 +0530841 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800842 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530843 }
844
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800845 if(!postHeuristicsHandling(ctx, list)) {
846 ALOGD_IF(isDebug(), "post heuristic handling failed");
847 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700848 return false;
849 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700850 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
851 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700852 return true;
853}
854
Sushil Chauhandefd3522014-05-13 18:17:12 -0700855/* Full MDP Composition with Peripheral Tiny Overlap Removal.
856 * MDP bandwidth limitations can be avoided, if the overlap region
857 * covered by the smallest layer at a higher z-order, gets composed
858 * by Copybit on a render buffer, which can be queued to MDP.
859 */
860bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
861 hwc_display_contents_1_t* list) {
862
863 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
864 const int stagesForMDP = min(sMaxPipesPerMixer,
865 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
866
867 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700868 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700869 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
870 return false;
871 }
872
873 // Frame level checks
874 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
875 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
876 isSecurePresent(ctx, mDpy)) {
877 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
878 return false;
879 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700880 // MDP comp checks
881 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700882 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700883 if(not isSupportedForMDPComp(ctx, layer)) {
884 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
885 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700886 }
887 }
888
Sushil Chauhandefd3522014-05-13 18:17:12 -0700889 /* We cannot use this composition mode, if:
890 1. A below layer needs scaling.
891 2. Overlap is not peripheral to display.
892 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700893 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700894 */
895
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700896 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
897 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
898 memset(overlapRect, 0, sizeof(overlapRect));
899 int layerPixelCount, minPixelCount = 0;
900 int numPTORLayersFound = 0;
901 for (int i = numAppLayers-1; (i >= 0 &&
902 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700903 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700904 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700905 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700906 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
907 // PTOR layer should be peripheral and cannot have transform
908 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
909 has90Transform(layer)) {
910 continue;
911 }
912 if((3 * (layerPixelCount + minPixelCount)) >
913 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
914 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
915 continue;
916 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700917 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700918 for (int j = i-1; j >= 0; j--) {
919 // Check if the layers below this layer qualifies for PTOR comp
920 hwc_layer_1_t* layer = &list->hwLayers[j];
921 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700922 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700923 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700924 if (isValidRect(getIntersection(dispFrame, disFrame))) {
925 if (has90Transform(layer) || needsScaling(layer)) {
926 found = false;
927 break;
928 }
929 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700930 }
931 }
932 // Store the minLayer Index
933 if(found) {
934 minLayerIndex[numPTORLayersFound] = i;
935 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
936 minPixelCount += layerPixelCount;
937 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700938 }
939 }
940
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700941 // No overlap layers
942 if (!numPTORLayersFound)
943 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700944
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700945 // Store the displayFrame and the sourceCrops of the layers
946 hwc_rect_t displayFrame[numAppLayers];
947 hwc_rect_t sourceCrop[numAppLayers];
948 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700949 hwc_layer_1_t* layer = &list->hwLayers[i];
950 displayFrame[i] = layer->displayFrame;
951 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700952 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700953
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530954 /**
955 * It's possible that 2 PTOR layers might have overlapping.
956 * In such case, remove the intersection(again if peripheral)
957 * from the lower PTOR layer to avoid overlapping.
958 * If intersection is not on peripheral then compromise
959 * by reducing number of PTOR layers.
960 **/
961 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
962 if(isValidRect(commonRect)) {
963 overlapRect[1] = deductRect(overlapRect[1], commonRect);
964 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
965 }
966
967 ctx->mPtorInfo.count = numPTORLayersFound;
968 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
969 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
970 }
971
972 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
973 // reset PTOR
974 ctx->mPtorInfo.count = 0;
975 if(isValidRect(commonRect)) {
976 // If PTORs are intersecting restore displayframe of PTOR[1]
977 // before returning, as we have modified it above.
978 list->hwLayers[minLayerIndex[1]].displayFrame =
979 displayFrame[minLayerIndex[1]];
980 }
981 return false;
982 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700983 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
984 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
985
Xu Yangcda012c2014-07-30 21:57:21 +0800986 // Store the blending mode, planeAlpha, and transform of PTOR layers
987 int32_t blending[numPTORLayersFound];
988 uint8_t planeAlpha[numPTORLayersFound];
989 uint32_t transform[numPTORLayersFound];
990
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700991 for(int j = 0; j < numPTORLayersFound; j++) {
992 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700993
994 // Update src crop of PTOR layer
995 hwc_layer_1_t* layer = &list->hwLayers[index];
996 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
997 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
998 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
999 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1000
1001 // Store & update w, h, format of PTOR layer
1002 private_handle_t *hnd = (private_handle_t *)layer->handle;
1003 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1004 layerWhf[j] = whf;
1005 hnd->width = renderBuf->width;
1006 hnd->height = renderBuf->height;
1007 hnd->format = renderBuf->format;
1008
Xu Yangcda012c2014-07-30 21:57:21 +08001009 // Store & update blending mode, planeAlpha and transform of PTOR layer
1010 blending[j] = layer->blending;
1011 planeAlpha[j] = layer->planeAlpha;
1012 transform[j] = layer->transform;
1013 layer->blending = HWC_BLENDING_NONE;
1014 layer->planeAlpha = 0xFF;
1015 layer->transform = 0;
1016
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001017 // Remove overlap from crop & displayFrame of below layers
1018 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001019 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001020 if(!isValidRect(getIntersection(layer->displayFrame,
1021 overlapRect[j]))) {
1022 continue;
1023 }
1024 // Update layer attributes
1025 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1026 hwc_rect_t destRect = deductRect(layer->displayFrame,
1027 overlapRect[j]);
1028 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1029 layer->transform);
1030 layer->sourceCropf.left = (float)srcCrop.left;
1031 layer->sourceCropf.top = (float)srcCrop.top;
1032 layer->sourceCropf.right = (float)srcCrop.right;
1033 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1034 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001035 }
1036
1037 mCurrentFrame.mdpCount = numAppLayers;
1038 mCurrentFrame.fbCount = 0;
1039 mCurrentFrame.fbZ = -1;
1040
1041 for (int j = 0; j < numAppLayers; j++)
1042 mCurrentFrame.isFBComposed[j] = false;
1043
1044 bool result = postHeuristicsHandling(ctx, list);
1045
1046 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001047 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001048 hwc_layer_1_t* layer = &list->hwLayers[i];
1049 layer->displayFrame = displayFrame[i];
1050 layer->sourceCropf.left = (float)sourceCrop[i].left;
1051 layer->sourceCropf.top = (float)sourceCrop[i].top;
1052 layer->sourceCropf.right = (float)sourceCrop[i].right;
1053 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1054 }
1055
Xu Yangcda012c2014-07-30 21:57:21 +08001056 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001057 for (int i = 0; i < numPTORLayersFound; i++) {
1058 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001059 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001060 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1061 hnd->width = layerWhf[i].w;
1062 hnd->height = layerWhf[i].h;
1063 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001064 layer->blending = blending[i];
1065 layer->planeAlpha = planeAlpha[i];
1066 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001067 }
1068
Sushil Chauhandefd3522014-05-13 18:17:12 -07001069 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001070 // reset PTOR
1071 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001072 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001073 } else {
1074 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1075 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001076 }
1077
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001078 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1079 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001080 return result;
1081}
1082
Saurabh Shahaa236822013-04-24 18:07:26 -07001083bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1084{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001085 if(!sEnableMixedMode) {
1086 //Mixed mode is disabled. No need to even try caching.
1087 return false;
1088 }
1089
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001090 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001091 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001092 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001093 cacheBasedComp(ctx, list);
1094 } else {
1095 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001096 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001097 }
1098
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001099 return ret;
1100}
1101
1102bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1103 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001104 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1105 return false;
1106
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001107 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001108 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001109 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001110
1111 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1112 for(int i = 0; i < numAppLayers; i++) {
1113 if(!mCurrentFrame.isFBComposed[i]) {
1114 hwc_layer_1_t* layer = &list->hwLayers[i];
1115 if(not isSupportedForMDPComp(ctx, layer)) {
1116 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1117 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001118 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001119 return false;
1120 }
1121 }
1122 }
1123
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001124 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001125 /* mark secure RGB layers for MDP comp */
1126 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301127 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001128 if(!ret) {
1129 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001130 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001131 return false;
1132 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001133
1134 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001135
Raj Kamal389d6e32014-08-04 14:43:24 +05301136 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001137 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301138 }
1139
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001140 //Will benefit cases where a video has non-updating background.
1141 if((mDpy > HWC_DISPLAY_PRIMARY) and
1142 (mdpCount > MAX_SEC_LAYERS)) {
1143 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001144 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001145 return false;
1146 }
1147
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001148 if(!postHeuristicsHandling(ctx, list)) {
1149 ALOGD_IF(isDebug(), "post heuristic handling failed");
1150 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001151 return false;
1152 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001153 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1154 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001155
Saurabh Shahaa236822013-04-24 18:07:26 -07001156 return true;
1157}
1158
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001159bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001160 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001161 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1162 return false;
1163
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001164 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001165 return false;
1166 }
1167
Saurabh Shahb772ae32013-11-18 15:40:02 -08001168 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001169 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1170 const int stagesForMDP = min(sMaxPipesPerMixer,
1171 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001172
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001173 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1174 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1175 int lastMDPSupportedIndex = numAppLayers;
1176 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001177
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001178 //Find the minimum MDP batch size
1179 for(int i = 0; i < numAppLayers;i++) {
1180 if(mCurrentFrame.drop[i]) {
1181 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001182 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001183 }
1184 hwc_layer_1_t* layer = &list->hwLayers[i];
1185 if(not isSupportedForMDPComp(ctx, layer)) {
1186 lastMDPSupportedIndex = i;
1187 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1188 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001189 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001190 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001191 }
1192
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001193 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1194 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1195 mCurrentFrame.dropCount);
1196
1197 //Start at a point where the fb batch should at least have 2 layers, for
1198 //this mode to be justified.
1199 while(fbBatchSize < 2) {
1200 ++fbBatchSize;
1201 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001202 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001203
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001204 //If there are no layers for MDP, this mode doesnt make sense.
1205 if(mdpBatchSize < 1) {
1206 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1207 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001208 return false;
1209 }
1210
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001211 mCurrentFrame.reset(numAppLayers);
1212
1213 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1214 while(mdpBatchSize > 0) {
1215 //Mark layers for MDP comp
1216 int mdpBatchLeft = mdpBatchSize;
1217 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1218 if(mCurrentFrame.drop[i]) {
1219 continue;
1220 }
1221 mCurrentFrame.isFBComposed[i] = false;
1222 --mdpBatchLeft;
1223 }
1224
1225 mCurrentFrame.fbZ = mdpBatchSize;
1226 mCurrentFrame.fbCount = fbBatchSize;
1227 mCurrentFrame.mdpCount = mdpBatchSize;
1228
1229 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1230 __FUNCTION__, mdpBatchSize, fbBatchSize,
1231 mCurrentFrame.dropCount);
1232
1233 if(postHeuristicsHandling(ctx, list)) {
1234 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001235 __FUNCTION__);
1236 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1237 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001238 return true;
1239 }
1240
1241 reset(ctx);
1242 --mdpBatchSize;
1243 ++fbBatchSize;
1244 }
1245
1246 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001247}
1248
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001249bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301250 if(mDpy or isSecurePresent(ctx, mDpy) or
1251 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001252 return false;
1253 }
1254 return true;
1255}
1256
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001257bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1258 hwc_display_contents_1_t* list){
1259 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1260 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1261 mDpy ) {
1262 return false;
1263 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001264 if(ctx->listStats[mDpy].secureUI)
1265 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001266 return true;
1267}
1268
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001269bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1270 hwc_display_contents_1_t* list) {
1271 const bool secureOnly = true;
1272 return videoOnlyComp(ctx, list, not secureOnly) or
1273 videoOnlyComp(ctx, list, secureOnly);
1274}
1275
1276bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001277 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001278 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1279 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001280 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001281
Saurabh Shahaa236822013-04-24 18:07:26 -07001282 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001283 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001284 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001285 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001286
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001287 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1288 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001289 return false;
1290 }
1291
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001292 /* Bail out if we are processing only secured video layers
1293 * and we dont have any */
1294 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001295 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001296 return false;
1297 }
1298
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001299 if(mCurrentFrame.fbCount)
1300 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001301
Raj Kamal389d6e32014-08-04 14:43:24 +05301302 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001303 adjustForSourceSplit(ctx, list);
1304 }
1305
1306 if(!postHeuristicsHandling(ctx, list)) {
1307 ALOGD_IF(isDebug(), "post heuristic handling failed");
1308 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001309 return false;
1310 }
1311
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001312 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1313 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001314 return true;
1315}
1316
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001317/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1318bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1319 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001320 // Fall back to video only composition, if AIV video mode is enabled
1321 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001322 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1323 __FUNCTION__, mDpy);
1324 return false;
1325 }
1326
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001327 const bool secureOnly = true;
1328 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1329 mdpOnlyLayersComp(ctx, list, secureOnly);
1330
1331}
1332
1333bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1334 hwc_display_contents_1_t* list, bool secureOnly) {
1335
1336 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1337 return false;
1338
1339 /* Bail out if we are processing only secured video layers
1340 * and we dont have any */
1341 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1342 reset(ctx);
1343 return false;
1344 }
1345
1346 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1347 mCurrentFrame.reset(numAppLayers);
1348 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1349
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001350 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001351 /* mark secure RGB layers for MDP comp */
1352 updateSecureRGB(ctx, list);
1353
1354 if(mCurrentFrame.mdpCount == 0) {
1355 reset(ctx);
1356 return false;
1357 }
1358
1359 /* find the maximum batch of layers to be marked for framebuffer */
1360 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1361 if(!ret) {
1362 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1363 reset(ctx);
1364 return false;
1365 }
1366
1367 if(sEnableYUVsplit){
1368 adjustForSourceSplit(ctx, list);
1369 }
1370
1371 if(!postHeuristicsHandling(ctx, list)) {
1372 ALOGD_IF(isDebug(), "post heuristic handling failed");
1373 reset(ctx);
1374 return false;
1375 }
1376
1377 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1378 __FUNCTION__);
1379 return true;
1380}
1381
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001382/* Checks for conditions where YUV layers cannot be bypassed */
1383bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001384 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001385 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001386 return false;
1387 }
1388
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001389 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001390 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1391 return false;
1392 }
1393
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001394 if(isSecuring(ctx, layer)) {
1395 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1396 return false;
1397 }
1398
Saurabh Shah4fdde762013-04-30 18:47:33 -07001399 if(!isValidDimension(ctx, layer)) {
1400 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1401 __FUNCTION__);
1402 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001403 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001404
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001405 if(layer->planeAlpha < 0xFF) {
1406 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1407 in video only mode",
1408 __FUNCTION__);
1409 return false;
1410 }
1411
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001412 return true;
1413}
1414
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001415/* Checks for conditions where Secure RGB layers cannot be bypassed */
1416bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1417 if(isSkipLayer(layer)) {
1418 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1419 __FUNCTION__, mDpy);
1420 return false;
1421 }
1422
1423 if(isSecuring(ctx, layer)) {
1424 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1425 return false;
1426 }
1427
1428 if(not isSupportedForMDPComp(ctx, layer)) {
1429 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1430 __FUNCTION__);
1431 return false;
1432 }
1433 return true;
1434}
1435
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301436/* starts at fromIndex and check for each layer to find
1437 * if it it has overlapping with any Updating layer above it in zorder
1438 * till the end of the batch. returns true if it finds any intersection */
1439bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1440 int fromIndex, int toIndex) {
1441 for(int i = fromIndex; i < toIndex; i++) {
1442 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1443 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1444 return false;
1445 }
1446 }
1447 }
1448 return true;
1449}
1450
1451/* Checks if given layer at targetLayerIndex has any
1452 * intersection with all the updating layers in beween
1453 * fromIndex and toIndex. Returns true if it finds intersectiion */
1454bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1455 int fromIndex, int toIndex, int targetLayerIndex) {
1456 for(int i = fromIndex; i <= toIndex; i++) {
1457 if(!mCurrentFrame.isFBComposed[i]) {
1458 if(areLayersIntersecting(&list->hwLayers[i],
1459 &list->hwLayers[targetLayerIndex])) {
1460 return true;
1461 }
1462 }
1463 }
1464 return false;
1465}
1466
1467int MDPComp::getBatch(hwc_display_contents_1_t* list,
1468 int& maxBatchStart, int& maxBatchEnd,
1469 int& maxBatchCount) {
1470 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301471 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001472 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301473 while (i < mCurrentFrame.layerCount) {
1474 int batchCount = 0;
1475 int batchStart = i;
1476 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001477 /* Adjust batch Z order with the dropped layers so far */
1478 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301479 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301480 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301481 while(i < mCurrentFrame.layerCount) {
1482 if(!mCurrentFrame.isFBComposed[i]) {
1483 if(!batchCount) {
1484 i++;
1485 break;
1486 }
1487 updatingLayersAbove++;
1488 i++;
1489 continue;
1490 } else {
1491 if(mCurrentFrame.drop[i]) {
1492 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001493 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301494 continue;
1495 } else if(updatingLayersAbove <= 0) {
1496 batchCount++;
1497 batchEnd = i;
1498 i++;
1499 continue;
1500 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1501
1502 // We have a valid updating layer already. If layer-i not
1503 // have overlapping with all updating layers in between
1504 // batch-start and i, then we can add layer i to batch.
1505 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1506 batchCount++;
1507 batchEnd = i;
1508 i++;
1509 continue;
1510 } else if(canPushBatchToTop(list, batchStart, i)) {
1511 //If All the non-updating layers with in this batch
1512 //does not have intersection with the updating layers
1513 //above in z-order, then we can safely move the batch to
1514 //higher z-order. Increment fbZ as it is moving up.
1515 if( firstZReverseIndex < 0) {
1516 firstZReverseIndex = i;
1517 }
1518 batchCount++;
1519 batchEnd = i;
1520 fbZ += updatingLayersAbove;
1521 i++;
1522 updatingLayersAbove = 0;
1523 continue;
1524 } else {
1525 //both failed.start the loop again from here.
1526 if(firstZReverseIndex >= 0) {
1527 i = firstZReverseIndex;
1528 }
1529 break;
1530 }
1531 }
1532 }
1533 }
1534 if(batchCount > maxBatchCount) {
1535 maxBatchCount = batchCount;
1536 maxBatchStart = batchStart;
1537 maxBatchEnd = batchEnd;
1538 fbZOrder = fbZ;
1539 }
1540 }
1541 return fbZOrder;
1542}
1543
1544bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1545 hwc_display_contents_1_t* list) {
1546 /* Idea is to keep as many non-updating(cached) layers in FB and
1547 * send rest of them through MDP. This is done in 2 steps.
1548 * 1. Find the maximum contiguous batch of non-updating layers.
1549 * 2. See if we can improve this batch size for caching by adding
1550 * opaque layers around the batch, if they don't have
1551 * any overlapping with the updating layers in between.
1552 * NEVER mark an updating layer for caching.
1553 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001554
1555 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001556 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001557 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301558 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001559
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001560 /* Nothing is cached. No batching needed */
1561 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001562 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001563 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001564
1565 /* No MDP comp layers, try to use other comp modes */
1566 if(mCurrentFrame.mdpCount == 0) {
1567 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001568 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001569
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301570 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001571
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301572 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001573 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001574 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001575 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301576 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001577 if(!mCurrentFrame.drop[i]){
1578 //If an unsupported layer is being attempted to
1579 //be pulled out we should fail
1580 if(not isSupportedForMDPComp(ctx, layer)) {
1581 return false;
1582 }
1583 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001584 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001585 }
1586 }
1587
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301588 // update the frame data
1589 mCurrentFrame.fbZ = fbZ;
1590 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001591 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001592 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001593
1594 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301595 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001596
1597 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001598}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001599
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001600void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001601 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001602 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001603 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001604
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001605 for(int i = 0; i < numAppLayers; i++) {
1606 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001607 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001608 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001609 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001610 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001611 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001612 }
1613 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001614
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001615 frame.fbCount = fbCount;
1616 frame.mdpCount = frame.layerCount - frame.fbCount
1617 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001618
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001619 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1620 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001621}
1622
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001623// drop other non-AIV layers from external display list.
1624void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001625 hwc_display_contents_1_t* list) {
1626 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1627 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001628 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001629 mCurrentFrame.dropCount++;
1630 mCurrentFrame.drop[i] = true;
1631 }
1632 }
1633 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1634 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1635 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1636 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1637 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1638 mCurrentFrame.dropCount);
1639}
1640
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001641void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001642 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001643 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1644 for(int index = 0;index < nYuvCount; index++){
1645 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1646 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1647
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001648 if(mCurrentFrame.drop[nYuvIndex]) {
1649 continue;
1650 }
1651
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001652 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001653 if(!frame.isFBComposed[nYuvIndex]) {
1654 frame.isFBComposed[nYuvIndex] = true;
1655 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001656 }
1657 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001658 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001659 private_handle_t *hnd = (private_handle_t *)layer->handle;
1660 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001661 frame.isFBComposed[nYuvIndex] = false;
1662 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001663 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001664 }
1665 }
1666 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001667
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001668 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1669 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001670}
1671
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001672void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1673 hwc_display_contents_1_t* list) {
1674 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1675 for(int index = 0;index < nSecureRGBCount; index++){
1676 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1677 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1678
1679 if(!isSecureRGBDoable(ctx, layer)) {
1680 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1681 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1682 mCurrentFrame.fbCount++;
1683 }
1684 } else {
1685 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1686 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1687 mCurrentFrame.fbCount--;
1688 }
1689 }
1690 }
1691
1692 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1693 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1694 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1695 mCurrentFrame.fbCount);
1696}
1697
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001698hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1699 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001700 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001701
1702 /* Update only the region of FB needed for composition */
1703 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1704 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1705 hwc_layer_1_t* layer = &list->hwLayers[i];
1706 hwc_rect_t dst = layer->displayFrame;
1707 fbRect = getUnion(fbRect, dst);
1708 }
1709 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001710 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001711 return fbRect;
1712}
1713
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001714bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1715 hwc_display_contents_1_t* list) {
1716
1717 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001718 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001719 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1720 return false;
1721 }
1722
1723 //Limitations checks
1724 if(!hwLimitationsCheck(ctx, list)) {
1725 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1726 return false;
1727 }
1728
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001729 //Configure framebuffer first if applicable
1730 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001731 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001732 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1733 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001734 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1735 __FUNCTION__);
1736 return false;
1737 }
1738 }
1739
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001740 mCurrentFrame.map();
1741
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001742 if(!allocLayerPipes(ctx, list)) {
1743 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001744 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001745 }
1746
1747 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001748 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001749 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001750 int mdpIndex = mCurrentFrame.layerToMDP[index];
1751 hwc_layer_1_t* layer = &list->hwLayers[index];
1752
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301753 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1754 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1755 mdpNextZOrder++;
1756 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001757 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1758 cur_pipe->zOrder = mdpNextZOrder++;
1759
radhakrishnac9a67412013-09-25 17:40:42 +05301760 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301761 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301762 if(configure4k2kYuv(ctx, layer,
1763 mCurrentFrame.mdpToLayer[mdpIndex])
1764 != 0 ){
1765 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1766 for layer %d",__FUNCTION__, index);
1767 return false;
1768 }
1769 else{
1770 mdpNextZOrder++;
1771 }
1772 continue;
1773 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001774 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1775 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301776 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001777 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001778 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001779 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001780 }
1781
Saurabh Shaha36be922013-12-16 18:18:39 -08001782 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1783 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1784 ,__FUNCTION__, mDpy);
1785 return false;
1786 }
1787
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001788 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001789 return true;
1790}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001791
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001792bool MDPComp::resourceCheck(hwc_context_t* ctx,
1793 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001794 const bool fbUsed = mCurrentFrame.fbCount;
1795 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1796 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1797 return false;
1798 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001799 // Init rotCount to number of rotate sessions used by other displays
1800 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1801 // Count the number of rotator sessions required for current display
1802 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1803 if(!mCurrentFrame.isFBComposed[index]) {
1804 hwc_layer_1_t* layer = &list->hwLayers[index];
1805 private_handle_t *hnd = (private_handle_t *)layer->handle;
1806 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1807 rotCount++;
1808 }
1809 }
1810 }
1811 // if number of layers to rotate exceeds max rotator sessions, bail out.
1812 if(rotCount > RotMgr::MAX_ROT_SESS) {
1813 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1814 __FUNCTION__, mDpy);
1815 return false;
1816 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001817 return true;
1818}
1819
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301820bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1821 hwc_display_contents_1_t* list) {
1822
1823 //A-family hw limitation:
1824 //If a layer need alpha scaling, MDP can not support.
1825 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1826 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1827 if(!mCurrentFrame.isFBComposed[i] &&
1828 isAlphaScaled( &list->hwLayers[i])) {
1829 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1830 return false;
1831 }
1832 }
1833 }
1834
1835 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1836 //If multiple layers requires downscaling and also they are overlapping
1837 //fall back to GPU since MDSS can not handle it.
1838 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1839 qdutils::MDPVersion::getInstance().is8x26()) {
1840 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1841 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1842 if(!mCurrentFrame.isFBComposed[i] &&
1843 isDownscaleRequired(botLayer)) {
1844 //if layer-i is marked for MDP and needs downscaling
1845 //check if any MDP layer on top of i & overlaps with layer-i
1846 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1847 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1848 if(!mCurrentFrame.isFBComposed[j] &&
1849 isDownscaleRequired(topLayer)) {
1850 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1851 topLayer->displayFrame);
1852 if(isValidRect(r))
1853 return false;
1854 }
1855 }
1856 }
1857 }
1858 }
1859 return true;
1860}
1861
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001862int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001863 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001864 char property[PROPERTY_VALUE_MAX];
1865
Raj Kamal4393eaa2014-06-06 13:45:20 +05301866 if(!ctx || !list) {
1867 ALOGE("%s: Invalid context or list",__FUNCTION__);
1868 mCachedFrame.reset();
1869 return -1;
1870 }
1871
1872 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001873 if(mDpy == HWC_DISPLAY_PRIMARY) {
1874 sSimulationFlags = 0;
1875 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1876 int currentFlags = atoi(property);
1877 if(currentFlags != sSimulationFlags) {
1878 sSimulationFlags = currentFlags;
1879 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1880 sSimulationFlags, sSimulationFlags);
1881 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001882 }
1883 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001884 // reset PTOR
1885 if(!mDpy)
1886 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001887
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301888 //Do not cache the information for next draw cycle.
1889 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1890 ALOGI("%s: Unsupported layer count for mdp composition",
1891 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001892 mCachedFrame.reset();
1893 return -1;
1894 }
1895
Saurabh Shahb39f8152013-08-22 10:21:44 -07001896 //reset old data
1897 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001898 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1899 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301900
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001901 // Detect the start of animation and fall back to GPU only once to cache
1902 // all the layers in FB and display FB content untill animation completes.
1903 if(ctx->listStats[mDpy].isDisplayAnimating) {
1904 mCurrentFrame.needsRedraw = false;
1905 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1906 mCurrentFrame.needsRedraw = true;
1907 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1908 }
1909 setMDPCompLayerFlags(ctx, list);
1910 mCachedFrame.updateCounts(mCurrentFrame);
1911 ret = -1;
1912 return ret;
1913 } else {
1914 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1915 }
1916
Saurabh Shahb39f8152013-08-22 10:21:44 -07001917 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001918 if(isFrameDoable(ctx)) {
1919 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001920 // if AIV Video mode is enabled, drop all non AIV layers from the
1921 // external display list.
1922 if(ctx->listStats[mDpy].mAIVVideoMode) {
1923 dropNonAIVLayers(ctx, list);
1924 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001925
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001926 // if tryFullFrame fails, try to push all video and secure RGB layers
1927 // to MDP for composition.
1928 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001929 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301930 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001931 setMDPCompLayerFlags(ctx, list);
1932 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001933 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001934 reset(ctx);
1935 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1936 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001937 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001938 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1939 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001940 }
1941 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05301942 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
1943 enablePartialUpdateForMDP3) {
1944 generateROI(ctx, list);
1945 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
1946 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
1947 }
1948 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001949 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1950 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001951 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001952 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001953
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001954 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001955 ALOGD("GEOMETRY change: %d",
1956 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001957 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001958 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001959 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001960 }
1961
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001962#ifdef DYNAMIC_FPS
1963 //For primary display, set the dynamic refreshrate
1964 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported()) {
1965 FrameInfo frame;
1966 frame.reset(mCurrentFrame.layerCount);
Raj Kamal18e946e2014-10-10 14:23:47 +05301967 memset(&frame.drop, 0, sizeof(frame.drop));
1968 frame.dropCount = 0;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001969 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
1970 __FUNCTION__);
1971 updateLayerCache(ctx, list, frame);
1972 updateYUV(ctx, list, false /*secure only*/, frame);
1973 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1974 //Set the new fresh rate, if there is only one updating YUV layer
1975 //or there is one single RGB layer with this request
1976 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1977 (frame.layerCount == 1)) {
1978 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1979 }
1980 setRefreshRate(ctx, mDpy, refreshRate);
1981 }
1982#endif
1983
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001984 mCachedFrame.cacheAll(list);
1985 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001986 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001987}
1988
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001989bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301990
1991 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301992 int mdpIndex = mCurrentFrame.layerToMDP[index];
1993 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1994 info.pipeInfo = new MdpYUVPipeInfo;
1995 info.rot = NULL;
1996 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301997
1998 pipe_info.lIndex = ovutils::OV_INVALID;
1999 pipe_info.rIndex = ovutils::OV_INVALID;
2000
Saurabh Shahc62f3982014-03-05 14:28:26 -08002001 Overlay::PipeSpecs pipeSpecs;
2002 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2003 pipeSpecs.needsScaling = true;
2004 pipeSpecs.dpy = mDpy;
2005 pipeSpecs.fb = false;
2006
2007 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302008 if(pipe_info.lIndex == ovutils::OV_INVALID){
2009 bRet = false;
2010 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2011 __FUNCTION__);
2012 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002013 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302014 if(pipe_info.rIndex == ovutils::OV_INVALID){
2015 bRet = false;
2016 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2017 __FUNCTION__);
2018 }
2019 return bRet;
2020}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002021
2022int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2023 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002024 if (ctx->mPtorInfo.isActive()) {
2025 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002026 if (fd < 0) {
2027 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002028 }
2029 }
2030 return fd;
2031}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002032//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002033
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002034void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302035 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002036 //If 4k2k Yuv layer split is possible, and if
2037 //fbz is above 4k2k layer, increment fb zorder by 1
2038 //as we split 4k2k layer and increment zorder for right half
2039 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002040 if(!ctx)
2041 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002042 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302043 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2044 index++) {
2045 if(!mCurrentFrame.isFBComposed[index]) {
2046 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2047 mdpNextZOrder++;
2048 }
2049 mdpNextZOrder++;
2050 hwc_layer_1_t* layer = &list->hwLayers[index];
2051 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302052 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302053 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2054 mCurrentFrame.fbZ += 1;
2055 mdpNextZOrder++;
2056 //As we split 4kx2k yuv layer and program to 2 VG pipes
2057 //(if available) increase mdpcount by 1.
2058 mCurrentFrame.mdpCount++;
2059 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002060 }
2061 }
2062 }
radhakrishnac9a67412013-09-25 17:40:42 +05302063}
2064
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002065/*
2066 * Configures pipe(s) for MDP composition
2067 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002068int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002069 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002070 MdpPipeInfoNonSplit& mdp_info =
2071 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002072 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
2073 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002074 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002075
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002076 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2077 __FUNCTION__, layer, zOrder, dest);
2078
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002079 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002080 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002081}
2082
Saurabh Shah88e4d272013-09-03 13:31:29 -07002083bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002084 hwc_display_contents_1_t* list) {
2085 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002086
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002087 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002088
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002089 hwc_layer_1_t* layer = &list->hwLayers[index];
2090 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302091 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002092 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302093 continue;
2094 }
2095 }
2096
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002097 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002098 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002099 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002100 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002101 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002102
Saurabh Shahc62f3982014-03-05 14:28:26 -08002103 Overlay::PipeSpecs pipeSpecs;
2104 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2105 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2106 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2107 (qdutils::MDPVersion::getInstance().is8x26() and
2108 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2109 pipeSpecs.dpy = mDpy;
2110 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002111 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002112
Saurabh Shahc62f3982014-03-05 14:28:26 -08002113 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2114
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002115 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002116 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002117 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002118 }
2119 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002120 return true;
2121}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002122
radhakrishnac9a67412013-09-25 17:40:42 +05302123int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2124 PipeLayerPair& PipeLayerPair) {
2125 MdpYUVPipeInfo& mdp_info =
2126 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2127 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302128 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2129 eDest lDest = mdp_info.lIndex;
2130 eDest rDest = mdp_info.rIndex;
2131
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002132 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302133 lDest, rDest, &PipeLayerPair.rot);
2134}
2135
Saurabh Shah88e4d272013-09-03 13:31:29 -07002136bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002137
Raj Kamal4393eaa2014-06-06 13:45:20 +05302138 if(!isEnabled() or !mModeOn) {
2139 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302140 return true;
2141 }
2142
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002143 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002144 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002145 sHandleTimeout = true;
2146 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002147
2148 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002149 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002150
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002151 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2152 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002153 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002154 if(mCurrentFrame.isFBComposed[i]) continue;
2155
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002156 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002157 private_handle_t *hnd = (private_handle_t *)layer->handle;
2158 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002159 if (!(layer->flags & HWC_COLOR_FILL)) {
2160 ALOGE("%s handle null", __FUNCTION__);
2161 return false;
2162 }
2163 // No PLAY for Color layer
2164 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2165 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002166 }
2167
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002168 int mdpIndex = mCurrentFrame.layerToMDP[i];
2169
Raj Kamal389d6e32014-08-04 14:43:24 +05302170 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302171 {
2172 MdpYUVPipeInfo& pipe_info =
2173 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2174 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2175 ovutils::eDest indexL = pipe_info.lIndex;
2176 ovutils::eDest indexR = pipe_info.rIndex;
2177 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302178 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302179 if(rot) {
2180 rot->queueBuffer(fd, offset);
2181 fd = rot->getDstMemId();
2182 offset = rot->getDstOffset();
2183 }
2184 if(indexL != ovutils::OV_INVALID) {
2185 ovutils::eDest destL = (ovutils::eDest)indexL;
2186 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2187 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2188 if (!ov.queueBuffer(fd, offset, destL)) {
2189 ALOGE("%s: queueBuffer failed for display:%d",
2190 __FUNCTION__, mDpy);
2191 return false;
2192 }
2193 }
2194
2195 if(indexR != ovutils::OV_INVALID) {
2196 ovutils::eDest destR = (ovutils::eDest)indexR;
2197 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2198 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2199 if (!ov.queueBuffer(fd, offset, destR)) {
2200 ALOGE("%s: queueBuffer failed for display:%d",
2201 __FUNCTION__, mDpy);
2202 return false;
2203 }
2204 }
2205 }
2206 else{
2207 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002208 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302209 ovutils::eDest dest = pipe_info.index;
2210 if(dest == ovutils::OV_INVALID) {
2211 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002212 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302213 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002214
radhakrishnac9a67412013-09-25 17:40:42 +05302215 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2216 continue;
2217 }
2218
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002219 int fd = hnd->fd;
2220 uint32_t offset = (uint32_t)hnd->offset;
2221 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2222 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002223 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002224 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002225 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002226 }
2227
radhakrishnac9a67412013-09-25 17:40:42 +05302228 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2229 using pipe: %d", __FUNCTION__, layer,
2230 hnd, dest );
2231
radhakrishnac9a67412013-09-25 17:40:42 +05302232 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2233 if(rot) {
2234 if(!rot->queueBuffer(fd, offset))
2235 return false;
2236 fd = rot->getDstMemId();
2237 offset = rot->getDstOffset();
2238 }
2239
2240 if (!ov.queueBuffer(fd, offset, dest)) {
2241 ALOGE("%s: queueBuffer failed for display:%d ",
2242 __FUNCTION__, mDpy);
2243 return false;
2244 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002245 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002246
2247 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002248 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002249 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002250}
2251
Saurabh Shah88e4d272013-09-03 13:31:29 -07002252//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002253
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002254void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302255 hwc_display_contents_1_t* list){
2256 //if 4kx2k yuv layer is totally present in either in left half
2257 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302258 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302259 if(mCurrentFrame.fbZ >= 0) {
2260 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2261 index++) {
2262 if(!mCurrentFrame.isFBComposed[index]) {
2263 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2264 mdpNextZOrder++;
2265 }
2266 mdpNextZOrder++;
2267 hwc_layer_1_t* layer = &list->hwLayers[index];
2268 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302269 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302270 hwc_rect_t dst = layer->displayFrame;
2271 if((dst.left > lSplit) || (dst.right < lSplit)) {
2272 mCurrentFrame.mdpCount += 1;
2273 }
2274 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2275 mCurrentFrame.fbZ += 1;
2276 mdpNextZOrder++;
2277 }
2278 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002279 }
radhakrishnac9a67412013-09-25 17:40:42 +05302280 }
2281}
2282
Saurabh Shah88e4d272013-09-03 13:31:29 -07002283bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002284 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002285
Saurabh Shahc62f3982014-03-05 14:28:26 -08002286 const int lSplit = getLeftSplit(ctx, mDpy);
2287 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002288 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002289 pipe_info.lIndex = ovutils::OV_INVALID;
2290 pipe_info.rIndex = ovutils::OV_INVALID;
2291
Saurabh Shahc62f3982014-03-05 14:28:26 -08002292 Overlay::PipeSpecs pipeSpecs;
2293 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2294 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2295 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2296 pipeSpecs.dpy = mDpy;
2297 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2298 pipeSpecs.fb = false;
2299
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002300 // Acquire pipe only for the updating half
2301 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2302 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2303
2304 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002305 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002306 if(pipe_info.lIndex == ovutils::OV_INVALID)
2307 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002308 }
2309
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002310 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002311 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2312 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002313 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002314 return false;
2315 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002316
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002317 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002318}
2319
Saurabh Shah88e4d272013-09-03 13:31:29 -07002320bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002321 hwc_display_contents_1_t* list) {
2322 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002323
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002324 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002325
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002326 hwc_layer_1_t* layer = &list->hwLayers[index];
2327 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302328 hwc_rect_t dst = layer->displayFrame;
2329 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302330 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302331 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002332 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302333 continue;
2334 }
2335 }
2336 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002337 int mdpIndex = mCurrentFrame.layerToMDP[index];
2338 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002339 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002340 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002341 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002342
Saurabh Shahc62f3982014-03-05 14:28:26 -08002343 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2344 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2345 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002346 return false;
2347 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002348 }
2349 return true;
2350}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002351
radhakrishnac9a67412013-09-25 17:40:42 +05302352int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2353 PipeLayerPair& PipeLayerPair) {
2354 const int lSplit = getLeftSplit(ctx, mDpy);
2355 hwc_rect_t dst = layer->displayFrame;
2356 if((dst.left > lSplit)||(dst.right < lSplit)){
2357 MdpYUVPipeInfo& mdp_info =
2358 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2359 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302360 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2361 eDest lDest = mdp_info.lIndex;
2362 eDest rDest = mdp_info.rIndex;
2363
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002364 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302365 lDest, rDest, &PipeLayerPair.rot);
2366 }
2367 else{
2368 return configure(ctx, layer, PipeLayerPair);
2369 }
2370}
2371
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002372/*
2373 * Configures pipe(s) for MDP composition
2374 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002375int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002376 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002377 MdpPipeInfoSplit& mdp_info =
2378 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002379 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002380 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2381 eDest lDest = mdp_info.lIndex;
2382 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002383
2384 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2385 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2386
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002387 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002388 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002389}
2390
Saurabh Shah88e4d272013-09-03 13:31:29 -07002391bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002392
Raj Kamal4393eaa2014-06-06 13:45:20 +05302393 if(!isEnabled() or !mModeOn) {
2394 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302395 return true;
2396 }
2397
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002398 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002399 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002400 sHandleTimeout = true;
2401 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002402
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002403 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002404 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002405
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002406 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2407 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002408 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002409 if(mCurrentFrame.isFBComposed[i]) continue;
2410
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002411 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002412 private_handle_t *hnd = (private_handle_t *)layer->handle;
2413 if(!hnd) {
2414 ALOGE("%s handle null", __FUNCTION__);
2415 return false;
2416 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002417
2418 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2419 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002420 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002421
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002422 int mdpIndex = mCurrentFrame.layerToMDP[i];
2423
Raj Kamal389d6e32014-08-04 14:43:24 +05302424 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302425 {
2426 MdpYUVPipeInfo& pipe_info =
2427 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2428 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2429 ovutils::eDest indexL = pipe_info.lIndex;
2430 ovutils::eDest indexR = pipe_info.rIndex;
2431 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302432 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302433 if(rot) {
2434 rot->queueBuffer(fd, offset);
2435 fd = rot->getDstMemId();
2436 offset = rot->getDstOffset();
2437 }
2438 if(indexL != ovutils::OV_INVALID) {
2439 ovutils::eDest destL = (ovutils::eDest)indexL;
2440 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2441 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2442 if (!ov.queueBuffer(fd, offset, destL)) {
2443 ALOGE("%s: queueBuffer failed for display:%d",
2444 __FUNCTION__, mDpy);
2445 return false;
2446 }
2447 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002448
radhakrishnac9a67412013-09-25 17:40:42 +05302449 if(indexR != ovutils::OV_INVALID) {
2450 ovutils::eDest destR = (ovutils::eDest)indexR;
2451 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2452 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2453 if (!ov.queueBuffer(fd, offset, destR)) {
2454 ALOGE("%s: queueBuffer failed for display:%d",
2455 __FUNCTION__, mDpy);
2456 return false;
2457 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002458 }
2459 }
radhakrishnac9a67412013-09-25 17:40:42 +05302460 else{
2461 MdpPipeInfoSplit& pipe_info =
2462 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2463 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002464
radhakrishnac9a67412013-09-25 17:40:42 +05302465 ovutils::eDest indexL = pipe_info.lIndex;
2466 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002467
radhakrishnac9a67412013-09-25 17:40:42 +05302468 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002469 uint32_t offset = (uint32_t)hnd->offset;
2470 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2471 if (!mDpy && (index != -1)) {
2472 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2473 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002474 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002475 }
radhakrishnac9a67412013-09-25 17:40:42 +05302476
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002477 if(ctx->mAD->draw(ctx, fd, offset)) {
2478 fd = ctx->mAD->getDstFd();
2479 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002480 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002481
radhakrishnac9a67412013-09-25 17:40:42 +05302482 if(rot) {
2483 rot->queueBuffer(fd, offset);
2484 fd = rot->getDstMemId();
2485 offset = rot->getDstOffset();
2486 }
2487
2488 //************* play left mixer **********
2489 if(indexL != ovutils::OV_INVALID) {
2490 ovutils::eDest destL = (ovutils::eDest)indexL;
2491 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2492 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2493 if (!ov.queueBuffer(fd, offset, destL)) {
2494 ALOGE("%s: queueBuffer failed for left mixer",
2495 __FUNCTION__);
2496 return false;
2497 }
2498 }
2499
2500 //************* play right mixer **********
2501 if(indexR != ovutils::OV_INVALID) {
2502 ovutils::eDest destR = (ovutils::eDest)indexR;
2503 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2504 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2505 if (!ov.queueBuffer(fd, offset, destR)) {
2506 ALOGE("%s: queueBuffer failed for right mixer",
2507 __FUNCTION__);
2508 return false;
2509 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002510 }
2511 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002512
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002513 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2514 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002515
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002516 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002517}
Saurabh Shahab47c692014-02-12 18:45:57 -08002518
2519//================MDPCompSrcSplit==============================================
2520bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002521 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002522 private_handle_t *hnd = (private_handle_t *)layer->handle;
2523 hwc_rect_t dst = layer->displayFrame;
2524 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2525 pipe_info.lIndex = ovutils::OV_INVALID;
2526 pipe_info.rIndex = ovutils::OV_INVALID;
2527
2528 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2529 //should have a higher priority than the right one. Pipe priorities are
2530 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002531
Saurabh Shahc62f3982014-03-05 14:28:26 -08002532 Overlay::PipeSpecs pipeSpecs;
2533 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2534 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2535 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2536 pipeSpecs.dpy = mDpy;
2537 pipeSpecs.fb = false;
2538
Saurabh Shahab47c692014-02-12 18:45:57 -08002539 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002540 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002541 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002542 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002543 }
2544
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002545 /* Use 2 pipes IF
2546 a) Layer's crop width is > 2048 or
2547 b) Layer's dest width > 2048 or
2548 c) On primary, driver has indicated with caps to split always. This is
2549 based on an empirically derived value of panel height. Applied only
2550 if the layer's width is > mixer's width
2551 */
2552
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302553 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002554 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302555 mdpHw.isSrcSplitAlways();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002556 int lSplit = getLeftSplit(ctx, mDpy);
2557 int dstWidth = dst.right - dst.left;
Saurabh Shah189f23d2014-09-26 17:21:00 -07002558 int cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
2559 crop.right - crop.left;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002560
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002561 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2562 //pipe line length, we are still using 2 pipes. This is fine just because
2563 //this is source split where destination doesn't matter. Evaluate later to
2564 //see if going through all the calcs to save a pipe is worth it
Naseer Ahmed9eb5e092014-09-25 13:24:44 -04002565 if(dstWidth > (int) mdpHw.getMaxMixerWidth() or
2566 cropWidth > (int) mdpHw.getMaxMixerWidth() or
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002567 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002568 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002569 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002570 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002571 }
2572
2573 // Return values
2574 // 1 Left pipe is higher priority, do nothing.
2575 // 0 Pipes of same priority.
2576 //-1 Right pipe is of higher priority, needs swap.
2577 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2578 pipe_info.rIndex) == -1) {
2579 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002580 }
2581 }
2582
2583 return true;
2584}
2585
Saurabh Shahab47c692014-02-12 18:45:57 -08002586int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2587 PipeLayerPair& PipeLayerPair) {
2588 private_handle_t *hnd = (private_handle_t *)layer->handle;
2589 if(!hnd) {
2590 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2591 return -1;
2592 }
2593 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2594 MdpPipeInfoSplit& mdp_info =
2595 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2596 Rotator **rot = &PipeLayerPair.rot;
2597 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002598 eDest lDest = mdp_info.lIndex;
2599 eDest rDest = mdp_info.rIndex;
2600 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2601 hwc_rect_t dst = layer->displayFrame;
2602 int transform = layer->transform;
2603 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002604 int rotFlags = ROT_FLAGS_NONE;
2605 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2606 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2607
2608 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2609 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2610
2611 // Handle R/B swap
2612 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2613 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2614 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2615 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2616 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2617 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002618 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002619 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2620 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002621 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002622 /* Calculate the external display position based on MDP downscale,
2623 ActionSafe, and extorientation features. */
2624 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002625
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002626 int downscale = getRotDownscale(ctx, layer);
Saurabh Shah97e2d802014-04-14 18:03:54 -07002627 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002628 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002629
2630 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2631 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002632 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002633 }
2634
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002635 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002636 (*rot) = ctx->mRotMgr->getNext();
2637 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002638 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002639 //If the video is using a single pipe, enable BWC
2640 if(rDest == OV_INVALID) {
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002641 BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002642 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002643 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002644 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002645 ALOGE("%s: configRotator failed!", __FUNCTION__);
2646 return -1;
2647 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002648 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002649 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002650 }
2651
2652 //If 2 pipes being used, divide layer into half, crop and dst
2653 hwc_rect_t cropL = crop;
2654 hwc_rect_t cropR = crop;
2655 hwc_rect_t dstL = dst;
2656 hwc_rect_t dstR = dst;
2657 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2658 cropL.right = (crop.right + crop.left) / 2;
2659 cropR.left = cropL.right;
2660 sanitizeSourceCrop(cropL, cropR, hnd);
2661
Saurabh Shahb729b192014-08-15 18:04:24 -07002662 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002663 //Swap crops on H flip since 2 pipes are being used
2664 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2665 hwc_rect_t tmp = cropL;
2666 cropL = cropR;
2667 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002668 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002669 }
2670
Saurabh Shahb729b192014-08-15 18:04:24 -07002671 //cropSwap trick: If the src and dst widths are both odd, let us say
2672 //2507, then splitting both into half would cause left width to be 1253
2673 //and right 1254. If crop is swapped because of H flip, this will cause
2674 //left crop width to be 1254, whereas left dst width remains 1253, thus
2675 //inducing a scaling that is unaccounted for. To overcome that we add 1
2676 //to the dst width if there is a cropSwap. So if the original width was
2677 //2507, the left dst width will be 1254. Even if the original width was
2678 //even for ex: 2508, the left dst width will still remain 1254.
2679 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002680 dstR.left = dstL.right;
2681 }
2682
2683 //For the mdp, since either we are pre-rotating or MDP does flips
2684 orient = OVERLAY_TRANSFORM_0;
2685 transform = 0;
2686
2687 //configure left pipe
2688 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002689 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002690 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2691 (ovutils::eBlending) getBlending(layer->blending));
2692
2693 if(configMdp(ctx->mOverlay, pargL, orient,
2694 cropL, dstL, metadata, lDest) < 0) {
2695 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2696 return -1;
2697 }
2698 }
2699
2700 //configure right pipe
2701 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002702 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002703 static_cast<eRotFlags>(rotFlags),
2704 layer->planeAlpha,
2705 (ovutils::eBlending) getBlending(layer->blending));
2706 if(configMdp(ctx->mOverlay, pargR, orient,
2707 cropR, dstR, metadata, rDest) < 0) {
2708 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2709 return -1;
2710 }
2711 }
2712
2713 return 0;
2714}
2715
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002716}; //namespace
2717