blob: 2a729683e88ec9b72b9b233667b705f4a4f86c98 [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 Sankaranbe93e272014-06-19 18:15:57 -070046int MDPComp::sMaxPipesPerMixer = 0;
Raj Kamal389d6e32014-08-04 14:43:24 +053047bool MDPComp::sEnableYUVsplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070048bool MDPComp::sSrcSplitEnabled = false;
Saurabh Shahacec8e42014-11-25 11:07:04 -080049int MDPComp::sMaxSecLayers = 1;
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +053050bool MDPComp::enablePartialUpdateForMDP3 = false;
Saurabh Shah88e4d272013-09-03 13:31:29 -070051MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070052 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
53 sSrcSplitEnabled = true;
54 return new MDPCompSrcSplit(dpy);
55 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070056 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080057 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070058 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080059}
60
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080061MDPComp::MDPComp(int dpy):mDpy(dpy){};
62
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070063void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080064{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070065 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
66 return;
67
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080068 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070069 (mDpy == 0) ? "\"PRIMARY\"" :
70 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070071 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
72 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080073 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
74 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
75 (mCurrentFrame.needsRedraw? "YES" : "NO"),
76 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070077 if(isDisplaySplit(ctx, mDpy)) {
78 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
79 "Right: [%d, %d, %d, %d] \n",
80 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
81 ctx->listStats[mDpy].lRoi.right,
82 ctx->listStats[mDpy].lRoi.bottom,
83 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
84 ctx->listStats[mDpy].rRoi.right,
85 ctx->listStats[mDpy].rRoi.bottom);
86 } else {
87 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
88 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
89 ctx->listStats[mDpy].lRoi.right,
90 ctx->listStats[mDpy].lRoi.bottom);
91 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080092 dumpsys_log(buf," --------------------------------------------- \n");
93 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
94 dumpsys_log(buf," --------------------------------------------- \n");
95 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
96 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
97 index,
98 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070099 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800100 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700101 (mCurrentFrame.drop[index] ? "DROP" :
102 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800103 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
104 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
105 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800106}
107
108bool MDPComp::init(hwc_context_t *ctx) {
109
110 if(!ctx) {
111 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
112 return false;
113 }
114
Saurabh Shah59562ff2014-09-30 16:13:12 -0700115 char property[PROPERTY_VALUE_MAX] = {0};
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800116
117 sEnabled = false;
Dileep Kumar Reddid8e601d2014-10-28 18:20:43 +0530118 if((ctx->mMDP.version >= qdutils::MDP_V4_0) &&
119 (property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800120 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
121 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800122 sEnabled = true;
123 }
124
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700125 sEnableMixedMode = true;
126 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
127 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
128 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
129 sEnableMixedMode = false;
130 }
131
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700132 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
133
134 /* MDSS_MDP_STAGE_UNUSED and MDSS_MDP_STAGE_BASE are not available for MDP
135 * composition. */
136 sMaxPipesPerMixer = (int)mdpVersion.getBlendStages() - 2;
137 if(property_get("persist.hwc.mdpcomp.maxpermixer", property, "-1") > 0) {
Saurabh Shah85234ec2013-04-12 17:09:00 -0700138 int val = atoi(property);
139 if(val >= 0)
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700140 sMaxPipesPerMixer = min(val, sMaxPipesPerMixer);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800141 }
142
Saurabh Shahacec8e42014-11-25 11:07:04 -0800143 /* Maximum layers allowed to use MDP on secondary panels. If property
144 * doesn't exist, default to 1. Using the property it can be set to 0 or
145 * more.
146 */
147 if(property_get("persist.hwc.maxseclayers", property, "1") > 0) {
148 int val = atoi(property);
149 sMaxSecLayers = (val >= 0) ? val : 1;
150 sMaxSecLayers = min(sMaxSecLayers, sMaxPipesPerMixer);
151 }
152
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400153 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
Saurabh Shah59562ff2014-09-30 16:13:12 -0700154 sIdleInvalidator = IdleInvalidator::getInstance();
155 if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
156 delete sIdleInvalidator;
157 sIdleInvalidator = NULL;
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400158 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800159 }
radhakrishnac9a67412013-09-25 17:40:42 +0530160
Saurabh Shah7c727642014-06-02 15:47:14 -0700161 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700162 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700163 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
164 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
165 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530166 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530167 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700168
Dileep Kumar Reddic6ef3472014-09-24 19:07:08 +0530169 bool defaultPTOR = false;
170 //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
171 //8x16 and 8x39 targets by default
172 if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
173 (qdutils::MDPVersion::getInstance().is8x16() ||
174 qdutils::MDPVersion::getInstance().is8x39())) {
175 defaultPTOR = true;
176 }
177
178 if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
179 (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700180 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
181 HWC_DISPLAY_PRIMARY);
182 }
183
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +0530184 if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
185 (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
186 enablePartialUpdateForMDP3 = true;
187 }
188
189 if(!enablePartialUpdateForMDP3 &&
190 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
191 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
192 enablePartialUpdateForMDP3 = true;
193 }
194
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700195 return true;
196}
197
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800198void MDPComp::reset(hwc_context_t *ctx) {
199 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700200 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800201 ctx->mOverlay->clear(mDpy);
202 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700203}
204
Raj Kamal4393eaa2014-06-06 13:45:20 +0530205void MDPComp::reset() {
206 sHandleTimeout = false;
207 mModeOn = false;
208}
209
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700210void MDPComp::timeout_handler(void *udata) {
211 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
212
213 if(!ctx) {
214 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
215 return;
216 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800217 Locker::Autolock _l(ctx->mDrawLock);
218 // Handle timeout event only if the previous composition is MDP or MIXED.
219 if(!sHandleTimeout) {
220 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
221 return;
222 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700223 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700224 ALOGE("%s: HWC proc not registered", __FUNCTION__);
225 return;
226 }
227 sIdleFallBack = true;
228 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700229 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700230}
231
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700232void MDPComp::setMaxPipesPerMixer(const uint32_t value) {
233 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
234 uint32_t maxSupported = (int)mdpVersion.getBlendStages() - 2;
235 if(value > maxSupported) {
236 ALOGW("%s: Input exceeds max value supported. Setting to"
237 "max value: %d", __FUNCTION__, maxSupported);
238 }
239 sMaxPipesPerMixer = min(value, maxSupported);
240}
241
Saurabh Shah59562ff2014-09-30 16:13:12 -0700242void MDPComp::setIdleTimeout(const uint32_t& timeout) {
243 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
244
245 if(sIdleInvalidator) {
246 if(timeout <= ONE_REFRESH_PERIOD_MS) {
247 //If the specified timeout is < 1 draw cycle worth, "virtually"
248 //disable idle timeout. The ideal way for clients to disable
249 //timeout is to set it to 0
250 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
251 ALOGI("Disabled idle timeout");
252 return;
253 }
254 sIdleInvalidator->setIdleTimeout(timeout);
255 ALOGI("Idle timeout set to %u", timeout);
256 } else {
257 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
258 }
259}
260
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800261void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800262 hwc_display_contents_1_t* list) {
263 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800264
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800265 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800266 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800267 if(!mCurrentFrame.isFBComposed[index]) {
268 layerProp[index].mFlags |= HWC_MDPCOMP;
269 layer->compositionType = HWC_OVERLAY;
270 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800271 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700272 /* Drop the layer when its already present in FB OR when it lies
273 * outside frame's ROI */
274 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800275 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700276 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800277 }
278 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700279}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500280
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800281void MDPComp::setRedraw(hwc_context_t *ctx,
282 hwc_display_contents_1_t* list) {
283 mCurrentFrame.needsRedraw = false;
284 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
285 (list->flags & HWC_GEOMETRY_CHANGED) ||
286 isSkipPresent(ctx, mDpy)) {
287 mCurrentFrame.needsRedraw = true;
288 }
289}
290
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800291MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700292 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700293 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800294}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800295
Saurabh Shahaa236822013-04-24 18:07:26 -0700296void MDPComp::FrameInfo::reset(const int& numLayers) {
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700297 for(int i = 0 ; i < MAX_NUM_BLEND_STAGES; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800298 if(mdpToLayer[i].pipeInfo) {
299 delete mdpToLayer[i].pipeInfo;
300 mdpToLayer[i].pipeInfo = NULL;
301 //We dont own the rotator
302 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800303 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800304 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800305
306 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
307 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700308 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800309
Saurabh Shahaa236822013-04-24 18:07:26 -0700310 layerCount = numLayers;
311 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800312 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700313 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800314 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800315}
316
Saurabh Shahaa236822013-04-24 18:07:26 -0700317void MDPComp::FrameInfo::map() {
318 // populate layer and MDP maps
319 int mdpIdx = 0;
320 for(int idx = 0; idx < layerCount; idx++) {
321 if(!isFBComposed[idx]) {
322 mdpToLayer[mdpIdx].listIndex = idx;
323 layerToMDP[idx] = mdpIdx++;
324 }
325 }
326}
327
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800328MDPComp::LayerCache::LayerCache() {
329 reset();
330}
331
332void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700333 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530334 memset(&isFBComposed, true, sizeof(isFBComposed));
335 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800336 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700337}
338
339void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530340 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700341 for(int i = 0; i < numAppLayers; i++) {
342 hnd[i] = list->hwLayers[i].handle;
343 }
344}
345
346void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700347 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530348 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
349 memcpy(&drop, &curFrame.drop, sizeof(drop));
350}
351
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800352bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
353 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530354 if(layerCount != curFrame.layerCount)
355 return false;
356 for(int i = 0; i < curFrame.layerCount; i++) {
357 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
358 (curFrame.drop[i] != drop[i])) {
359 return false;
360 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800361 if(curFrame.isFBComposed[i] &&
362 (hnd[i] != list->hwLayers[i].handle)){
363 return false;
364 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530365 }
366 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800367}
368
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700369bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
370 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800371 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700372 (not isValidDimension(ctx,layer))
373 //More conditions here, SKIP, sRGB+Blend etc
374 ) {
375 return false;
376 }
377 return true;
378}
379
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530380bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800381 private_handle_t *hnd = (private_handle_t *)layer->handle;
382
383 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700384 if (layer->flags & HWC_COLOR_FILL) {
385 // Color layer
386 return true;
387 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700388 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800389 return false;
390 }
391
Naseer Ahmede850a802013-09-06 13:12:52 -0400392 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400393 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400394 return false;
395
Saurabh Shah62e1d732013-09-17 10:44:05 -0700396 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700397 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700398 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700399 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
400 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700401 int dst_w = dst.right - dst.left;
402 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800403 float w_scale = ((float)crop_w / (float)dst_w);
404 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530405 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700406
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800407 /* Workaround for MDP HW limitation in DSI command mode panels where
408 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
409 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530410 * There also is a HW limilation in MDP, minimum block size is 2x2
411 * Fallback to GPU if height is less than 2.
412 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700413 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800414 return false;
415
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800416 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530417 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800418 const float w_dscale = w_scale;
419 const float h_dscale = h_scale;
420
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800421 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700422
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530423 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700424 /* On targets that doesnt support Decimation (eg.,8x26)
425 * maximum downscale support is overlay pipe downscale.
426 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400427 if(crop_w > (int) mdpHw.getMaxMixerWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530428 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700429 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800430 return false;
431 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700432 // Decimation on macrotile format layers is not supported.
433 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530434 /* Bail out if
435 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700436 * 2. exceeds maximum downscale limit
437 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400438 if(((crop_w > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530439 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700440 w_dscale > maxMDPDownscale ||
441 h_dscale > maxMDPDownscale) {
442 return false;
443 }
444 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800445 return false;
446 }
447 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700448 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700449 return false;
450 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700451 }
452
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800453 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530454 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800455 const float w_uscale = 1.0f / w_scale;
456 const float h_uscale = 1.0f / h_scale;
457
458 if(w_uscale > upscale || h_uscale > upscale)
459 return false;
460 }
461
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800462 return true;
463}
464
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800465bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700466 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800467
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800468 if(!isEnabled()) {
469 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700470 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530471 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530472 qdutils::MDPVersion::getInstance().is8x16() ||
473 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800474 ctx->mVideoTransFlag &&
475 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700476 //1 Padding round to shift pipes across mixers
477 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
478 __FUNCTION__);
479 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700480 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
481 /* TODO: freeing up all the resources only for the targets having total
482 number of pipes < 8. Need to analyze number of VIG pipes used
483 for primary in previous draw cycle and accordingly decide
484 whether to fall back to full GPU comp or video only comp
485 */
486 if(isSecondaryConfiguring(ctx)) {
487 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
488 __FUNCTION__);
489 ret = false;
490 } else if(ctx->isPaddingRound) {
491 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
492 __FUNCTION__,mDpy);
493 ret = false;
494 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800495 } else if (ctx->isDMAStateChanging) {
496 // Bail out if a padding round has been invoked in order to switch DMA
497 // state to block mode. We need this to cater for the case when a layer
498 // requires rotation in the current frame.
499 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
500 __FUNCTION__);
501 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700502 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800503
Saurabh Shahaa236822013-04-24 18:07:26 -0700504 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800505}
506
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800507void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
508 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
509 fbRect = getIntersection(fbRect, roi);
510}
511
512/* 1) Identify layers that are not visible or lying outside the updating ROI and
513 * drop them from composition.
514 * 2) If we have a scaling layer which needs cropping against generated
515 * ROI, reset ROI to full resolution. */
516bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
517 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700518 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800519 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800520
521 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800522 if(!isValidRect(visibleRect)) {
523 mCurrentFrame.drop[i] = true;
524 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800525 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800526 }
527
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700528 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700529 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800530 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700531
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700532 if(!isValidRect(res)) {
533 mCurrentFrame.drop[i] = true;
534 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800535 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700536 /* Reset frame ROI when any layer which needs scaling also needs ROI
537 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800538 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800539 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700540 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
541 mCurrentFrame.dropCount = 0;
542 return false;
543 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800544
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800545 /* deduct any opaque region from visibleRect */
radhakrishna4efbdd62014-11-03 13:19:27 +0530546 if (layer->blending == HWC_BLENDING_NONE &&
547 layer->planeAlpha == 0xFF)
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800548 visibleRect = deductRect(visibleRect, res);
549 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700550 }
551 return true;
552}
553
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800554/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
555 * are updating. If DirtyRegion is applicable, calculate it by accounting all
556 * the changing layer's dirtyRegion. */
557void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
558 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700559 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800560 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700561 return;
562
563 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800564 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
565 (int)ctx->dpyAttr[mDpy].yres};
566
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700567 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800568 hwc_layer_1_t* layer = &list->hwLayers[index];
569 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800570 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700571 hwc_rect_t dst = layer->displayFrame;
572 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800573
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800574#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800575 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700576 {
577 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
578 int x_off = dst.left - src.left;
579 int y_off = dst.top - src.top;
580 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
581 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800582#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800583
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800584 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700585 }
586 }
587
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800588 /* No layer is updating. Still SF wants a refresh.*/
589 if(!isValidRect(roi))
590 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800591
592 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800593 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800594
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800595 ctx->listStats[mDpy].lRoi = roi;
596 if(!validateAndApplyROI(ctx, list))
597 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700598
599 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800600 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
601 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
602}
603
604void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
605 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
606 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
607
608 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
609 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
610 fbRect = getUnion(l_fbRect, r_fbRect);
611}
612/* 1) Identify layers that are not visible or lying outside BOTH the updating
613 * ROI's and drop them from composition. If a layer is spanning across both
614 * the halves of the screen but needed by only ROI, the non-contributing
615 * half will not be programmed for MDP.
616 * 2) If we have a scaling layer which needs cropping against generated
617 * ROI, reset ROI to full resolution. */
618bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
619 hwc_display_contents_1_t* list) {
620
621 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
622
623 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
624 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
625
626 for(int i = numAppLayers - 1; i >= 0; i--){
627 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
628 {
629 mCurrentFrame.drop[i] = true;
630 mCurrentFrame.dropCount++;
631 continue;
632 }
633
634 const hwc_layer_1_t* layer = &list->hwLayers[i];
635 hwc_rect_t dstRect = layer->displayFrame;
636
637 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
638 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
639 hwc_rect_t res = getUnion(l_res, r_res);
640
641 if(!isValidRect(l_res) && !isValidRect(r_res)) {
642 mCurrentFrame.drop[i] = true;
643 mCurrentFrame.dropCount++;
644 } else {
645 /* Reset frame ROI when any layer which needs scaling also needs ROI
646 * cropping */
647 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
648 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
649 mCurrentFrame.dropCount = 0;
650 return false;
651 }
652
radhakrishna4efbdd62014-11-03 13:19:27 +0530653 if (layer->blending == HWC_BLENDING_NONE &&
654 layer->planeAlpha == 0xFF) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800655 visibleRectL = deductRect(visibleRectL, l_res);
656 visibleRectR = deductRect(visibleRectR, r_res);
657 }
658 }
659 }
660 return true;
661}
662/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
663 * are updating. If DirtyRegion is applicable, calculate it by accounting all
664 * the changing layer's dirtyRegion. */
665void MDPCompSplit::generateROI(hwc_context_t *ctx,
666 hwc_display_contents_1_t* list) {
667 if(!canPartialUpdate(ctx, list))
668 return;
669
670 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
671 int lSplit = getLeftSplit(ctx, mDpy);
672
673 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
674 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
675
676 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
677 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
678
679 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
680 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
681
682 for(int index = 0; index < numAppLayers; index++ ) {
683 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800684 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800685 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800686 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700687 hwc_rect_t dst = layer->displayFrame;
688 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800689
690#ifdef QCOM_BSP
691 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700692 {
693 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
694 int x_off = dst.left - src.left;
695 int y_off = dst.top - src.top;
696 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
697 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800698#endif
699
700 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
701 if(isValidRect(l_dst))
702 l_roi = getUnion(l_roi, l_dst);
703
704 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
705 if(isValidRect(r_dst))
706 r_roi = getUnion(r_roi, r_dst);
707 }
708 }
709
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700710 /* For panels that cannot accept commands in both the interfaces, we cannot
711 * send two ROI's (for each half). We merge them into single ROI and split
712 * them across lSplit for MDP mixer use. The ROI's will be merged again
713 * finally before udpating the panel in the driver. */
714 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
715 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
716 l_roi = getIntersection(temp_roi, l_frame);
717 r_roi = getIntersection(temp_roi, r_frame);
718 }
719
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800720 /* No layer is updating. Still SF wants a refresh. */
721 if(!isValidRect(l_roi) && !isValidRect(r_roi))
722 return;
723
724 l_roi = getSanitizeROI(l_roi, l_frame);
725 r_roi = getSanitizeROI(r_roi, r_frame);
726
727 ctx->listStats[mDpy].lRoi = l_roi;
728 ctx->listStats[mDpy].rRoi = r_roi;
729
730 if(!validateAndApplyROI(ctx, list))
731 resetROI(ctx, mDpy);
732
733 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
734 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
735 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
736 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
737 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
738 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700739}
740
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800741/* Checks for conditions where all the layers marked for MDP comp cannot be
742 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800743bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800744 hwc_display_contents_1_t* list){
745
Saurabh Shahaa236822013-04-24 18:07:26 -0700746 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800747 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800748
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700749 // Fall back to video only composition, if AIV video mode is enabled
750 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700751 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
752 __FUNCTION__, mDpy);
753 return false;
754 }
755
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400756 // No Idle fall back, if secure display or secure RGB layers are present or
757 // if there's only a single layer being composed
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -0700758 if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400759 !ctx->listStats[mDpy].secureRGBCount) &&
760 (ctx->listStats[mDpy].numAppLayers != 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700761 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
762 return false;
763 }
764
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800765 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700766 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
767 __FUNCTION__,
768 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800769 return false;
770 }
771
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700772 // if secondary is configuring or Padding round, fall back to video only
773 // composition and release all assigned non VIG pipes from primary.
774 if(isSecondaryConfiguring(ctx)) {
775 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
776 __FUNCTION__);
777 return false;
778 } else if(ctx->isPaddingRound) {
779 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
780 __FUNCTION__,mDpy);
781 return false;
782 }
783
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530784 MDPVersion& mdpHw = MDPVersion::getInstance();
785 if(mDpy > HWC_DISPLAY_PRIMARY &&
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400786 (priDispW > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530787 (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800788 // Disable MDP comp on Secondary when the primary is highres panel and
789 // the secondary is a normal 1080p, because, MDP comp on secondary under
790 // in such usecase, decimation gets used for downscale and there will be
791 // a quality mismatch when there will be a fallback to GPU comp
792 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
793 __FUNCTION__);
794 return false;
795 }
796
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700797 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800798 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700799 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800800 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
801 return false;
802 }
803
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800804 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800805 hwc_layer_1_t* layer = &list->hwLayers[i];
806 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800807
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800808 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700809 if(!canUseRotator(ctx, mDpy)) {
810 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
811 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700812 return false;
813 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800814 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530815
816 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
817 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700818 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530819 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
820 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
821 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800822 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700823
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700824 if(ctx->mAD->isDoable()) {
825 return false;
826 }
827
Saurabh Shahaa236822013-04-24 18:07:26 -0700828 //If all above hard conditions are met we can do full or partial MDP comp.
829 bool ret = false;
830 if(fullMDPComp(ctx, list)) {
831 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700832 } else if(fullMDPCompWithPTOR(ctx, list)) {
833 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700834 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700835 ret = true;
836 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530837
Saurabh Shahaa236822013-04-24 18:07:26 -0700838 return ret;
839}
840
841bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700842
843 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
844 return false;
845
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700846 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
847 for(int i = 0; i < numAppLayers; i++) {
848 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700849 if(not mCurrentFrame.drop[i] and
850 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700851 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
852 return false;
853 }
854 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800855
Saurabh Shahaa236822013-04-24 18:07:26 -0700856 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700857 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
858 sizeof(mCurrentFrame.isFBComposed));
859 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
860 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700861
Raj Kamal389d6e32014-08-04 14:43:24 +0530862 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800863 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530864 }
865
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800866 if(!postHeuristicsHandling(ctx, list)) {
867 ALOGD_IF(isDebug(), "post heuristic handling failed");
868 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700869 return false;
870 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700871 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
872 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700873 return true;
874}
875
Sushil Chauhandefd3522014-05-13 18:17:12 -0700876/* Full MDP Composition with Peripheral Tiny Overlap Removal.
877 * MDP bandwidth limitations can be avoided, if the overlap region
878 * covered by the smallest layer at a higher z-order, gets composed
879 * by Copybit on a render buffer, which can be queued to MDP.
880 */
881bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
882 hwc_display_contents_1_t* list) {
883
884 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
885 const int stagesForMDP = min(sMaxPipesPerMixer,
886 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
887
888 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700889 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700890 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
891 return false;
892 }
893
894 // Frame level checks
895 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
896 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
897 isSecurePresent(ctx, mDpy)) {
898 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
899 return false;
900 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700901 // MDP comp checks
902 for(int i = 0; i < numAppLayers; 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 if(not isSupportedForMDPComp(ctx, layer)) {
905 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
906 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700907 }
908 }
909
Sushil Chauhandefd3522014-05-13 18:17:12 -0700910 /* We cannot use this composition mode, if:
911 1. A below layer needs scaling.
912 2. Overlap is not peripheral to display.
913 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700914 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700915 */
916
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700917 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
918 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
919 memset(overlapRect, 0, sizeof(overlapRect));
920 int layerPixelCount, minPixelCount = 0;
921 int numPTORLayersFound = 0;
922 for (int i = numAppLayers-1; (i >= 0 &&
923 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700924 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700925 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700926 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700927 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
928 // PTOR layer should be peripheral and cannot have transform
929 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
930 has90Transform(layer)) {
931 continue;
932 }
933 if((3 * (layerPixelCount + minPixelCount)) >
934 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
935 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
936 continue;
937 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700938 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700939 for (int j = i-1; j >= 0; j--) {
940 // Check if the layers below this layer qualifies for PTOR comp
941 hwc_layer_1_t* layer = &list->hwLayers[j];
942 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700943 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700944 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700945 if (isValidRect(getIntersection(dispFrame, disFrame))) {
946 if (has90Transform(layer) || needsScaling(layer)) {
947 found = false;
948 break;
949 }
950 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700951 }
952 }
953 // Store the minLayer Index
954 if(found) {
955 minLayerIndex[numPTORLayersFound] = i;
956 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
957 minPixelCount += layerPixelCount;
958 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700959 }
960 }
961
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700962 // No overlap layers
963 if (!numPTORLayersFound)
964 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700965
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700966 // Store the displayFrame and the sourceCrops of the layers
967 hwc_rect_t displayFrame[numAppLayers];
968 hwc_rect_t sourceCrop[numAppLayers];
969 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700970 hwc_layer_1_t* layer = &list->hwLayers[i];
971 displayFrame[i] = layer->displayFrame;
972 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700973 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700974
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530975 /**
976 * It's possible that 2 PTOR layers might have overlapping.
977 * In such case, remove the intersection(again if peripheral)
978 * from the lower PTOR layer to avoid overlapping.
979 * If intersection is not on peripheral then compromise
980 * by reducing number of PTOR layers.
981 **/
982 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
983 if(isValidRect(commonRect)) {
984 overlapRect[1] = deductRect(overlapRect[1], commonRect);
985 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
986 }
987
988 ctx->mPtorInfo.count = numPTORLayersFound;
989 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
990 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
991 }
992
993 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
994 // reset PTOR
995 ctx->mPtorInfo.count = 0;
996 if(isValidRect(commonRect)) {
997 // If PTORs are intersecting restore displayframe of PTOR[1]
998 // before returning, as we have modified it above.
999 list->hwLayers[minLayerIndex[1]].displayFrame =
1000 displayFrame[minLayerIndex[1]];
1001 }
1002 return false;
1003 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001004 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1005 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
1006
Xu Yangcda012c2014-07-30 21:57:21 +08001007 // Store the blending mode, planeAlpha, and transform of PTOR layers
1008 int32_t blending[numPTORLayersFound];
1009 uint8_t planeAlpha[numPTORLayersFound];
1010 uint32_t transform[numPTORLayersFound];
1011
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001012 for(int j = 0; j < numPTORLayersFound; j++) {
1013 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001014
1015 // Update src crop of PTOR layer
1016 hwc_layer_1_t* layer = &list->hwLayers[index];
1017 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1018 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1019 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1020 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1021
1022 // Store & update w, h, format of PTOR layer
1023 private_handle_t *hnd = (private_handle_t *)layer->handle;
1024 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1025 layerWhf[j] = whf;
1026 hnd->width = renderBuf->width;
1027 hnd->height = renderBuf->height;
1028 hnd->format = renderBuf->format;
1029
Xu Yangcda012c2014-07-30 21:57:21 +08001030 // Store & update blending mode, planeAlpha and transform of PTOR layer
1031 blending[j] = layer->blending;
1032 planeAlpha[j] = layer->planeAlpha;
1033 transform[j] = layer->transform;
1034 layer->blending = HWC_BLENDING_NONE;
1035 layer->planeAlpha = 0xFF;
1036 layer->transform = 0;
1037
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001038 // Remove overlap from crop & displayFrame of below layers
1039 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001040 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001041 if(!isValidRect(getIntersection(layer->displayFrame,
1042 overlapRect[j]))) {
1043 continue;
1044 }
1045 // Update layer attributes
1046 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1047 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301048 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001049 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1050 layer->transform);
1051 layer->sourceCropf.left = (float)srcCrop.left;
1052 layer->sourceCropf.top = (float)srcCrop.top;
1053 layer->sourceCropf.right = (float)srcCrop.right;
1054 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1055 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001056 }
1057
1058 mCurrentFrame.mdpCount = numAppLayers;
1059 mCurrentFrame.fbCount = 0;
1060 mCurrentFrame.fbZ = -1;
1061
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301062 for (int j = 0; j < numAppLayers; j++) {
1063 if(isValidRect(list->hwLayers[j].displayFrame)) {
1064 mCurrentFrame.isFBComposed[j] = false;
1065 } else {
1066 mCurrentFrame.mdpCount--;
1067 mCurrentFrame.drop[j] = true;
1068 }
1069 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001070
1071 bool result = postHeuristicsHandling(ctx, list);
1072
1073 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001074 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001075 hwc_layer_1_t* layer = &list->hwLayers[i];
1076 layer->displayFrame = displayFrame[i];
1077 layer->sourceCropf.left = (float)sourceCrop[i].left;
1078 layer->sourceCropf.top = (float)sourceCrop[i].top;
1079 layer->sourceCropf.right = (float)sourceCrop[i].right;
1080 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1081 }
1082
Xu Yangcda012c2014-07-30 21:57:21 +08001083 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001084 for (int i = 0; i < numPTORLayersFound; i++) {
1085 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001086 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001087 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1088 hnd->width = layerWhf[i].w;
1089 hnd->height = layerWhf[i].h;
1090 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001091 layer->blending = blending[i];
1092 layer->planeAlpha = planeAlpha[i];
1093 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001094 }
1095
Sushil Chauhandefd3522014-05-13 18:17:12 -07001096 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001097 // reset PTOR
1098 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001099 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001100 } else {
1101 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1102 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001103 }
1104
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001105 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1106 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001107 return result;
1108}
1109
Saurabh Shahaa236822013-04-24 18:07:26 -07001110bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1111{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001112 if(!sEnableMixedMode) {
1113 //Mixed mode is disabled. No need to even try caching.
1114 return false;
1115 }
1116
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001117 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001118 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001119 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001120 cacheBasedComp(ctx, list);
1121 } else {
1122 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001123 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001124 }
1125
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001126 return ret;
1127}
1128
1129bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1130 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001131 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1132 return false;
1133
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001134 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001135 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001136 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001137
1138 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1139 for(int i = 0; i < numAppLayers; i++) {
1140 if(!mCurrentFrame.isFBComposed[i]) {
1141 hwc_layer_1_t* layer = &list->hwLayers[i];
1142 if(not isSupportedForMDPComp(ctx, layer)) {
1143 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1144 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001145 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001146 return false;
1147 }
1148 }
1149 }
1150
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001151 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001152 /* mark secure RGB layers for MDP comp */
1153 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301154 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001155 if(!ret) {
1156 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001157 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001158 return false;
1159 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001160
1161 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001162
Raj Kamal389d6e32014-08-04 14:43:24 +05301163 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001164 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301165 }
1166
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001167 if(!postHeuristicsHandling(ctx, list)) {
1168 ALOGD_IF(isDebug(), "post heuristic handling failed");
1169 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001170 return false;
1171 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001172 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1173 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001174
Saurabh Shahaa236822013-04-24 18:07:26 -07001175 return true;
1176}
1177
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001178bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001179 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001180 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1181 return false;
1182
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001183 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001184 return false;
1185 }
1186
Saurabh Shahb772ae32013-11-18 15:40:02 -08001187 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001188 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1189 const int stagesForMDP = min(sMaxPipesPerMixer,
1190 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001191
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001192 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1193 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1194 int lastMDPSupportedIndex = numAppLayers;
1195 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001196
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001197 //Find the minimum MDP batch size
1198 for(int i = 0; i < numAppLayers;i++) {
1199 if(mCurrentFrame.drop[i]) {
1200 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001201 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001202 }
1203 hwc_layer_1_t* layer = &list->hwLayers[i];
1204 if(not isSupportedForMDPComp(ctx, layer)) {
1205 lastMDPSupportedIndex = i;
1206 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1207 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001208 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001209 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001210 }
1211
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001212 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1213 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1214 mCurrentFrame.dropCount);
1215
1216 //Start at a point where the fb batch should at least have 2 layers, for
1217 //this mode to be justified.
1218 while(fbBatchSize < 2) {
1219 ++fbBatchSize;
1220 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001221 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001222
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001223 //If there are no layers for MDP, this mode doesnt make sense.
1224 if(mdpBatchSize < 1) {
1225 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1226 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001227 return false;
1228 }
1229
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001230 mCurrentFrame.reset(numAppLayers);
1231
1232 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1233 while(mdpBatchSize > 0) {
1234 //Mark layers for MDP comp
1235 int mdpBatchLeft = mdpBatchSize;
1236 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1237 if(mCurrentFrame.drop[i]) {
1238 continue;
1239 }
1240 mCurrentFrame.isFBComposed[i] = false;
1241 --mdpBatchLeft;
1242 }
1243
1244 mCurrentFrame.fbZ = mdpBatchSize;
1245 mCurrentFrame.fbCount = fbBatchSize;
1246 mCurrentFrame.mdpCount = mdpBatchSize;
1247
1248 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1249 __FUNCTION__, mdpBatchSize, fbBatchSize,
1250 mCurrentFrame.dropCount);
1251
1252 if(postHeuristicsHandling(ctx, list)) {
1253 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001254 __FUNCTION__);
1255 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1256 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001257 return true;
1258 }
1259
1260 reset(ctx);
1261 --mdpBatchSize;
1262 ++fbBatchSize;
1263 }
1264
1265 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001266}
1267
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001268bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301269 if(mDpy or isSecurePresent(ctx, mDpy) or
1270 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001271 return false;
1272 }
1273 return true;
1274}
1275
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001276bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1277 hwc_display_contents_1_t* list){
1278 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1279 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1280 mDpy ) {
1281 return false;
1282 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001283 if(ctx->listStats[mDpy].secureUI)
1284 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001285 return true;
1286}
1287
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001288bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1289 hwc_display_contents_1_t* list) {
1290 const bool secureOnly = true;
1291 return videoOnlyComp(ctx, list, not secureOnly) or
1292 videoOnlyComp(ctx, list, secureOnly);
1293}
1294
1295bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001296 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001297 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1298 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001299 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001300
Saurabh Shahaa236822013-04-24 18:07:26 -07001301 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001302 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001303 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001304 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001305
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001306 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1307 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001308 return false;
1309 }
1310
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001311 /* Bail out if we are processing only secured video layers
1312 * and we dont have any */
1313 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001314 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001315 return false;
1316 }
1317
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001318 if(mCurrentFrame.fbCount)
1319 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001320
Raj Kamal389d6e32014-08-04 14:43:24 +05301321 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001322 adjustForSourceSplit(ctx, list);
1323 }
1324
1325 if(!postHeuristicsHandling(ctx, list)) {
1326 ALOGD_IF(isDebug(), "post heuristic handling failed");
1327 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001328 return false;
1329 }
1330
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001331 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1332 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001333 return true;
1334}
1335
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001336/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1337bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1338 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001339 // Fall back to video only composition, if AIV video mode is enabled
1340 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001341 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1342 __FUNCTION__, mDpy);
1343 return false;
1344 }
1345
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001346 const bool secureOnly = true;
1347 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1348 mdpOnlyLayersComp(ctx, list, secureOnly);
1349
1350}
1351
1352bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1353 hwc_display_contents_1_t* list, bool secureOnly) {
1354
1355 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1356 return false;
1357
1358 /* Bail out if we are processing only secured video layers
1359 * and we dont have any */
1360 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1361 reset(ctx);
1362 return false;
1363 }
1364
1365 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1366 mCurrentFrame.reset(numAppLayers);
1367 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1368
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001369 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001370 /* mark secure RGB layers for MDP comp */
1371 updateSecureRGB(ctx, list);
1372
1373 if(mCurrentFrame.mdpCount == 0) {
1374 reset(ctx);
1375 return false;
1376 }
1377
1378 /* find the maximum batch of layers to be marked for framebuffer */
1379 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1380 if(!ret) {
1381 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1382 reset(ctx);
1383 return false;
1384 }
1385
1386 if(sEnableYUVsplit){
1387 adjustForSourceSplit(ctx, list);
1388 }
1389
1390 if(!postHeuristicsHandling(ctx, list)) {
1391 ALOGD_IF(isDebug(), "post heuristic handling failed");
1392 reset(ctx);
1393 return false;
1394 }
1395
1396 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1397 __FUNCTION__);
1398 return true;
1399}
1400
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001401/* Checks for conditions where YUV layers cannot be bypassed */
1402bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001403 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001404 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001405 return false;
1406 }
1407
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001408 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001409 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1410 return false;
1411 }
1412
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001413 if(isSecuring(ctx, layer)) {
1414 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1415 return false;
1416 }
1417
Saurabh Shah4fdde762013-04-30 18:47:33 -07001418 if(!isValidDimension(ctx, layer)) {
1419 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1420 __FUNCTION__);
1421 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001422 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001423
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001424 if(layer->planeAlpha < 0xFF) {
1425 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1426 in video only mode",
1427 __FUNCTION__);
1428 return false;
1429 }
1430
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001431 return true;
1432}
1433
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001434/* Checks for conditions where Secure RGB layers cannot be bypassed */
1435bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1436 if(isSkipLayer(layer)) {
1437 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1438 __FUNCTION__, mDpy);
1439 return false;
1440 }
1441
1442 if(isSecuring(ctx, layer)) {
1443 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1444 return false;
1445 }
1446
1447 if(not isSupportedForMDPComp(ctx, layer)) {
1448 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1449 __FUNCTION__);
1450 return false;
1451 }
1452 return true;
1453}
1454
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301455/* starts at fromIndex and check for each layer to find
1456 * if it it has overlapping with any Updating layer above it in zorder
1457 * till the end of the batch. returns true if it finds any intersection */
1458bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1459 int fromIndex, int toIndex) {
1460 for(int i = fromIndex; i < toIndex; i++) {
1461 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1462 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1463 return false;
1464 }
1465 }
1466 }
1467 return true;
1468}
1469
1470/* Checks if given layer at targetLayerIndex has any
1471 * intersection with all the updating layers in beween
1472 * fromIndex and toIndex. Returns true if it finds intersectiion */
1473bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1474 int fromIndex, int toIndex, int targetLayerIndex) {
1475 for(int i = fromIndex; i <= toIndex; i++) {
1476 if(!mCurrentFrame.isFBComposed[i]) {
1477 if(areLayersIntersecting(&list->hwLayers[i],
1478 &list->hwLayers[targetLayerIndex])) {
1479 return true;
1480 }
1481 }
1482 }
1483 return false;
1484}
1485
1486int MDPComp::getBatch(hwc_display_contents_1_t* list,
1487 int& maxBatchStart, int& maxBatchEnd,
1488 int& maxBatchCount) {
1489 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301490 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001491 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301492 while (i < mCurrentFrame.layerCount) {
1493 int batchCount = 0;
1494 int batchStart = i;
1495 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001496 /* Adjust batch Z order with the dropped layers so far */
1497 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301498 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301499 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301500 while(i < mCurrentFrame.layerCount) {
1501 if(!mCurrentFrame.isFBComposed[i]) {
1502 if(!batchCount) {
1503 i++;
1504 break;
1505 }
1506 updatingLayersAbove++;
1507 i++;
1508 continue;
1509 } else {
1510 if(mCurrentFrame.drop[i]) {
1511 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001512 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301513 continue;
1514 } else if(updatingLayersAbove <= 0) {
1515 batchCount++;
1516 batchEnd = i;
1517 i++;
1518 continue;
1519 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1520
1521 // We have a valid updating layer already. If layer-i not
1522 // have overlapping with all updating layers in between
1523 // batch-start and i, then we can add layer i to batch.
1524 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1525 batchCount++;
1526 batchEnd = i;
1527 i++;
1528 continue;
1529 } else if(canPushBatchToTop(list, batchStart, i)) {
1530 //If All the non-updating layers with in this batch
1531 //does not have intersection with the updating layers
1532 //above in z-order, then we can safely move the batch to
1533 //higher z-order. Increment fbZ as it is moving up.
1534 if( firstZReverseIndex < 0) {
1535 firstZReverseIndex = i;
1536 }
1537 batchCount++;
1538 batchEnd = i;
1539 fbZ += updatingLayersAbove;
1540 i++;
1541 updatingLayersAbove = 0;
1542 continue;
1543 } else {
1544 //both failed.start the loop again from here.
1545 if(firstZReverseIndex >= 0) {
1546 i = firstZReverseIndex;
1547 }
1548 break;
1549 }
1550 }
1551 }
1552 }
1553 if(batchCount > maxBatchCount) {
1554 maxBatchCount = batchCount;
1555 maxBatchStart = batchStart;
1556 maxBatchEnd = batchEnd;
1557 fbZOrder = fbZ;
1558 }
1559 }
1560 return fbZOrder;
1561}
1562
1563bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1564 hwc_display_contents_1_t* list) {
1565 /* Idea is to keep as many non-updating(cached) layers in FB and
1566 * send rest of them through MDP. This is done in 2 steps.
1567 * 1. Find the maximum contiguous batch of non-updating layers.
1568 * 2. See if we can improve this batch size for caching by adding
1569 * opaque layers around the batch, if they don't have
1570 * any overlapping with the updating layers in between.
1571 * NEVER mark an updating layer for caching.
1572 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001573
1574 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001575 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001576 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301577 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001578
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001579 /* Nothing is cached. No batching needed */
1580 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001581 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001582 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001583
1584 /* No MDP comp layers, try to use other comp modes */
1585 if(mCurrentFrame.mdpCount == 0) {
1586 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001587 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001588
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301589 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001590
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301591 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001592 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001593 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001594 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301595 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001596 if(!mCurrentFrame.drop[i]){
1597 //If an unsupported layer is being attempted to
1598 //be pulled out we should fail
1599 if(not isSupportedForMDPComp(ctx, layer)) {
1600 return false;
1601 }
1602 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001603 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001604 }
1605 }
1606
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301607 // update the frame data
1608 mCurrentFrame.fbZ = fbZ;
1609 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001610 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001611 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001612
1613 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301614 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001615
1616 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001617}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001618
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001619void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001620 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001621 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001622 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001623
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001624 for(int i = 0; i < numAppLayers; i++) {
1625 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001626 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001627 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001628 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001629 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001630 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001631 }
1632 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001633
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001634 frame.fbCount = fbCount;
1635 frame.mdpCount = frame.layerCount - frame.fbCount
1636 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001637
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001638 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1639 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001640}
1641
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001642// drop other non-AIV layers from external display list.
1643void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001644 hwc_display_contents_1_t* list) {
1645 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1646 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001647 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001648 mCurrentFrame.dropCount++;
1649 mCurrentFrame.drop[i] = true;
1650 }
1651 }
1652 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1653 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1654 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1655 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1656 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1657 mCurrentFrame.dropCount);
1658}
1659
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001660void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001661 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001662 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1663 for(int index = 0;index < nYuvCount; index++){
1664 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1665 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1666
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001667 if(mCurrentFrame.drop[nYuvIndex]) {
1668 continue;
1669 }
1670
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001671 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001672 if(!frame.isFBComposed[nYuvIndex]) {
1673 frame.isFBComposed[nYuvIndex] = true;
1674 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001675 }
1676 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001677 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001678 private_handle_t *hnd = (private_handle_t *)layer->handle;
1679 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001680 frame.isFBComposed[nYuvIndex] = false;
1681 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001682 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001683 }
1684 }
1685 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001686
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001687 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1688 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001689}
1690
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001691void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1692 hwc_display_contents_1_t* list) {
1693 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1694 for(int index = 0;index < nSecureRGBCount; index++){
1695 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1696 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1697
1698 if(!isSecureRGBDoable(ctx, layer)) {
1699 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1700 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1701 mCurrentFrame.fbCount++;
1702 }
1703 } else {
1704 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1705 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1706 mCurrentFrame.fbCount--;
1707 }
1708 }
1709 }
1710
1711 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1712 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1713 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1714 mCurrentFrame.fbCount);
1715}
1716
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001717hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1718 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001719 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001720
1721 /* Update only the region of FB needed for composition */
1722 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1723 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1724 hwc_layer_1_t* layer = &list->hwLayers[i];
1725 hwc_rect_t dst = layer->displayFrame;
1726 fbRect = getUnion(fbRect, dst);
1727 }
1728 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001729 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001730 return fbRect;
1731}
1732
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001733bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1734 hwc_display_contents_1_t* list) {
1735
1736 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001737 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001738 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1739 return false;
1740 }
1741
1742 //Limitations checks
1743 if(!hwLimitationsCheck(ctx, list)) {
1744 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1745 return false;
1746 }
1747
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001748 //Configure framebuffer first if applicable
1749 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001750 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001751 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1752 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001753 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1754 __FUNCTION__);
1755 return false;
1756 }
1757 }
1758
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001759 mCurrentFrame.map();
1760
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001761 if(!allocLayerPipes(ctx, list)) {
1762 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001763 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001764 }
1765
1766 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001767 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001768 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001769 int mdpIndex = mCurrentFrame.layerToMDP[index];
1770 hwc_layer_1_t* layer = &list->hwLayers[index];
1771
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301772 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1773 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1774 mdpNextZOrder++;
1775 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001776 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1777 cur_pipe->zOrder = mdpNextZOrder++;
1778
radhakrishnac9a67412013-09-25 17:40:42 +05301779 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301780 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301781 if(configure4k2kYuv(ctx, layer,
1782 mCurrentFrame.mdpToLayer[mdpIndex])
1783 != 0 ){
1784 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1785 for layer %d",__FUNCTION__, index);
1786 return false;
1787 }
1788 else{
1789 mdpNextZOrder++;
1790 }
1791 continue;
1792 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001793 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1794 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301795 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001796 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001797 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001798 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001799 }
1800
Saurabh Shaha36be922013-12-16 18:18:39 -08001801 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1802 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1803 ,__FUNCTION__, mDpy);
1804 return false;
1805 }
1806
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001807 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001808 return true;
1809}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001810
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001811bool MDPComp::resourceCheck(hwc_context_t* ctx,
1812 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001813 const bool fbUsed = mCurrentFrame.fbCount;
1814 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1815 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1816 return false;
1817 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001818
1819 //Will benefit cases where a video has non-updating background.
1820 if((mDpy > HWC_DISPLAY_PRIMARY) and
1821 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1822 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1823 return false;
1824 }
1825
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001826 // Init rotCount to number of rotate sessions used by other displays
1827 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1828 // Count the number of rotator sessions required for current display
1829 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1830 if(!mCurrentFrame.isFBComposed[index]) {
1831 hwc_layer_1_t* layer = &list->hwLayers[index];
1832 private_handle_t *hnd = (private_handle_t *)layer->handle;
1833 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1834 rotCount++;
1835 }
1836 }
1837 }
1838 // if number of layers to rotate exceeds max rotator sessions, bail out.
1839 if(rotCount > RotMgr::MAX_ROT_SESS) {
1840 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1841 __FUNCTION__, mDpy);
1842 return false;
1843 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001844 return true;
1845}
1846
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301847bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1848 hwc_display_contents_1_t* list) {
1849
1850 //A-family hw limitation:
1851 //If a layer need alpha scaling, MDP can not support.
1852 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1853 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1854 if(!mCurrentFrame.isFBComposed[i] &&
1855 isAlphaScaled( &list->hwLayers[i])) {
1856 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1857 return false;
1858 }
1859 }
1860 }
1861
1862 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1863 //If multiple layers requires downscaling and also they are overlapping
1864 //fall back to GPU since MDSS can not handle it.
1865 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1866 qdutils::MDPVersion::getInstance().is8x26()) {
1867 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1868 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1869 if(!mCurrentFrame.isFBComposed[i] &&
1870 isDownscaleRequired(botLayer)) {
1871 //if layer-i is marked for MDP and needs downscaling
1872 //check if any MDP layer on top of i & overlaps with layer-i
1873 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1874 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1875 if(!mCurrentFrame.isFBComposed[j] &&
1876 isDownscaleRequired(topLayer)) {
1877 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1878 topLayer->displayFrame);
1879 if(isValidRect(r))
1880 return false;
1881 }
1882 }
1883 }
1884 }
1885 }
1886 return true;
1887}
1888
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001889int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001890 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001891 char property[PROPERTY_VALUE_MAX];
1892
Raj Kamal4393eaa2014-06-06 13:45:20 +05301893 if(!ctx || !list) {
1894 ALOGE("%s: Invalid context or list",__FUNCTION__);
1895 mCachedFrame.reset();
1896 return -1;
1897 }
1898
1899 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001900 if(mDpy == HWC_DISPLAY_PRIMARY) {
1901 sSimulationFlags = 0;
1902 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1903 int currentFlags = atoi(property);
1904 if(currentFlags != sSimulationFlags) {
1905 sSimulationFlags = currentFlags;
1906 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1907 sSimulationFlags, sSimulationFlags);
1908 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001909 }
1910 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001911 // reset PTOR
1912 if(!mDpy)
1913 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001914
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301915 //Do not cache the information for next draw cycle.
1916 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1917 ALOGI("%s: Unsupported layer count for mdp composition",
1918 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001919 mCachedFrame.reset();
1920 return -1;
1921 }
1922
Saurabh Shahb39f8152013-08-22 10:21:44 -07001923 //reset old data
1924 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001925 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1926 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301927
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001928 // Detect the start of animation and fall back to GPU only once to cache
1929 // all the layers in FB and display FB content untill animation completes.
1930 if(ctx->listStats[mDpy].isDisplayAnimating) {
1931 mCurrentFrame.needsRedraw = false;
1932 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1933 mCurrentFrame.needsRedraw = true;
1934 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1935 }
1936 setMDPCompLayerFlags(ctx, list);
1937 mCachedFrame.updateCounts(mCurrentFrame);
1938 ret = -1;
1939 return ret;
1940 } else {
1941 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1942 }
1943
Saurabh Shahb39f8152013-08-22 10:21:44 -07001944 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001945 if(isFrameDoable(ctx)) {
1946 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001947 // if AIV Video mode is enabled, drop all non AIV layers from the
1948 // external display list.
1949 if(ctx->listStats[mDpy].mAIVVideoMode) {
1950 dropNonAIVLayers(ctx, list);
1951 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001952
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001953 // if tryFullFrame fails, try to push all video and secure RGB layers
1954 // to MDP for composition.
1955 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001956 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301957 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001958 setMDPCompLayerFlags(ctx, list);
1959 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001960 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001961 reset(ctx);
1962 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1963 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001964 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001965 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1966 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001967 }
1968 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05301969 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
1970 enablePartialUpdateForMDP3) {
1971 generateROI(ctx, list);
1972 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
1973 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
1974 }
1975 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001976 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1977 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001978 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001979 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001980
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001981 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001982 ALOGD("GEOMETRY change: %d",
1983 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001984 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001985 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001986 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001987 }
1988
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001989#ifdef DYNAMIC_FPS
1990 //For primary display, set the dynamic refreshrate
1991 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported()) {
1992 FrameInfo frame;
1993 frame.reset(mCurrentFrame.layerCount);
Raj Kamal18e946e2014-10-10 14:23:47 +05301994 memset(&frame.drop, 0, sizeof(frame.drop));
1995 frame.dropCount = 0;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001996 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
1997 __FUNCTION__);
1998 updateLayerCache(ctx, list, frame);
1999 updateYUV(ctx, list, false /*secure only*/, frame);
2000 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
2001 //Set the new fresh rate, if there is only one updating YUV layer
2002 //or there is one single RGB layer with this request
2003 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
2004 (frame.layerCount == 1)) {
2005 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
2006 }
2007 setRefreshRate(ctx, mDpy, refreshRate);
2008 }
2009#endif
2010
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002011 mCachedFrame.cacheAll(list);
2012 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002013 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002014}
2015
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002016bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302017
2018 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302019 int mdpIndex = mCurrentFrame.layerToMDP[index];
2020 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2021 info.pipeInfo = new MdpYUVPipeInfo;
2022 info.rot = NULL;
2023 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302024
2025 pipe_info.lIndex = ovutils::OV_INVALID;
2026 pipe_info.rIndex = ovutils::OV_INVALID;
2027
Saurabh Shahc62f3982014-03-05 14:28:26 -08002028 Overlay::PipeSpecs pipeSpecs;
2029 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2030 pipeSpecs.needsScaling = true;
2031 pipeSpecs.dpy = mDpy;
2032 pipeSpecs.fb = false;
2033
2034 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302035 if(pipe_info.lIndex == ovutils::OV_INVALID){
2036 bRet = false;
2037 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2038 __FUNCTION__);
2039 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002040 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302041 if(pipe_info.rIndex == ovutils::OV_INVALID){
2042 bRet = false;
2043 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2044 __FUNCTION__);
2045 }
2046 return bRet;
2047}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002048
2049int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2050 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002051 if (ctx->mPtorInfo.isActive()) {
2052 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002053 if (fd < 0) {
2054 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002055 }
2056 }
2057 return fd;
2058}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002059//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002060
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002061void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302062 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002063 //If 4k2k Yuv layer split is possible, and if
2064 //fbz is above 4k2k layer, increment fb zorder by 1
2065 //as we split 4k2k layer and increment zorder for right half
2066 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002067 if(!ctx)
2068 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002069 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302070 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2071 index++) {
2072 if(!mCurrentFrame.isFBComposed[index]) {
2073 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2074 mdpNextZOrder++;
2075 }
2076 mdpNextZOrder++;
2077 hwc_layer_1_t* layer = &list->hwLayers[index];
2078 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302079 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302080 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2081 mCurrentFrame.fbZ += 1;
2082 mdpNextZOrder++;
2083 //As we split 4kx2k yuv layer and program to 2 VG pipes
2084 //(if available) increase mdpcount by 1.
2085 mCurrentFrame.mdpCount++;
2086 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002087 }
2088 }
2089 }
radhakrishnac9a67412013-09-25 17:40:42 +05302090}
2091
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002092/*
2093 * Configures pipe(s) for MDP composition
2094 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002095int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002096 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002097 MdpPipeInfoNonSplit& mdp_info =
2098 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302099 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002100 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002101 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002102
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002103 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2104 __FUNCTION__, layer, zOrder, dest);
2105
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002106 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002107 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002108}
2109
Saurabh Shah88e4d272013-09-03 13:31:29 -07002110bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002111 hwc_display_contents_1_t* list) {
2112 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002113
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002114 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002115
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002116 hwc_layer_1_t* layer = &list->hwLayers[index];
2117 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302118 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002119 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302120 continue;
2121 }
2122 }
2123
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002124 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002125 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002126 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002127 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002128 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002129
Saurabh Shahc62f3982014-03-05 14:28:26 -08002130 Overlay::PipeSpecs pipeSpecs;
2131 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2132 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2133 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2134 (qdutils::MDPVersion::getInstance().is8x26() and
2135 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2136 pipeSpecs.dpy = mDpy;
2137 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002138 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002139
Saurabh Shahc62f3982014-03-05 14:28:26 -08002140 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2141
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002142 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002143 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002144 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002145 }
2146 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002147 return true;
2148}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002149
radhakrishnac9a67412013-09-25 17:40:42 +05302150int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2151 PipeLayerPair& PipeLayerPair) {
2152 MdpYUVPipeInfo& mdp_info =
2153 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2154 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302155 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302156 eDest lDest = mdp_info.lIndex;
2157 eDest rDest = mdp_info.rIndex;
2158
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002159 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302160 lDest, rDest, &PipeLayerPair.rot);
2161}
2162
Saurabh Shah88e4d272013-09-03 13:31:29 -07002163bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002164
Raj Kamal4393eaa2014-06-06 13:45:20 +05302165 if(!isEnabled() or !mModeOn) {
2166 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302167 return true;
2168 }
2169
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002170 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002171 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002172 sHandleTimeout = true;
2173 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002174
2175 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002176 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002177
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002178 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2179 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002180 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002181 if(mCurrentFrame.isFBComposed[i]) continue;
2182
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002183 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002184 private_handle_t *hnd = (private_handle_t *)layer->handle;
2185 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002186 if (!(layer->flags & HWC_COLOR_FILL)) {
2187 ALOGE("%s handle null", __FUNCTION__);
2188 return false;
2189 }
2190 // No PLAY for Color layer
2191 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2192 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002193 }
2194
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002195 int mdpIndex = mCurrentFrame.layerToMDP[i];
2196
Raj Kamal389d6e32014-08-04 14:43:24 +05302197 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302198 {
2199 MdpYUVPipeInfo& pipe_info =
2200 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2201 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2202 ovutils::eDest indexL = pipe_info.lIndex;
2203 ovutils::eDest indexR = pipe_info.rIndex;
2204 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302205 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302206 if(rot) {
2207 rot->queueBuffer(fd, offset);
2208 fd = rot->getDstMemId();
2209 offset = rot->getDstOffset();
2210 }
2211 if(indexL != ovutils::OV_INVALID) {
2212 ovutils::eDest destL = (ovutils::eDest)indexL;
2213 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2214 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2215 if (!ov.queueBuffer(fd, offset, destL)) {
2216 ALOGE("%s: queueBuffer failed for display:%d",
2217 __FUNCTION__, mDpy);
2218 return false;
2219 }
2220 }
2221
2222 if(indexR != ovutils::OV_INVALID) {
2223 ovutils::eDest destR = (ovutils::eDest)indexR;
2224 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2225 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2226 if (!ov.queueBuffer(fd, offset, destR)) {
2227 ALOGE("%s: queueBuffer failed for display:%d",
2228 __FUNCTION__, mDpy);
2229 return false;
2230 }
2231 }
2232 }
2233 else{
2234 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002235 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302236 ovutils::eDest dest = pipe_info.index;
2237 if(dest == ovutils::OV_INVALID) {
2238 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002239 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302240 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002241
radhakrishnac9a67412013-09-25 17:40:42 +05302242 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2243 continue;
2244 }
2245
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002246 int fd = hnd->fd;
2247 uint32_t offset = (uint32_t)hnd->offset;
2248 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2249 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002250 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002251 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002252 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002253 }
2254
radhakrishnac9a67412013-09-25 17:40:42 +05302255 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2256 using pipe: %d", __FUNCTION__, layer,
2257 hnd, dest );
2258
radhakrishnac9a67412013-09-25 17:40:42 +05302259 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2260 if(rot) {
2261 if(!rot->queueBuffer(fd, offset))
2262 return false;
2263 fd = rot->getDstMemId();
2264 offset = rot->getDstOffset();
2265 }
2266
2267 if (!ov.queueBuffer(fd, offset, dest)) {
2268 ALOGE("%s: queueBuffer failed for display:%d ",
2269 __FUNCTION__, mDpy);
2270 return false;
2271 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002272 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002273
2274 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002275 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002276 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002277}
2278
Saurabh Shah88e4d272013-09-03 13:31:29 -07002279//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002280
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002281void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302282 hwc_display_contents_1_t* list){
2283 //if 4kx2k yuv layer is totally present in either in left half
2284 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302285 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302286 if(mCurrentFrame.fbZ >= 0) {
2287 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2288 index++) {
2289 if(!mCurrentFrame.isFBComposed[index]) {
2290 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2291 mdpNextZOrder++;
2292 }
2293 mdpNextZOrder++;
2294 hwc_layer_1_t* layer = &list->hwLayers[index];
2295 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302296 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302297 hwc_rect_t dst = layer->displayFrame;
2298 if((dst.left > lSplit) || (dst.right < lSplit)) {
2299 mCurrentFrame.mdpCount += 1;
2300 }
2301 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2302 mCurrentFrame.fbZ += 1;
2303 mdpNextZOrder++;
2304 }
2305 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002306 }
radhakrishnac9a67412013-09-25 17:40:42 +05302307 }
2308}
2309
Saurabh Shah88e4d272013-09-03 13:31:29 -07002310bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002311 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002312
Saurabh Shahc62f3982014-03-05 14:28:26 -08002313 const int lSplit = getLeftSplit(ctx, mDpy);
2314 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002315 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002316 pipe_info.lIndex = ovutils::OV_INVALID;
2317 pipe_info.rIndex = ovutils::OV_INVALID;
2318
Saurabh Shahc62f3982014-03-05 14:28:26 -08002319 Overlay::PipeSpecs pipeSpecs;
2320 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2321 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2322 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2323 pipeSpecs.dpy = mDpy;
2324 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2325 pipeSpecs.fb = false;
2326
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002327 // Acquire pipe only for the updating half
2328 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2329 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2330
2331 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002332 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002333 if(pipe_info.lIndex == ovutils::OV_INVALID)
2334 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002335 }
2336
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002337 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002338 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2339 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002340 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002341 return false;
2342 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002343
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002344 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002345}
2346
Saurabh Shah88e4d272013-09-03 13:31:29 -07002347bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002348 hwc_display_contents_1_t* list) {
2349 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002350
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002351 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002352
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002353 hwc_layer_1_t* layer = &list->hwLayers[index];
2354 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302355 hwc_rect_t dst = layer->displayFrame;
2356 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302357 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302358 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002359 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302360 continue;
2361 }
2362 }
2363 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002364 int mdpIndex = mCurrentFrame.layerToMDP[index];
2365 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002366 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002367 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002368 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002369
Saurabh Shahc62f3982014-03-05 14:28:26 -08002370 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2371 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2372 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002373 return false;
2374 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002375 }
2376 return true;
2377}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002378
radhakrishnac9a67412013-09-25 17:40:42 +05302379int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2380 PipeLayerPair& PipeLayerPair) {
2381 const int lSplit = getLeftSplit(ctx, mDpy);
2382 hwc_rect_t dst = layer->displayFrame;
2383 if((dst.left > lSplit)||(dst.right < lSplit)){
2384 MdpYUVPipeInfo& mdp_info =
2385 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2386 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302387 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302388 eDest lDest = mdp_info.lIndex;
2389 eDest rDest = mdp_info.rIndex;
2390
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002391 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302392 lDest, rDest, &PipeLayerPair.rot);
2393 }
2394 else{
2395 return configure(ctx, layer, PipeLayerPair);
2396 }
2397}
2398
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002399/*
2400 * Configures pipe(s) for MDP composition
2401 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002402int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002403 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002404 MdpPipeInfoSplit& mdp_info =
2405 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002406 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302407 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002408 eDest lDest = mdp_info.lIndex;
2409 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002410
2411 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2412 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2413
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002414 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002415 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002416}
2417
Saurabh Shah88e4d272013-09-03 13:31:29 -07002418bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002419
Raj Kamal4393eaa2014-06-06 13:45:20 +05302420 if(!isEnabled() or !mModeOn) {
2421 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302422 return true;
2423 }
2424
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002425 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002426 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002427 sHandleTimeout = true;
2428 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002429
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002430 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002431 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002432
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002433 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2434 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002435 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002436 if(mCurrentFrame.isFBComposed[i]) continue;
2437
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002438 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002439 private_handle_t *hnd = (private_handle_t *)layer->handle;
2440 if(!hnd) {
2441 ALOGE("%s handle null", __FUNCTION__);
2442 return false;
2443 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002444
2445 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2446 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002447 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002448
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002449 int mdpIndex = mCurrentFrame.layerToMDP[i];
2450
Raj Kamal389d6e32014-08-04 14:43:24 +05302451 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302452 {
2453 MdpYUVPipeInfo& pipe_info =
2454 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2455 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2456 ovutils::eDest indexL = pipe_info.lIndex;
2457 ovutils::eDest indexR = pipe_info.rIndex;
2458 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302459 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302460 if(rot) {
2461 rot->queueBuffer(fd, offset);
2462 fd = rot->getDstMemId();
2463 offset = rot->getDstOffset();
2464 }
2465 if(indexL != ovutils::OV_INVALID) {
2466 ovutils::eDest destL = (ovutils::eDest)indexL;
2467 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2468 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2469 if (!ov.queueBuffer(fd, offset, destL)) {
2470 ALOGE("%s: queueBuffer failed for display:%d",
2471 __FUNCTION__, mDpy);
2472 return false;
2473 }
2474 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002475
radhakrishnac9a67412013-09-25 17:40:42 +05302476 if(indexR != ovutils::OV_INVALID) {
2477 ovutils::eDest destR = (ovutils::eDest)indexR;
2478 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2479 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2480 if (!ov.queueBuffer(fd, offset, destR)) {
2481 ALOGE("%s: queueBuffer failed for display:%d",
2482 __FUNCTION__, mDpy);
2483 return false;
2484 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002485 }
2486 }
radhakrishnac9a67412013-09-25 17:40:42 +05302487 else{
2488 MdpPipeInfoSplit& pipe_info =
2489 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2490 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002491
radhakrishnac9a67412013-09-25 17:40:42 +05302492 ovutils::eDest indexL = pipe_info.lIndex;
2493 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002494
radhakrishnac9a67412013-09-25 17:40:42 +05302495 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002496 uint32_t offset = (uint32_t)hnd->offset;
2497 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2498 if (!mDpy && (index != -1)) {
2499 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2500 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002501 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002502 }
radhakrishnac9a67412013-09-25 17:40:42 +05302503
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002504 if(ctx->mAD->draw(ctx, fd, offset)) {
2505 fd = ctx->mAD->getDstFd();
2506 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002507 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002508
radhakrishnac9a67412013-09-25 17:40:42 +05302509 if(rot) {
2510 rot->queueBuffer(fd, offset);
2511 fd = rot->getDstMemId();
2512 offset = rot->getDstOffset();
2513 }
2514
2515 //************* play left mixer **********
2516 if(indexL != ovutils::OV_INVALID) {
2517 ovutils::eDest destL = (ovutils::eDest)indexL;
2518 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2519 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2520 if (!ov.queueBuffer(fd, offset, destL)) {
2521 ALOGE("%s: queueBuffer failed for left mixer",
2522 __FUNCTION__);
2523 return false;
2524 }
2525 }
2526
2527 //************* play right mixer **********
2528 if(indexR != ovutils::OV_INVALID) {
2529 ovutils::eDest destR = (ovutils::eDest)indexR;
2530 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2531 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2532 if (!ov.queueBuffer(fd, offset, destR)) {
2533 ALOGE("%s: queueBuffer failed for right mixer",
2534 __FUNCTION__);
2535 return false;
2536 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002537 }
2538 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002539
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002540 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2541 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002542
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002543 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002544}
Saurabh Shahab47c692014-02-12 18:45:57 -08002545
2546//================MDPCompSrcSplit==============================================
2547bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002548 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002549 private_handle_t *hnd = (private_handle_t *)layer->handle;
2550 hwc_rect_t dst = layer->displayFrame;
2551 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2552 pipe_info.lIndex = ovutils::OV_INVALID;
2553 pipe_info.rIndex = ovutils::OV_INVALID;
2554
2555 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2556 //should have a higher priority than the right one. Pipe priorities are
2557 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002558
Saurabh Shahc62f3982014-03-05 14:28:26 -08002559 Overlay::PipeSpecs pipeSpecs;
2560 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2561 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2562 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2563 pipeSpecs.dpy = mDpy;
2564 pipeSpecs.fb = false;
2565
Saurabh Shahab47c692014-02-12 18:45:57 -08002566 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002567 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002568 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002569 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002570 }
2571
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002572 /* Use 2 pipes IF
2573 a) Layer's crop width is > 2048 or
2574 b) Layer's dest width > 2048 or
2575 c) On primary, driver has indicated with caps to split always. This is
2576 based on an empirically derived value of panel height. Applied only
2577 if the layer's width is > mixer's width
2578 */
2579
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302580 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002581 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302582 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002583 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2584 const uint32_t dstWidth = dst.right - dst.left;
2585 const uint32_t dstHeight = dst.bottom - dst.top;
2586 const uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002587 crop.right - crop.left;
Saurabh Shah514759d2014-11-11 18:02:24 -08002588 const uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
2589 crop.bottom - crop.top;
2590 //Approximation to actual clock, ignoring the common factors in pipe and
2591 //mixer cases like line_time
2592 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2593 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002594
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002595 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2596 //pipe line length, we are still using 2 pipes. This is fine just because
2597 //this is source split where destination doesn't matter. Evaluate later to
2598 //see if going through all the calcs to save a pipe is worth it
Saurabh Shah514759d2014-11-11 18:02:24 -08002599 if(dstWidth > mdpHw.getMaxMixerWidth() or
2600 cropWidth > mdpHw.getMaxMixerWidth() or
2601 (primarySplitAlways and
2602 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002603 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002604 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002605 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002606 }
2607
2608 // Return values
2609 // 1 Left pipe is higher priority, do nothing.
2610 // 0 Pipes of same priority.
2611 //-1 Right pipe is of higher priority, needs swap.
2612 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2613 pipe_info.rIndex) == -1) {
2614 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002615 }
2616 }
2617
2618 return true;
2619}
2620
Saurabh Shahab47c692014-02-12 18:45:57 -08002621int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2622 PipeLayerPair& PipeLayerPair) {
2623 private_handle_t *hnd = (private_handle_t *)layer->handle;
2624 if(!hnd) {
2625 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2626 return -1;
2627 }
2628 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2629 MdpPipeInfoSplit& mdp_info =
2630 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2631 Rotator **rot = &PipeLayerPair.rot;
2632 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002633 eDest lDest = mdp_info.lIndex;
2634 eDest rDest = mdp_info.rIndex;
2635 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2636 hwc_rect_t dst = layer->displayFrame;
2637 int transform = layer->transform;
2638 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002639 int rotFlags = ROT_FLAGS_NONE;
2640 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2641 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2642
2643 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2644 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2645
2646 // Handle R/B swap
2647 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2648 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2649 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2650 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2651 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2652 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002653 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002654 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2655 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002656 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002657 /* Calculate the external display position based on MDP downscale,
2658 ActionSafe, and extorientation features. */
2659 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002660
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002661 int downscale = getRotDownscale(ctx, layer);
Justin Philipd6166602014-08-12 13:42:21 +05302662 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002663 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002664
2665 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2666 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002667 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002668 }
2669
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002670 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002671 (*rot) = ctx->mRotMgr->getNext();
2672 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002673 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002674 //If the video is using a single pipe, enable BWC
2675 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002676 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2677 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002678 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002679 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002680 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002681 ALOGE("%s: configRotator failed!", __FUNCTION__);
2682 return -1;
2683 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002684 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002685 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002686 }
2687
2688 //If 2 pipes being used, divide layer into half, crop and dst
2689 hwc_rect_t cropL = crop;
2690 hwc_rect_t cropR = crop;
2691 hwc_rect_t dstL = dst;
2692 hwc_rect_t dstR = dst;
2693 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2694 cropL.right = (crop.right + crop.left) / 2;
2695 cropR.left = cropL.right;
2696 sanitizeSourceCrop(cropL, cropR, hnd);
2697
Saurabh Shahb729b192014-08-15 18:04:24 -07002698 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002699 //Swap crops on H flip since 2 pipes are being used
2700 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2701 hwc_rect_t tmp = cropL;
2702 cropL = cropR;
2703 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002704 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002705 }
2706
Saurabh Shahb729b192014-08-15 18:04:24 -07002707 //cropSwap trick: If the src and dst widths are both odd, let us say
2708 //2507, then splitting both into half would cause left width to be 1253
2709 //and right 1254. If crop is swapped because of H flip, this will cause
2710 //left crop width to be 1254, whereas left dst width remains 1253, thus
2711 //inducing a scaling that is unaccounted for. To overcome that we add 1
2712 //to the dst width if there is a cropSwap. So if the original width was
2713 //2507, the left dst width will be 1254. Even if the original width was
2714 //even for ex: 2508, the left dst width will still remain 1254.
2715 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002716 dstR.left = dstL.right;
2717 }
2718
2719 //For the mdp, since either we are pre-rotating or MDP does flips
2720 orient = OVERLAY_TRANSFORM_0;
2721 transform = 0;
2722
2723 //configure left pipe
2724 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002725 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002726 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2727 (ovutils::eBlending) getBlending(layer->blending));
2728
2729 if(configMdp(ctx->mOverlay, pargL, orient,
2730 cropL, dstL, metadata, lDest) < 0) {
2731 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2732 return -1;
2733 }
2734 }
2735
2736 //configure right pipe
2737 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002738 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002739 static_cast<eRotFlags>(rotFlags),
2740 layer->planeAlpha,
2741 (ovutils::eBlending) getBlending(layer->blending));
2742 if(configMdp(ctx->mOverlay, pargR, orient,
2743 cropR, dstR, metadata, rDest) < 0) {
2744 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2745 return -1;
2746 }
2747 }
2748
2749 return 0;
2750}
2751
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002752}; //namespace
2753