blob: 9426106f70f01c961ef6296ce31172f49ee17af7 [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;
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +053049bool MDPComp::enablePartialUpdateForMDP3 = false;
Saurabh Shah88e4d272013-09-03 13:31:29 -070050MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070051 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
52 sSrcSplitEnabled = true;
53 return new MDPCompSrcSplit(dpy);
54 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070055 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080056 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070057 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080058}
59
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080060MDPComp::MDPComp(int dpy):mDpy(dpy){};
61
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070062void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080063{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070064 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
65 return;
66
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080067 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070068 (mDpy == 0) ? "\"PRIMARY\"" :
69 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070070 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
71 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080072 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
73 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
74 (mCurrentFrame.needsRedraw? "YES" : "NO"),
75 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070076 if(isDisplaySplit(ctx, mDpy)) {
77 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
78 "Right: [%d, %d, %d, %d] \n",
79 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
80 ctx->listStats[mDpy].lRoi.right,
81 ctx->listStats[mDpy].lRoi.bottom,
82 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
83 ctx->listStats[mDpy].rRoi.right,
84 ctx->listStats[mDpy].rRoi.bottom);
85 } else {
86 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
87 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
88 ctx->listStats[mDpy].lRoi.right,
89 ctx->listStats[mDpy].lRoi.bottom);
90 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080091 dumpsys_log(buf," --------------------------------------------- \n");
92 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
93 dumpsys_log(buf," --------------------------------------------- \n");
94 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
95 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
96 index,
97 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070098 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080099 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700100 (mCurrentFrame.drop[index] ? "DROP" :
101 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800102 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
103 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
104 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800105}
106
107bool MDPComp::init(hwc_context_t *ctx) {
108
109 if(!ctx) {
110 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
111 return false;
112 }
113
Saurabh Shah59562ff2014-09-30 16:13:12 -0700114 char property[PROPERTY_VALUE_MAX] = {0};
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800115
116 sEnabled = false;
117 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800118 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
119 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800120 sEnabled = true;
121 }
122
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700123 sEnableMixedMode = true;
124 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
125 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
126 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
127 sEnableMixedMode = false;
128 }
129
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700130 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
131
132 /* MDSS_MDP_STAGE_UNUSED and MDSS_MDP_STAGE_BASE are not available for MDP
133 * composition. */
134 sMaxPipesPerMixer = (int)mdpVersion.getBlendStages() - 2;
135 if(property_get("persist.hwc.mdpcomp.maxpermixer", property, "-1") > 0) {
Saurabh Shah85234ec2013-04-12 17:09:00 -0700136 int val = atoi(property);
137 if(val >= 0)
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700138 sMaxPipesPerMixer = min(val, sMaxPipesPerMixer);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800139 }
140
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400141 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
Saurabh Shah59562ff2014-09-30 16:13:12 -0700142 sIdleInvalidator = IdleInvalidator::getInstance();
143 if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
144 delete sIdleInvalidator;
145 sIdleInvalidator = NULL;
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400146 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800147 }
radhakrishnac9a67412013-09-25 17:40:42 +0530148
Saurabh Shah7c727642014-06-02 15:47:14 -0700149 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700150 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700151 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
152 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
153 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530154 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530155 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700156
Dileep Kumar Reddic6ef3472014-09-24 19:07:08 +0530157 bool defaultPTOR = false;
158 //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
159 //8x16 and 8x39 targets by default
160 if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
161 (qdutils::MDPVersion::getInstance().is8x16() ||
162 qdutils::MDPVersion::getInstance().is8x39())) {
163 defaultPTOR = true;
164 }
165
166 if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
167 (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700168 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
169 HWC_DISPLAY_PRIMARY);
170 }
171
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +0530172 if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
173 (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
174 enablePartialUpdateForMDP3 = true;
175 }
176
177 if(!enablePartialUpdateForMDP3 &&
178 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
179 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
180 enablePartialUpdateForMDP3 = true;
181 }
182
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700183 return true;
184}
185
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800186void MDPComp::reset(hwc_context_t *ctx) {
187 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700188 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800189 ctx->mOverlay->clear(mDpy);
190 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700191}
192
Raj Kamal4393eaa2014-06-06 13:45:20 +0530193void MDPComp::reset() {
194 sHandleTimeout = false;
195 mModeOn = false;
196}
197
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700198void MDPComp::timeout_handler(void *udata) {
199 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
200
201 if(!ctx) {
202 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
203 return;
204 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800205 Locker::Autolock _l(ctx->mDrawLock);
206 // Handle timeout event only if the previous composition is MDP or MIXED.
207 if(!sHandleTimeout) {
208 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
209 return;
210 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700211 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700212 ALOGE("%s: HWC proc not registered", __FUNCTION__);
213 return;
214 }
215 sIdleFallBack = true;
216 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700217 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700218}
219
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700220void MDPComp::setMaxPipesPerMixer(const uint32_t value) {
221 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
222 uint32_t maxSupported = (int)mdpVersion.getBlendStages() - 2;
223 if(value > maxSupported) {
224 ALOGW("%s: Input exceeds max value supported. Setting to"
225 "max value: %d", __FUNCTION__, maxSupported);
226 }
227 sMaxPipesPerMixer = min(value, maxSupported);
228}
229
Saurabh Shah59562ff2014-09-30 16:13:12 -0700230void MDPComp::setIdleTimeout(const uint32_t& timeout) {
231 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
232
233 if(sIdleInvalidator) {
234 if(timeout <= ONE_REFRESH_PERIOD_MS) {
235 //If the specified timeout is < 1 draw cycle worth, "virtually"
236 //disable idle timeout. The ideal way for clients to disable
237 //timeout is to set it to 0
238 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
239 ALOGI("Disabled idle timeout");
240 return;
241 }
242 sIdleInvalidator->setIdleTimeout(timeout);
243 ALOGI("Idle timeout set to %u", timeout);
244 } else {
245 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
246 }
247}
248
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800249void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800250 hwc_display_contents_1_t* list) {
251 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800252
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800253 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800254 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800255 if(!mCurrentFrame.isFBComposed[index]) {
256 layerProp[index].mFlags |= HWC_MDPCOMP;
257 layer->compositionType = HWC_OVERLAY;
258 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800259 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700260 /* Drop the layer when its already present in FB OR when it lies
261 * outside frame's ROI */
262 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800263 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700264 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800265 }
266 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700267}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500268
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800269void MDPComp::setRedraw(hwc_context_t *ctx,
270 hwc_display_contents_1_t* list) {
271 mCurrentFrame.needsRedraw = false;
272 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
273 (list->flags & HWC_GEOMETRY_CHANGED) ||
274 isSkipPresent(ctx, mDpy)) {
275 mCurrentFrame.needsRedraw = true;
276 }
277}
278
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800279MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700280 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700281 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800282}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800283
Saurabh Shahaa236822013-04-24 18:07:26 -0700284void MDPComp::FrameInfo::reset(const int& numLayers) {
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700285 for(int i = 0 ; i < MAX_NUM_BLEND_STAGES; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800286 if(mdpToLayer[i].pipeInfo) {
287 delete mdpToLayer[i].pipeInfo;
288 mdpToLayer[i].pipeInfo = NULL;
289 //We dont own the rotator
290 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800291 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800292 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800293
294 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
295 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700296 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800297
Saurabh Shahaa236822013-04-24 18:07:26 -0700298 layerCount = numLayers;
299 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800300 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700301 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800302 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800303}
304
Saurabh Shahaa236822013-04-24 18:07:26 -0700305void MDPComp::FrameInfo::map() {
306 // populate layer and MDP maps
307 int mdpIdx = 0;
308 for(int idx = 0; idx < layerCount; idx++) {
309 if(!isFBComposed[idx]) {
310 mdpToLayer[mdpIdx].listIndex = idx;
311 layerToMDP[idx] = mdpIdx++;
312 }
313 }
314}
315
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800316MDPComp::LayerCache::LayerCache() {
317 reset();
318}
319
320void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700321 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530322 memset(&isFBComposed, true, sizeof(isFBComposed));
323 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800324 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700325}
326
327void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530328 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700329 for(int i = 0; i < numAppLayers; i++) {
330 hnd[i] = list->hwLayers[i].handle;
331 }
332}
333
334void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700335 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530336 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
337 memcpy(&drop, &curFrame.drop, sizeof(drop));
338}
339
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800340bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
341 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530342 if(layerCount != curFrame.layerCount)
343 return false;
344 for(int i = 0; i < curFrame.layerCount; i++) {
345 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
346 (curFrame.drop[i] != drop[i])) {
347 return false;
348 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800349 if(curFrame.isFBComposed[i] &&
350 (hnd[i] != list->hwLayers[i].handle)){
351 return false;
352 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530353 }
354 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800355}
356
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700357bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
358 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800359 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700360 (not isValidDimension(ctx,layer))
361 //More conditions here, SKIP, sRGB+Blend etc
362 ) {
363 return false;
364 }
365 return true;
366}
367
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530368bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800369 private_handle_t *hnd = (private_handle_t *)layer->handle;
370
371 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700372 if (layer->flags & HWC_COLOR_FILL) {
373 // Color layer
374 return true;
375 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700376 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800377 return false;
378 }
379
Naseer Ahmede850a802013-09-06 13:12:52 -0400380 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400381 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400382 return false;
383
Saurabh Shah62e1d732013-09-17 10:44:05 -0700384 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700385 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700386 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700387 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
388 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700389 int dst_w = dst.right - dst.left;
390 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800391 float w_scale = ((float)crop_w / (float)dst_w);
392 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530393 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700394
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800395 /* Workaround for MDP HW limitation in DSI command mode panels where
396 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
397 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530398 * There also is a HW limilation in MDP, minimum block size is 2x2
399 * Fallback to GPU if height is less than 2.
400 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700401 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800402 return false;
403
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800404 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530405 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800406 const float w_dscale = w_scale;
407 const float h_dscale = h_scale;
408
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800409 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700410
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530411 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700412 /* On targets that doesnt support Decimation (eg.,8x26)
413 * maximum downscale support is overlay pipe downscale.
414 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400415 if(crop_w > (int) mdpHw.getMaxMixerWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530416 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700417 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800418 return false;
419 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700420 // Decimation on macrotile format layers is not supported.
421 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530422 /* Bail out if
423 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700424 * 2. exceeds maximum downscale limit
425 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400426 if(((crop_w > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530427 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700428 w_dscale > maxMDPDownscale ||
429 h_dscale > maxMDPDownscale) {
430 return false;
431 }
432 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800433 return false;
434 }
435 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700436 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700437 return false;
438 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700439 }
440
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800441 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530442 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800443 const float w_uscale = 1.0f / w_scale;
444 const float h_uscale = 1.0f / h_scale;
445
446 if(w_uscale > upscale || h_uscale > upscale)
447 return false;
448 }
449
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800450 return true;
451}
452
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800453bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700454 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800455
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800456 if(!isEnabled()) {
457 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700458 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530459 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530460 qdutils::MDPVersion::getInstance().is8x16() ||
461 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800462 ctx->mVideoTransFlag &&
463 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700464 //1 Padding round to shift pipes across mixers
465 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
466 __FUNCTION__);
467 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700468 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
469 /* TODO: freeing up all the resources only for the targets having total
470 number of pipes < 8. Need to analyze number of VIG pipes used
471 for primary in previous draw cycle and accordingly decide
472 whether to fall back to full GPU comp or video only comp
473 */
474 if(isSecondaryConfiguring(ctx)) {
475 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
476 __FUNCTION__);
477 ret = false;
478 } else if(ctx->isPaddingRound) {
479 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
480 __FUNCTION__,mDpy);
481 ret = false;
482 }
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700483 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700484 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800485}
486
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800487void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
488 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
489 fbRect = getIntersection(fbRect, roi);
490}
491
492/* 1) Identify layers that are not visible or lying outside the updating ROI and
493 * drop them from composition.
494 * 2) If we have a scaling layer which needs cropping against generated
495 * ROI, reset ROI to full resolution. */
496bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
497 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700498 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800499 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800500
501 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800502 if(!isValidRect(visibleRect)) {
503 mCurrentFrame.drop[i] = true;
504 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800505 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800506 }
507
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700508 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700509 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800510 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700511
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700512 if(!isValidRect(res)) {
513 mCurrentFrame.drop[i] = true;
514 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800515 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700516 /* Reset frame ROI when any layer which needs scaling also needs ROI
517 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800518 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800519 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700520 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
521 mCurrentFrame.dropCount = 0;
522 return false;
523 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800524
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800525 /* deduct any opaque region from visibleRect */
526 if (layer->blending == HWC_BLENDING_NONE)
527 visibleRect = deductRect(visibleRect, res);
528 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700529 }
530 return true;
531}
532
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800533/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
534 * are updating. If DirtyRegion is applicable, calculate it by accounting all
535 * the changing layer's dirtyRegion. */
536void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
537 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700538 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800539 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700540 return;
541
542 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800543 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
544 (int)ctx->dpyAttr[mDpy].yres};
545
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700546 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800547 hwc_layer_1_t* layer = &list->hwLayers[index];
548 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800549 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700550 hwc_rect_t dst = layer->displayFrame;
551 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800552
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800553#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800554 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700555 {
556 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
557 int x_off = dst.left - src.left;
558 int y_off = dst.top - src.top;
559 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
560 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800561#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800562
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800563 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700564 }
565 }
566
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800567 /* No layer is updating. Still SF wants a refresh.*/
568 if(!isValidRect(roi))
569 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800570
571 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800572 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800573
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800574 ctx->listStats[mDpy].lRoi = roi;
575 if(!validateAndApplyROI(ctx, list))
576 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700577
578 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800579 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
580 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
581}
582
583void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
584 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
585 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
586
587 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
588 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
589 fbRect = getUnion(l_fbRect, r_fbRect);
590}
591/* 1) Identify layers that are not visible or lying outside BOTH the updating
592 * ROI's and drop them from composition. If a layer is spanning across both
593 * the halves of the screen but needed by only ROI, the non-contributing
594 * half will not be programmed for MDP.
595 * 2) If we have a scaling layer which needs cropping against generated
596 * ROI, reset ROI to full resolution. */
597bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
598 hwc_display_contents_1_t* list) {
599
600 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
601
602 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
603 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
604
605 for(int i = numAppLayers - 1; i >= 0; i--){
606 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
607 {
608 mCurrentFrame.drop[i] = true;
609 mCurrentFrame.dropCount++;
610 continue;
611 }
612
613 const hwc_layer_1_t* layer = &list->hwLayers[i];
614 hwc_rect_t dstRect = layer->displayFrame;
615
616 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
617 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
618 hwc_rect_t res = getUnion(l_res, r_res);
619
620 if(!isValidRect(l_res) && !isValidRect(r_res)) {
621 mCurrentFrame.drop[i] = true;
622 mCurrentFrame.dropCount++;
623 } else {
624 /* Reset frame ROI when any layer which needs scaling also needs ROI
625 * cropping */
626 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
627 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
628 mCurrentFrame.dropCount = 0;
629 return false;
630 }
631
632 if (layer->blending == HWC_BLENDING_NONE) {
633 visibleRectL = deductRect(visibleRectL, l_res);
634 visibleRectR = deductRect(visibleRectR, r_res);
635 }
636 }
637 }
638 return true;
639}
640/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
641 * are updating. If DirtyRegion is applicable, calculate it by accounting all
642 * the changing layer's dirtyRegion. */
643void MDPCompSplit::generateROI(hwc_context_t *ctx,
644 hwc_display_contents_1_t* list) {
645 if(!canPartialUpdate(ctx, list))
646 return;
647
648 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
649 int lSplit = getLeftSplit(ctx, mDpy);
650
651 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
652 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
653
654 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
655 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
656
657 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
658 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
659
660 for(int index = 0; index < numAppLayers; index++ ) {
661 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800662 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800663 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800664 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700665 hwc_rect_t dst = layer->displayFrame;
666 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800667
668#ifdef QCOM_BSP
669 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700670 {
671 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
672 int x_off = dst.left - src.left;
673 int y_off = dst.top - src.top;
674 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
675 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800676#endif
677
678 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
679 if(isValidRect(l_dst))
680 l_roi = getUnion(l_roi, l_dst);
681
682 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
683 if(isValidRect(r_dst))
684 r_roi = getUnion(r_roi, r_dst);
685 }
686 }
687
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700688 /* For panels that cannot accept commands in both the interfaces, we cannot
689 * send two ROI's (for each half). We merge them into single ROI and split
690 * them across lSplit for MDP mixer use. The ROI's will be merged again
691 * finally before udpating the panel in the driver. */
692 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
693 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
694 l_roi = getIntersection(temp_roi, l_frame);
695 r_roi = getIntersection(temp_roi, r_frame);
696 }
697
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800698 /* No layer is updating. Still SF wants a refresh. */
699 if(!isValidRect(l_roi) && !isValidRect(r_roi))
700 return;
701
702 l_roi = getSanitizeROI(l_roi, l_frame);
703 r_roi = getSanitizeROI(r_roi, r_frame);
704
705 ctx->listStats[mDpy].lRoi = l_roi;
706 ctx->listStats[mDpy].rRoi = r_roi;
707
708 if(!validateAndApplyROI(ctx, list))
709 resetROI(ctx, mDpy);
710
711 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
712 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
713 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
714 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
715 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
716 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700717}
718
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800719/* Checks for conditions where all the layers marked for MDP comp cannot be
720 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800721bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800722 hwc_display_contents_1_t* list){
723
Saurabh Shahaa236822013-04-24 18:07:26 -0700724 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800725 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800726
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700727 // Fall back to video only composition, if AIV video mode is enabled
728 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700729 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
730 __FUNCTION__, mDpy);
731 return false;
732 }
733
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400734 // No Idle fall back, if secure display or secure RGB layers are present or
735 // if there's only a single layer being composed
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -0700736 if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400737 !ctx->listStats[mDpy].secureRGBCount) &&
738 (ctx->listStats[mDpy].numAppLayers != 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700739 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
740 return false;
741 }
742
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800743 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700744 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
745 __FUNCTION__,
746 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800747 return false;
748 }
749
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700750 // if secondary is configuring or Padding round, fall back to video only
751 // composition and release all assigned non VIG pipes from primary.
752 if(isSecondaryConfiguring(ctx)) {
753 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
754 __FUNCTION__);
755 return false;
756 } else if(ctx->isPaddingRound) {
757 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
758 __FUNCTION__,mDpy);
759 return false;
760 }
761
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530762 MDPVersion& mdpHw = MDPVersion::getInstance();
763 if(mDpy > HWC_DISPLAY_PRIMARY &&
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400764 (priDispW > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530765 (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800766 // Disable MDP comp on Secondary when the primary is highres panel and
767 // the secondary is a normal 1080p, because, MDP comp on secondary under
768 // in such usecase, decimation gets used for downscale and there will be
769 // a quality mismatch when there will be a fallback to GPU comp
770 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
771 __FUNCTION__);
772 return false;
773 }
774
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700775 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800776 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700777 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800778 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
779 return false;
780 }
781
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800782 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800783 hwc_layer_1_t* layer = &list->hwLayers[i];
784 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800785
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800786 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700787 if(!canUseRotator(ctx, mDpy)) {
788 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
789 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700790 return false;
791 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800792 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530793
794 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
795 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700796 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530797 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
798 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
799 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800800 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700801
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700802 if(ctx->mAD->isDoable()) {
803 return false;
804 }
805
Saurabh Shahaa236822013-04-24 18:07:26 -0700806 //If all above hard conditions are met we can do full or partial MDP comp.
807 bool ret = false;
808 if(fullMDPComp(ctx, list)) {
809 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700810 } else if(fullMDPCompWithPTOR(ctx, list)) {
811 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700812 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700813 ret = true;
814 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530815
Saurabh Shahaa236822013-04-24 18:07:26 -0700816 return ret;
817}
818
819bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700820
821 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
822 return false;
823
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700824 //Will benefit presentation / secondary-only layer.
825 if((mDpy > HWC_DISPLAY_PRIMARY) &&
826 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
827 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
828 return false;
829 }
830
831 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
832 for(int i = 0; i < numAppLayers; i++) {
833 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700834 if(not mCurrentFrame.drop[i] and
835 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700836 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
837 return false;
838 }
839 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800840
Saurabh Shahaa236822013-04-24 18:07:26 -0700841 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700842 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
843 sizeof(mCurrentFrame.isFBComposed));
844 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
845 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700846
Raj Kamal389d6e32014-08-04 14:43:24 +0530847 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800848 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530849 }
850
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800851 if(!postHeuristicsHandling(ctx, list)) {
852 ALOGD_IF(isDebug(), "post heuristic handling failed");
853 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700854 return false;
855 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700856 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
857 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700858 return true;
859}
860
Sushil Chauhandefd3522014-05-13 18:17:12 -0700861/* Full MDP Composition with Peripheral Tiny Overlap Removal.
862 * MDP bandwidth limitations can be avoided, if the overlap region
863 * covered by the smallest layer at a higher z-order, gets composed
864 * by Copybit on a render buffer, which can be queued to MDP.
865 */
866bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
867 hwc_display_contents_1_t* list) {
868
869 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
870 const int stagesForMDP = min(sMaxPipesPerMixer,
871 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
872
873 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700874 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700875 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
876 return false;
877 }
878
879 // Frame level checks
880 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
881 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
882 isSecurePresent(ctx, mDpy)) {
883 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
884 return false;
885 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700886 // MDP comp checks
887 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700888 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700889 if(not isSupportedForMDPComp(ctx, layer)) {
890 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
891 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700892 }
893 }
894
Sushil Chauhandefd3522014-05-13 18:17:12 -0700895 /* We cannot use this composition mode, if:
896 1. A below layer needs scaling.
897 2. Overlap is not peripheral to display.
898 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700899 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700900 */
901
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700902 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
903 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
904 memset(overlapRect, 0, sizeof(overlapRect));
905 int layerPixelCount, minPixelCount = 0;
906 int numPTORLayersFound = 0;
907 for (int i = numAppLayers-1; (i >= 0 &&
908 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700909 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700910 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700911 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700912 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
913 // PTOR layer should be peripheral and cannot have transform
914 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
915 has90Transform(layer)) {
916 continue;
917 }
918 if((3 * (layerPixelCount + minPixelCount)) >
919 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
920 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
921 continue;
922 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700923 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700924 for (int j = i-1; j >= 0; j--) {
925 // Check if the layers below this layer qualifies for PTOR comp
926 hwc_layer_1_t* layer = &list->hwLayers[j];
927 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700928 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700929 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700930 if (isValidRect(getIntersection(dispFrame, disFrame))) {
931 if (has90Transform(layer) || needsScaling(layer)) {
932 found = false;
933 break;
934 }
935 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700936 }
937 }
938 // Store the minLayer Index
939 if(found) {
940 minLayerIndex[numPTORLayersFound] = i;
941 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
942 minPixelCount += layerPixelCount;
943 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700944 }
945 }
946
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700947 // No overlap layers
948 if (!numPTORLayersFound)
949 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700950
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700951 // Store the displayFrame and the sourceCrops of the layers
952 hwc_rect_t displayFrame[numAppLayers];
953 hwc_rect_t sourceCrop[numAppLayers];
954 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700955 hwc_layer_1_t* layer = &list->hwLayers[i];
956 displayFrame[i] = layer->displayFrame;
957 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700958 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700959
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530960 /**
961 * It's possible that 2 PTOR layers might have overlapping.
962 * In such case, remove the intersection(again if peripheral)
963 * from the lower PTOR layer to avoid overlapping.
964 * If intersection is not on peripheral then compromise
965 * by reducing number of PTOR layers.
966 **/
967 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
968 if(isValidRect(commonRect)) {
969 overlapRect[1] = deductRect(overlapRect[1], commonRect);
970 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
971 }
972
973 ctx->mPtorInfo.count = numPTORLayersFound;
974 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
975 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
976 }
977
978 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
979 // reset PTOR
980 ctx->mPtorInfo.count = 0;
981 if(isValidRect(commonRect)) {
982 // If PTORs are intersecting restore displayframe of PTOR[1]
983 // before returning, as we have modified it above.
984 list->hwLayers[minLayerIndex[1]].displayFrame =
985 displayFrame[minLayerIndex[1]];
986 }
987 return false;
988 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700989 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
990 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
991
Xu Yangcda012c2014-07-30 21:57:21 +0800992 // Store the blending mode, planeAlpha, and transform of PTOR layers
993 int32_t blending[numPTORLayersFound];
994 uint8_t planeAlpha[numPTORLayersFound];
995 uint32_t transform[numPTORLayersFound];
996
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700997 for(int j = 0; j < numPTORLayersFound; j++) {
998 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700999
1000 // Update src crop of PTOR layer
1001 hwc_layer_1_t* layer = &list->hwLayers[index];
1002 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1003 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1004 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1005 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1006
1007 // Store & update w, h, format of PTOR layer
1008 private_handle_t *hnd = (private_handle_t *)layer->handle;
1009 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1010 layerWhf[j] = whf;
1011 hnd->width = renderBuf->width;
1012 hnd->height = renderBuf->height;
1013 hnd->format = renderBuf->format;
1014
Xu Yangcda012c2014-07-30 21:57:21 +08001015 // Store & update blending mode, planeAlpha and transform of PTOR layer
1016 blending[j] = layer->blending;
1017 planeAlpha[j] = layer->planeAlpha;
1018 transform[j] = layer->transform;
1019 layer->blending = HWC_BLENDING_NONE;
1020 layer->planeAlpha = 0xFF;
1021 layer->transform = 0;
1022
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001023 // Remove overlap from crop & displayFrame of below layers
1024 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001025 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001026 if(!isValidRect(getIntersection(layer->displayFrame,
1027 overlapRect[j]))) {
1028 continue;
1029 }
1030 // Update layer attributes
1031 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1032 hwc_rect_t destRect = deductRect(layer->displayFrame,
1033 overlapRect[j]);
1034 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1035 layer->transform);
1036 layer->sourceCropf.left = (float)srcCrop.left;
1037 layer->sourceCropf.top = (float)srcCrop.top;
1038 layer->sourceCropf.right = (float)srcCrop.right;
1039 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1040 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001041 }
1042
1043 mCurrentFrame.mdpCount = numAppLayers;
1044 mCurrentFrame.fbCount = 0;
1045 mCurrentFrame.fbZ = -1;
1046
1047 for (int j = 0; j < numAppLayers; j++)
1048 mCurrentFrame.isFBComposed[j] = false;
1049
1050 bool result = postHeuristicsHandling(ctx, list);
1051
1052 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001053 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001054 hwc_layer_1_t* layer = &list->hwLayers[i];
1055 layer->displayFrame = displayFrame[i];
1056 layer->sourceCropf.left = (float)sourceCrop[i].left;
1057 layer->sourceCropf.top = (float)sourceCrop[i].top;
1058 layer->sourceCropf.right = (float)sourceCrop[i].right;
1059 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1060 }
1061
Xu Yangcda012c2014-07-30 21:57:21 +08001062 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001063 for (int i = 0; i < numPTORLayersFound; i++) {
1064 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001065 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001066 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1067 hnd->width = layerWhf[i].w;
1068 hnd->height = layerWhf[i].h;
1069 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001070 layer->blending = blending[i];
1071 layer->planeAlpha = planeAlpha[i];
1072 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001073 }
1074
Sushil Chauhandefd3522014-05-13 18:17:12 -07001075 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001076 // reset PTOR
1077 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001078 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001079 } else {
1080 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1081 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001082 }
1083
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001084 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1085 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001086 return result;
1087}
1088
Saurabh Shahaa236822013-04-24 18:07:26 -07001089bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1090{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001091 if(!sEnableMixedMode) {
1092 //Mixed mode is disabled. No need to even try caching.
1093 return false;
1094 }
1095
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001096 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001097 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001098 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001099 cacheBasedComp(ctx, list);
1100 } else {
1101 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001102 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001103 }
1104
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001105 return ret;
1106}
1107
1108bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1109 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001110 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1111 return false;
1112
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001113 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001114 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001115 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001116
1117 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1118 for(int i = 0; i < numAppLayers; i++) {
1119 if(!mCurrentFrame.isFBComposed[i]) {
1120 hwc_layer_1_t* layer = &list->hwLayers[i];
1121 if(not isSupportedForMDPComp(ctx, layer)) {
1122 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1123 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001124 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001125 return false;
1126 }
1127 }
1128 }
1129
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001130 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001131 /* mark secure RGB layers for MDP comp */
1132 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301133 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001134 if(!ret) {
1135 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001136 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001137 return false;
1138 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001139
1140 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001141
Raj Kamal389d6e32014-08-04 14:43:24 +05301142 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001143 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301144 }
1145
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001146 //Will benefit cases where a video has non-updating background.
1147 if((mDpy > HWC_DISPLAY_PRIMARY) and
1148 (mdpCount > MAX_SEC_LAYERS)) {
1149 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001150 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001151 return false;
1152 }
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;
Saurabh Shahaa236822013-04-24 18:07:26 -07001286 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001287
Saurabh Shahaa236822013-04-24 18:07:26 -07001288 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001289 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001290 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001291 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001292
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001293 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1294 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001295 return false;
1296 }
1297
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001298 /* Bail out if we are processing only secured video layers
1299 * and we dont have any */
1300 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001301 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001302 return false;
1303 }
1304
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001305 if(mCurrentFrame.fbCount)
1306 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001307
Raj Kamal389d6e32014-08-04 14:43:24 +05301308 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001309 adjustForSourceSplit(ctx, list);
1310 }
1311
1312 if(!postHeuristicsHandling(ctx, list)) {
1313 ALOGD_IF(isDebug(), "post heuristic handling failed");
1314 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001315 return false;
1316 }
1317
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001318 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1319 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001320 return true;
1321}
1322
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001323/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1324bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1325 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001326 // Fall back to video only composition, if AIV video mode is enabled
1327 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001328 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1329 __FUNCTION__, mDpy);
1330 return false;
1331 }
1332
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001333 const bool secureOnly = true;
1334 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1335 mdpOnlyLayersComp(ctx, list, secureOnly);
1336
1337}
1338
1339bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1340 hwc_display_contents_1_t* list, bool secureOnly) {
1341
1342 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1343 return false;
1344
1345 /* Bail out if we are processing only secured video layers
1346 * and we dont have any */
1347 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1348 reset(ctx);
1349 return false;
1350 }
1351
1352 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1353 mCurrentFrame.reset(numAppLayers);
1354 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1355
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001356 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001357 /* mark secure RGB layers for MDP comp */
1358 updateSecureRGB(ctx, list);
1359
1360 if(mCurrentFrame.mdpCount == 0) {
1361 reset(ctx);
1362 return false;
1363 }
1364
1365 /* find the maximum batch of layers to be marked for framebuffer */
1366 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1367 if(!ret) {
1368 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1369 reset(ctx);
1370 return false;
1371 }
1372
1373 if(sEnableYUVsplit){
1374 adjustForSourceSplit(ctx, list);
1375 }
1376
1377 if(!postHeuristicsHandling(ctx, list)) {
1378 ALOGD_IF(isDebug(), "post heuristic handling failed");
1379 reset(ctx);
1380 return false;
1381 }
1382
1383 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1384 __FUNCTION__);
1385 return true;
1386}
1387
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001388/* Checks for conditions where YUV layers cannot be bypassed */
1389bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001390 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001391 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001392 return false;
1393 }
1394
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001395 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001396 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1397 return false;
1398 }
1399
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001400 if(isSecuring(ctx, layer)) {
1401 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1402 return false;
1403 }
1404
Saurabh Shah4fdde762013-04-30 18:47:33 -07001405 if(!isValidDimension(ctx, layer)) {
1406 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1407 __FUNCTION__);
1408 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001409 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001410
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001411 if(layer->planeAlpha < 0xFF) {
1412 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1413 in video only mode",
1414 __FUNCTION__);
1415 return false;
1416 }
1417
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001418 return true;
1419}
1420
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001421/* Checks for conditions where Secure RGB layers cannot be bypassed */
1422bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1423 if(isSkipLayer(layer)) {
1424 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1425 __FUNCTION__, mDpy);
1426 return false;
1427 }
1428
1429 if(isSecuring(ctx, layer)) {
1430 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1431 return false;
1432 }
1433
1434 if(not isSupportedForMDPComp(ctx, layer)) {
1435 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1436 __FUNCTION__);
1437 return false;
1438 }
1439 return true;
1440}
1441
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301442/* starts at fromIndex and check for each layer to find
1443 * if it it has overlapping with any Updating layer above it in zorder
1444 * till the end of the batch. returns true if it finds any intersection */
1445bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1446 int fromIndex, int toIndex) {
1447 for(int i = fromIndex; i < toIndex; i++) {
1448 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1449 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1450 return false;
1451 }
1452 }
1453 }
1454 return true;
1455}
1456
1457/* Checks if given layer at targetLayerIndex has any
1458 * intersection with all the updating layers in beween
1459 * fromIndex and toIndex. Returns true if it finds intersectiion */
1460bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1461 int fromIndex, int toIndex, int targetLayerIndex) {
1462 for(int i = fromIndex; i <= toIndex; i++) {
1463 if(!mCurrentFrame.isFBComposed[i]) {
1464 if(areLayersIntersecting(&list->hwLayers[i],
1465 &list->hwLayers[targetLayerIndex])) {
1466 return true;
1467 }
1468 }
1469 }
1470 return false;
1471}
1472
1473int MDPComp::getBatch(hwc_display_contents_1_t* list,
1474 int& maxBatchStart, int& maxBatchEnd,
1475 int& maxBatchCount) {
1476 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301477 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001478 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301479 while (i < mCurrentFrame.layerCount) {
1480 int batchCount = 0;
1481 int batchStart = i;
1482 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001483 /* Adjust batch Z order with the dropped layers so far */
1484 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301485 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301486 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301487 while(i < mCurrentFrame.layerCount) {
1488 if(!mCurrentFrame.isFBComposed[i]) {
1489 if(!batchCount) {
1490 i++;
1491 break;
1492 }
1493 updatingLayersAbove++;
1494 i++;
1495 continue;
1496 } else {
1497 if(mCurrentFrame.drop[i]) {
1498 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001499 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301500 continue;
1501 } else if(updatingLayersAbove <= 0) {
1502 batchCount++;
1503 batchEnd = i;
1504 i++;
1505 continue;
1506 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1507
1508 // We have a valid updating layer already. If layer-i not
1509 // have overlapping with all updating layers in between
1510 // batch-start and i, then we can add layer i to batch.
1511 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1512 batchCount++;
1513 batchEnd = i;
1514 i++;
1515 continue;
1516 } else if(canPushBatchToTop(list, batchStart, i)) {
1517 //If All the non-updating layers with in this batch
1518 //does not have intersection with the updating layers
1519 //above in z-order, then we can safely move the batch to
1520 //higher z-order. Increment fbZ as it is moving up.
1521 if( firstZReverseIndex < 0) {
1522 firstZReverseIndex = i;
1523 }
1524 batchCount++;
1525 batchEnd = i;
1526 fbZ += updatingLayersAbove;
1527 i++;
1528 updatingLayersAbove = 0;
1529 continue;
1530 } else {
1531 //both failed.start the loop again from here.
1532 if(firstZReverseIndex >= 0) {
1533 i = firstZReverseIndex;
1534 }
1535 break;
1536 }
1537 }
1538 }
1539 }
1540 if(batchCount > maxBatchCount) {
1541 maxBatchCount = batchCount;
1542 maxBatchStart = batchStart;
1543 maxBatchEnd = batchEnd;
1544 fbZOrder = fbZ;
1545 }
1546 }
1547 return fbZOrder;
1548}
1549
1550bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1551 hwc_display_contents_1_t* list) {
1552 /* Idea is to keep as many non-updating(cached) layers in FB and
1553 * send rest of them through MDP. This is done in 2 steps.
1554 * 1. Find the maximum contiguous batch of non-updating layers.
1555 * 2. See if we can improve this batch size for caching by adding
1556 * opaque layers around the batch, if they don't have
1557 * any overlapping with the updating layers in between.
1558 * NEVER mark an updating layer for caching.
1559 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001560
1561 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001562 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001563 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301564 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001565
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001566 /* Nothing is cached. No batching needed */
1567 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001568 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001569 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001570
1571 /* No MDP comp layers, try to use other comp modes */
1572 if(mCurrentFrame.mdpCount == 0) {
1573 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001574 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001575
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301576 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001577
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301578 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001579 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001580 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001581 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301582 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001583 if(!mCurrentFrame.drop[i]){
1584 //If an unsupported layer is being attempted to
1585 //be pulled out we should fail
1586 if(not isSupportedForMDPComp(ctx, layer)) {
1587 return false;
1588 }
1589 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001590 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001591 }
1592 }
1593
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301594 // update the frame data
1595 mCurrentFrame.fbZ = fbZ;
1596 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001597 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001598 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001599
1600 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301601 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001602
1603 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001604}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001605
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001606void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001607 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001608 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001609 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001610
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001611 for(int i = 0; i < numAppLayers; i++) {
1612 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001613 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001614 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001615 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001616 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001617 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001618 }
1619 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001620
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001621 frame.fbCount = fbCount;
1622 frame.mdpCount = frame.layerCount - frame.fbCount
1623 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001624
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001625 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1626 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001627}
1628
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001629// drop other non-AIV layers from external display list.
1630void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001631 hwc_display_contents_1_t* list) {
1632 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1633 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001634 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001635 mCurrentFrame.dropCount++;
1636 mCurrentFrame.drop[i] = true;
1637 }
1638 }
1639 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1640 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1641 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1642 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1643 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1644 mCurrentFrame.dropCount);
1645}
1646
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001647void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001648 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001649 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1650 for(int index = 0;index < nYuvCount; index++){
1651 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1652 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1653
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001654 if(mCurrentFrame.drop[nYuvIndex]) {
1655 continue;
1656 }
1657
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001658 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001659 if(!frame.isFBComposed[nYuvIndex]) {
1660 frame.isFBComposed[nYuvIndex] = true;
1661 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001662 }
1663 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001664 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001665 private_handle_t *hnd = (private_handle_t *)layer->handle;
1666 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001667 frame.isFBComposed[nYuvIndex] = false;
1668 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001669 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001670 }
1671 }
1672 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001673
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001674 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1675 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001676}
1677
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001678void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1679 hwc_display_contents_1_t* list) {
1680 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1681 for(int index = 0;index < nSecureRGBCount; index++){
1682 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1683 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1684
1685 if(!isSecureRGBDoable(ctx, layer)) {
1686 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1687 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1688 mCurrentFrame.fbCount++;
1689 }
1690 } else {
1691 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1692 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1693 mCurrentFrame.fbCount--;
1694 }
1695 }
1696 }
1697
1698 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1699 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1700 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1701 mCurrentFrame.fbCount);
1702}
1703
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001704hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1705 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001706 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001707
1708 /* Update only the region of FB needed for composition */
1709 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1710 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1711 hwc_layer_1_t* layer = &list->hwLayers[i];
1712 hwc_rect_t dst = layer->displayFrame;
1713 fbRect = getUnion(fbRect, dst);
1714 }
1715 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001716 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001717 return fbRect;
1718}
1719
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001720bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1721 hwc_display_contents_1_t* list) {
1722
1723 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001724 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001725 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1726 return false;
1727 }
1728
1729 //Limitations checks
1730 if(!hwLimitationsCheck(ctx, list)) {
1731 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1732 return false;
1733 }
1734
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001735 //Configure framebuffer first if applicable
1736 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001737 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001738 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1739 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001740 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1741 __FUNCTION__);
1742 return false;
1743 }
1744 }
1745
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001746 mCurrentFrame.map();
1747
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001748 if(!allocLayerPipes(ctx, list)) {
1749 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001750 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001751 }
1752
1753 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001754 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001755 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001756 int mdpIndex = mCurrentFrame.layerToMDP[index];
1757 hwc_layer_1_t* layer = &list->hwLayers[index];
1758
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301759 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1760 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1761 mdpNextZOrder++;
1762 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001763 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1764 cur_pipe->zOrder = mdpNextZOrder++;
1765
radhakrishnac9a67412013-09-25 17:40:42 +05301766 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301767 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301768 if(configure4k2kYuv(ctx, layer,
1769 mCurrentFrame.mdpToLayer[mdpIndex])
1770 != 0 ){
1771 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1772 for layer %d",__FUNCTION__, index);
1773 return false;
1774 }
1775 else{
1776 mdpNextZOrder++;
1777 }
1778 continue;
1779 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001780 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1781 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301782 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001783 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001784 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001785 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001786 }
1787
Saurabh Shaha36be922013-12-16 18:18:39 -08001788 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1789 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1790 ,__FUNCTION__, mDpy);
1791 return false;
1792 }
1793
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001794 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001795 return true;
1796}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001797
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001798bool MDPComp::resourceCheck(hwc_context_t* ctx,
1799 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001800 const bool fbUsed = mCurrentFrame.fbCount;
1801 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1802 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1803 return false;
1804 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001805 // Init rotCount to number of rotate sessions used by other displays
1806 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1807 // Count the number of rotator sessions required for current display
1808 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1809 if(!mCurrentFrame.isFBComposed[index]) {
1810 hwc_layer_1_t* layer = &list->hwLayers[index];
1811 private_handle_t *hnd = (private_handle_t *)layer->handle;
1812 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1813 rotCount++;
1814 }
1815 }
1816 }
1817 // if number of layers to rotate exceeds max rotator sessions, bail out.
1818 if(rotCount > RotMgr::MAX_ROT_SESS) {
1819 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1820 __FUNCTION__, mDpy);
1821 return false;
1822 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001823 return true;
1824}
1825
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301826bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1827 hwc_display_contents_1_t* list) {
1828
1829 //A-family hw limitation:
1830 //If a layer need alpha scaling, MDP can not support.
1831 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1832 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1833 if(!mCurrentFrame.isFBComposed[i] &&
1834 isAlphaScaled( &list->hwLayers[i])) {
1835 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1836 return false;
1837 }
1838 }
1839 }
1840
1841 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1842 //If multiple layers requires downscaling and also they are overlapping
1843 //fall back to GPU since MDSS can not handle it.
1844 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1845 qdutils::MDPVersion::getInstance().is8x26()) {
1846 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1847 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1848 if(!mCurrentFrame.isFBComposed[i] &&
1849 isDownscaleRequired(botLayer)) {
1850 //if layer-i is marked for MDP and needs downscaling
1851 //check if any MDP layer on top of i & overlaps with layer-i
1852 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1853 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1854 if(!mCurrentFrame.isFBComposed[j] &&
1855 isDownscaleRequired(topLayer)) {
1856 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1857 topLayer->displayFrame);
1858 if(isValidRect(r))
1859 return false;
1860 }
1861 }
1862 }
1863 }
1864 }
1865 return true;
1866}
1867
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001868int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001869 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001870 char property[PROPERTY_VALUE_MAX];
1871
Raj Kamal4393eaa2014-06-06 13:45:20 +05301872 if(!ctx || !list) {
1873 ALOGE("%s: Invalid context or list",__FUNCTION__);
1874 mCachedFrame.reset();
1875 return -1;
1876 }
1877
1878 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001879 if(mDpy == HWC_DISPLAY_PRIMARY) {
1880 sSimulationFlags = 0;
1881 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1882 int currentFlags = atoi(property);
1883 if(currentFlags != sSimulationFlags) {
1884 sSimulationFlags = currentFlags;
1885 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1886 sSimulationFlags, sSimulationFlags);
1887 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001888 }
1889 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001890 // reset PTOR
1891 if(!mDpy)
1892 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001893
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301894 //Do not cache the information for next draw cycle.
1895 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1896 ALOGI("%s: Unsupported layer count for mdp composition",
1897 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001898 mCachedFrame.reset();
1899 return -1;
1900 }
1901
Saurabh Shahb39f8152013-08-22 10:21:44 -07001902 //reset old data
1903 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001904 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1905 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301906
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001907 // Detect the start of animation and fall back to GPU only once to cache
1908 // all the layers in FB and display FB content untill animation completes.
1909 if(ctx->listStats[mDpy].isDisplayAnimating) {
1910 mCurrentFrame.needsRedraw = false;
1911 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1912 mCurrentFrame.needsRedraw = true;
1913 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1914 }
1915 setMDPCompLayerFlags(ctx, list);
1916 mCachedFrame.updateCounts(mCurrentFrame);
1917 ret = -1;
1918 return ret;
1919 } else {
1920 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1921 }
1922
Saurabh Shahb39f8152013-08-22 10:21:44 -07001923 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001924 if(isFrameDoable(ctx)) {
1925 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001926 // if AIV Video mode is enabled, drop all non AIV layers from the
1927 // external display list.
1928 if(ctx->listStats[mDpy].mAIVVideoMode) {
1929 dropNonAIVLayers(ctx, list);
1930 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001931
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001932 // if tryFullFrame fails, try to push all video and secure RGB layers
1933 // to MDP for composition.
1934 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001935 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301936 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001937 setMDPCompLayerFlags(ctx, list);
1938 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001939 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001940 reset(ctx);
1941 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1942 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001943 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001944 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1945 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001946 }
1947 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05301948 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
1949 enablePartialUpdateForMDP3) {
1950 generateROI(ctx, list);
1951 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
1952 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
1953 }
1954 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001955 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1956 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001957 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001958 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001959
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001960 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001961 ALOGD("GEOMETRY change: %d",
1962 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001963 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001964 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001965 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001966 }
1967
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001968#ifdef DYNAMIC_FPS
1969 //For primary display, set the dynamic refreshrate
1970 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported()) {
1971 FrameInfo frame;
1972 frame.reset(mCurrentFrame.layerCount);
Raj Kamal18e946e2014-10-10 14:23:47 +05301973 memset(&frame.drop, 0, sizeof(frame.drop));
1974 frame.dropCount = 0;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001975 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
1976 __FUNCTION__);
1977 updateLayerCache(ctx, list, frame);
1978 updateYUV(ctx, list, false /*secure only*/, frame);
1979 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1980 //Set the new fresh rate, if there is only one updating YUV layer
1981 //or there is one single RGB layer with this request
1982 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1983 (frame.layerCount == 1)) {
1984 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1985 }
1986 setRefreshRate(ctx, mDpy, refreshRate);
1987 }
1988#endif
1989
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001990 mCachedFrame.cacheAll(list);
1991 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001992 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001993}
1994
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001995bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301996
1997 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301998 int mdpIndex = mCurrentFrame.layerToMDP[index];
1999 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2000 info.pipeInfo = new MdpYUVPipeInfo;
2001 info.rot = NULL;
2002 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302003
2004 pipe_info.lIndex = ovutils::OV_INVALID;
2005 pipe_info.rIndex = ovutils::OV_INVALID;
2006
Saurabh Shahc62f3982014-03-05 14:28:26 -08002007 Overlay::PipeSpecs pipeSpecs;
2008 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2009 pipeSpecs.needsScaling = true;
2010 pipeSpecs.dpy = mDpy;
2011 pipeSpecs.fb = false;
2012
2013 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302014 if(pipe_info.lIndex == ovutils::OV_INVALID){
2015 bRet = false;
2016 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2017 __FUNCTION__);
2018 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002019 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302020 if(pipe_info.rIndex == ovutils::OV_INVALID){
2021 bRet = false;
2022 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2023 __FUNCTION__);
2024 }
2025 return bRet;
2026}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002027
2028int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2029 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002030 if (ctx->mPtorInfo.isActive()) {
2031 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002032 if (fd < 0) {
2033 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002034 }
2035 }
2036 return fd;
2037}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002038//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002039
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002040void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302041 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002042 //If 4k2k Yuv layer split is possible, and if
2043 //fbz is above 4k2k layer, increment fb zorder by 1
2044 //as we split 4k2k layer and increment zorder for right half
2045 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002046 if(!ctx)
2047 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002048 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302049 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2050 index++) {
2051 if(!mCurrentFrame.isFBComposed[index]) {
2052 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2053 mdpNextZOrder++;
2054 }
2055 mdpNextZOrder++;
2056 hwc_layer_1_t* layer = &list->hwLayers[index];
2057 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302058 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302059 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2060 mCurrentFrame.fbZ += 1;
2061 mdpNextZOrder++;
2062 //As we split 4kx2k yuv layer and program to 2 VG pipes
2063 //(if available) increase mdpcount by 1.
2064 mCurrentFrame.mdpCount++;
2065 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002066 }
2067 }
2068 }
radhakrishnac9a67412013-09-25 17:40:42 +05302069}
2070
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002071/*
2072 * Configures pipe(s) for MDP composition
2073 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002074int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002075 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002076 MdpPipeInfoNonSplit& mdp_info =
2077 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302078 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002079 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002080 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002081
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002082 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2083 __FUNCTION__, layer, zOrder, dest);
2084
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002085 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002086 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002087}
2088
Saurabh Shah88e4d272013-09-03 13:31:29 -07002089bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002090 hwc_display_contents_1_t* list) {
2091 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002092
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002093 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002094
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002095 hwc_layer_1_t* layer = &list->hwLayers[index];
2096 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302097 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002098 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302099 continue;
2100 }
2101 }
2102
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002103 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002104 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002105 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002106 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002107 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002108
Saurabh Shahc62f3982014-03-05 14:28:26 -08002109 Overlay::PipeSpecs pipeSpecs;
2110 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2111 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2112 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2113 (qdutils::MDPVersion::getInstance().is8x26() and
2114 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2115 pipeSpecs.dpy = mDpy;
2116 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002117 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002118
Saurabh Shahc62f3982014-03-05 14:28:26 -08002119 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2120
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002121 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002122 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002123 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002124 }
2125 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002126 return true;
2127}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002128
radhakrishnac9a67412013-09-25 17:40:42 +05302129int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2130 PipeLayerPair& PipeLayerPair) {
2131 MdpYUVPipeInfo& mdp_info =
2132 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2133 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302134 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302135 eDest lDest = mdp_info.lIndex;
2136 eDest rDest = mdp_info.rIndex;
2137
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002138 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302139 lDest, rDest, &PipeLayerPair.rot);
2140}
2141
Saurabh Shah88e4d272013-09-03 13:31:29 -07002142bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002143
Raj Kamal4393eaa2014-06-06 13:45:20 +05302144 if(!isEnabled() or !mModeOn) {
2145 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302146 return true;
2147 }
2148
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002149 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002150 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002151 sHandleTimeout = true;
2152 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002153
2154 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002155 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002156
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002157 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2158 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002159 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002160 if(mCurrentFrame.isFBComposed[i]) continue;
2161
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002162 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002163 private_handle_t *hnd = (private_handle_t *)layer->handle;
2164 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002165 if (!(layer->flags & HWC_COLOR_FILL)) {
2166 ALOGE("%s handle null", __FUNCTION__);
2167 return false;
2168 }
2169 // No PLAY for Color layer
2170 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2171 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002172 }
2173
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002174 int mdpIndex = mCurrentFrame.layerToMDP[i];
2175
Raj Kamal389d6e32014-08-04 14:43:24 +05302176 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302177 {
2178 MdpYUVPipeInfo& pipe_info =
2179 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2180 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2181 ovutils::eDest indexL = pipe_info.lIndex;
2182 ovutils::eDest indexR = pipe_info.rIndex;
2183 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302184 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302185 if(rot) {
2186 rot->queueBuffer(fd, offset);
2187 fd = rot->getDstMemId();
2188 offset = rot->getDstOffset();
2189 }
2190 if(indexL != ovutils::OV_INVALID) {
2191 ovutils::eDest destL = (ovutils::eDest)indexL;
2192 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2193 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2194 if (!ov.queueBuffer(fd, offset, destL)) {
2195 ALOGE("%s: queueBuffer failed for display:%d",
2196 __FUNCTION__, mDpy);
2197 return false;
2198 }
2199 }
2200
2201 if(indexR != ovutils::OV_INVALID) {
2202 ovutils::eDest destR = (ovutils::eDest)indexR;
2203 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2204 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2205 if (!ov.queueBuffer(fd, offset, destR)) {
2206 ALOGE("%s: queueBuffer failed for display:%d",
2207 __FUNCTION__, mDpy);
2208 return false;
2209 }
2210 }
2211 }
2212 else{
2213 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002214 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302215 ovutils::eDest dest = pipe_info.index;
2216 if(dest == ovutils::OV_INVALID) {
2217 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002218 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302219 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002220
radhakrishnac9a67412013-09-25 17:40:42 +05302221 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2222 continue;
2223 }
2224
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002225 int fd = hnd->fd;
2226 uint32_t offset = (uint32_t)hnd->offset;
2227 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2228 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002229 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002230 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002231 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002232 }
2233
radhakrishnac9a67412013-09-25 17:40:42 +05302234 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2235 using pipe: %d", __FUNCTION__, layer,
2236 hnd, dest );
2237
radhakrishnac9a67412013-09-25 17:40:42 +05302238 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2239 if(rot) {
2240 if(!rot->queueBuffer(fd, offset))
2241 return false;
2242 fd = rot->getDstMemId();
2243 offset = rot->getDstOffset();
2244 }
2245
2246 if (!ov.queueBuffer(fd, offset, dest)) {
2247 ALOGE("%s: queueBuffer failed for display:%d ",
2248 __FUNCTION__, mDpy);
2249 return false;
2250 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002251 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002252
2253 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002254 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002255 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002256}
2257
Saurabh Shah88e4d272013-09-03 13:31:29 -07002258//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002259
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002260void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302261 hwc_display_contents_1_t* list){
2262 //if 4kx2k yuv layer is totally present in either in left half
2263 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302264 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302265 if(mCurrentFrame.fbZ >= 0) {
2266 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2267 index++) {
2268 if(!mCurrentFrame.isFBComposed[index]) {
2269 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2270 mdpNextZOrder++;
2271 }
2272 mdpNextZOrder++;
2273 hwc_layer_1_t* layer = &list->hwLayers[index];
2274 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302275 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302276 hwc_rect_t dst = layer->displayFrame;
2277 if((dst.left > lSplit) || (dst.right < lSplit)) {
2278 mCurrentFrame.mdpCount += 1;
2279 }
2280 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2281 mCurrentFrame.fbZ += 1;
2282 mdpNextZOrder++;
2283 }
2284 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002285 }
radhakrishnac9a67412013-09-25 17:40:42 +05302286 }
2287}
2288
Saurabh Shah88e4d272013-09-03 13:31:29 -07002289bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002290 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002291
Saurabh Shahc62f3982014-03-05 14:28:26 -08002292 const int lSplit = getLeftSplit(ctx, mDpy);
2293 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002294 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002295 pipe_info.lIndex = ovutils::OV_INVALID;
2296 pipe_info.rIndex = ovutils::OV_INVALID;
2297
Saurabh Shahc62f3982014-03-05 14:28:26 -08002298 Overlay::PipeSpecs pipeSpecs;
2299 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2300 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2301 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2302 pipeSpecs.dpy = mDpy;
2303 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2304 pipeSpecs.fb = false;
2305
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002306 // Acquire pipe only for the updating half
2307 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2308 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2309
2310 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002311 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002312 if(pipe_info.lIndex == ovutils::OV_INVALID)
2313 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002314 }
2315
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002316 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002317 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2318 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002319 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002320 return false;
2321 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002322
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002323 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002324}
2325
Saurabh Shah88e4d272013-09-03 13:31:29 -07002326bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002327 hwc_display_contents_1_t* list) {
2328 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002329
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002330 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002331
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002332 hwc_layer_1_t* layer = &list->hwLayers[index];
2333 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302334 hwc_rect_t dst = layer->displayFrame;
2335 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302336 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302337 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002338 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302339 continue;
2340 }
2341 }
2342 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002343 int mdpIndex = mCurrentFrame.layerToMDP[index];
2344 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002345 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002346 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002347 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002348
Saurabh Shahc62f3982014-03-05 14:28:26 -08002349 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2350 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2351 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002352 return false;
2353 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002354 }
2355 return true;
2356}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002357
radhakrishnac9a67412013-09-25 17:40:42 +05302358int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2359 PipeLayerPair& PipeLayerPair) {
2360 const int lSplit = getLeftSplit(ctx, mDpy);
2361 hwc_rect_t dst = layer->displayFrame;
2362 if((dst.left > lSplit)||(dst.right < lSplit)){
2363 MdpYUVPipeInfo& mdp_info =
2364 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2365 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302366 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302367 eDest lDest = mdp_info.lIndex;
2368 eDest rDest = mdp_info.rIndex;
2369
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002370 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302371 lDest, rDest, &PipeLayerPair.rot);
2372 }
2373 else{
2374 return configure(ctx, layer, PipeLayerPair);
2375 }
2376}
2377
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002378/*
2379 * Configures pipe(s) for MDP composition
2380 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002381int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002382 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002383 MdpPipeInfoSplit& mdp_info =
2384 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002385 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302386 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002387 eDest lDest = mdp_info.lIndex;
2388 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002389
2390 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2391 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2392
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002393 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002394 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002395}
2396
Saurabh Shah88e4d272013-09-03 13:31:29 -07002397bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002398
Raj Kamal4393eaa2014-06-06 13:45:20 +05302399 if(!isEnabled() or !mModeOn) {
2400 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302401 return true;
2402 }
2403
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002404 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002405 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002406 sHandleTimeout = true;
2407 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002408
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002409 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002410 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002411
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002412 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2413 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002414 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002415 if(mCurrentFrame.isFBComposed[i]) continue;
2416
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002417 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002418 private_handle_t *hnd = (private_handle_t *)layer->handle;
2419 if(!hnd) {
2420 ALOGE("%s handle null", __FUNCTION__);
2421 return false;
2422 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002423
2424 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2425 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002426 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002427
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002428 int mdpIndex = mCurrentFrame.layerToMDP[i];
2429
Raj Kamal389d6e32014-08-04 14:43:24 +05302430 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302431 {
2432 MdpYUVPipeInfo& pipe_info =
2433 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2434 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2435 ovutils::eDest indexL = pipe_info.lIndex;
2436 ovutils::eDest indexR = pipe_info.rIndex;
2437 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302438 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302439 if(rot) {
2440 rot->queueBuffer(fd, offset);
2441 fd = rot->getDstMemId();
2442 offset = rot->getDstOffset();
2443 }
2444 if(indexL != ovutils::OV_INVALID) {
2445 ovutils::eDest destL = (ovutils::eDest)indexL;
2446 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2447 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2448 if (!ov.queueBuffer(fd, offset, destL)) {
2449 ALOGE("%s: queueBuffer failed for display:%d",
2450 __FUNCTION__, mDpy);
2451 return false;
2452 }
2453 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002454
radhakrishnac9a67412013-09-25 17:40:42 +05302455 if(indexR != ovutils::OV_INVALID) {
2456 ovutils::eDest destR = (ovutils::eDest)indexR;
2457 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2458 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2459 if (!ov.queueBuffer(fd, offset, destR)) {
2460 ALOGE("%s: queueBuffer failed for display:%d",
2461 __FUNCTION__, mDpy);
2462 return false;
2463 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002464 }
2465 }
radhakrishnac9a67412013-09-25 17:40:42 +05302466 else{
2467 MdpPipeInfoSplit& pipe_info =
2468 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2469 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002470
radhakrishnac9a67412013-09-25 17:40:42 +05302471 ovutils::eDest indexL = pipe_info.lIndex;
2472 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002473
radhakrishnac9a67412013-09-25 17:40:42 +05302474 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002475 uint32_t offset = (uint32_t)hnd->offset;
2476 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2477 if (!mDpy && (index != -1)) {
2478 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2479 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002480 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002481 }
radhakrishnac9a67412013-09-25 17:40:42 +05302482
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002483 if(ctx->mAD->draw(ctx, fd, offset)) {
2484 fd = ctx->mAD->getDstFd();
2485 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002486 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002487
radhakrishnac9a67412013-09-25 17:40:42 +05302488 if(rot) {
2489 rot->queueBuffer(fd, offset);
2490 fd = rot->getDstMemId();
2491 offset = rot->getDstOffset();
2492 }
2493
2494 //************* play left mixer **********
2495 if(indexL != ovutils::OV_INVALID) {
2496 ovutils::eDest destL = (ovutils::eDest)indexL;
2497 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2498 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2499 if (!ov.queueBuffer(fd, offset, destL)) {
2500 ALOGE("%s: queueBuffer failed for left mixer",
2501 __FUNCTION__);
2502 return false;
2503 }
2504 }
2505
2506 //************* play right mixer **********
2507 if(indexR != ovutils::OV_INVALID) {
2508 ovutils::eDest destR = (ovutils::eDest)indexR;
2509 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2510 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2511 if (!ov.queueBuffer(fd, offset, destR)) {
2512 ALOGE("%s: queueBuffer failed for right mixer",
2513 __FUNCTION__);
2514 return false;
2515 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002516 }
2517 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002518
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002519 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2520 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002521
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002522 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002523}
Saurabh Shahab47c692014-02-12 18:45:57 -08002524
2525//================MDPCompSrcSplit==============================================
2526bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002527 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002528 private_handle_t *hnd = (private_handle_t *)layer->handle;
2529 hwc_rect_t dst = layer->displayFrame;
2530 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2531 pipe_info.lIndex = ovutils::OV_INVALID;
2532 pipe_info.rIndex = ovutils::OV_INVALID;
2533
2534 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2535 //should have a higher priority than the right one. Pipe priorities are
2536 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002537
Saurabh Shahc62f3982014-03-05 14:28:26 -08002538 Overlay::PipeSpecs pipeSpecs;
2539 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2540 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2541 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2542 pipeSpecs.dpy = mDpy;
2543 pipeSpecs.fb = false;
2544
Saurabh Shahab47c692014-02-12 18:45:57 -08002545 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002546 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002547 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002548 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002549 }
2550
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002551 /* Use 2 pipes IF
2552 a) Layer's crop width is > 2048 or
2553 b) Layer's dest width > 2048 or
2554 c) On primary, driver has indicated with caps to split always. This is
2555 based on an empirically derived value of panel height. Applied only
2556 if the layer's width is > mixer's width
2557 */
2558
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302559 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002560 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302561 mdpHw.isSrcSplitAlways();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002562 int lSplit = getLeftSplit(ctx, mDpy);
2563 int dstWidth = dst.right - dst.left;
Saurabh Shah189f23d2014-09-26 17:21:00 -07002564 int cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
2565 crop.right - crop.left;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002566
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002567 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2568 //pipe line length, we are still using 2 pipes. This is fine just because
2569 //this is source split where destination doesn't matter. Evaluate later to
2570 //see if going through all the calcs to save a pipe is worth it
Naseer Ahmed9eb5e092014-09-25 13:24:44 -04002571 if(dstWidth > (int) mdpHw.getMaxMixerWidth() or
2572 cropWidth > (int) mdpHw.getMaxMixerWidth() or
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002573 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002574 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002575 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002576 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002577 }
2578
2579 // Return values
2580 // 1 Left pipe is higher priority, do nothing.
2581 // 0 Pipes of same priority.
2582 //-1 Right pipe is of higher priority, needs swap.
2583 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2584 pipe_info.rIndex) == -1) {
2585 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002586 }
2587 }
2588
2589 return true;
2590}
2591
Saurabh Shahab47c692014-02-12 18:45:57 -08002592int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2593 PipeLayerPair& PipeLayerPair) {
2594 private_handle_t *hnd = (private_handle_t *)layer->handle;
2595 if(!hnd) {
2596 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2597 return -1;
2598 }
2599 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2600 MdpPipeInfoSplit& mdp_info =
2601 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2602 Rotator **rot = &PipeLayerPair.rot;
2603 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002604 eDest lDest = mdp_info.lIndex;
2605 eDest rDest = mdp_info.rIndex;
2606 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2607 hwc_rect_t dst = layer->displayFrame;
2608 int transform = layer->transform;
2609 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002610 int rotFlags = ROT_FLAGS_NONE;
2611 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2612 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2613
2614 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2615 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2616
2617 // Handle R/B swap
2618 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2619 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2620 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2621 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2622 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2623 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002624 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002625 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2626 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002627 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002628 /* Calculate the external display position based on MDP downscale,
2629 ActionSafe, and extorientation features. */
2630 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002631
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002632 int downscale = getRotDownscale(ctx, layer);
Justin Philipd6166602014-08-12 13:42:21 +05302633 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002634 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002635
2636 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2637 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002638 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002639 }
2640
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002641 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002642 (*rot) = ctx->mRotMgr->getNext();
2643 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002644 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002645 //If the video is using a single pipe, enable BWC
2646 if(rDest == OV_INVALID) {
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002647 BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002648 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002649 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002650 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002651 ALOGE("%s: configRotator failed!", __FUNCTION__);
2652 return -1;
2653 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002654 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002655 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002656 }
2657
2658 //If 2 pipes being used, divide layer into half, crop and dst
2659 hwc_rect_t cropL = crop;
2660 hwc_rect_t cropR = crop;
2661 hwc_rect_t dstL = dst;
2662 hwc_rect_t dstR = dst;
2663 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2664 cropL.right = (crop.right + crop.left) / 2;
2665 cropR.left = cropL.right;
2666 sanitizeSourceCrop(cropL, cropR, hnd);
2667
Saurabh Shahb729b192014-08-15 18:04:24 -07002668 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002669 //Swap crops on H flip since 2 pipes are being used
2670 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2671 hwc_rect_t tmp = cropL;
2672 cropL = cropR;
2673 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002674 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002675 }
2676
Saurabh Shahb729b192014-08-15 18:04:24 -07002677 //cropSwap trick: If the src and dst widths are both odd, let us say
2678 //2507, then splitting both into half would cause left width to be 1253
2679 //and right 1254. If crop is swapped because of H flip, this will cause
2680 //left crop width to be 1254, whereas left dst width remains 1253, thus
2681 //inducing a scaling that is unaccounted for. To overcome that we add 1
2682 //to the dst width if there is a cropSwap. So if the original width was
2683 //2507, the left dst width will be 1254. Even if the original width was
2684 //even for ex: 2508, the left dst width will still remain 1254.
2685 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002686 dstR.left = dstL.right;
2687 }
2688
2689 //For the mdp, since either we are pre-rotating or MDP does flips
2690 orient = OVERLAY_TRANSFORM_0;
2691 transform = 0;
2692
2693 //configure left pipe
2694 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002695 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002696 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2697 (ovutils::eBlending) getBlending(layer->blending));
2698
2699 if(configMdp(ctx->mOverlay, pargL, orient,
2700 cropL, dstL, metadata, lDest) < 0) {
2701 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2702 return -1;
2703 }
2704 }
2705
2706 //configure right pipe
2707 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002708 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002709 static_cast<eRotFlags>(rotFlags),
2710 layer->planeAlpha,
2711 (ovutils::eBlending) getBlending(layer->blending));
2712 if(configMdp(ctx->mOverlay, pargR, orient,
2713 cropR, dstR, metadata, rDest) < 0) {
2714 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2715 return -1;
2716 }
2717 }
2718
2719 return 0;
2720}
2721
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002722}; //namespace
2723