blob: 56d86ec07a6d3ead2cda0e0f78f3c03bd1ceb4dc [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 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800483 } else if (ctx->isDMAStateChanging) {
484 // Bail out if a padding round has been invoked in order to switch DMA
485 // state to block mode. We need this to cater for the case when a layer
486 // requires rotation in the current frame.
487 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
488 __FUNCTION__);
489 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700490 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800491
Saurabh Shahaa236822013-04-24 18:07:26 -0700492 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800493}
494
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800495void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
496 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
497 fbRect = getIntersection(fbRect, roi);
498}
499
500/* 1) Identify layers that are not visible or lying outside the updating ROI and
501 * drop them from composition.
502 * 2) If we have a scaling layer which needs cropping against generated
503 * ROI, reset ROI to full resolution. */
504bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
505 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700506 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800507 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800508
509 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800510 if(!isValidRect(visibleRect)) {
511 mCurrentFrame.drop[i] = true;
512 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800513 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800514 }
515
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700516 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700517 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800518 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700519
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700520 if(!isValidRect(res)) {
521 mCurrentFrame.drop[i] = true;
522 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800523 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700524 /* Reset frame ROI when any layer which needs scaling also needs ROI
525 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800526 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800527 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700528 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
529 mCurrentFrame.dropCount = 0;
530 return false;
531 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800532
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800533 /* deduct any opaque region from visibleRect */
534 if (layer->blending == HWC_BLENDING_NONE)
535 visibleRect = deductRect(visibleRect, res);
536 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700537 }
538 return true;
539}
540
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800541/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
542 * are updating. If DirtyRegion is applicable, calculate it by accounting all
543 * the changing layer's dirtyRegion. */
544void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
545 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700546 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800547 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700548 return;
549
550 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800551 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
552 (int)ctx->dpyAttr[mDpy].yres};
553
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700554 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800555 hwc_layer_1_t* layer = &list->hwLayers[index];
556 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800557 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700558 hwc_rect_t dst = layer->displayFrame;
559 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800560
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800561#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800562 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700563 {
564 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
565 int x_off = dst.left - src.left;
566 int y_off = dst.top - src.top;
567 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
568 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800569#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800570
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800571 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700572 }
573 }
574
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800575 /* No layer is updating. Still SF wants a refresh.*/
576 if(!isValidRect(roi))
577 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800578
579 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800580 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800581
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800582 ctx->listStats[mDpy].lRoi = roi;
583 if(!validateAndApplyROI(ctx, list))
584 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700585
586 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800587 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
588 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
589}
590
591void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
592 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
593 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
594
595 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
596 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
597 fbRect = getUnion(l_fbRect, r_fbRect);
598}
599/* 1) Identify layers that are not visible or lying outside BOTH the updating
600 * ROI's and drop them from composition. If a layer is spanning across both
601 * the halves of the screen but needed by only ROI, the non-contributing
602 * half will not be programmed for MDP.
603 * 2) If we have a scaling layer which needs cropping against generated
604 * ROI, reset ROI to full resolution. */
605bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
606 hwc_display_contents_1_t* list) {
607
608 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
609
610 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
611 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
612
613 for(int i = numAppLayers - 1; i >= 0; i--){
614 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
615 {
616 mCurrentFrame.drop[i] = true;
617 mCurrentFrame.dropCount++;
618 continue;
619 }
620
621 const hwc_layer_1_t* layer = &list->hwLayers[i];
622 hwc_rect_t dstRect = layer->displayFrame;
623
624 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
625 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
626 hwc_rect_t res = getUnion(l_res, r_res);
627
628 if(!isValidRect(l_res) && !isValidRect(r_res)) {
629 mCurrentFrame.drop[i] = true;
630 mCurrentFrame.dropCount++;
631 } else {
632 /* Reset frame ROI when any layer which needs scaling also needs ROI
633 * cropping */
634 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
635 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
636 mCurrentFrame.dropCount = 0;
637 return false;
638 }
639
640 if (layer->blending == HWC_BLENDING_NONE) {
641 visibleRectL = deductRect(visibleRectL, l_res);
642 visibleRectR = deductRect(visibleRectR, r_res);
643 }
644 }
645 }
646 return true;
647}
648/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
649 * are updating. If DirtyRegion is applicable, calculate it by accounting all
650 * the changing layer's dirtyRegion. */
651void MDPCompSplit::generateROI(hwc_context_t *ctx,
652 hwc_display_contents_1_t* list) {
653 if(!canPartialUpdate(ctx, list))
654 return;
655
656 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
657 int lSplit = getLeftSplit(ctx, mDpy);
658
659 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
660 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
661
662 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
663 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
664
665 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
666 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
667
668 for(int index = 0; index < numAppLayers; index++ ) {
669 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800670 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800671 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800672 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700673 hwc_rect_t dst = layer->displayFrame;
674 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800675
676#ifdef QCOM_BSP
677 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700678 {
679 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
680 int x_off = dst.left - src.left;
681 int y_off = dst.top - src.top;
682 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
683 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800684#endif
685
686 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
687 if(isValidRect(l_dst))
688 l_roi = getUnion(l_roi, l_dst);
689
690 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
691 if(isValidRect(r_dst))
692 r_roi = getUnion(r_roi, r_dst);
693 }
694 }
695
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700696 /* For panels that cannot accept commands in both the interfaces, we cannot
697 * send two ROI's (for each half). We merge them into single ROI and split
698 * them across lSplit for MDP mixer use. The ROI's will be merged again
699 * finally before udpating the panel in the driver. */
700 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
701 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
702 l_roi = getIntersection(temp_roi, l_frame);
703 r_roi = getIntersection(temp_roi, r_frame);
704 }
705
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800706 /* No layer is updating. Still SF wants a refresh. */
707 if(!isValidRect(l_roi) && !isValidRect(r_roi))
708 return;
709
710 l_roi = getSanitizeROI(l_roi, l_frame);
711 r_roi = getSanitizeROI(r_roi, r_frame);
712
713 ctx->listStats[mDpy].lRoi = l_roi;
714 ctx->listStats[mDpy].rRoi = r_roi;
715
716 if(!validateAndApplyROI(ctx, list))
717 resetROI(ctx, mDpy);
718
719 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
720 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
721 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
722 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
723 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
724 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700725}
726
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800727/* Checks for conditions where all the layers marked for MDP comp cannot be
728 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800729bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800730 hwc_display_contents_1_t* list){
731
Saurabh Shahaa236822013-04-24 18:07:26 -0700732 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800733 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800734
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700735 // Fall back to video only composition, if AIV video mode is enabled
736 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700737 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
738 __FUNCTION__, mDpy);
739 return false;
740 }
741
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400742 // No Idle fall back, if secure display or secure RGB layers are present or
743 // if there's only a single layer being composed
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -0700744 if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400745 !ctx->listStats[mDpy].secureRGBCount) &&
746 (ctx->listStats[mDpy].numAppLayers != 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700747 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
748 return false;
749 }
750
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800751 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700752 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
753 __FUNCTION__,
754 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800755 return false;
756 }
757
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700758 // if secondary is configuring or Padding round, fall back to video only
759 // composition and release all assigned non VIG pipes from primary.
760 if(isSecondaryConfiguring(ctx)) {
761 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
762 __FUNCTION__);
763 return false;
764 } else if(ctx->isPaddingRound) {
765 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
766 __FUNCTION__,mDpy);
767 return false;
768 }
769
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530770 MDPVersion& mdpHw = MDPVersion::getInstance();
771 if(mDpy > HWC_DISPLAY_PRIMARY &&
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400772 (priDispW > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530773 (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800774 // Disable MDP comp on Secondary when the primary is highres panel and
775 // the secondary is a normal 1080p, because, MDP comp on secondary under
776 // in such usecase, decimation gets used for downscale and there will be
777 // a quality mismatch when there will be a fallback to GPU comp
778 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
779 __FUNCTION__);
780 return false;
781 }
782
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700783 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800784 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700785 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800786 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
787 return false;
788 }
789
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800790 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800791 hwc_layer_1_t* layer = &list->hwLayers[i];
792 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800793
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800794 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700795 if(!canUseRotator(ctx, mDpy)) {
796 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
797 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700798 return false;
799 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800800 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530801
802 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
803 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700804 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530805 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
806 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
807 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800808 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700809
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700810 if(ctx->mAD->isDoable()) {
811 return false;
812 }
813
Saurabh Shahaa236822013-04-24 18:07:26 -0700814 //If all above hard conditions are met we can do full or partial MDP comp.
815 bool ret = false;
816 if(fullMDPComp(ctx, list)) {
817 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700818 } else if(fullMDPCompWithPTOR(ctx, list)) {
819 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700820 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700821 ret = true;
822 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530823
Saurabh Shahaa236822013-04-24 18:07:26 -0700824 return ret;
825}
826
827bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700828
829 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
830 return false;
831
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700832 //Will benefit presentation / secondary-only layer.
833 if((mDpy > HWC_DISPLAY_PRIMARY) &&
834 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
835 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
836 return false;
837 }
838
839 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
840 for(int i = 0; i < numAppLayers; i++) {
841 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700842 if(not mCurrentFrame.drop[i] and
843 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700844 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
845 return false;
846 }
847 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800848
Saurabh Shahaa236822013-04-24 18:07:26 -0700849 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700850 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
851 sizeof(mCurrentFrame.isFBComposed));
852 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
853 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700854
Raj Kamal389d6e32014-08-04 14:43:24 +0530855 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800856 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530857 }
858
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800859 if(!postHeuristicsHandling(ctx, list)) {
860 ALOGD_IF(isDebug(), "post heuristic handling failed");
861 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700862 return false;
863 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700864 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
865 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700866 return true;
867}
868
Sushil Chauhandefd3522014-05-13 18:17:12 -0700869/* Full MDP Composition with Peripheral Tiny Overlap Removal.
870 * MDP bandwidth limitations can be avoided, if the overlap region
871 * covered by the smallest layer at a higher z-order, gets composed
872 * by Copybit on a render buffer, which can be queued to MDP.
873 */
874bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
875 hwc_display_contents_1_t* list) {
876
877 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
878 const int stagesForMDP = min(sMaxPipesPerMixer,
879 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
880
881 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700882 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700883 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
884 return false;
885 }
886
887 // Frame level checks
888 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
889 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
890 isSecurePresent(ctx, mDpy)) {
891 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
892 return false;
893 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700894 // MDP comp checks
895 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700896 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700897 if(not isSupportedForMDPComp(ctx, layer)) {
898 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
899 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700900 }
901 }
902
Sushil Chauhandefd3522014-05-13 18:17:12 -0700903 /* We cannot use this composition mode, if:
904 1. A below layer needs scaling.
905 2. Overlap is not peripheral to display.
906 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700907 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700908 */
909
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700910 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
911 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
912 memset(overlapRect, 0, sizeof(overlapRect));
913 int layerPixelCount, minPixelCount = 0;
914 int numPTORLayersFound = 0;
915 for (int i = numAppLayers-1; (i >= 0 &&
916 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700917 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700918 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700919 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700920 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
921 // PTOR layer should be peripheral and cannot have transform
922 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
923 has90Transform(layer)) {
924 continue;
925 }
926 if((3 * (layerPixelCount + minPixelCount)) >
927 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
928 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
929 continue;
930 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700931 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700932 for (int j = i-1; j >= 0; j--) {
933 // Check if the layers below this layer qualifies for PTOR comp
934 hwc_layer_1_t* layer = &list->hwLayers[j];
935 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700936 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700937 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700938 if (isValidRect(getIntersection(dispFrame, disFrame))) {
939 if (has90Transform(layer) || needsScaling(layer)) {
940 found = false;
941 break;
942 }
943 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700944 }
945 }
946 // Store the minLayer Index
947 if(found) {
948 minLayerIndex[numPTORLayersFound] = i;
949 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
950 minPixelCount += layerPixelCount;
951 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700952 }
953 }
954
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700955 // No overlap layers
956 if (!numPTORLayersFound)
957 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700958
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700959 // Store the displayFrame and the sourceCrops of the layers
960 hwc_rect_t displayFrame[numAppLayers];
961 hwc_rect_t sourceCrop[numAppLayers];
962 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700963 hwc_layer_1_t* layer = &list->hwLayers[i];
964 displayFrame[i] = layer->displayFrame;
965 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700966 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700967
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530968 /**
969 * It's possible that 2 PTOR layers might have overlapping.
970 * In such case, remove the intersection(again if peripheral)
971 * from the lower PTOR layer to avoid overlapping.
972 * If intersection is not on peripheral then compromise
973 * by reducing number of PTOR layers.
974 **/
975 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
976 if(isValidRect(commonRect)) {
977 overlapRect[1] = deductRect(overlapRect[1], commonRect);
978 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
979 }
980
981 ctx->mPtorInfo.count = numPTORLayersFound;
982 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
983 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
984 }
985
986 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
987 // reset PTOR
988 ctx->mPtorInfo.count = 0;
989 if(isValidRect(commonRect)) {
990 // If PTORs are intersecting restore displayframe of PTOR[1]
991 // before returning, as we have modified it above.
992 list->hwLayers[minLayerIndex[1]].displayFrame =
993 displayFrame[minLayerIndex[1]];
994 }
995 return false;
996 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700997 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
998 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
999
Xu Yangcda012c2014-07-30 21:57:21 +08001000 // Store the blending mode, planeAlpha, and transform of PTOR layers
1001 int32_t blending[numPTORLayersFound];
1002 uint8_t planeAlpha[numPTORLayersFound];
1003 uint32_t transform[numPTORLayersFound];
1004
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001005 for(int j = 0; j < numPTORLayersFound; j++) {
1006 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001007
1008 // Update src crop of PTOR layer
1009 hwc_layer_1_t* layer = &list->hwLayers[index];
1010 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1011 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1012 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1013 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1014
1015 // Store & update w, h, format of PTOR layer
1016 private_handle_t *hnd = (private_handle_t *)layer->handle;
1017 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1018 layerWhf[j] = whf;
1019 hnd->width = renderBuf->width;
1020 hnd->height = renderBuf->height;
1021 hnd->format = renderBuf->format;
1022
Xu Yangcda012c2014-07-30 21:57:21 +08001023 // Store & update blending mode, planeAlpha and transform of PTOR layer
1024 blending[j] = layer->blending;
1025 planeAlpha[j] = layer->planeAlpha;
1026 transform[j] = layer->transform;
1027 layer->blending = HWC_BLENDING_NONE;
1028 layer->planeAlpha = 0xFF;
1029 layer->transform = 0;
1030
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001031 // Remove overlap from crop & displayFrame of below layers
1032 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001033 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001034 if(!isValidRect(getIntersection(layer->displayFrame,
1035 overlapRect[j]))) {
1036 continue;
1037 }
1038 // Update layer attributes
1039 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1040 hwc_rect_t destRect = deductRect(layer->displayFrame,
1041 overlapRect[j]);
1042 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1043 layer->transform);
1044 layer->sourceCropf.left = (float)srcCrop.left;
1045 layer->sourceCropf.top = (float)srcCrop.top;
1046 layer->sourceCropf.right = (float)srcCrop.right;
1047 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1048 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001049 }
1050
1051 mCurrentFrame.mdpCount = numAppLayers;
1052 mCurrentFrame.fbCount = 0;
1053 mCurrentFrame.fbZ = -1;
1054
1055 for (int j = 0; j < numAppLayers; j++)
1056 mCurrentFrame.isFBComposed[j] = false;
1057
1058 bool result = postHeuristicsHandling(ctx, list);
1059
1060 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001061 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001062 hwc_layer_1_t* layer = &list->hwLayers[i];
1063 layer->displayFrame = displayFrame[i];
1064 layer->sourceCropf.left = (float)sourceCrop[i].left;
1065 layer->sourceCropf.top = (float)sourceCrop[i].top;
1066 layer->sourceCropf.right = (float)sourceCrop[i].right;
1067 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1068 }
1069
Xu Yangcda012c2014-07-30 21:57:21 +08001070 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001071 for (int i = 0; i < numPTORLayersFound; i++) {
1072 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001073 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001074 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1075 hnd->width = layerWhf[i].w;
1076 hnd->height = layerWhf[i].h;
1077 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001078 layer->blending = blending[i];
1079 layer->planeAlpha = planeAlpha[i];
1080 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001081 }
1082
Sushil Chauhandefd3522014-05-13 18:17:12 -07001083 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001084 // reset PTOR
1085 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001086 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001087 } else {
1088 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1089 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001090 }
1091
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001092 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1093 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001094 return result;
1095}
1096
Saurabh Shahaa236822013-04-24 18:07:26 -07001097bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1098{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001099 if(!sEnableMixedMode) {
1100 //Mixed mode is disabled. No need to even try caching.
1101 return false;
1102 }
1103
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001104 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001105 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001106 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001107 cacheBasedComp(ctx, list);
1108 } else {
1109 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001110 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001111 }
1112
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001113 return ret;
1114}
1115
1116bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1117 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001118 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1119 return false;
1120
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001121 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001122 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001123 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001124
1125 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1126 for(int i = 0; i < numAppLayers; i++) {
1127 if(!mCurrentFrame.isFBComposed[i]) {
1128 hwc_layer_1_t* layer = &list->hwLayers[i];
1129 if(not isSupportedForMDPComp(ctx, layer)) {
1130 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1131 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001132 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001133 return false;
1134 }
1135 }
1136 }
1137
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001138 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001139 /* mark secure RGB layers for MDP comp */
1140 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301141 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001142 if(!ret) {
1143 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001144 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001145 return false;
1146 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001147
1148 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001149
Raj Kamal389d6e32014-08-04 14:43:24 +05301150 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001151 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301152 }
1153
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001154 //Will benefit cases where a video has non-updating background.
1155 if((mDpy > HWC_DISPLAY_PRIMARY) and
1156 (mdpCount > MAX_SEC_LAYERS)) {
1157 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001158 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001159 return false;
1160 }
1161
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001162 if(!postHeuristicsHandling(ctx, list)) {
1163 ALOGD_IF(isDebug(), "post heuristic handling failed");
1164 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001165 return false;
1166 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001167 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1168 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001169
Saurabh Shahaa236822013-04-24 18:07:26 -07001170 return true;
1171}
1172
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001173bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001174 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001175 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1176 return false;
1177
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001178 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001179 return false;
1180 }
1181
Saurabh Shahb772ae32013-11-18 15:40:02 -08001182 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001183 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1184 const int stagesForMDP = min(sMaxPipesPerMixer,
1185 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001186
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001187 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1188 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1189 int lastMDPSupportedIndex = numAppLayers;
1190 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001191
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001192 //Find the minimum MDP batch size
1193 for(int i = 0; i < numAppLayers;i++) {
1194 if(mCurrentFrame.drop[i]) {
1195 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001196 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001197 }
1198 hwc_layer_1_t* layer = &list->hwLayers[i];
1199 if(not isSupportedForMDPComp(ctx, layer)) {
1200 lastMDPSupportedIndex = i;
1201 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1202 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001203 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001204 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001205 }
1206
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001207 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1208 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1209 mCurrentFrame.dropCount);
1210
1211 //Start at a point where the fb batch should at least have 2 layers, for
1212 //this mode to be justified.
1213 while(fbBatchSize < 2) {
1214 ++fbBatchSize;
1215 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001216 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001217
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001218 //If there are no layers for MDP, this mode doesnt make sense.
1219 if(mdpBatchSize < 1) {
1220 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1221 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001222 return false;
1223 }
1224
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001225 mCurrentFrame.reset(numAppLayers);
1226
1227 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1228 while(mdpBatchSize > 0) {
1229 //Mark layers for MDP comp
1230 int mdpBatchLeft = mdpBatchSize;
1231 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1232 if(mCurrentFrame.drop[i]) {
1233 continue;
1234 }
1235 mCurrentFrame.isFBComposed[i] = false;
1236 --mdpBatchLeft;
1237 }
1238
1239 mCurrentFrame.fbZ = mdpBatchSize;
1240 mCurrentFrame.fbCount = fbBatchSize;
1241 mCurrentFrame.mdpCount = mdpBatchSize;
1242
1243 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1244 __FUNCTION__, mdpBatchSize, fbBatchSize,
1245 mCurrentFrame.dropCount);
1246
1247 if(postHeuristicsHandling(ctx, list)) {
1248 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001249 __FUNCTION__);
1250 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1251 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001252 return true;
1253 }
1254
1255 reset(ctx);
1256 --mdpBatchSize;
1257 ++fbBatchSize;
1258 }
1259
1260 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001261}
1262
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001263bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301264 if(mDpy or isSecurePresent(ctx, mDpy) or
1265 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001266 return false;
1267 }
1268 return true;
1269}
1270
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001271bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1272 hwc_display_contents_1_t* list){
1273 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1274 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1275 mDpy ) {
1276 return false;
1277 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001278 if(ctx->listStats[mDpy].secureUI)
1279 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001280 return true;
1281}
1282
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001283bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1284 hwc_display_contents_1_t* list) {
1285 const bool secureOnly = true;
1286 return videoOnlyComp(ctx, list, not secureOnly) or
1287 videoOnlyComp(ctx, list, secureOnly);
1288}
1289
1290bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001291 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001292 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1293 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001294 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001295
Saurabh Shahaa236822013-04-24 18:07:26 -07001296 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001297 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001298 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001299 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001300
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001301 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1302 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001303 return false;
1304 }
1305
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001306 /* Bail out if we are processing only secured video layers
1307 * and we dont have any */
1308 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001309 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001310 return false;
1311 }
1312
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001313 if(mCurrentFrame.fbCount)
1314 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001315
Raj Kamal389d6e32014-08-04 14:43:24 +05301316 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001317 adjustForSourceSplit(ctx, list);
1318 }
1319
1320 if(!postHeuristicsHandling(ctx, list)) {
1321 ALOGD_IF(isDebug(), "post heuristic handling failed");
1322 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001323 return false;
1324 }
1325
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001326 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1327 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001328 return true;
1329}
1330
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001331/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1332bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1333 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001334 // Fall back to video only composition, if AIV video mode is enabled
1335 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001336 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1337 __FUNCTION__, mDpy);
1338 return false;
1339 }
1340
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001341 const bool secureOnly = true;
1342 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1343 mdpOnlyLayersComp(ctx, list, secureOnly);
1344
1345}
1346
1347bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1348 hwc_display_contents_1_t* list, bool secureOnly) {
1349
1350 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1351 return false;
1352
1353 /* Bail out if we are processing only secured video layers
1354 * and we dont have any */
1355 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1356 reset(ctx);
1357 return false;
1358 }
1359
1360 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1361 mCurrentFrame.reset(numAppLayers);
1362 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1363
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001364 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001365 /* mark secure RGB layers for MDP comp */
1366 updateSecureRGB(ctx, list);
1367
1368 if(mCurrentFrame.mdpCount == 0) {
1369 reset(ctx);
1370 return false;
1371 }
1372
1373 /* find the maximum batch of layers to be marked for framebuffer */
1374 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1375 if(!ret) {
1376 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1377 reset(ctx);
1378 return false;
1379 }
1380
1381 if(sEnableYUVsplit){
1382 adjustForSourceSplit(ctx, list);
1383 }
1384
1385 if(!postHeuristicsHandling(ctx, list)) {
1386 ALOGD_IF(isDebug(), "post heuristic handling failed");
1387 reset(ctx);
1388 return false;
1389 }
1390
1391 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1392 __FUNCTION__);
1393 return true;
1394}
1395
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001396/* Checks for conditions where YUV layers cannot be bypassed */
1397bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001398 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001399 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001400 return false;
1401 }
1402
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001403 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001404 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1405 return false;
1406 }
1407
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001408 if(isSecuring(ctx, layer)) {
1409 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1410 return false;
1411 }
1412
Saurabh Shah4fdde762013-04-30 18:47:33 -07001413 if(!isValidDimension(ctx, layer)) {
1414 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1415 __FUNCTION__);
1416 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001417 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001418
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001419 if(layer->planeAlpha < 0xFF) {
1420 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1421 in video only mode",
1422 __FUNCTION__);
1423 return false;
1424 }
1425
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001426 return true;
1427}
1428
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001429/* Checks for conditions where Secure RGB layers cannot be bypassed */
1430bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1431 if(isSkipLayer(layer)) {
1432 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1433 __FUNCTION__, mDpy);
1434 return false;
1435 }
1436
1437 if(isSecuring(ctx, layer)) {
1438 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1439 return false;
1440 }
1441
1442 if(not isSupportedForMDPComp(ctx, layer)) {
1443 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1444 __FUNCTION__);
1445 return false;
1446 }
1447 return true;
1448}
1449
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301450/* starts at fromIndex and check for each layer to find
1451 * if it it has overlapping with any Updating layer above it in zorder
1452 * till the end of the batch. returns true if it finds any intersection */
1453bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1454 int fromIndex, int toIndex) {
1455 for(int i = fromIndex; i < toIndex; i++) {
1456 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1457 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1458 return false;
1459 }
1460 }
1461 }
1462 return true;
1463}
1464
1465/* Checks if given layer at targetLayerIndex has any
1466 * intersection with all the updating layers in beween
1467 * fromIndex and toIndex. Returns true if it finds intersectiion */
1468bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1469 int fromIndex, int toIndex, int targetLayerIndex) {
1470 for(int i = fromIndex; i <= toIndex; i++) {
1471 if(!mCurrentFrame.isFBComposed[i]) {
1472 if(areLayersIntersecting(&list->hwLayers[i],
1473 &list->hwLayers[targetLayerIndex])) {
1474 return true;
1475 }
1476 }
1477 }
1478 return false;
1479}
1480
1481int MDPComp::getBatch(hwc_display_contents_1_t* list,
1482 int& maxBatchStart, int& maxBatchEnd,
1483 int& maxBatchCount) {
1484 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301485 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001486 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301487 while (i < mCurrentFrame.layerCount) {
1488 int batchCount = 0;
1489 int batchStart = i;
1490 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001491 /* Adjust batch Z order with the dropped layers so far */
1492 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301493 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301494 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301495 while(i < mCurrentFrame.layerCount) {
1496 if(!mCurrentFrame.isFBComposed[i]) {
1497 if(!batchCount) {
1498 i++;
1499 break;
1500 }
1501 updatingLayersAbove++;
1502 i++;
1503 continue;
1504 } else {
1505 if(mCurrentFrame.drop[i]) {
1506 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001507 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301508 continue;
1509 } else if(updatingLayersAbove <= 0) {
1510 batchCount++;
1511 batchEnd = i;
1512 i++;
1513 continue;
1514 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1515
1516 // We have a valid updating layer already. If layer-i not
1517 // have overlapping with all updating layers in between
1518 // batch-start and i, then we can add layer i to batch.
1519 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1520 batchCount++;
1521 batchEnd = i;
1522 i++;
1523 continue;
1524 } else if(canPushBatchToTop(list, batchStart, i)) {
1525 //If All the non-updating layers with in this batch
1526 //does not have intersection with the updating layers
1527 //above in z-order, then we can safely move the batch to
1528 //higher z-order. Increment fbZ as it is moving up.
1529 if( firstZReverseIndex < 0) {
1530 firstZReverseIndex = i;
1531 }
1532 batchCount++;
1533 batchEnd = i;
1534 fbZ += updatingLayersAbove;
1535 i++;
1536 updatingLayersAbove = 0;
1537 continue;
1538 } else {
1539 //both failed.start the loop again from here.
1540 if(firstZReverseIndex >= 0) {
1541 i = firstZReverseIndex;
1542 }
1543 break;
1544 }
1545 }
1546 }
1547 }
1548 if(batchCount > maxBatchCount) {
1549 maxBatchCount = batchCount;
1550 maxBatchStart = batchStart;
1551 maxBatchEnd = batchEnd;
1552 fbZOrder = fbZ;
1553 }
1554 }
1555 return fbZOrder;
1556}
1557
1558bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1559 hwc_display_contents_1_t* list) {
1560 /* Idea is to keep as many non-updating(cached) layers in FB and
1561 * send rest of them through MDP. This is done in 2 steps.
1562 * 1. Find the maximum contiguous batch of non-updating layers.
1563 * 2. See if we can improve this batch size for caching by adding
1564 * opaque layers around the batch, if they don't have
1565 * any overlapping with the updating layers in between.
1566 * NEVER mark an updating layer for caching.
1567 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001568
1569 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001570 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001571 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301572 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001573
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001574 /* Nothing is cached. No batching needed */
1575 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001576 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001577 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001578
1579 /* No MDP comp layers, try to use other comp modes */
1580 if(mCurrentFrame.mdpCount == 0) {
1581 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001582 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001583
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301584 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001585
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301586 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001587 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001588 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001589 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301590 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001591 if(!mCurrentFrame.drop[i]){
1592 //If an unsupported layer is being attempted to
1593 //be pulled out we should fail
1594 if(not isSupportedForMDPComp(ctx, layer)) {
1595 return false;
1596 }
1597 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001598 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001599 }
1600 }
1601
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301602 // update the frame data
1603 mCurrentFrame.fbZ = fbZ;
1604 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001605 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001606 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001607
1608 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301609 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001610
1611 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001612}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001613
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001614void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001615 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001616 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001617 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001618
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001619 for(int i = 0; i < numAppLayers; i++) {
1620 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001621 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001622 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001623 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001624 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001625 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001626 }
1627 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001628
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001629 frame.fbCount = fbCount;
1630 frame.mdpCount = frame.layerCount - frame.fbCount
1631 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001632
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001633 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1634 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001635}
1636
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001637// drop other non-AIV layers from external display list.
1638void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001639 hwc_display_contents_1_t* list) {
1640 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1641 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001642 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001643 mCurrentFrame.dropCount++;
1644 mCurrentFrame.drop[i] = true;
1645 }
1646 }
1647 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1648 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1649 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1650 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1651 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1652 mCurrentFrame.dropCount);
1653}
1654
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001655void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001656 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001657 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1658 for(int index = 0;index < nYuvCount; index++){
1659 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1660 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1661
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001662 if(mCurrentFrame.drop[nYuvIndex]) {
1663 continue;
1664 }
1665
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001666 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001667 if(!frame.isFBComposed[nYuvIndex]) {
1668 frame.isFBComposed[nYuvIndex] = true;
1669 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001670 }
1671 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001672 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001673 private_handle_t *hnd = (private_handle_t *)layer->handle;
1674 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001675 frame.isFBComposed[nYuvIndex] = false;
1676 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001677 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001678 }
1679 }
1680 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001681
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001682 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1683 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001684}
1685
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001686void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1687 hwc_display_contents_1_t* list) {
1688 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1689 for(int index = 0;index < nSecureRGBCount; index++){
1690 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1691 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1692
1693 if(!isSecureRGBDoable(ctx, layer)) {
1694 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1695 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1696 mCurrentFrame.fbCount++;
1697 }
1698 } else {
1699 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1700 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1701 mCurrentFrame.fbCount--;
1702 }
1703 }
1704 }
1705
1706 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1707 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1708 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1709 mCurrentFrame.fbCount);
1710}
1711
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001712hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1713 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001714 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001715
1716 /* Update only the region of FB needed for composition */
1717 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1718 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1719 hwc_layer_1_t* layer = &list->hwLayers[i];
1720 hwc_rect_t dst = layer->displayFrame;
1721 fbRect = getUnion(fbRect, dst);
1722 }
1723 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001724 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001725 return fbRect;
1726}
1727
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001728bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1729 hwc_display_contents_1_t* list) {
1730
1731 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001732 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001733 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1734 return false;
1735 }
1736
1737 //Limitations checks
1738 if(!hwLimitationsCheck(ctx, list)) {
1739 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1740 return false;
1741 }
1742
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001743 //Configure framebuffer first if applicable
1744 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001745 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001746 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1747 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001748 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1749 __FUNCTION__);
1750 return false;
1751 }
1752 }
1753
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001754 mCurrentFrame.map();
1755
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001756 if(!allocLayerPipes(ctx, list)) {
1757 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001758 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001759 }
1760
1761 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001762 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001763 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001764 int mdpIndex = mCurrentFrame.layerToMDP[index];
1765 hwc_layer_1_t* layer = &list->hwLayers[index];
1766
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301767 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1768 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1769 mdpNextZOrder++;
1770 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001771 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1772 cur_pipe->zOrder = mdpNextZOrder++;
1773
radhakrishnac9a67412013-09-25 17:40:42 +05301774 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301775 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301776 if(configure4k2kYuv(ctx, layer,
1777 mCurrentFrame.mdpToLayer[mdpIndex])
1778 != 0 ){
1779 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1780 for layer %d",__FUNCTION__, index);
1781 return false;
1782 }
1783 else{
1784 mdpNextZOrder++;
1785 }
1786 continue;
1787 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001788 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1789 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301790 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001791 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001792 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001793 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001794 }
1795
Saurabh Shaha36be922013-12-16 18:18:39 -08001796 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1797 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1798 ,__FUNCTION__, mDpy);
1799 return false;
1800 }
1801
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001802 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001803 return true;
1804}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001805
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001806bool MDPComp::resourceCheck(hwc_context_t* ctx,
1807 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001808 const bool fbUsed = mCurrentFrame.fbCount;
1809 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1810 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1811 return false;
1812 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001813 // Init rotCount to number of rotate sessions used by other displays
1814 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1815 // Count the number of rotator sessions required for current display
1816 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1817 if(!mCurrentFrame.isFBComposed[index]) {
1818 hwc_layer_1_t* layer = &list->hwLayers[index];
1819 private_handle_t *hnd = (private_handle_t *)layer->handle;
1820 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1821 rotCount++;
1822 }
1823 }
1824 }
1825 // if number of layers to rotate exceeds max rotator sessions, bail out.
1826 if(rotCount > RotMgr::MAX_ROT_SESS) {
1827 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1828 __FUNCTION__, mDpy);
1829 return false;
1830 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001831 return true;
1832}
1833
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301834bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1835 hwc_display_contents_1_t* list) {
1836
1837 //A-family hw limitation:
1838 //If a layer need alpha scaling, MDP can not support.
1839 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1840 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1841 if(!mCurrentFrame.isFBComposed[i] &&
1842 isAlphaScaled( &list->hwLayers[i])) {
1843 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1844 return false;
1845 }
1846 }
1847 }
1848
1849 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1850 //If multiple layers requires downscaling and also they are overlapping
1851 //fall back to GPU since MDSS can not handle it.
1852 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1853 qdutils::MDPVersion::getInstance().is8x26()) {
1854 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1855 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1856 if(!mCurrentFrame.isFBComposed[i] &&
1857 isDownscaleRequired(botLayer)) {
1858 //if layer-i is marked for MDP and needs downscaling
1859 //check if any MDP layer on top of i & overlaps with layer-i
1860 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1861 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1862 if(!mCurrentFrame.isFBComposed[j] &&
1863 isDownscaleRequired(topLayer)) {
1864 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1865 topLayer->displayFrame);
1866 if(isValidRect(r))
1867 return false;
1868 }
1869 }
1870 }
1871 }
1872 }
1873 return true;
1874}
1875
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001876int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001877 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001878 char property[PROPERTY_VALUE_MAX];
1879
Raj Kamal4393eaa2014-06-06 13:45:20 +05301880 if(!ctx || !list) {
1881 ALOGE("%s: Invalid context or list",__FUNCTION__);
1882 mCachedFrame.reset();
1883 return -1;
1884 }
1885
1886 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001887 if(mDpy == HWC_DISPLAY_PRIMARY) {
1888 sSimulationFlags = 0;
1889 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1890 int currentFlags = atoi(property);
1891 if(currentFlags != sSimulationFlags) {
1892 sSimulationFlags = currentFlags;
1893 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1894 sSimulationFlags, sSimulationFlags);
1895 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001896 }
1897 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001898 // reset PTOR
1899 if(!mDpy)
1900 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001901
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301902 //Do not cache the information for next draw cycle.
1903 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1904 ALOGI("%s: Unsupported layer count for mdp composition",
1905 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001906 mCachedFrame.reset();
1907 return -1;
1908 }
1909
Saurabh Shahb39f8152013-08-22 10:21:44 -07001910 //reset old data
1911 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001912 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1913 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301914
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001915 // Detect the start of animation and fall back to GPU only once to cache
1916 // all the layers in FB and display FB content untill animation completes.
1917 if(ctx->listStats[mDpy].isDisplayAnimating) {
1918 mCurrentFrame.needsRedraw = false;
1919 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1920 mCurrentFrame.needsRedraw = true;
1921 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1922 }
1923 setMDPCompLayerFlags(ctx, list);
1924 mCachedFrame.updateCounts(mCurrentFrame);
1925 ret = -1;
1926 return ret;
1927 } else {
1928 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1929 }
1930
Saurabh Shahb39f8152013-08-22 10:21:44 -07001931 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001932 if(isFrameDoable(ctx)) {
1933 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001934 // if AIV Video mode is enabled, drop all non AIV layers from the
1935 // external display list.
1936 if(ctx->listStats[mDpy].mAIVVideoMode) {
1937 dropNonAIVLayers(ctx, list);
1938 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001939
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001940 // if tryFullFrame fails, try to push all video and secure RGB layers
1941 // to MDP for composition.
1942 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001943 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301944 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001945 setMDPCompLayerFlags(ctx, list);
1946 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001947 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001948 reset(ctx);
1949 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1950 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001951 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001952 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1953 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001954 }
1955 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05301956 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
1957 enablePartialUpdateForMDP3) {
1958 generateROI(ctx, list);
1959 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
1960 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
1961 }
1962 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001963 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1964 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001965 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001966 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001967
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001968 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001969 ALOGD("GEOMETRY change: %d",
1970 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001971 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001972 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001973 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001974 }
1975
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001976#ifdef DYNAMIC_FPS
1977 //For primary display, set the dynamic refreshrate
1978 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported()) {
1979 FrameInfo frame;
1980 frame.reset(mCurrentFrame.layerCount);
Raj Kamal18e946e2014-10-10 14:23:47 +05301981 memset(&frame.drop, 0, sizeof(frame.drop));
1982 frame.dropCount = 0;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001983 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
1984 __FUNCTION__);
1985 updateLayerCache(ctx, list, frame);
1986 updateYUV(ctx, list, false /*secure only*/, frame);
1987 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1988 //Set the new fresh rate, if there is only one updating YUV layer
1989 //or there is one single RGB layer with this request
1990 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1991 (frame.layerCount == 1)) {
1992 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1993 }
1994 setRefreshRate(ctx, mDpy, refreshRate);
1995 }
1996#endif
1997
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001998 mCachedFrame.cacheAll(list);
1999 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002000 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002001}
2002
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002003bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302004
2005 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302006 int mdpIndex = mCurrentFrame.layerToMDP[index];
2007 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2008 info.pipeInfo = new MdpYUVPipeInfo;
2009 info.rot = NULL;
2010 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302011
2012 pipe_info.lIndex = ovutils::OV_INVALID;
2013 pipe_info.rIndex = ovutils::OV_INVALID;
2014
Saurabh Shahc62f3982014-03-05 14:28:26 -08002015 Overlay::PipeSpecs pipeSpecs;
2016 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2017 pipeSpecs.needsScaling = true;
2018 pipeSpecs.dpy = mDpy;
2019 pipeSpecs.fb = false;
2020
2021 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302022 if(pipe_info.lIndex == ovutils::OV_INVALID){
2023 bRet = false;
2024 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2025 __FUNCTION__);
2026 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002027 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302028 if(pipe_info.rIndex == ovutils::OV_INVALID){
2029 bRet = false;
2030 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2031 __FUNCTION__);
2032 }
2033 return bRet;
2034}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002035
2036int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2037 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002038 if (ctx->mPtorInfo.isActive()) {
2039 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002040 if (fd < 0) {
2041 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002042 }
2043 }
2044 return fd;
2045}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002046//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002047
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002048void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302049 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002050 //If 4k2k Yuv layer split is possible, and if
2051 //fbz is above 4k2k layer, increment fb zorder by 1
2052 //as we split 4k2k layer and increment zorder for right half
2053 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002054 if(!ctx)
2055 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002056 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302057 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2058 index++) {
2059 if(!mCurrentFrame.isFBComposed[index]) {
2060 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2061 mdpNextZOrder++;
2062 }
2063 mdpNextZOrder++;
2064 hwc_layer_1_t* layer = &list->hwLayers[index];
2065 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302066 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302067 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2068 mCurrentFrame.fbZ += 1;
2069 mdpNextZOrder++;
2070 //As we split 4kx2k yuv layer and program to 2 VG pipes
2071 //(if available) increase mdpcount by 1.
2072 mCurrentFrame.mdpCount++;
2073 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002074 }
2075 }
2076 }
radhakrishnac9a67412013-09-25 17:40:42 +05302077}
2078
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002079/*
2080 * Configures pipe(s) for MDP composition
2081 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002082int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002083 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002084 MdpPipeInfoNonSplit& mdp_info =
2085 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302086 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002087 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002088 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002089
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002090 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2091 __FUNCTION__, layer, zOrder, dest);
2092
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002093 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002094 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002095}
2096
Saurabh Shah88e4d272013-09-03 13:31:29 -07002097bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002098 hwc_display_contents_1_t* list) {
2099 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002100
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002101 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002102
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002103 hwc_layer_1_t* layer = &list->hwLayers[index];
2104 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302105 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002106 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302107 continue;
2108 }
2109 }
2110
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002111 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002112 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002113 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002114 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002115 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002116
Saurabh Shahc62f3982014-03-05 14:28:26 -08002117 Overlay::PipeSpecs pipeSpecs;
2118 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2119 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2120 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2121 (qdutils::MDPVersion::getInstance().is8x26() and
2122 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2123 pipeSpecs.dpy = mDpy;
2124 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002125 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002126
Saurabh Shahc62f3982014-03-05 14:28:26 -08002127 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2128
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002129 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002130 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002131 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002132 }
2133 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002134 return true;
2135}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002136
radhakrishnac9a67412013-09-25 17:40:42 +05302137int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2138 PipeLayerPair& PipeLayerPair) {
2139 MdpYUVPipeInfo& mdp_info =
2140 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2141 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302142 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302143 eDest lDest = mdp_info.lIndex;
2144 eDest rDest = mdp_info.rIndex;
2145
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002146 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302147 lDest, rDest, &PipeLayerPair.rot);
2148}
2149
Saurabh Shah88e4d272013-09-03 13:31:29 -07002150bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002151
Raj Kamal4393eaa2014-06-06 13:45:20 +05302152 if(!isEnabled() or !mModeOn) {
2153 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302154 return true;
2155 }
2156
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002157 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002158 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002159 sHandleTimeout = true;
2160 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002161
2162 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002163 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002164
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002165 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2166 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002167 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002168 if(mCurrentFrame.isFBComposed[i]) continue;
2169
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002170 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002171 private_handle_t *hnd = (private_handle_t *)layer->handle;
2172 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002173 if (!(layer->flags & HWC_COLOR_FILL)) {
2174 ALOGE("%s handle null", __FUNCTION__);
2175 return false;
2176 }
2177 // No PLAY for Color layer
2178 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2179 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002180 }
2181
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002182 int mdpIndex = mCurrentFrame.layerToMDP[i];
2183
Raj Kamal389d6e32014-08-04 14:43:24 +05302184 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302185 {
2186 MdpYUVPipeInfo& pipe_info =
2187 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2188 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2189 ovutils::eDest indexL = pipe_info.lIndex;
2190 ovutils::eDest indexR = pipe_info.rIndex;
2191 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302192 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302193 if(rot) {
2194 rot->queueBuffer(fd, offset);
2195 fd = rot->getDstMemId();
2196 offset = rot->getDstOffset();
2197 }
2198 if(indexL != ovutils::OV_INVALID) {
2199 ovutils::eDest destL = (ovutils::eDest)indexL;
2200 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2201 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2202 if (!ov.queueBuffer(fd, offset, destL)) {
2203 ALOGE("%s: queueBuffer failed for display:%d",
2204 __FUNCTION__, mDpy);
2205 return false;
2206 }
2207 }
2208
2209 if(indexR != ovutils::OV_INVALID) {
2210 ovutils::eDest destR = (ovutils::eDest)indexR;
2211 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2212 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2213 if (!ov.queueBuffer(fd, offset, destR)) {
2214 ALOGE("%s: queueBuffer failed for display:%d",
2215 __FUNCTION__, mDpy);
2216 return false;
2217 }
2218 }
2219 }
2220 else{
2221 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002222 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302223 ovutils::eDest dest = pipe_info.index;
2224 if(dest == ovutils::OV_INVALID) {
2225 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002226 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302227 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002228
radhakrishnac9a67412013-09-25 17:40:42 +05302229 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2230 continue;
2231 }
2232
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002233 int fd = hnd->fd;
2234 uint32_t offset = (uint32_t)hnd->offset;
2235 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2236 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002237 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002238 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002239 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002240 }
2241
radhakrishnac9a67412013-09-25 17:40:42 +05302242 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2243 using pipe: %d", __FUNCTION__, layer,
2244 hnd, dest );
2245
radhakrishnac9a67412013-09-25 17:40:42 +05302246 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2247 if(rot) {
2248 if(!rot->queueBuffer(fd, offset))
2249 return false;
2250 fd = rot->getDstMemId();
2251 offset = rot->getDstOffset();
2252 }
2253
2254 if (!ov.queueBuffer(fd, offset, dest)) {
2255 ALOGE("%s: queueBuffer failed for display:%d ",
2256 __FUNCTION__, mDpy);
2257 return false;
2258 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002259 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002260
2261 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002262 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002263 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002264}
2265
Saurabh Shah88e4d272013-09-03 13:31:29 -07002266//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002267
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002268void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302269 hwc_display_contents_1_t* list){
2270 //if 4kx2k yuv layer is totally present in either in left half
2271 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302272 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302273 if(mCurrentFrame.fbZ >= 0) {
2274 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2275 index++) {
2276 if(!mCurrentFrame.isFBComposed[index]) {
2277 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2278 mdpNextZOrder++;
2279 }
2280 mdpNextZOrder++;
2281 hwc_layer_1_t* layer = &list->hwLayers[index];
2282 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302283 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302284 hwc_rect_t dst = layer->displayFrame;
2285 if((dst.left > lSplit) || (dst.right < lSplit)) {
2286 mCurrentFrame.mdpCount += 1;
2287 }
2288 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2289 mCurrentFrame.fbZ += 1;
2290 mdpNextZOrder++;
2291 }
2292 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002293 }
radhakrishnac9a67412013-09-25 17:40:42 +05302294 }
2295}
2296
Saurabh Shah88e4d272013-09-03 13:31:29 -07002297bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002298 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002299
Saurabh Shahc62f3982014-03-05 14:28:26 -08002300 const int lSplit = getLeftSplit(ctx, mDpy);
2301 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002302 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002303 pipe_info.lIndex = ovutils::OV_INVALID;
2304 pipe_info.rIndex = ovutils::OV_INVALID;
2305
Saurabh Shahc62f3982014-03-05 14:28:26 -08002306 Overlay::PipeSpecs pipeSpecs;
2307 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2308 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2309 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2310 pipeSpecs.dpy = mDpy;
2311 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2312 pipeSpecs.fb = false;
2313
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002314 // Acquire pipe only for the updating half
2315 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2316 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2317
2318 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002319 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002320 if(pipe_info.lIndex == ovutils::OV_INVALID)
2321 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002322 }
2323
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002324 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002325 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2326 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002327 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002328 return false;
2329 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002330
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002331 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002332}
2333
Saurabh Shah88e4d272013-09-03 13:31:29 -07002334bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002335 hwc_display_contents_1_t* list) {
2336 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002337
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002338 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002339
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002340 hwc_layer_1_t* layer = &list->hwLayers[index];
2341 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302342 hwc_rect_t dst = layer->displayFrame;
2343 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302344 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302345 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002346 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302347 continue;
2348 }
2349 }
2350 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002351 int mdpIndex = mCurrentFrame.layerToMDP[index];
2352 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002353 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002354 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002355 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002356
Saurabh Shahc62f3982014-03-05 14:28:26 -08002357 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2358 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2359 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002360 return false;
2361 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002362 }
2363 return true;
2364}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002365
radhakrishnac9a67412013-09-25 17:40:42 +05302366int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2367 PipeLayerPair& PipeLayerPair) {
2368 const int lSplit = getLeftSplit(ctx, mDpy);
2369 hwc_rect_t dst = layer->displayFrame;
2370 if((dst.left > lSplit)||(dst.right < lSplit)){
2371 MdpYUVPipeInfo& mdp_info =
2372 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2373 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302374 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302375 eDest lDest = mdp_info.lIndex;
2376 eDest rDest = mdp_info.rIndex;
2377
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002378 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302379 lDest, rDest, &PipeLayerPair.rot);
2380 }
2381 else{
2382 return configure(ctx, layer, PipeLayerPair);
2383 }
2384}
2385
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002386/*
2387 * Configures pipe(s) for MDP composition
2388 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002389int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002390 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002391 MdpPipeInfoSplit& mdp_info =
2392 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002393 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302394 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002395 eDest lDest = mdp_info.lIndex;
2396 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002397
2398 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2399 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2400
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002401 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002402 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002403}
2404
Saurabh Shah88e4d272013-09-03 13:31:29 -07002405bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002406
Raj Kamal4393eaa2014-06-06 13:45:20 +05302407 if(!isEnabled() or !mModeOn) {
2408 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302409 return true;
2410 }
2411
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002412 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002413 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002414 sHandleTimeout = true;
2415 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002416
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002417 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002418 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002419
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002420 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2421 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002422 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002423 if(mCurrentFrame.isFBComposed[i]) continue;
2424
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002425 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002426 private_handle_t *hnd = (private_handle_t *)layer->handle;
2427 if(!hnd) {
2428 ALOGE("%s handle null", __FUNCTION__);
2429 return false;
2430 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002431
2432 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2433 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002434 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002435
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002436 int mdpIndex = mCurrentFrame.layerToMDP[i];
2437
Raj Kamal389d6e32014-08-04 14:43:24 +05302438 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302439 {
2440 MdpYUVPipeInfo& pipe_info =
2441 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2442 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2443 ovutils::eDest indexL = pipe_info.lIndex;
2444 ovutils::eDest indexR = pipe_info.rIndex;
2445 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302446 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302447 if(rot) {
2448 rot->queueBuffer(fd, offset);
2449 fd = rot->getDstMemId();
2450 offset = rot->getDstOffset();
2451 }
2452 if(indexL != ovutils::OV_INVALID) {
2453 ovutils::eDest destL = (ovutils::eDest)indexL;
2454 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2455 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2456 if (!ov.queueBuffer(fd, offset, destL)) {
2457 ALOGE("%s: queueBuffer failed for display:%d",
2458 __FUNCTION__, mDpy);
2459 return false;
2460 }
2461 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002462
radhakrishnac9a67412013-09-25 17:40:42 +05302463 if(indexR != ovutils::OV_INVALID) {
2464 ovutils::eDest destR = (ovutils::eDest)indexR;
2465 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2466 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2467 if (!ov.queueBuffer(fd, offset, destR)) {
2468 ALOGE("%s: queueBuffer failed for display:%d",
2469 __FUNCTION__, mDpy);
2470 return false;
2471 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002472 }
2473 }
radhakrishnac9a67412013-09-25 17:40:42 +05302474 else{
2475 MdpPipeInfoSplit& pipe_info =
2476 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2477 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002478
radhakrishnac9a67412013-09-25 17:40:42 +05302479 ovutils::eDest indexL = pipe_info.lIndex;
2480 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002481
radhakrishnac9a67412013-09-25 17:40:42 +05302482 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002483 uint32_t offset = (uint32_t)hnd->offset;
2484 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2485 if (!mDpy && (index != -1)) {
2486 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2487 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002488 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002489 }
radhakrishnac9a67412013-09-25 17:40:42 +05302490
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002491 if(ctx->mAD->draw(ctx, fd, offset)) {
2492 fd = ctx->mAD->getDstFd();
2493 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002494 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002495
radhakrishnac9a67412013-09-25 17:40:42 +05302496 if(rot) {
2497 rot->queueBuffer(fd, offset);
2498 fd = rot->getDstMemId();
2499 offset = rot->getDstOffset();
2500 }
2501
2502 //************* play left mixer **********
2503 if(indexL != ovutils::OV_INVALID) {
2504 ovutils::eDest destL = (ovutils::eDest)indexL;
2505 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2506 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2507 if (!ov.queueBuffer(fd, offset, destL)) {
2508 ALOGE("%s: queueBuffer failed for left mixer",
2509 __FUNCTION__);
2510 return false;
2511 }
2512 }
2513
2514 //************* play right mixer **********
2515 if(indexR != ovutils::OV_INVALID) {
2516 ovutils::eDest destR = (ovutils::eDest)indexR;
2517 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2518 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2519 if (!ov.queueBuffer(fd, offset, destR)) {
2520 ALOGE("%s: queueBuffer failed for right mixer",
2521 __FUNCTION__);
2522 return false;
2523 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002524 }
2525 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002526
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002527 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2528 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002529
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002530 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002531}
Saurabh Shahab47c692014-02-12 18:45:57 -08002532
2533//================MDPCompSrcSplit==============================================
2534bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002535 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002536 private_handle_t *hnd = (private_handle_t *)layer->handle;
2537 hwc_rect_t dst = layer->displayFrame;
2538 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2539 pipe_info.lIndex = ovutils::OV_INVALID;
2540 pipe_info.rIndex = ovutils::OV_INVALID;
2541
2542 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2543 //should have a higher priority than the right one. Pipe priorities are
2544 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002545
Saurabh Shahc62f3982014-03-05 14:28:26 -08002546 Overlay::PipeSpecs pipeSpecs;
2547 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2548 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2549 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2550 pipeSpecs.dpy = mDpy;
2551 pipeSpecs.fb = false;
2552
Saurabh Shahab47c692014-02-12 18:45:57 -08002553 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002554 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002555 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002556 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002557 }
2558
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002559 /* Use 2 pipes IF
2560 a) Layer's crop width is > 2048 or
2561 b) Layer's dest width > 2048 or
2562 c) On primary, driver has indicated with caps to split always. This is
2563 based on an empirically derived value of panel height. Applied only
2564 if the layer's width is > mixer's width
2565 */
2566
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302567 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002568 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302569 mdpHw.isSrcSplitAlways();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002570 int lSplit = getLeftSplit(ctx, mDpy);
2571 int dstWidth = dst.right - dst.left;
Saurabh Shah189f23d2014-09-26 17:21:00 -07002572 int cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
2573 crop.right - crop.left;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002574
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002575 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2576 //pipe line length, we are still using 2 pipes. This is fine just because
2577 //this is source split where destination doesn't matter. Evaluate later to
2578 //see if going through all the calcs to save a pipe is worth it
Naseer Ahmed9eb5e092014-09-25 13:24:44 -04002579 if(dstWidth > (int) mdpHw.getMaxMixerWidth() or
2580 cropWidth > (int) mdpHw.getMaxMixerWidth() or
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002581 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002582 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002583 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002584 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002585 }
2586
2587 // Return values
2588 // 1 Left pipe is higher priority, do nothing.
2589 // 0 Pipes of same priority.
2590 //-1 Right pipe is of higher priority, needs swap.
2591 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2592 pipe_info.rIndex) == -1) {
2593 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002594 }
2595 }
2596
2597 return true;
2598}
2599
Saurabh Shahab47c692014-02-12 18:45:57 -08002600int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2601 PipeLayerPair& PipeLayerPair) {
2602 private_handle_t *hnd = (private_handle_t *)layer->handle;
2603 if(!hnd) {
2604 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2605 return -1;
2606 }
2607 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2608 MdpPipeInfoSplit& mdp_info =
2609 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2610 Rotator **rot = &PipeLayerPair.rot;
2611 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002612 eDest lDest = mdp_info.lIndex;
2613 eDest rDest = mdp_info.rIndex;
2614 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2615 hwc_rect_t dst = layer->displayFrame;
2616 int transform = layer->transform;
2617 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002618 int rotFlags = ROT_FLAGS_NONE;
2619 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2620 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2621
2622 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2623 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2624
2625 // Handle R/B swap
2626 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2627 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2628 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2629 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2630 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2631 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002632 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002633 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2634 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002635 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002636 /* Calculate the external display position based on MDP downscale,
2637 ActionSafe, and extorientation features. */
2638 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002639
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002640 int downscale = getRotDownscale(ctx, layer);
Justin Philipd6166602014-08-12 13:42:21 +05302641 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002642 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002643
2644 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2645 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002646 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002647 }
2648
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002649 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002650 (*rot) = ctx->mRotMgr->getNext();
2651 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002652 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002653 //If the video is using a single pipe, enable BWC
2654 if(rDest == OV_INVALID) {
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002655 BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002656 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002657 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002658 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002659 ALOGE("%s: configRotator failed!", __FUNCTION__);
2660 return -1;
2661 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002662 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002663 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002664 }
2665
2666 //If 2 pipes being used, divide layer into half, crop and dst
2667 hwc_rect_t cropL = crop;
2668 hwc_rect_t cropR = crop;
2669 hwc_rect_t dstL = dst;
2670 hwc_rect_t dstR = dst;
2671 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2672 cropL.right = (crop.right + crop.left) / 2;
2673 cropR.left = cropL.right;
2674 sanitizeSourceCrop(cropL, cropR, hnd);
2675
Saurabh Shahb729b192014-08-15 18:04:24 -07002676 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002677 //Swap crops on H flip since 2 pipes are being used
2678 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2679 hwc_rect_t tmp = cropL;
2680 cropL = cropR;
2681 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002682 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002683 }
2684
Saurabh Shahb729b192014-08-15 18:04:24 -07002685 //cropSwap trick: If the src and dst widths are both odd, let us say
2686 //2507, then splitting both into half would cause left width to be 1253
2687 //and right 1254. If crop is swapped because of H flip, this will cause
2688 //left crop width to be 1254, whereas left dst width remains 1253, thus
2689 //inducing a scaling that is unaccounted for. To overcome that we add 1
2690 //to the dst width if there is a cropSwap. So if the original width was
2691 //2507, the left dst width will be 1254. Even if the original width was
2692 //even for ex: 2508, the left dst width will still remain 1254.
2693 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002694 dstR.left = dstL.right;
2695 }
2696
2697 //For the mdp, since either we are pre-rotating or MDP does flips
2698 orient = OVERLAY_TRANSFORM_0;
2699 transform = 0;
2700
2701 //configure left pipe
2702 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002703 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002704 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2705 (ovutils::eBlending) getBlending(layer->blending));
2706
2707 if(configMdp(ctx->mOverlay, pargL, orient,
2708 cropL, dstL, metadata, lDest) < 0) {
2709 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2710 return -1;
2711 }
2712 }
2713
2714 //configure right pipe
2715 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002716 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002717 static_cast<eRotFlags>(rotFlags),
2718 layer->planeAlpha,
2719 (ovutils::eBlending) getBlending(layer->blending));
2720 if(configMdp(ctx->mOverlay, pargR, orient,
2721 cropR, dstR, metadata, rDest) < 0) {
2722 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2723 return -1;
2724 }
2725 }
2726
2727 return 0;
2728}
2729
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002730}; //namespace
2731