blob: 1c390ef846cacc5b06c01308aa6202dc323d9941 [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;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800747
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700748 // Fall back to video only composition, if AIV video mode is enabled
749 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700750 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
751 __FUNCTION__, mDpy);
752 return false;
753 }
754
Praveena Pachipulusu47346c22014-12-04 11:06:41 +0530755 /* No Idle fall back if secure display or secure RGB layers are present
756 * or if there is only a single layer being composed */
757 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI &&
758 !ctx->listStats[mDpy].secureRGBCount &&
759 (ctx->listStats[mDpy].numAppLayers > 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700760 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
761 return false;
762 }
763
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800764 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700765 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
766 __FUNCTION__,
767 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800768 return false;
769 }
770
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700771 // if secondary is configuring or Padding round, fall back to video only
772 // composition and release all assigned non VIG pipes from primary.
773 if(isSecondaryConfiguring(ctx)) {
774 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
775 __FUNCTION__);
776 return false;
777 } else if(ctx->isPaddingRound) {
778 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
779 __FUNCTION__,mDpy);
780 return false;
781 }
782
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700783 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800784 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700785 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800786 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
787 return false;
788 }
789
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800790 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800791 hwc_layer_1_t* layer = &list->hwLayers[i];
792 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800793
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800794 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700795 if(!canUseRotator(ctx, mDpy)) {
796 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
797 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700798 return false;
799 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800800 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530801
802 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
803 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800804 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700805 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530806 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
807 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
808 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800809 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700810
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700811 if(ctx->mAD->isDoable()) {
812 return false;
813 }
814
Saurabh Shahaa236822013-04-24 18:07:26 -0700815 //If all above hard conditions are met we can do full or partial MDP comp.
816 bool ret = false;
817 if(fullMDPComp(ctx, list)) {
818 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700819 } else if(fullMDPCompWithPTOR(ctx, list)) {
820 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700821 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700822 ret = true;
823 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530824
Saurabh Shahaa236822013-04-24 18:07:26 -0700825 return ret;
826}
827
828bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700829
830 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
831 return false;
832
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700833 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
834 for(int i = 0; i < numAppLayers; i++) {
835 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700836 if(not mCurrentFrame.drop[i] and
837 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700838 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
839 return false;
840 }
841 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800842
Saurabh Shahaa236822013-04-24 18:07:26 -0700843 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700844 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
845 sizeof(mCurrentFrame.isFBComposed));
846 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
847 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700848
Raj Kamal389d6e32014-08-04 14:43:24 +0530849 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800850 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530851 }
852
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800853 if(!postHeuristicsHandling(ctx, list)) {
854 ALOGD_IF(isDebug(), "post heuristic handling failed");
855 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700856 return false;
857 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700858 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
859 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700860 return true;
861}
862
Sushil Chauhandefd3522014-05-13 18:17:12 -0700863/* Full MDP Composition with Peripheral Tiny Overlap Removal.
864 * MDP bandwidth limitations can be avoided, if the overlap region
865 * covered by the smallest layer at a higher z-order, gets composed
866 * by Copybit on a render buffer, which can be queued to MDP.
867 */
868bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
869 hwc_display_contents_1_t* list) {
870
871 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
872 const int stagesForMDP = min(sMaxPipesPerMixer,
873 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
874
875 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700876 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700877 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
878 return false;
879 }
880
881 // Frame level checks
882 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
883 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
884 isSecurePresent(ctx, mDpy)) {
885 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
886 return false;
887 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700888 // MDP comp checks
889 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700890 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700891 if(not isSupportedForMDPComp(ctx, layer)) {
892 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
893 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700894 }
895 }
896
Sushil Chauhandefd3522014-05-13 18:17:12 -0700897 /* We cannot use this composition mode, if:
898 1. A below layer needs scaling.
899 2. Overlap is not peripheral to display.
900 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700901 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700902 */
903
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700904 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
905 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
906 memset(overlapRect, 0, sizeof(overlapRect));
907 int layerPixelCount, minPixelCount = 0;
908 int numPTORLayersFound = 0;
909 for (int i = numAppLayers-1; (i >= 0 &&
910 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700911 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700912 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700913 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700914 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
915 // PTOR layer should be peripheral and cannot have transform
916 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
917 has90Transform(layer)) {
918 continue;
919 }
920 if((3 * (layerPixelCount + minPixelCount)) >
921 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
922 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
923 continue;
924 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700925 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700926 for (int j = i-1; j >= 0; j--) {
927 // Check if the layers below this layer qualifies for PTOR comp
928 hwc_layer_1_t* layer = &list->hwLayers[j];
929 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700930 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700931 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700932 if (isValidRect(getIntersection(dispFrame, disFrame))) {
933 if (has90Transform(layer) || needsScaling(layer)) {
934 found = false;
935 break;
936 }
937 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700938 }
939 }
940 // Store the minLayer Index
941 if(found) {
942 minLayerIndex[numPTORLayersFound] = i;
943 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
944 minPixelCount += layerPixelCount;
945 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700946 }
947 }
948
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700949 // No overlap layers
950 if (!numPTORLayersFound)
951 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700952
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700953 // Store the displayFrame and the sourceCrops of the layers
954 hwc_rect_t displayFrame[numAppLayers];
955 hwc_rect_t sourceCrop[numAppLayers];
956 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700957 hwc_layer_1_t* layer = &list->hwLayers[i];
958 displayFrame[i] = layer->displayFrame;
959 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700960 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700961
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530962 /**
963 * It's possible that 2 PTOR layers might have overlapping.
964 * In such case, remove the intersection(again if peripheral)
965 * from the lower PTOR layer to avoid overlapping.
966 * If intersection is not on peripheral then compromise
967 * by reducing number of PTOR layers.
968 **/
969 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
970 if(isValidRect(commonRect)) {
971 overlapRect[1] = deductRect(overlapRect[1], commonRect);
972 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
973 }
974
975 ctx->mPtorInfo.count = numPTORLayersFound;
976 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
977 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
978 }
979
980 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
981 // reset PTOR
982 ctx->mPtorInfo.count = 0;
983 if(isValidRect(commonRect)) {
984 // If PTORs are intersecting restore displayframe of PTOR[1]
985 // before returning, as we have modified it above.
986 list->hwLayers[minLayerIndex[1]].displayFrame =
987 displayFrame[minLayerIndex[1]];
988 }
989 return false;
990 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700991 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
992 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
993
Xu Yangcda012c2014-07-30 21:57:21 +0800994 // Store the blending mode, planeAlpha, and transform of PTOR layers
995 int32_t blending[numPTORLayersFound];
996 uint8_t planeAlpha[numPTORLayersFound];
997 uint32_t transform[numPTORLayersFound];
998
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700999 for(int j = 0; j < numPTORLayersFound; j++) {
1000 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001001
1002 // Update src crop of PTOR layer
1003 hwc_layer_1_t* layer = &list->hwLayers[index];
1004 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1005 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1006 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1007 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1008
1009 // Store & update w, h, format of PTOR layer
1010 private_handle_t *hnd = (private_handle_t *)layer->handle;
1011 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1012 layerWhf[j] = whf;
1013 hnd->width = renderBuf->width;
1014 hnd->height = renderBuf->height;
1015 hnd->format = renderBuf->format;
1016
Xu Yangcda012c2014-07-30 21:57:21 +08001017 // Store & update blending mode, planeAlpha and transform of PTOR layer
1018 blending[j] = layer->blending;
1019 planeAlpha[j] = layer->planeAlpha;
1020 transform[j] = layer->transform;
1021 layer->blending = HWC_BLENDING_NONE;
1022 layer->planeAlpha = 0xFF;
1023 layer->transform = 0;
1024
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001025 // Remove overlap from crop & displayFrame of below layers
1026 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001027 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001028 if(!isValidRect(getIntersection(layer->displayFrame,
1029 overlapRect[j]))) {
1030 continue;
1031 }
1032 // Update layer attributes
1033 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1034 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301035 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001036 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1037 layer->transform);
1038 layer->sourceCropf.left = (float)srcCrop.left;
1039 layer->sourceCropf.top = (float)srcCrop.top;
1040 layer->sourceCropf.right = (float)srcCrop.right;
1041 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1042 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001043 }
1044
1045 mCurrentFrame.mdpCount = numAppLayers;
1046 mCurrentFrame.fbCount = 0;
1047 mCurrentFrame.fbZ = -1;
1048
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301049 for (int j = 0; j < numAppLayers; j++) {
1050 if(isValidRect(list->hwLayers[j].displayFrame)) {
1051 mCurrentFrame.isFBComposed[j] = false;
1052 } else {
1053 mCurrentFrame.mdpCount--;
1054 mCurrentFrame.drop[j] = true;
1055 }
1056 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001057
1058 bool result = postHeuristicsHandling(ctx, list);
1059
1060 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001061 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001062 hwc_layer_1_t* layer = &list->hwLayers[i];
1063 layer->displayFrame = displayFrame[i];
1064 layer->sourceCropf.left = (float)sourceCrop[i].left;
1065 layer->sourceCropf.top = (float)sourceCrop[i].top;
1066 layer->sourceCropf.right = (float)sourceCrop[i].right;
1067 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1068 }
1069
Xu Yangcda012c2014-07-30 21:57:21 +08001070 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001071 for (int i = 0; i < numPTORLayersFound; i++) {
1072 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001073 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001074 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1075 hnd->width = layerWhf[i].w;
1076 hnd->height = layerWhf[i].h;
1077 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001078 layer->blending = blending[i];
1079 layer->planeAlpha = planeAlpha[i];
1080 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001081 }
1082
Sushil Chauhandefd3522014-05-13 18:17:12 -07001083 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001084 // reset PTOR
1085 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001086 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001087 } else {
1088 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1089 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001090 }
1091
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001092 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1093 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001094 return result;
1095}
1096
Saurabh Shahaa236822013-04-24 18:07:26 -07001097bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1098{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001099 if(!sEnableMixedMode) {
1100 //Mixed mode is disabled. No need to even try caching.
1101 return false;
1102 }
1103
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001104 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001105 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001106 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001107 cacheBasedComp(ctx, list);
1108 } else {
1109 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001110 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001111 }
1112
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001113 return ret;
1114}
1115
1116bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1117 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001118 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1119 return false;
1120
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001121 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001122 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001123 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001124
1125 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1126 for(int i = 0; i < numAppLayers; i++) {
1127 if(!mCurrentFrame.isFBComposed[i]) {
1128 hwc_layer_1_t* layer = &list->hwLayers[i];
1129 if(not isSupportedForMDPComp(ctx, layer)) {
1130 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1131 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001132 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001133 return false;
1134 }
1135 }
1136 }
1137
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001138 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001139 /* mark secure RGB layers for MDP comp */
1140 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301141 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001142 if(!ret) {
1143 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001144 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001145 return false;
1146 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001147
1148 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001149
Raj Kamal389d6e32014-08-04 14:43:24 +05301150 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001151 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301152 }
1153
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001154 if(!postHeuristicsHandling(ctx, list)) {
1155 ALOGD_IF(isDebug(), "post heuristic handling failed");
1156 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001157 return false;
1158 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001159 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1160 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001161
Saurabh Shahaa236822013-04-24 18:07:26 -07001162 return true;
1163}
1164
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001165bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001166 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001167 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1168 return false;
1169
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001170 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001171 return false;
1172 }
1173
Saurabh Shahb772ae32013-11-18 15:40:02 -08001174 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001175 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1176 const int stagesForMDP = min(sMaxPipesPerMixer,
1177 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001178
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001179 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1180 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1181 int lastMDPSupportedIndex = numAppLayers;
1182 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001183
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001184 //Find the minimum MDP batch size
1185 for(int i = 0; i < numAppLayers;i++) {
1186 if(mCurrentFrame.drop[i]) {
1187 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001188 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001189 }
1190 hwc_layer_1_t* layer = &list->hwLayers[i];
1191 if(not isSupportedForMDPComp(ctx, layer)) {
1192 lastMDPSupportedIndex = i;
1193 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1194 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001195 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001196 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001197 }
1198
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001199 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1200 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1201 mCurrentFrame.dropCount);
1202
1203 //Start at a point where the fb batch should at least have 2 layers, for
1204 //this mode to be justified.
1205 while(fbBatchSize < 2) {
1206 ++fbBatchSize;
1207 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001208 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001209
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001210 //If there are no layers for MDP, this mode doesnt make sense.
1211 if(mdpBatchSize < 1) {
1212 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1213 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001214 return false;
1215 }
1216
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001217 mCurrentFrame.reset(numAppLayers);
1218
1219 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1220 while(mdpBatchSize > 0) {
1221 //Mark layers for MDP comp
1222 int mdpBatchLeft = mdpBatchSize;
1223 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1224 if(mCurrentFrame.drop[i]) {
1225 continue;
1226 }
1227 mCurrentFrame.isFBComposed[i] = false;
1228 --mdpBatchLeft;
1229 }
1230
1231 mCurrentFrame.fbZ = mdpBatchSize;
1232 mCurrentFrame.fbCount = fbBatchSize;
1233 mCurrentFrame.mdpCount = mdpBatchSize;
1234
1235 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1236 __FUNCTION__, mdpBatchSize, fbBatchSize,
1237 mCurrentFrame.dropCount);
1238
1239 if(postHeuristicsHandling(ctx, list)) {
1240 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001241 __FUNCTION__);
1242 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1243 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001244 return true;
1245 }
1246
1247 reset(ctx);
1248 --mdpBatchSize;
1249 ++fbBatchSize;
1250 }
1251
1252 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001253}
1254
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001255bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301256 if(mDpy or isSecurePresent(ctx, mDpy) or
1257 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001258 return false;
1259 }
1260 return true;
1261}
1262
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001263bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1264 hwc_display_contents_1_t* list){
1265 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1266 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1267 mDpy ) {
1268 return false;
1269 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001270 if(ctx->listStats[mDpy].secureUI)
1271 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001272 return true;
1273}
1274
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001275bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1276 hwc_display_contents_1_t* list) {
1277 const bool secureOnly = true;
1278 return videoOnlyComp(ctx, list, not secureOnly) or
1279 videoOnlyComp(ctx, list, secureOnly);
1280}
1281
1282bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001283 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001284 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1285 return false;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301286
Saurabh Shahaa236822013-04-24 18:07:26 -07001287 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301288 if(!isSecurePresent(ctx, mDpy)) {
1289 /* Bail out if we are processing only secured video layers
1290 * and we dont have any */
1291 if(secureOnly) {
1292 ALOGD_IF(isDebug(),"%s: No Secure Video Layers", __FUNCTION__);
1293 return false;
1294 }
1295 /* No Idle fall back for secure video layers and if there is only
1296 * single layer being composed. */
1297 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1298 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1299 return false;
1300 }
1301 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001302
Saurabh Shahaa236822013-04-24 18:07:26 -07001303 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001304 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001305 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001306 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001307
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001308 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1309 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001310 return false;
1311 }
1312
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001313 if(mCurrentFrame.fbCount)
1314 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001315
Raj Kamal389d6e32014-08-04 14:43:24 +05301316 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001317 adjustForSourceSplit(ctx, list);
1318 }
1319
1320 if(!postHeuristicsHandling(ctx, list)) {
1321 ALOGD_IF(isDebug(), "post heuristic handling failed");
1322 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001323 return false;
1324 }
1325
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001326 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1327 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001328 return true;
1329}
1330
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001331/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1332bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1333 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001334 // Fall back to video only composition, if AIV video mode is enabled
1335 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001336 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1337 __FUNCTION__, mDpy);
1338 return false;
1339 }
1340
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001341 const bool secureOnly = true;
1342 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1343 mdpOnlyLayersComp(ctx, list, secureOnly);
1344
1345}
1346
1347bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1348 hwc_display_contents_1_t* list, bool secureOnly) {
1349
1350 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1351 return false;
1352
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301353 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1354 if(!isSecurePresent(ctx, mDpy) && !ctx->listStats[mDpy].secureUI) {
1355 /* Bail out if we are processing only secured video/ui layers
1356 * and we dont have any */
1357 if(secureOnly) {
1358 ALOGD_IF(isDebug(), "%s: No secure video/ui layers");
1359 return false;
1360 }
1361 /* No Idle fall back for secure video/ui layers and if there is only
1362 * single layer being composed. */
1363 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1364 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1365 return false;
1366 }
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001367 }
1368
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001369 mCurrentFrame.reset(numAppLayers);
1370 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1371
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001372 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001373 /* mark secure RGB layers for MDP comp */
1374 updateSecureRGB(ctx, list);
1375
1376 if(mCurrentFrame.mdpCount == 0) {
1377 reset(ctx);
1378 return false;
1379 }
1380
1381 /* find the maximum batch of layers to be marked for framebuffer */
1382 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1383 if(!ret) {
1384 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1385 reset(ctx);
1386 return false;
1387 }
1388
1389 if(sEnableYUVsplit){
1390 adjustForSourceSplit(ctx, list);
1391 }
1392
1393 if(!postHeuristicsHandling(ctx, list)) {
1394 ALOGD_IF(isDebug(), "post heuristic handling failed");
1395 reset(ctx);
1396 return false;
1397 }
1398
1399 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1400 __FUNCTION__);
1401 return true;
1402}
1403
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001404/* Checks for conditions where YUV layers cannot be bypassed */
1405bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001406 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001407 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001408 return false;
1409 }
1410
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001411 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001412 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1413 return false;
1414 }
1415
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001416 if(isSecuring(ctx, layer)) {
1417 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1418 return false;
1419 }
1420
Saurabh Shah4fdde762013-04-30 18:47:33 -07001421 if(!isValidDimension(ctx, layer)) {
1422 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1423 __FUNCTION__);
1424 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001425 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001426
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001427 if(layer->planeAlpha < 0xFF) {
1428 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1429 in video only mode",
1430 __FUNCTION__);
1431 return false;
1432 }
1433
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001434 return true;
1435}
1436
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001437/* Checks for conditions where Secure RGB layers cannot be bypassed */
1438bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1439 if(isSkipLayer(layer)) {
1440 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1441 __FUNCTION__, mDpy);
1442 return false;
1443 }
1444
1445 if(isSecuring(ctx, layer)) {
1446 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1447 return false;
1448 }
1449
1450 if(not isSupportedForMDPComp(ctx, layer)) {
1451 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1452 __FUNCTION__);
1453 return false;
1454 }
1455 return true;
1456}
1457
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301458/* starts at fromIndex and check for each layer to find
1459 * if it it has overlapping with any Updating layer above it in zorder
1460 * till the end of the batch. returns true if it finds any intersection */
1461bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1462 int fromIndex, int toIndex) {
1463 for(int i = fromIndex; i < toIndex; i++) {
1464 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1465 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1466 return false;
1467 }
1468 }
1469 }
1470 return true;
1471}
1472
1473/* Checks if given layer at targetLayerIndex has any
1474 * intersection with all the updating layers in beween
1475 * fromIndex and toIndex. Returns true if it finds intersectiion */
1476bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1477 int fromIndex, int toIndex, int targetLayerIndex) {
1478 for(int i = fromIndex; i <= toIndex; i++) {
1479 if(!mCurrentFrame.isFBComposed[i]) {
1480 if(areLayersIntersecting(&list->hwLayers[i],
1481 &list->hwLayers[targetLayerIndex])) {
1482 return true;
1483 }
1484 }
1485 }
1486 return false;
1487}
1488
1489int MDPComp::getBatch(hwc_display_contents_1_t* list,
1490 int& maxBatchStart, int& maxBatchEnd,
1491 int& maxBatchCount) {
1492 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301493 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001494 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301495 while (i < mCurrentFrame.layerCount) {
1496 int batchCount = 0;
1497 int batchStart = i;
1498 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001499 /* Adjust batch Z order with the dropped layers so far */
1500 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301501 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301502 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301503 while(i < mCurrentFrame.layerCount) {
1504 if(!mCurrentFrame.isFBComposed[i]) {
1505 if(!batchCount) {
1506 i++;
1507 break;
1508 }
1509 updatingLayersAbove++;
1510 i++;
1511 continue;
1512 } else {
1513 if(mCurrentFrame.drop[i]) {
1514 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001515 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301516 continue;
1517 } else if(updatingLayersAbove <= 0) {
1518 batchCount++;
1519 batchEnd = i;
1520 i++;
1521 continue;
1522 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1523
1524 // We have a valid updating layer already. If layer-i not
1525 // have overlapping with all updating layers in between
1526 // batch-start and i, then we can add layer i to batch.
1527 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1528 batchCount++;
1529 batchEnd = i;
1530 i++;
1531 continue;
1532 } else if(canPushBatchToTop(list, batchStart, i)) {
1533 //If All the non-updating layers with in this batch
1534 //does not have intersection with the updating layers
1535 //above in z-order, then we can safely move the batch to
1536 //higher z-order. Increment fbZ as it is moving up.
1537 if( firstZReverseIndex < 0) {
1538 firstZReverseIndex = i;
1539 }
1540 batchCount++;
1541 batchEnd = i;
1542 fbZ += updatingLayersAbove;
1543 i++;
1544 updatingLayersAbove = 0;
1545 continue;
1546 } else {
1547 //both failed.start the loop again from here.
1548 if(firstZReverseIndex >= 0) {
1549 i = firstZReverseIndex;
1550 }
1551 break;
1552 }
1553 }
1554 }
1555 }
1556 if(batchCount > maxBatchCount) {
1557 maxBatchCount = batchCount;
1558 maxBatchStart = batchStart;
1559 maxBatchEnd = batchEnd;
1560 fbZOrder = fbZ;
1561 }
1562 }
1563 return fbZOrder;
1564}
1565
1566bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1567 hwc_display_contents_1_t* list) {
1568 /* Idea is to keep as many non-updating(cached) layers in FB and
1569 * send rest of them through MDP. This is done in 2 steps.
1570 * 1. Find the maximum contiguous batch of non-updating layers.
1571 * 2. See if we can improve this batch size for caching by adding
1572 * opaque layers around the batch, if they don't have
1573 * any overlapping with the updating layers in between.
1574 * NEVER mark an updating layer for caching.
1575 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001576
1577 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001578 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001579 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301580 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001581
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001582 /* Nothing is cached. No batching needed */
1583 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001584 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001585 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001586
1587 /* No MDP comp layers, try to use other comp modes */
1588 if(mCurrentFrame.mdpCount == 0) {
1589 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001590 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001591
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301592 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001593
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301594 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001595 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001596 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001597 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301598 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001599 if(!mCurrentFrame.drop[i]){
1600 //If an unsupported layer is being attempted to
1601 //be pulled out we should fail
1602 if(not isSupportedForMDPComp(ctx, layer)) {
1603 return false;
1604 }
1605 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001606 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001607 }
1608 }
1609
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301610 // update the frame data
1611 mCurrentFrame.fbZ = fbZ;
1612 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001613 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001614 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001615
1616 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301617 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001618
1619 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001620}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001621
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001622void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001623 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001624 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001625 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001626
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001627 for(int i = 0; i < numAppLayers; i++) {
1628 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001629 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001630 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001631 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001632 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001633 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001634 }
1635 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001636
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001637 frame.fbCount = fbCount;
1638 frame.mdpCount = frame.layerCount - frame.fbCount
1639 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001640
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001641 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1642 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001643}
1644
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001645// drop other non-AIV layers from external display list.
1646void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001647 hwc_display_contents_1_t* list) {
1648 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1649 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001650 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001651 mCurrentFrame.dropCount++;
1652 mCurrentFrame.drop[i] = true;
1653 }
1654 }
1655 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1656 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1657 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1658 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1659 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1660 mCurrentFrame.dropCount);
1661}
1662
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001663void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001664 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001665 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1666 for(int index = 0;index < nYuvCount; index++){
1667 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1668 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1669
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001670 if(mCurrentFrame.drop[nYuvIndex]) {
1671 continue;
1672 }
1673
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001674 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001675 if(!frame.isFBComposed[nYuvIndex]) {
1676 frame.isFBComposed[nYuvIndex] = true;
1677 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001678 }
1679 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001680 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001681 private_handle_t *hnd = (private_handle_t *)layer->handle;
1682 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001683 frame.isFBComposed[nYuvIndex] = false;
1684 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001685 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001686 }
1687 }
1688 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001689
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001690 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1691 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001692}
1693
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001694void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1695 hwc_display_contents_1_t* list) {
1696 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1697 for(int index = 0;index < nSecureRGBCount; index++){
1698 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1699 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1700
1701 if(!isSecureRGBDoable(ctx, layer)) {
1702 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1703 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1704 mCurrentFrame.fbCount++;
1705 }
1706 } else {
1707 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1708 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1709 mCurrentFrame.fbCount--;
1710 }
1711 }
1712 }
1713
1714 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1715 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1716 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1717 mCurrentFrame.fbCount);
1718}
1719
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001720hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1721 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001722 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001723
1724 /* Update only the region of FB needed for composition */
1725 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1726 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1727 hwc_layer_1_t* layer = &list->hwLayers[i];
1728 hwc_rect_t dst = layer->displayFrame;
1729 fbRect = getUnion(fbRect, dst);
1730 }
1731 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001732 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001733 return fbRect;
1734}
1735
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001736bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1737 hwc_display_contents_1_t* list) {
1738
1739 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001740 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001741 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1742 return false;
1743 }
1744
1745 //Limitations checks
1746 if(!hwLimitationsCheck(ctx, list)) {
1747 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1748 return false;
1749 }
1750
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001751 //Configure framebuffer first if applicable
1752 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001753 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001754 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1755 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001756 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1757 __FUNCTION__);
1758 return false;
1759 }
1760 }
1761
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001762 mCurrentFrame.map();
1763
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001764 if(!allocLayerPipes(ctx, list)) {
1765 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001766 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001767 }
1768
1769 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001770 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001771 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001772 int mdpIndex = mCurrentFrame.layerToMDP[index];
1773 hwc_layer_1_t* layer = &list->hwLayers[index];
1774
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301775 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1776 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1777 mdpNextZOrder++;
1778 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001779 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1780 cur_pipe->zOrder = mdpNextZOrder++;
1781
radhakrishnac9a67412013-09-25 17:40:42 +05301782 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301783 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301784 if(configure4k2kYuv(ctx, layer,
1785 mCurrentFrame.mdpToLayer[mdpIndex])
1786 != 0 ){
1787 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1788 for layer %d",__FUNCTION__, index);
1789 return false;
1790 }
1791 else{
1792 mdpNextZOrder++;
1793 }
1794 continue;
1795 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001796 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1797 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301798 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001799 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001800 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001801 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001802 }
1803
Saurabh Shaha36be922013-12-16 18:18:39 -08001804 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1805 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1806 ,__FUNCTION__, mDpy);
1807 return false;
1808 }
1809
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001810 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001811 return true;
1812}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001813
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001814bool MDPComp::resourceCheck(hwc_context_t* ctx,
1815 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001816 const bool fbUsed = mCurrentFrame.fbCount;
1817 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1818 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1819 return false;
1820 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001821
1822 //Will benefit cases where a video has non-updating background.
1823 if((mDpy > HWC_DISPLAY_PRIMARY) and
1824 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1825 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1826 return false;
1827 }
1828
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001829 // Init rotCount to number of rotate sessions used by other displays
1830 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1831 // Count the number of rotator sessions required for current display
1832 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1833 if(!mCurrentFrame.isFBComposed[index]) {
1834 hwc_layer_1_t* layer = &list->hwLayers[index];
1835 private_handle_t *hnd = (private_handle_t *)layer->handle;
1836 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1837 rotCount++;
1838 }
1839 }
1840 }
1841 // if number of layers to rotate exceeds max rotator sessions, bail out.
1842 if(rotCount > RotMgr::MAX_ROT_SESS) {
1843 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1844 __FUNCTION__, mDpy);
1845 return false;
1846 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001847 return true;
1848}
1849
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301850bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1851 hwc_display_contents_1_t* list) {
1852
1853 //A-family hw limitation:
1854 //If a layer need alpha scaling, MDP can not support.
1855 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1856 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1857 if(!mCurrentFrame.isFBComposed[i] &&
1858 isAlphaScaled( &list->hwLayers[i])) {
1859 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1860 return false;
1861 }
1862 }
1863 }
1864
1865 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1866 //If multiple layers requires downscaling and also they are overlapping
1867 //fall back to GPU since MDSS can not handle it.
1868 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1869 qdutils::MDPVersion::getInstance().is8x26()) {
1870 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1871 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1872 if(!mCurrentFrame.isFBComposed[i] &&
1873 isDownscaleRequired(botLayer)) {
1874 //if layer-i is marked for MDP and needs downscaling
1875 //check if any MDP layer on top of i & overlaps with layer-i
1876 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1877 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1878 if(!mCurrentFrame.isFBComposed[j] &&
1879 isDownscaleRequired(topLayer)) {
1880 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1881 topLayer->displayFrame);
1882 if(isValidRect(r))
1883 return false;
1884 }
1885 }
1886 }
1887 }
1888 }
1889 return true;
1890}
1891
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001892int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001893 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001894 char property[PROPERTY_VALUE_MAX];
1895
Raj Kamal4393eaa2014-06-06 13:45:20 +05301896 if(!ctx || !list) {
1897 ALOGE("%s: Invalid context or list",__FUNCTION__);
1898 mCachedFrame.reset();
1899 return -1;
1900 }
1901
1902 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001903 if(mDpy == HWC_DISPLAY_PRIMARY) {
1904 sSimulationFlags = 0;
1905 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1906 int currentFlags = atoi(property);
1907 if(currentFlags != sSimulationFlags) {
1908 sSimulationFlags = currentFlags;
1909 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1910 sSimulationFlags, sSimulationFlags);
1911 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001912 }
1913 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001914 // reset PTOR
1915 if(!mDpy)
1916 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001917
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301918 //Do not cache the information for next draw cycle.
1919 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1920 ALOGI("%s: Unsupported layer count for mdp composition",
1921 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001922 mCachedFrame.reset();
1923 return -1;
1924 }
1925
Saurabh Shahb39f8152013-08-22 10:21:44 -07001926 //reset old data
1927 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001928 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1929 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301930
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001931 // Detect the start of animation and fall back to GPU only once to cache
1932 // all the layers in FB and display FB content untill animation completes.
1933 if(ctx->listStats[mDpy].isDisplayAnimating) {
1934 mCurrentFrame.needsRedraw = false;
1935 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1936 mCurrentFrame.needsRedraw = true;
1937 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1938 }
1939 setMDPCompLayerFlags(ctx, list);
1940 mCachedFrame.updateCounts(mCurrentFrame);
1941 ret = -1;
1942 return ret;
1943 } else {
1944 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1945 }
1946
Saurabh Shahb39f8152013-08-22 10:21:44 -07001947 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001948 if(isFrameDoable(ctx)) {
1949 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001950 // if AIV Video mode is enabled, drop all non AIV layers from the
1951 // external display list.
1952 if(ctx->listStats[mDpy].mAIVVideoMode) {
1953 dropNonAIVLayers(ctx, list);
1954 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001955
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001956 // if tryFullFrame fails, try to push all video and secure RGB layers
1957 // to MDP for composition.
1958 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001959 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301960 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001961 setMDPCompLayerFlags(ctx, list);
1962 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001963 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001964 reset(ctx);
1965 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1966 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001967 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001968 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1969 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001970 }
1971 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05301972 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
1973 enablePartialUpdateForMDP3) {
1974 generateROI(ctx, list);
1975 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
1976 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
1977 }
1978 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001979 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1980 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001981 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001982 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001983
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001984 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001985 ALOGD("GEOMETRY change: %d",
1986 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001987 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001988 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001989 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001990 }
1991
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001992#ifdef DYNAMIC_FPS
1993 //For primary display, set the dynamic refreshrate
Raj Kamal0d53fc62014-11-25 17:36:36 +05301994 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
1995 ctx->mUseMetaDataRefreshRate) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001996 FrameInfo frame;
1997 frame.reset(mCurrentFrame.layerCount);
Raj Kamal18e946e2014-10-10 14:23:47 +05301998 memset(&frame.drop, 0, sizeof(frame.drop));
1999 frame.dropCount = 0;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002000 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
2001 __FUNCTION__);
2002 updateLayerCache(ctx, list, frame);
2003 updateYUV(ctx, list, false /*secure only*/, frame);
2004 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
2005 //Set the new fresh rate, if there is only one updating YUV layer
2006 //or there is one single RGB layer with this request
2007 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
2008 (frame.layerCount == 1)) {
2009 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
2010 }
2011 setRefreshRate(ctx, mDpy, refreshRate);
2012 }
2013#endif
2014
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002015 mCachedFrame.cacheAll(list);
2016 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002017 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002018}
2019
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002020bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302021
2022 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302023 int mdpIndex = mCurrentFrame.layerToMDP[index];
2024 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2025 info.pipeInfo = new MdpYUVPipeInfo;
2026 info.rot = NULL;
2027 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302028
2029 pipe_info.lIndex = ovutils::OV_INVALID;
2030 pipe_info.rIndex = ovutils::OV_INVALID;
2031
Saurabh Shahc62f3982014-03-05 14:28:26 -08002032 Overlay::PipeSpecs pipeSpecs;
2033 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2034 pipeSpecs.needsScaling = true;
2035 pipeSpecs.dpy = mDpy;
2036 pipeSpecs.fb = false;
2037
2038 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302039 if(pipe_info.lIndex == ovutils::OV_INVALID){
2040 bRet = false;
2041 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2042 __FUNCTION__);
2043 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002044 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302045 if(pipe_info.rIndex == ovutils::OV_INVALID){
2046 bRet = false;
2047 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2048 __FUNCTION__);
2049 }
2050 return bRet;
2051}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002052
2053int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2054 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002055 if (ctx->mPtorInfo.isActive()) {
2056 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002057 if (fd < 0) {
2058 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002059 }
2060 }
2061 return fd;
2062}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002063//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002064
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002065void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302066 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002067 //If 4k2k Yuv layer split is possible, and if
2068 //fbz is above 4k2k layer, increment fb zorder by 1
2069 //as we split 4k2k layer and increment zorder for right half
2070 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002071 if(!ctx)
2072 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002073 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302074 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2075 index++) {
2076 if(!mCurrentFrame.isFBComposed[index]) {
2077 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2078 mdpNextZOrder++;
2079 }
2080 mdpNextZOrder++;
2081 hwc_layer_1_t* layer = &list->hwLayers[index];
2082 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302083 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302084 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2085 mCurrentFrame.fbZ += 1;
2086 mdpNextZOrder++;
2087 //As we split 4kx2k yuv layer and program to 2 VG pipes
2088 //(if available) increase mdpcount by 1.
2089 mCurrentFrame.mdpCount++;
2090 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002091 }
2092 }
2093 }
radhakrishnac9a67412013-09-25 17:40:42 +05302094}
2095
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002096/*
2097 * Configures pipe(s) for MDP composition
2098 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002099int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002100 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002101 MdpPipeInfoNonSplit& mdp_info =
2102 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302103 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002104 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002105 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002106
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002107 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2108 __FUNCTION__, layer, zOrder, dest);
2109
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002110 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002111 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002112}
2113
Saurabh Shah88e4d272013-09-03 13:31:29 -07002114bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002115 hwc_display_contents_1_t* list) {
2116 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002117
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002118 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002119
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002120 hwc_layer_1_t* layer = &list->hwLayers[index];
2121 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302122 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002123 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302124 continue;
2125 }
2126 }
2127
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002128 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002129 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002130 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002131 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002132 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002133
Saurabh Shahc62f3982014-03-05 14:28:26 -08002134 Overlay::PipeSpecs pipeSpecs;
2135 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2136 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2137 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2138 (qdutils::MDPVersion::getInstance().is8x26() and
2139 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2140 pipeSpecs.dpy = mDpy;
2141 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002142 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002143
Saurabh Shahc62f3982014-03-05 14:28:26 -08002144 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2145
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002146 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002147 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002148 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002149 }
2150 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002151 return true;
2152}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002153
radhakrishnac9a67412013-09-25 17:40:42 +05302154int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2155 PipeLayerPair& PipeLayerPair) {
2156 MdpYUVPipeInfo& mdp_info =
2157 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2158 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302159 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302160 eDest lDest = mdp_info.lIndex;
2161 eDest rDest = mdp_info.rIndex;
2162
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002163 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302164 lDest, rDest, &PipeLayerPair.rot);
2165}
2166
Saurabh Shah88e4d272013-09-03 13:31:29 -07002167bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002168
Raj Kamal4393eaa2014-06-06 13:45:20 +05302169 if(!isEnabled() or !mModeOn) {
2170 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302171 return true;
2172 }
2173
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002174 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002175 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002176 sHandleTimeout = true;
2177 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002178
2179 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002180 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002181
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002182 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2183 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002184 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002185 if(mCurrentFrame.isFBComposed[i]) continue;
2186
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002187 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002188 private_handle_t *hnd = (private_handle_t *)layer->handle;
2189 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002190 if (!(layer->flags & HWC_COLOR_FILL)) {
2191 ALOGE("%s handle null", __FUNCTION__);
2192 return false;
2193 }
2194 // No PLAY for Color layer
2195 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2196 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002197 }
2198
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002199 int mdpIndex = mCurrentFrame.layerToMDP[i];
2200
Raj Kamal389d6e32014-08-04 14:43:24 +05302201 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302202 {
2203 MdpYUVPipeInfo& pipe_info =
2204 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2205 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2206 ovutils::eDest indexL = pipe_info.lIndex;
2207 ovutils::eDest indexR = pipe_info.rIndex;
2208 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302209 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302210 if(rot) {
2211 rot->queueBuffer(fd, offset);
2212 fd = rot->getDstMemId();
2213 offset = rot->getDstOffset();
2214 }
2215 if(indexL != ovutils::OV_INVALID) {
2216 ovutils::eDest destL = (ovutils::eDest)indexL;
2217 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2218 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2219 if (!ov.queueBuffer(fd, offset, destL)) {
2220 ALOGE("%s: queueBuffer failed for display:%d",
2221 __FUNCTION__, mDpy);
2222 return false;
2223 }
2224 }
2225
2226 if(indexR != ovutils::OV_INVALID) {
2227 ovutils::eDest destR = (ovutils::eDest)indexR;
2228 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2229 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2230 if (!ov.queueBuffer(fd, offset, destR)) {
2231 ALOGE("%s: queueBuffer failed for display:%d",
2232 __FUNCTION__, mDpy);
2233 return false;
2234 }
2235 }
2236 }
2237 else{
2238 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002239 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302240 ovutils::eDest dest = pipe_info.index;
2241 if(dest == ovutils::OV_INVALID) {
2242 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002243 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302244 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002245
radhakrishnac9a67412013-09-25 17:40:42 +05302246 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2247 continue;
2248 }
2249
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002250 int fd = hnd->fd;
2251 uint32_t offset = (uint32_t)hnd->offset;
2252 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2253 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002254 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002255 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002256 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002257 }
2258
radhakrishnac9a67412013-09-25 17:40:42 +05302259 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2260 using pipe: %d", __FUNCTION__, layer,
2261 hnd, dest );
2262
radhakrishnac9a67412013-09-25 17:40:42 +05302263 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2264 if(rot) {
2265 if(!rot->queueBuffer(fd, offset))
2266 return false;
2267 fd = rot->getDstMemId();
2268 offset = rot->getDstOffset();
2269 }
2270
2271 if (!ov.queueBuffer(fd, offset, dest)) {
2272 ALOGE("%s: queueBuffer failed for display:%d ",
2273 __FUNCTION__, mDpy);
2274 return false;
2275 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002276 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002277
2278 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002279 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002280 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002281}
2282
Saurabh Shah88e4d272013-09-03 13:31:29 -07002283//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002284
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002285void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302286 hwc_display_contents_1_t* list){
2287 //if 4kx2k yuv layer is totally present in either in left half
2288 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302289 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302290 if(mCurrentFrame.fbZ >= 0) {
2291 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2292 index++) {
2293 if(!mCurrentFrame.isFBComposed[index]) {
2294 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2295 mdpNextZOrder++;
2296 }
2297 mdpNextZOrder++;
2298 hwc_layer_1_t* layer = &list->hwLayers[index];
2299 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302300 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302301 hwc_rect_t dst = layer->displayFrame;
2302 if((dst.left > lSplit) || (dst.right < lSplit)) {
2303 mCurrentFrame.mdpCount += 1;
2304 }
2305 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2306 mCurrentFrame.fbZ += 1;
2307 mdpNextZOrder++;
2308 }
2309 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002310 }
radhakrishnac9a67412013-09-25 17:40:42 +05302311 }
2312}
2313
Saurabh Shah88e4d272013-09-03 13:31:29 -07002314bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002315 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002316
Saurabh Shahc62f3982014-03-05 14:28:26 -08002317 const int lSplit = getLeftSplit(ctx, mDpy);
2318 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002319 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002320 pipe_info.lIndex = ovutils::OV_INVALID;
2321 pipe_info.rIndex = ovutils::OV_INVALID;
2322
Saurabh Shahc62f3982014-03-05 14:28:26 -08002323 Overlay::PipeSpecs pipeSpecs;
2324 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2325 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2326 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2327 pipeSpecs.dpy = mDpy;
2328 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2329 pipeSpecs.fb = false;
2330
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002331 // Acquire pipe only for the updating half
2332 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2333 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2334
2335 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002336 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002337 if(pipe_info.lIndex == ovutils::OV_INVALID)
2338 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002339 }
2340
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002341 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002342 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2343 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002344 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002345 return false;
2346 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002347
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002348 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002349}
2350
Saurabh Shah88e4d272013-09-03 13:31:29 -07002351bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002352 hwc_display_contents_1_t* list) {
2353 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002354
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002355 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002356
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002357 hwc_layer_1_t* layer = &list->hwLayers[index];
2358 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302359 hwc_rect_t dst = layer->displayFrame;
2360 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302361 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302362 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002363 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302364 continue;
2365 }
2366 }
2367 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002368 int mdpIndex = mCurrentFrame.layerToMDP[index];
2369 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002370 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002371 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002372 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002373
Saurabh Shahc62f3982014-03-05 14:28:26 -08002374 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2375 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2376 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002377 return false;
2378 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002379 }
2380 return true;
2381}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002382
radhakrishnac9a67412013-09-25 17:40:42 +05302383int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2384 PipeLayerPair& PipeLayerPair) {
2385 const int lSplit = getLeftSplit(ctx, mDpy);
2386 hwc_rect_t dst = layer->displayFrame;
2387 if((dst.left > lSplit)||(dst.right < lSplit)){
2388 MdpYUVPipeInfo& mdp_info =
2389 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2390 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302391 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302392 eDest lDest = mdp_info.lIndex;
2393 eDest rDest = mdp_info.rIndex;
2394
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002395 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302396 lDest, rDest, &PipeLayerPair.rot);
2397 }
2398 else{
2399 return configure(ctx, layer, PipeLayerPair);
2400 }
2401}
2402
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002403/*
2404 * Configures pipe(s) for MDP composition
2405 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002406int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002407 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002408 MdpPipeInfoSplit& mdp_info =
2409 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002410 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302411 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002412 eDest lDest = mdp_info.lIndex;
2413 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002414
2415 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2416 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2417
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002418 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002419 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002420}
2421
Saurabh Shah88e4d272013-09-03 13:31:29 -07002422bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002423
Raj Kamal4393eaa2014-06-06 13:45:20 +05302424 if(!isEnabled() or !mModeOn) {
2425 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302426 return true;
2427 }
2428
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002429 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002430 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002431 sHandleTimeout = true;
2432 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002433
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002434 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002435 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002436
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002437 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2438 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002439 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002440 if(mCurrentFrame.isFBComposed[i]) continue;
2441
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002442 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002443 private_handle_t *hnd = (private_handle_t *)layer->handle;
2444 if(!hnd) {
2445 ALOGE("%s handle null", __FUNCTION__);
2446 return false;
2447 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002448
2449 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2450 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002451 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002452
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002453 int mdpIndex = mCurrentFrame.layerToMDP[i];
2454
Raj Kamal389d6e32014-08-04 14:43:24 +05302455 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302456 {
2457 MdpYUVPipeInfo& pipe_info =
2458 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2459 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2460 ovutils::eDest indexL = pipe_info.lIndex;
2461 ovutils::eDest indexR = pipe_info.rIndex;
2462 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302463 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302464 if(rot) {
2465 rot->queueBuffer(fd, offset);
2466 fd = rot->getDstMemId();
2467 offset = rot->getDstOffset();
2468 }
2469 if(indexL != ovutils::OV_INVALID) {
2470 ovutils::eDest destL = (ovutils::eDest)indexL;
2471 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2472 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2473 if (!ov.queueBuffer(fd, offset, destL)) {
2474 ALOGE("%s: queueBuffer failed for display:%d",
2475 __FUNCTION__, mDpy);
2476 return false;
2477 }
2478 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002479
radhakrishnac9a67412013-09-25 17:40:42 +05302480 if(indexR != ovutils::OV_INVALID) {
2481 ovutils::eDest destR = (ovutils::eDest)indexR;
2482 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2483 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2484 if (!ov.queueBuffer(fd, offset, destR)) {
2485 ALOGE("%s: queueBuffer failed for display:%d",
2486 __FUNCTION__, mDpy);
2487 return false;
2488 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002489 }
2490 }
radhakrishnac9a67412013-09-25 17:40:42 +05302491 else{
2492 MdpPipeInfoSplit& pipe_info =
2493 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2494 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002495
radhakrishnac9a67412013-09-25 17:40:42 +05302496 ovutils::eDest indexL = pipe_info.lIndex;
2497 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002498
radhakrishnac9a67412013-09-25 17:40:42 +05302499 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002500 uint32_t offset = (uint32_t)hnd->offset;
2501 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2502 if (!mDpy && (index != -1)) {
2503 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2504 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002505 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002506 }
radhakrishnac9a67412013-09-25 17:40:42 +05302507
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002508 if(ctx->mAD->draw(ctx, fd, offset)) {
2509 fd = ctx->mAD->getDstFd();
2510 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002511 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002512
radhakrishnac9a67412013-09-25 17:40:42 +05302513 if(rot) {
2514 rot->queueBuffer(fd, offset);
2515 fd = rot->getDstMemId();
2516 offset = rot->getDstOffset();
2517 }
2518
2519 //************* play left mixer **********
2520 if(indexL != ovutils::OV_INVALID) {
2521 ovutils::eDest destL = (ovutils::eDest)indexL;
2522 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2523 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2524 if (!ov.queueBuffer(fd, offset, destL)) {
2525 ALOGE("%s: queueBuffer failed for left mixer",
2526 __FUNCTION__);
2527 return false;
2528 }
2529 }
2530
2531 //************* play right mixer **********
2532 if(indexR != ovutils::OV_INVALID) {
2533 ovutils::eDest destR = (ovutils::eDest)indexR;
2534 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2535 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2536 if (!ov.queueBuffer(fd, offset, destR)) {
2537 ALOGE("%s: queueBuffer failed for right mixer",
2538 __FUNCTION__);
2539 return false;
2540 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002541 }
2542 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002543
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002544 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2545 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002546
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002547 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002548}
Saurabh Shahab47c692014-02-12 18:45:57 -08002549
2550//================MDPCompSrcSplit==============================================
2551bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002552 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002553 private_handle_t *hnd = (private_handle_t *)layer->handle;
2554 hwc_rect_t dst = layer->displayFrame;
2555 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2556 pipe_info.lIndex = ovutils::OV_INVALID;
2557 pipe_info.rIndex = ovutils::OV_INVALID;
2558
2559 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2560 //should have a higher priority than the right one. Pipe priorities are
2561 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002562
Saurabh Shahc62f3982014-03-05 14:28:26 -08002563 Overlay::PipeSpecs pipeSpecs;
2564 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2565 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2566 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2567 pipeSpecs.dpy = mDpy;
2568 pipeSpecs.fb = false;
2569
Saurabh Shahab47c692014-02-12 18:45:57 -08002570 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002571 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002572 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002573 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002574 }
2575
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002576 /* Use 2 pipes IF
2577 a) Layer's crop width is > 2048 or
2578 b) Layer's dest width > 2048 or
2579 c) On primary, driver has indicated with caps to split always. This is
2580 based on an empirically derived value of panel height. Applied only
2581 if the layer's width is > mixer's width
2582 */
2583
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302584 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002585 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302586 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002587 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2588 const uint32_t dstWidth = dst.right - dst.left;
2589 const uint32_t dstHeight = dst.bottom - dst.top;
2590 const uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002591 crop.right - crop.left;
Saurabh Shah514759d2014-11-11 18:02:24 -08002592 const uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
2593 crop.bottom - crop.top;
2594 //Approximation to actual clock, ignoring the common factors in pipe and
2595 //mixer cases like line_time
2596 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2597 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002598
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002599 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2600 //pipe line length, we are still using 2 pipes. This is fine just because
2601 //this is source split where destination doesn't matter. Evaluate later to
2602 //see if going through all the calcs to save a pipe is worth it
Saurabh Shah514759d2014-11-11 18:02:24 -08002603 if(dstWidth > mdpHw.getMaxMixerWidth() or
2604 cropWidth > mdpHw.getMaxMixerWidth() or
2605 (primarySplitAlways and
2606 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002607 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002608 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002609 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002610 }
2611
2612 // Return values
2613 // 1 Left pipe is higher priority, do nothing.
2614 // 0 Pipes of same priority.
2615 //-1 Right pipe is of higher priority, needs swap.
2616 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2617 pipe_info.rIndex) == -1) {
2618 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002619 }
2620 }
2621
2622 return true;
2623}
2624
Saurabh Shahab47c692014-02-12 18:45:57 -08002625int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2626 PipeLayerPair& PipeLayerPair) {
2627 private_handle_t *hnd = (private_handle_t *)layer->handle;
2628 if(!hnd) {
2629 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2630 return -1;
2631 }
2632 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2633 MdpPipeInfoSplit& mdp_info =
2634 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2635 Rotator **rot = &PipeLayerPair.rot;
2636 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002637 eDest lDest = mdp_info.lIndex;
2638 eDest rDest = mdp_info.rIndex;
2639 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2640 hwc_rect_t dst = layer->displayFrame;
2641 int transform = layer->transform;
2642 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002643 int rotFlags = ROT_FLAGS_NONE;
2644 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2645 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2646
2647 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2648 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2649
2650 // Handle R/B swap
2651 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2652 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2653 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2654 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2655 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2656 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002657 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002658 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2659 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002660 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002661 /* Calculate the external display position based on MDP downscale,
2662 ActionSafe, and extorientation features. */
2663 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002664
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002665 int downscale = getRotDownscale(ctx, layer);
Justin Philipd6166602014-08-12 13:42:21 +05302666 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002667 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002668
2669 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2670 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002671 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002672 }
2673
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002674 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002675 (*rot) = ctx->mRotMgr->getNext();
2676 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002677 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002678 //If the video is using a single pipe, enable BWC
2679 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002680 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2681 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002682 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002683 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002684 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002685 ALOGE("%s: configRotator failed!", __FUNCTION__);
2686 return -1;
2687 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002688 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002689 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002690 }
2691
2692 //If 2 pipes being used, divide layer into half, crop and dst
2693 hwc_rect_t cropL = crop;
2694 hwc_rect_t cropR = crop;
2695 hwc_rect_t dstL = dst;
2696 hwc_rect_t dstR = dst;
2697 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2698 cropL.right = (crop.right + crop.left) / 2;
2699 cropR.left = cropL.right;
2700 sanitizeSourceCrop(cropL, cropR, hnd);
2701
Saurabh Shahb729b192014-08-15 18:04:24 -07002702 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002703 //Swap crops on H flip since 2 pipes are being used
2704 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2705 hwc_rect_t tmp = cropL;
2706 cropL = cropR;
2707 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002708 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002709 }
2710
Saurabh Shahb729b192014-08-15 18:04:24 -07002711 //cropSwap trick: If the src and dst widths are both odd, let us say
2712 //2507, then splitting both into half would cause left width to be 1253
2713 //and right 1254. If crop is swapped because of H flip, this will cause
2714 //left crop width to be 1254, whereas left dst width remains 1253, thus
2715 //inducing a scaling that is unaccounted for. To overcome that we add 1
2716 //to the dst width if there is a cropSwap. So if the original width was
2717 //2507, the left dst width will be 1254. Even if the original width was
2718 //even for ex: 2508, the left dst width will still remain 1254.
2719 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002720 dstR.left = dstL.right;
2721 }
2722
2723 //For the mdp, since either we are pre-rotating or MDP does flips
2724 orient = OVERLAY_TRANSFORM_0;
2725 transform = 0;
2726
2727 //configure left pipe
2728 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002729 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002730 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2731 (ovutils::eBlending) getBlending(layer->blending));
2732
2733 if(configMdp(ctx->mOverlay, pargL, orient,
2734 cropL, dstL, metadata, lDest) < 0) {
2735 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2736 return -1;
2737 }
2738 }
2739
2740 //configure right pipe
2741 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002742 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002743 static_cast<eRotFlags>(rotFlags),
2744 layer->planeAlpha,
2745 (ovutils::eBlending) getBlending(layer->blending));
2746 if(configMdp(ctx->mOverlay, pargR, orient,
2747 cropR, dstR, metadata, rDest) < 0) {
2748 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2749 return -1;
2750 }
2751 }
2752
2753 return 0;
2754}
2755
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002756}; //namespace
2757