blob: 9160b578c7754b7eb5e242b86ee7a306b62054a6 [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08002 * Copyright (C) 2012-2015, 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"
Arun Kumar K.R299bcda2014-12-18 19:36:40 -080021#include <dlfcn.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>
Arun Kumar K.R00b84792015-03-27 11:28:36 -070028#include <overlayCursor.h>
Sushil Chauhandefd3522014-05-13 18:17:12 -070029#include "hwc_copybit.h"
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -070030#include "qd_utils.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080031
Saurabh Shah85234ec2013-04-12 17:09:00 -070032using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070033using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080034using namespace overlay::utils;
35namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070036
Naseer Ahmed7c958d42012-07-31 18:57:03 -070037namespace qhwc {
38
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080039//==============MDPComp========================================================
40
Saurabh Shah59562ff2014-09-30 16:13:12 -070041IdleInvalidator *MDPComp::sIdleInvalidator = NULL;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070042bool MDPComp::sIdleFallBack = false;
43bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050044bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070045bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -070046int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -070047int MDPComp::sMaxPipesPerMixer = 0;
Raj Kamal389d6e32014-08-04 14:43:24 +053048bool MDPComp::sEnableYUVsplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070049bool MDPComp::sSrcSplitEnabled = false;
Saurabh Shahacec8e42014-11-25 11:07:04 -080050int MDPComp::sMaxSecLayers = 1;
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +053051bool MDPComp::enablePartialUpdateForMDP3 = false;
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -070052bool MDPComp::sIsPartialUpdateActive = true;
Arun Kumar K.R299bcda2014-12-18 19:36:40 -080053void *MDPComp::sLibPerfHint = NULL;
54int MDPComp::sPerfLockHandle = 0;
55int (*MDPComp::sPerfLockAcquire)(int, int, int*, int) = NULL;
56int (*MDPComp::sPerfLockRelease)(int value) = NULL;
57int MDPComp::sPerfHintWindow = -1;
radhakrishna35e33072015-04-08 17:20:43 +053058float MDPComp::sDownscaleThreshold = 1.0;
Arun Kumar K.R299bcda2014-12-18 19:36:40 -080059
Saurabh Shah8cc77712015-03-31 10:48:51 -070060enum AllocOrder { FORMAT_YUV, FORMAT_RGB, FORMAT_MAX };
61
Saurabh Shah88e4d272013-09-03 13:31:29 -070062MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070063 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
64 sSrcSplitEnabled = true;
65 return new MDPCompSrcSplit(dpy);
66 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070067 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080068 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070069 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080070}
71
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080072MDPComp::MDPComp(int dpy):mDpy(dpy){};
73
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070074void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080075{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070076 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
77 return;
78
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080079 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070080 (mDpy == 0) ? "\"PRIMARY\"" :
81 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070082 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
Arun Kumar K.R00b84792015-03-27 11:28:36 -070083 "fbCount:%2d dropCount:%2d\n", mCurrentFrame.layerCount,
84 mCurrentFrame.mdpCount, mCurrentFrame.fbCount, mCurrentFrame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080085 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
86 (mCurrentFrame.needsRedraw? "YES" : "NO"),
87 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070088 if(isDisplaySplit(ctx, mDpy)) {
89 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
90 "Right: [%d, %d, %d, %d] \n",
91 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
92 ctx->listStats[mDpy].lRoi.right,
93 ctx->listStats[mDpy].lRoi.bottom,
94 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
95 ctx->listStats[mDpy].rRoi.right,
96 ctx->listStats[mDpy].rRoi.bottom);
97 } else {
98 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
99 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
100 ctx->listStats[mDpy].lRoi.right,
101 ctx->listStats[mDpy].lRoi.bottom);
102 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800103 dumpsys_log(buf," --------------------------------------------- \n");
104 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
105 dumpsys_log(buf," --------------------------------------------- \n");
106 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
107 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
108 index,
109 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700110 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800111 (mCurrentFrame.isFBComposed[index] ?
Arun Kumar K.R00b84792015-03-27 11:28:36 -0700112 (mCurrentFrame.drop[index] ?
113 ((mCurrentFrame.hwCursorIndex == index) ? "CURSOR": "DROP"):
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700114 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800115 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
116 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
117 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800118}
119
120bool MDPComp::init(hwc_context_t *ctx) {
121
122 if(!ctx) {
123 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
124 return false;
125 }
126
Saurabh Shah59562ff2014-09-30 16:13:12 -0700127 char property[PROPERTY_VALUE_MAX] = {0};
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800128
129 sEnabled = false;
Dileep Kumar Reddid8e601d2014-10-28 18:20:43 +0530130 if((ctx->mMDP.version >= qdutils::MDP_V4_0) &&
131 (property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800132 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
133 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800134 sEnabled = true;
135 }
136
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700137 sEnableMixedMode = true;
138 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
139 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
140 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
141 sEnableMixedMode = false;
142 }
143
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700144 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
145
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800146 sMaxPipesPerMixer = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700147 if(property_get("persist.hwc.mdpcomp.maxpermixer", property, "-1") > 0) {
Saurabh Shah85234ec2013-04-12 17:09:00 -0700148 int val = atoi(property);
149 if(val >= 0)
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700150 sMaxPipesPerMixer = min(val, sMaxPipesPerMixer);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800151 }
152
Saurabh Shahacec8e42014-11-25 11:07:04 -0800153 /* Maximum layers allowed to use MDP on secondary panels. If property
154 * doesn't exist, default to 1. Using the property it can be set to 0 or
155 * more.
156 */
157 if(property_get("persist.hwc.maxseclayers", property, "1") > 0) {
158 int val = atoi(property);
159 sMaxSecLayers = (val >= 0) ? val : 1;
160 sMaxSecLayers = min(sMaxSecLayers, sMaxPipesPerMixer);
161 }
162
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400163 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
Saurabh Shah59562ff2014-09-30 16:13:12 -0700164 sIdleInvalidator = IdleInvalidator::getInstance();
165 if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
166 delete sIdleInvalidator;
167 sIdleInvalidator = NULL;
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400168 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800169 }
radhakrishnac9a67412013-09-25 17:40:42 +0530170
Saurabh Shah7c727642014-06-02 15:47:14 -0700171 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700172 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700173 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
174 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
175 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530176 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530177 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700178
Dileep Kumar Reddic6ef3472014-09-24 19:07:08 +0530179 bool defaultPTOR = false;
180 //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
Prabhanjan Kandulafc541b32015-03-30 20:56:16 +0530181 //Bear family targets by default
Dileep Kumar Reddic6ef3472014-09-24 19:07:08 +0530182 if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
183 (qdutils::MDPVersion::getInstance().is8x16() ||
Prabhanjan Kandulafc541b32015-03-30 20:56:16 +0530184 qdutils::MDPVersion::getInstance().is8x39() ||
185 qdutils::MDPVersion::getInstance().is8x52())) {
Dileep Kumar Reddic6ef3472014-09-24 19:07:08 +0530186 defaultPTOR = true;
187 }
188
189 if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
190 (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700191 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
192 HWC_DISPLAY_PRIMARY);
193 }
194
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +0530195 if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
196 (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
197 enablePartialUpdateForMDP3 = true;
198 }
199
200 if(!enablePartialUpdateForMDP3 &&
201 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
202 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
203 enablePartialUpdateForMDP3 = true;
204 }
205
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -0800206 sIsPartialUpdateActive = getPartialUpdatePref(ctx);
207
Arun Kumar K.R299bcda2014-12-18 19:36:40 -0800208 if(property_get("persist.mdpcomp_perfhint", property, "-1") > 0) {
209 int val = atoi(property);
210 if(val > 0 && loadPerfLib()) {
211 sPerfHintWindow = val;
212 ALOGI("PerfHintWindow = %d", sPerfHintWindow);
213 }
214 }
215
radhakrishna35e33072015-04-08 17:20:43 +0530216 if(property_get("persist.hwc.downscale_threshold", property, "1.0") > 0) {
217 sDownscaleThreshold = (float)atof(property);
218 }
219
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700220 return true;
221}
222
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800223void MDPComp::reset(hwc_context_t *ctx) {
224 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700225 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800226 ctx->mOverlay->clear(mDpy);
227 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700228}
229
Raj Kamal4393eaa2014-06-06 13:45:20 +0530230void MDPComp::reset() {
Raj Kamalfdfdddf2015-03-16 21:59:25 +0530231 mPrevModeOn = mModeOn;
Raj Kamal4393eaa2014-06-06 13:45:20 +0530232 mModeOn = false;
233}
234
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700235void MDPComp::timeout_handler(void *udata) {
236 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
Raj Kamalfdfdddf2015-03-16 21:59:25 +0530237 bool handleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700238
239 if(!ctx) {
240 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
241 return;
242 }
Raj Kamal58b31a02014-12-16 15:53:53 +0530243
244 ctx->mDrawLock.lock();
Raj Kamalfdfdddf2015-03-16 21:59:25 +0530245
246 /* Handle timeout event only if the previous composition
247 on any display is MDP or MIXED*/
248 for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
249 if(ctx->mMDPComp[i])
250 handleTimeout =
251 ctx->mMDPComp[i]->isMDPComp() || handleTimeout;
252 }
253
254 if(!handleTimeout) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800255 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530256 ctx->mDrawLock.unlock();
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800257 return;
258 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700259 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700260 ALOGE("%s: HWC proc not registered", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530261 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700262 return;
263 }
264 sIdleFallBack = true;
Raj Kamal58b31a02014-12-16 15:53:53 +0530265 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700266 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700267 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700268}
269
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700270void MDPComp::setMaxPipesPerMixer(const uint32_t value) {
271 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800272 uint32_t maxSupported = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700273 if(value > maxSupported) {
274 ALOGW("%s: Input exceeds max value supported. Setting to"
275 "max value: %d", __FUNCTION__, maxSupported);
276 }
277 sMaxPipesPerMixer = min(value, maxSupported);
278}
279
Saurabh Shah59562ff2014-09-30 16:13:12 -0700280void MDPComp::setIdleTimeout(const uint32_t& timeout) {
281 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
282
283 if(sIdleInvalidator) {
284 if(timeout <= ONE_REFRESH_PERIOD_MS) {
285 //If the specified timeout is < 1 draw cycle worth, "virtually"
286 //disable idle timeout. The ideal way for clients to disable
287 //timeout is to set it to 0
288 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
289 ALOGI("Disabled idle timeout");
290 return;
291 }
292 sIdleInvalidator->setIdleTimeout(timeout);
293 ALOGI("Idle timeout set to %u", timeout);
294 } else {
295 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
296 }
297}
298
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800299void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800300 hwc_display_contents_1_t* list) {
301 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800302
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800303 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800304 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800305 if(!mCurrentFrame.isFBComposed[index]) {
306 layerProp[index].mFlags |= HWC_MDPCOMP;
307 layer->compositionType = HWC_OVERLAY;
308 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800309 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700310 /* Drop the layer when its already present in FB OR when it lies
311 * outside frame's ROI */
312 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Arun Kumar K.R00b84792015-03-27 11:28:36 -0700313 if(index == mCurrentFrame.hwCursorIndex) {
314 layer->compositionType = HWC_CURSOR_OVERLAY;
315 } else {
316 layer->compositionType = HWC_OVERLAY;
317 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700318 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800319 }
320 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700321}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500322
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800323void MDPComp::setRedraw(hwc_context_t *ctx,
324 hwc_display_contents_1_t* list) {
325 mCurrentFrame.needsRedraw = false;
326 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
327 (list->flags & HWC_GEOMETRY_CHANGED) ||
328 isSkipPresent(ctx, mDpy)) {
329 mCurrentFrame.needsRedraw = true;
330 }
331}
332
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800333MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700334 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700335 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800336}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800337
Saurabh Shahaa236822013-04-24 18:07:26 -0700338void MDPComp::FrameInfo::reset(const int& numLayers) {
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700339 for(int i = 0 ; i < MAX_NUM_BLEND_STAGES; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800340 if(mdpToLayer[i].pipeInfo) {
341 delete mdpToLayer[i].pipeInfo;
342 mdpToLayer[i].pipeInfo = NULL;
343 //We dont own the rotator
344 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800345 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800346 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800347
348 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
349 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700350 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800351
Saurabh Shahaa236822013-04-24 18:07:26 -0700352 layerCount = numLayers;
353 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800354 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700355 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800356 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800357}
358
Saurabh Shahaa236822013-04-24 18:07:26 -0700359void MDPComp::FrameInfo::map() {
360 // populate layer and MDP maps
361 int mdpIdx = 0;
362 for(int idx = 0; idx < layerCount; idx++) {
363 if(!isFBComposed[idx]) {
364 mdpToLayer[mdpIdx].listIndex = idx;
365 layerToMDP[idx] = mdpIdx++;
366 }
367 }
368}
369
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800370MDPComp::LayerCache::LayerCache() {
371 reset();
372}
373
374void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700375 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530376 memset(&isFBComposed, true, sizeof(isFBComposed));
377 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800378 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700379}
380
381void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530382 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700383 for(int i = 0; i < numAppLayers; i++) {
384 hnd[i] = list->hwLayers[i].handle;
385 }
386}
387
388void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700389 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530390 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
391 memcpy(&drop, &curFrame.drop, sizeof(drop));
392}
393
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800394bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
395 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530396 if(layerCount != curFrame.layerCount)
397 return false;
398 for(int i = 0; i < curFrame.layerCount; i++) {
399 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
400 (curFrame.drop[i] != drop[i])) {
401 return false;
402 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800403 if(curFrame.isFBComposed[i] &&
404 (hnd[i] != list->hwLayers[i].handle)){
405 return false;
406 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530407 }
408 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800409}
410
Raj Kamalfdfdddf2015-03-16 21:59:25 +0530411bool MDPComp::LayerCache::isSameFrame(hwc_context_t *ctx, int dpy,
412 hwc_display_contents_1_t* list) {
413
414 if(layerCount != ctx->listStats[dpy].numAppLayers)
415 return false;
416
417 if((list->flags & HWC_GEOMETRY_CHANGED) ||
418 isSkipPresent(ctx, dpy)) {
419 return false;
420 }
421
422 for(int i = 0; i < layerCount; i++) {
423 if(hnd[i] != list->hwLayers[i].handle)
424 return false;
425 }
426
427 return true;
428}
429
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700430bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
431 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800432 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Raj Kamal1179d9c2014-10-28 15:31:35 +0530433 (not isValidDimension(ctx,layer)) ||
434 isSkipLayer(layer)) {
435 //More conditions here, sRGB+Blend etc
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700436 return false;
437 }
radhakrishna35e33072015-04-08 17:20:43 +0530438
439 //In targets with fewer pipes, frequent composition switch between MDP/GPU
440 //can happen for a layer due to lack of pipes. When this switch happens
441 //continuously for RGB downscaled layer with downscale greater than
442 //threshold, it appears as flicker as output
443 //of MDP and GPU are different as they use different filters for downscale.
444 //To avoid this flicker, punt RGB downscaled layer with downscale greater
445 //than threshold value to GPU always.
446 if((sDownscaleThreshold > 1.0)) {
447 if(((not isYuvBuffer(hnd))
448 and (not isDownscaleWithinThreshold(layer,
449 sDownscaleThreshold)))) {
450 ALOGD_IF(isDebug(), "%s: required downscale is greater than \
451 threshold %f", __FUNCTION__, sDownscaleThreshold);
452 return false;
453 }
454 }
455
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700456 return true;
457}
458
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530459bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800460 private_handle_t *hnd = (private_handle_t *)layer->handle;
461
462 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700463 if (layer->flags & HWC_COLOR_FILL) {
464 // Color layer
465 return true;
466 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700467 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800468 return false;
469 }
470
Naseer Ahmede850a802013-09-06 13:12:52 -0400471 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400472 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400473 return false;
474
Saurabh Shah62e1d732013-09-17 10:44:05 -0700475 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700476 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700477 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700478 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
479 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700480 int dst_w = dst.right - dst.left;
481 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800482 float w_scale = ((float)crop_w / (float)dst_w);
483 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530484 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700485
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800486 /* Workaround for MDP HW limitation in DSI command mode panels where
487 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
488 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530489 * There also is a HW limilation in MDP, minimum block size is 2x2
490 * Fallback to GPU if height is less than 2.
491 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700492 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800493 return false;
494
Ramkumar Radhakrishnan1a763e92015-03-19 16:46:46 -0700495 /* crop_w and crop_h should be even for yuv layer, so fallback to GPU for
496 * those cases
497 */
498 if(isYuvBuffer(hnd) && (crop_w < 2 || crop_h < 2)) {
499 return false;
500 }
501
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800502 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530503 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800504 const float w_dscale = w_scale;
505 const float h_dscale = h_scale;
506
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800507 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700508
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530509 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700510 /* On targets that doesnt support Decimation (eg.,8x26)
511 * maximum downscale support is overlay pipe downscale.
512 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800513 if(crop_w > (int) mdpHw.getMaxPipeWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530514 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700515 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800516 return false;
517 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700518 // Decimation on macrotile format layers is not supported.
519 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530520 /* Bail out if
521 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700522 * 2. exceeds maximum downscale limit
523 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800524 if(((crop_w > (int) mdpHw.getMaxPipeWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530525 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700526 w_dscale > maxMDPDownscale ||
527 h_dscale > maxMDPDownscale) {
528 return false;
529 }
530 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800531 return false;
532 }
533 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700534 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700535 return false;
536 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700537 }
538
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800539 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530540 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800541 const float w_uscale = 1.0f / w_scale;
542 const float h_uscale = 1.0f / h_scale;
543
544 if(w_uscale > upscale || h_uscale > upscale)
545 return false;
546 }
547
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800548 return true;
549}
550
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800551bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700552 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800553
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800554 if(!isEnabled()) {
555 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700556 ret = false;
Saurabh Shah19740d02015-04-10 10:05:42 -0700557 } else if(ctx->mVideoTransFlag && isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700558 //1 Padding round to shift pipes across mixers
559 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
560 __FUNCTION__);
561 ret = false;
Raj Kamalc0d34242015-03-17 20:53:14 +0530562 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
563 qdutils::MDPVersion::getInstance().is8x16() ||
Prabhanjan Kandulafc541b32015-03-30 20:56:16 +0530564 qdutils::MDPVersion::getInstance().is8x39() ||
565 qdutils::MDPVersion::getInstance().is8x52()) &&
Raj Kamalc0d34242015-03-17 20:53:14 +0530566 !mDpy && isSecondaryAnimating(ctx) &&
567 isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL)) {
568 ALOGD_IF(isDebug(),"%s: Display animation in progress",
569 __FUNCTION__);
570 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700571 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
572 /* TODO: freeing up all the resources only for the targets having total
573 number of pipes < 8. Need to analyze number of VIG pipes used
574 for primary in previous draw cycle and accordingly decide
575 whether to fall back to full GPU comp or video only comp
576 */
577 if(isSecondaryConfiguring(ctx)) {
578 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
579 __FUNCTION__);
580 ret = false;
581 } else if(ctx->isPaddingRound) {
582 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
583 __FUNCTION__,mDpy);
584 ret = false;
585 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800586 } else if (ctx->isDMAStateChanging) {
587 // Bail out if a padding round has been invoked in order to switch DMA
588 // state to block mode. We need this to cater for the case when a layer
589 // requires rotation in the current frame.
590 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
591 __FUNCTION__);
592 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700593 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800594
Saurabh Shahaa236822013-04-24 18:07:26 -0700595 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800596}
597
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800598void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
599 hwc_rect &dst) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800600 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800601 dst = getIntersection(dst, roi);
602 crop = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800603}
604
605/* 1) Identify layers that are not visible or lying outside the updating ROI and
606 * drop them from composition.
607 * 2) If we have a scaling layer which needs cropping against generated
608 * ROI, reset ROI to full resolution. */
609bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
610 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700611 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800612 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800613
614 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800615 if(!isValidRect(visibleRect)) {
616 mCurrentFrame.drop[i] = true;
617 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800618 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800619 }
620
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700621 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700622 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800623 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700624
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700625 if(!isValidRect(res)) {
626 mCurrentFrame.drop[i] = true;
627 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800628 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700629 /* Reset frame ROI when any layer which needs scaling also needs ROI
630 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800631 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800632 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700633 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
634 mCurrentFrame.dropCount = 0;
635 return false;
636 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800637
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800638 /* deduct any opaque region from visibleRect */
radhakrishna4efbdd62014-11-03 13:19:27 +0530639 if (layer->blending == HWC_BLENDING_NONE &&
640 layer->planeAlpha == 0xFF)
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800641 visibleRect = deductRect(visibleRect, res);
642 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700643 }
644 return true;
645}
646
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800647/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
648 * are updating. If DirtyRegion is applicable, calculate it by accounting all
649 * the changing layer's dirtyRegion. */
650void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
651 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700652 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800653 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700654 return;
655
656 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800657 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
658 (int)ctx->dpyAttr[mDpy].yres};
659
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700660 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800661 hwc_layer_1_t* layer = &list->hwLayers[index];
662 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800663 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700664 hwc_rect_t dst = layer->displayFrame;
665 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800666
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800667#ifdef QCOM_BSP
Dileep Kumar Reddi7399d5c2014-12-31 18:01:19 +0530668 if(!needsScaling(layer) && !layer->transform &&
669 (!isYuvBuffer((private_handle_t *)layer->handle)))
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700670 {
671 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
672 int x_off = dst.left - src.left;
673 int y_off = dst.top - src.top;
674 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
675 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800676#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800677
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800678 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700679 }
680 }
681
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800682 /* No layer is updating. Still SF wants a refresh.*/
683 if(!isValidRect(roi))
684 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800685
686 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800687 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800688
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800689 ctx->listStats[mDpy].lRoi = roi;
690 if(!validateAndApplyROI(ctx, list))
691 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700692
693 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800694 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
695 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
696}
697
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800698void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
699 hwc_rect &dst) {
700 hwc_rect roi = getUnion(ctx->listStats[mDpy].lRoi,
701 ctx->listStats[mDpy].rRoi);
702 hwc_rect tmpDst = getIntersection(dst, roi);
703 if(!isSameRect(dst, tmpDst)) {
704 crop.left = crop.left + (tmpDst.left - dst.left);
705 crop.top = crop.top + (tmpDst.top - dst.top);
706 crop.right = crop.left + (tmpDst.right - tmpDst.left);
707 crop.bottom = crop.top + (tmpDst.bottom - tmpDst.top);
708 dst = tmpDst;
709 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800710}
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800711
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800712/* 1) Identify layers that are not visible or lying outside BOTH the updating
713 * ROI's and drop them from composition. If a layer is spanning across both
714 * the halves of the screen but needed by only ROI, the non-contributing
715 * half will not be programmed for MDP.
716 * 2) If we have a scaling layer which needs cropping against generated
717 * ROI, reset ROI to full resolution. */
718bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
719 hwc_display_contents_1_t* list) {
720
721 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
722
723 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
724 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
725
726 for(int i = numAppLayers - 1; i >= 0; i--){
727 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
728 {
729 mCurrentFrame.drop[i] = true;
730 mCurrentFrame.dropCount++;
731 continue;
732 }
733
734 const hwc_layer_1_t* layer = &list->hwLayers[i];
735 hwc_rect_t dstRect = layer->displayFrame;
736
737 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
738 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
739 hwc_rect_t res = getUnion(l_res, r_res);
740
741 if(!isValidRect(l_res) && !isValidRect(r_res)) {
742 mCurrentFrame.drop[i] = true;
743 mCurrentFrame.dropCount++;
744 } else {
745 /* Reset frame ROI when any layer which needs scaling also needs ROI
746 * cropping */
747 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
748 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
749 mCurrentFrame.dropCount = 0;
750 return false;
751 }
752
radhakrishna4efbdd62014-11-03 13:19:27 +0530753 if (layer->blending == HWC_BLENDING_NONE &&
754 layer->planeAlpha == 0xFF) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800755 visibleRectL = deductRect(visibleRectL, l_res);
756 visibleRectR = deductRect(visibleRectR, r_res);
757 }
758 }
759 }
760 return true;
761}
762/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
763 * are updating. If DirtyRegion is applicable, calculate it by accounting all
764 * the changing layer's dirtyRegion. */
765void MDPCompSplit::generateROI(hwc_context_t *ctx,
766 hwc_display_contents_1_t* list) {
767 if(!canPartialUpdate(ctx, list))
768 return;
769
770 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
771 int lSplit = getLeftSplit(ctx, mDpy);
772
773 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
774 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
775
776 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
777 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
778
779 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
780 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
781
782 for(int index = 0; index < numAppLayers; index++ ) {
783 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800784 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800785 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800786 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700787 hwc_rect_t dst = layer->displayFrame;
788 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800789
790#ifdef QCOM_BSP
791 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700792 {
793 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
794 int x_off = dst.left - src.left;
795 int y_off = dst.top - src.top;
796 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
797 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800798#endif
799
800 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
801 if(isValidRect(l_dst))
802 l_roi = getUnion(l_roi, l_dst);
803
804 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
805 if(isValidRect(r_dst))
806 r_roi = getUnion(r_roi, r_dst);
807 }
808 }
809
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700810 /* For panels that cannot accept commands in both the interfaces, we cannot
811 * send two ROI's (for each half). We merge them into single ROI and split
812 * them across lSplit for MDP mixer use. The ROI's will be merged again
813 * finally before udpating the panel in the driver. */
814 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
815 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
816 l_roi = getIntersection(temp_roi, l_frame);
817 r_roi = getIntersection(temp_roi, r_frame);
818 }
819
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800820 /* No layer is updating. Still SF wants a refresh. */
821 if(!isValidRect(l_roi) && !isValidRect(r_roi))
822 return;
823
824 l_roi = getSanitizeROI(l_roi, l_frame);
825 r_roi = getSanitizeROI(r_roi, r_frame);
826
827 ctx->listStats[mDpy].lRoi = l_roi;
828 ctx->listStats[mDpy].rRoi = r_roi;
829
830 if(!validateAndApplyROI(ctx, list))
831 resetROI(ctx, mDpy);
832
833 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
834 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
835 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
836 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
837 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
838 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700839}
840
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800841/* Checks for conditions where all the layers marked for MDP comp cannot be
842 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800843bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800844 hwc_display_contents_1_t* list){
845
Saurabh Shahaa236822013-04-24 18:07:26 -0700846 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800847
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700848 // Fall back to video only composition, if AIV video mode is enabled
849 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700850 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
851 __FUNCTION__, mDpy);
852 return false;
853 }
854
Praveena Pachipulusu47346c22014-12-04 11:06:41 +0530855 /* No Idle fall back if secure display or secure RGB layers are present
856 * or if there is only a single layer being composed */
857 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI &&
858 !ctx->listStats[mDpy].secureRGBCount &&
859 (ctx->listStats[mDpy].numAppLayers > 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700860 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
861 return false;
862 }
863
Raj Kamalc0d34242015-03-17 20:53:14 +0530864 if(!mDpy && isSecondaryAnimating(ctx) &&
865 (isYuvPresent(ctx,HWC_DISPLAY_EXTERNAL) ||
866 isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL)) ) {
867 ALOGD_IF(isDebug(),"%s: Display animation in progress",
868 __FUNCTION__);
869 return false;
870 }
871
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700872 // if secondary is configuring or Padding round, fall back to video only
873 // composition and release all assigned non VIG pipes from primary.
874 if(isSecondaryConfiguring(ctx)) {
875 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
876 __FUNCTION__);
877 return false;
878 } else if(ctx->isPaddingRound) {
879 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
880 __FUNCTION__,mDpy);
881 return false;
882 }
883
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -0500884 // No MDP composition for 3D
885 if(needs3DComposition(ctx, mDpy))
886 return false;
887
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700888 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800889 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700890 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800891 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
892 return false;
893 }
894
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800895 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800896 hwc_layer_1_t* layer = &list->hwLayers[i];
897 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800898
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800899 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700900 if(!canUseRotator(ctx, mDpy)) {
901 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
902 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700903 return false;
904 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800905 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530906
907 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
908 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800909 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700910 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530911 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
912 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
913 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800914 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700915
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700916 if(ctx->mAD->isDoable()) {
917 return false;
918 }
919
Saurabh Shahaa236822013-04-24 18:07:26 -0700920 //If all above hard conditions are met we can do full or partial MDP comp.
921 bool ret = false;
922 if(fullMDPComp(ctx, list)) {
923 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700924 } else if(fullMDPCompWithPTOR(ctx, list)) {
925 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700926 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700927 ret = true;
928 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530929
Saurabh Shahaa236822013-04-24 18:07:26 -0700930 return ret;
931}
932
933bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700934
935 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
936 return false;
937
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700938 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
939 for(int i = 0; i < numAppLayers; i++) {
940 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700941 if(not mCurrentFrame.drop[i] and
942 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700943 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
944 return false;
945 }
946 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800947
Raj Kamalb5f0b4a2015-04-08 15:10:37 +0530948 if(!mDpy && isSecondaryConnected(ctx) &&
949 (qdutils::MDPVersion::getInstance().is8x16() ||
950 qdutils::MDPVersion::getInstance().is8x26() ||
951 qdutils::MDPVersion::getInstance().is8x39()) &&
952 isYuvPresent(ctx, HWC_DISPLAY_VIRTUAL)) {
953 ALOGD_IF(isDebug(), "%s: YUV layer present on secondary", __FUNCTION__);
954 return false;
955 }
956
Saurabh Shahaa236822013-04-24 18:07:26 -0700957 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700958 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
959 sizeof(mCurrentFrame.isFBComposed));
960 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
961 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700962
Raj Kamal389d6e32014-08-04 14:43:24 +0530963 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800964 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530965 }
966
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800967 if(!postHeuristicsHandling(ctx, list)) {
968 ALOGD_IF(isDebug(), "post heuristic handling failed");
969 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700970 return false;
971 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700972 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
973 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700974 return true;
975}
976
Sushil Chauhandefd3522014-05-13 18:17:12 -0700977/* Full MDP Composition with Peripheral Tiny Overlap Removal.
978 * MDP bandwidth limitations can be avoided, if the overlap region
979 * covered by the smallest layer at a higher z-order, gets composed
980 * by Copybit on a render buffer, which can be queued to MDP.
981 */
982bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
983 hwc_display_contents_1_t* list) {
984
985 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R00b84792015-03-27 11:28:36 -0700986 // PTOR does not qualify when there are layers dropped, but if
987 // dropped layer is only a cursor, PTOR could qualify
988 const int numNonCursorLayers = numAppLayers - mCurrentFrame.dropCount;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700989 const int stagesForMDP = min(sMaxPipesPerMixer,
990 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
991
992 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700993 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700994 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
995 return false;
996 }
997
Arun Kumar K.R00b84792015-03-27 11:28:36 -0700998 // Frame level checks - consider PTOR in case of dropCount only if the cursor
999 // layer is dropped, otherwise bail out of PTOR
Sushil Chauhandefd3522014-05-13 18:17:12 -07001000 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001001 isYuvPresent(ctx, mDpy) || isSecurePresent(ctx, mDpy) ||
1002 (mCurrentFrame.dropCount - (int)isCursorPresent(ctx, mDpy))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001003 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
1004 return false;
1005 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001006 // MDP comp checks
1007 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001008 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001009 if(not isSupportedForMDPComp(ctx, layer)) {
1010 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
1011 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001012 }
1013 }
1014
Raj Kamalb5f0b4a2015-04-08 15:10:37 +05301015 if(!mDpy && isSecondaryConnected(ctx) &&
1016 (qdutils::MDPVersion::getInstance().is8x16() ||
1017 qdutils::MDPVersion::getInstance().is8x26() ||
1018 qdutils::MDPVersion::getInstance().is8x39()) &&
1019 isYuvPresent(ctx, HWC_DISPLAY_VIRTUAL)) {
1020 ALOGD_IF(isDebug(), "%s: YUV layer present on secondary", __FUNCTION__);
1021 return false;
1022 }
1023
Sushil Chauhandefd3522014-05-13 18:17:12 -07001024 /* We cannot use this composition mode, if:
1025 1. A below layer needs scaling.
1026 2. Overlap is not peripheral to display.
1027 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001028 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -07001029 */
1030
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001031 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
1032 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
1033 memset(overlapRect, 0, sizeof(overlapRect));
1034 int layerPixelCount, minPixelCount = 0;
1035 int numPTORLayersFound = 0;
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001036 for (int i = numNonCursorLayers - 1; (i >= 0 &&
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001037 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001038 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001039 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001040 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001041 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
1042 // PTOR layer should be peripheral and cannot have transform
1043 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
1044 has90Transform(layer)) {
1045 continue;
1046 }
1047 if((3 * (layerPixelCount + minPixelCount)) >
1048 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
1049 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
1050 continue;
1051 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001052 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001053 for (int j = i-1; j >= 0; j--) {
1054 // Check if the layers below this layer qualifies for PTOR comp
1055 hwc_layer_1_t* layer = &list->hwLayers[j];
1056 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001057 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001058 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001059 if (isValidRect(getIntersection(dispFrame, disFrame))) {
1060 if (has90Transform(layer) || needsScaling(layer)) {
1061 found = false;
1062 break;
1063 }
1064 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001065 }
1066 }
1067 // Store the minLayer Index
1068 if(found) {
1069 minLayerIndex[numPTORLayersFound] = i;
1070 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
1071 minPixelCount += layerPixelCount;
1072 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001073 }
1074 }
1075
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001076 // No overlap layers
1077 if (!numPTORLayersFound)
1078 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001079
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001080 // Store the displayFrame and the sourceCrops of the layers
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001081 hwc_rect_t displayFrame[numNonCursorLayers];
1082 hwc_rect_t sourceCrop[numNonCursorLayers];
1083 for(int i = 0; i < numNonCursorLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001084 hwc_layer_1_t* layer = &list->hwLayers[i];
1085 displayFrame[i] = layer->displayFrame;
1086 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001087 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001088
Prabhanjan Kandula9889a202014-09-04 21:50:35 +05301089 /**
1090 * It's possible that 2 PTOR layers might have overlapping.
1091 * In such case, remove the intersection(again if peripheral)
1092 * from the lower PTOR layer to avoid overlapping.
1093 * If intersection is not on peripheral then compromise
1094 * by reducing number of PTOR layers.
1095 **/
1096 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
1097 if(isValidRect(commonRect)) {
1098 overlapRect[1] = deductRect(overlapRect[1], commonRect);
1099 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
1100 }
1101
1102 ctx->mPtorInfo.count = numPTORLayersFound;
1103 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
1104 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
1105 }
1106
1107 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
1108 // reset PTOR
1109 ctx->mPtorInfo.count = 0;
1110 if(isValidRect(commonRect)) {
1111 // If PTORs are intersecting restore displayframe of PTOR[1]
1112 // before returning, as we have modified it above.
1113 list->hwLayers[minLayerIndex[1]].displayFrame =
1114 displayFrame[minLayerIndex[1]];
1115 }
1116 return false;
1117 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001118 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1119 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
1120
Xu Yangcda012c2014-07-30 21:57:21 +08001121 // Store the blending mode, planeAlpha, and transform of PTOR layers
1122 int32_t blending[numPTORLayersFound];
1123 uint8_t planeAlpha[numPTORLayersFound];
1124 uint32_t transform[numPTORLayersFound];
1125
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001126 for(int j = 0; j < numPTORLayersFound; j++) {
1127 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001128
1129 // Update src crop of PTOR layer
1130 hwc_layer_1_t* layer = &list->hwLayers[index];
1131 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1132 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1133 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1134 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1135
1136 // Store & update w, h, format of PTOR layer
1137 private_handle_t *hnd = (private_handle_t *)layer->handle;
1138 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1139 layerWhf[j] = whf;
1140 hnd->width = renderBuf->width;
1141 hnd->height = renderBuf->height;
1142 hnd->format = renderBuf->format;
1143
Xu Yangcda012c2014-07-30 21:57:21 +08001144 // Store & update blending mode, planeAlpha and transform of PTOR layer
1145 blending[j] = layer->blending;
1146 planeAlpha[j] = layer->planeAlpha;
1147 transform[j] = layer->transform;
1148 layer->blending = HWC_BLENDING_NONE;
1149 layer->planeAlpha = 0xFF;
1150 layer->transform = 0;
1151
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001152 // Remove overlap from crop & displayFrame of below layers
1153 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001154 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001155 if(!isValidRect(getIntersection(layer->displayFrame,
1156 overlapRect[j]))) {
1157 continue;
1158 }
1159 // Update layer attributes
1160 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1161 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301162 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001163 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1164 layer->transform);
1165 layer->sourceCropf.left = (float)srcCrop.left;
1166 layer->sourceCropf.top = (float)srcCrop.top;
1167 layer->sourceCropf.right = (float)srcCrop.right;
1168 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1169 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001170 }
1171
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001172 mCurrentFrame.mdpCount = numNonCursorLayers;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001173 mCurrentFrame.fbCount = 0;
1174 mCurrentFrame.fbZ = -1;
1175
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001176 for (int j = 0; j < numNonCursorLayers; j++) {
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301177 if(isValidRect(list->hwLayers[j].displayFrame)) {
1178 mCurrentFrame.isFBComposed[j] = false;
1179 } else {
1180 mCurrentFrame.mdpCount--;
1181 mCurrentFrame.drop[j] = true;
1182 }
1183 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001184
1185 bool result = postHeuristicsHandling(ctx, list);
1186
1187 // Restore layer attributes
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001188 for(int i = 0; i < numNonCursorLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001189 hwc_layer_1_t* layer = &list->hwLayers[i];
1190 layer->displayFrame = displayFrame[i];
1191 layer->sourceCropf.left = (float)sourceCrop[i].left;
1192 layer->sourceCropf.top = (float)sourceCrop[i].top;
1193 layer->sourceCropf.right = (float)sourceCrop[i].right;
1194 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1195 }
1196
Xu Yangcda012c2014-07-30 21:57:21 +08001197 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001198 for (int i = 0; i < numPTORLayersFound; i++) {
1199 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001200 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001201 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1202 hnd->width = layerWhf[i].w;
1203 hnd->height = layerWhf[i].h;
1204 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001205 layer->blending = blending[i];
1206 layer->planeAlpha = planeAlpha[i];
1207 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001208 }
1209
Sushil Chauhandefd3522014-05-13 18:17:12 -07001210 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001211 // reset PTOR
1212 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001213 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001214 } else {
1215 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1216 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001217 }
1218
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001219 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1220 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001221 return result;
1222}
1223
Saurabh Shahaa236822013-04-24 18:07:26 -07001224bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1225{
radhakrishnac3198ff2015-03-10 17:10:02 +05301226 if(!sEnableMixedMode || !isAlphaPresentinFB(ctx, mDpy)) {
1227 //Mixed mode is disabled/can't be used. No need to even try caching.
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001228 return false;
1229 }
1230
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001231 bool ret = false;
Raj Kamal1179d9c2014-10-28 15:31:35 +05301232 if(isSkipPresent(ctx, mDpy) or list->flags & HWC_GEOMETRY_CHANGED) {
1233 //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001234 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001235 cacheBasedComp(ctx, list);
1236 } else {
1237 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001238 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001239 }
1240
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001241 return ret;
1242}
1243
1244bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1245 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001246 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1247 return false;
1248
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001249 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001250 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001251 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001252
1253 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1254 for(int i = 0; i < numAppLayers; i++) {
1255 if(!mCurrentFrame.isFBComposed[i]) {
1256 hwc_layer_1_t* layer = &list->hwLayers[i];
1257 if(not isSupportedForMDPComp(ctx, layer)) {
1258 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1259 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001260 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001261 return false;
1262 }
1263 }
1264 }
1265
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001266 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001267 /* mark secure RGB layers for MDP comp */
1268 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301269 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001270 if(!ret) {
1271 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001272 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001273 return false;
1274 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001275
1276 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001277
Raj Kamal389d6e32014-08-04 14:43:24 +05301278 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001279 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301280 }
1281
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001282 if(!postHeuristicsHandling(ctx, list)) {
1283 ALOGD_IF(isDebug(), "post heuristic handling failed");
1284 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001285 return false;
1286 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001287 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1288 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001289
Saurabh Shahaa236822013-04-24 18:07:26 -07001290 return true;
1291}
1292
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001293bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001294 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001295 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1296 return false;
1297
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001298 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001299 return false;
1300 }
1301
Saurabh Shahb772ae32013-11-18 15:40:02 -08001302 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001303 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1304 const int stagesForMDP = min(sMaxPipesPerMixer,
1305 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001306
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001307 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1308 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1309 int lastMDPSupportedIndex = numAppLayers;
1310 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001311
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001312 //Find the minimum MDP batch size
1313 for(int i = 0; i < numAppLayers;i++) {
1314 if(mCurrentFrame.drop[i]) {
1315 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001316 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001317 }
1318 hwc_layer_1_t* layer = &list->hwLayers[i];
1319 if(not isSupportedForMDPComp(ctx, layer)) {
1320 lastMDPSupportedIndex = i;
1321 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1322 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001323 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001324 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001325 }
1326
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001327 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1328 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1329 mCurrentFrame.dropCount);
1330
1331 //Start at a point where the fb batch should at least have 2 layers, for
1332 //this mode to be justified.
1333 while(fbBatchSize < 2) {
1334 ++fbBatchSize;
1335 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001336 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001337
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001338 //If there are no layers for MDP, this mode doesnt make sense.
1339 if(mdpBatchSize < 1) {
1340 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1341 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001342 return false;
1343 }
1344
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001345 mCurrentFrame.reset(numAppLayers);
1346
1347 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1348 while(mdpBatchSize > 0) {
1349 //Mark layers for MDP comp
1350 int mdpBatchLeft = mdpBatchSize;
1351 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1352 if(mCurrentFrame.drop[i]) {
1353 continue;
1354 }
1355 mCurrentFrame.isFBComposed[i] = false;
1356 --mdpBatchLeft;
1357 }
1358
1359 mCurrentFrame.fbZ = mdpBatchSize;
1360 mCurrentFrame.fbCount = fbBatchSize;
1361 mCurrentFrame.mdpCount = mdpBatchSize;
1362
1363 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1364 __FUNCTION__, mdpBatchSize, fbBatchSize,
1365 mCurrentFrame.dropCount);
1366
1367 if(postHeuristicsHandling(ctx, list)) {
1368 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001369 __FUNCTION__);
1370 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1371 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001372 return true;
1373 }
1374
1375 reset(ctx);
1376 --mdpBatchSize;
1377 ++fbBatchSize;
1378 }
1379
1380 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001381}
1382
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001383bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301384 if(mDpy or isSecurePresent(ctx, mDpy) or
1385 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001386 return false;
1387 }
1388 return true;
1389}
1390
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001391bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1392 hwc_display_contents_1_t* list){
1393 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1394 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001395 isCursorPresent(ctx, mDpy) || !sIsPartialUpdateActive || mDpy) {
1396 // On Async position update, the ROI becomes invalid, hence disable PU
1397 // when cursor is present
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001398 return false;
1399 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001400 if(ctx->listStats[mDpy].secureUI)
1401 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001402 return true;
1403}
1404
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001405bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1406 hwc_display_contents_1_t* list) {
1407 const bool secureOnly = true;
1408 return videoOnlyComp(ctx, list, not secureOnly) or
1409 videoOnlyComp(ctx, list, secureOnly);
1410}
1411
1412bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001413 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001414 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1415 return false;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301416
Saurabh Shahaa236822013-04-24 18:07:26 -07001417 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301418 if(!isSecurePresent(ctx, mDpy)) {
1419 /* Bail out if we are processing only secured video layers
1420 * and we dont have any */
1421 if(secureOnly) {
1422 ALOGD_IF(isDebug(),"%s: No Secure Video Layers", __FUNCTION__);
1423 return false;
1424 }
1425 /* No Idle fall back for secure video layers and if there is only
1426 * single layer being composed. */
1427 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1428 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1429 return false;
1430 }
1431 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001432
Saurabh Shahaa236822013-04-24 18:07:26 -07001433 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001434 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001435 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001436 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001437
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001438 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1439 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001440 return false;
1441 }
1442
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001443 if(mCurrentFrame.fbCount)
1444 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001445
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001446 if(sEnableYUVsplit || needs3DComposition(ctx, mDpy)){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001447 adjustForSourceSplit(ctx, list);
1448 }
1449
1450 if(!postHeuristicsHandling(ctx, list)) {
1451 ALOGD_IF(isDebug(), "post heuristic handling failed");
Justin Philip37ab9a82015-01-06 11:55:12 +05301452 if(errno == ENOBUFS) {
1453 ALOGD_IF(isDebug(), "SMP Allocation failed");
1454 //On SMP allocation failure in video only comp add padding round
1455 ctx->isPaddingRound = true;
1456 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001457 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001458 return false;
1459 }
1460
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001461 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1462 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001463 return true;
1464}
1465
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001466/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1467bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1468 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001469 // Fall back to video only composition, if AIV video mode is enabled
1470 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001471 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1472 __FUNCTION__, mDpy);
1473 return false;
1474 }
1475
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001476 // No MDP composition for 3D
1477 if(needs3DComposition(ctx,mDpy))
1478 return false;
1479
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001480 const bool secureOnly = true;
1481 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1482 mdpOnlyLayersComp(ctx, list, secureOnly);
1483
1484}
1485
1486bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1487 hwc_display_contents_1_t* list, bool secureOnly) {
1488
1489 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1490 return false;
1491
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301492 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1493 if(!isSecurePresent(ctx, mDpy) && !ctx->listStats[mDpy].secureUI) {
1494 /* Bail out if we are processing only secured video/ui layers
1495 * and we dont have any */
1496 if(secureOnly) {
1497 ALOGD_IF(isDebug(), "%s: No secure video/ui layers");
1498 return false;
1499 }
1500 /* No Idle fall back for secure video/ui layers and if there is only
1501 * single layer being composed. */
1502 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1503 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1504 return false;
1505 }
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001506 }
1507
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08001508 /* Bail out if we dont have any secure RGB layers */
1509 if (!ctx->listStats[mDpy].secureRGBCount) {
1510 reset(ctx);
1511 return false;
1512 }
1513
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001514 mCurrentFrame.reset(numAppLayers);
1515 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1516
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001517 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001518 /* mark secure RGB layers for MDP comp */
1519 updateSecureRGB(ctx, list);
1520
1521 if(mCurrentFrame.mdpCount == 0) {
1522 reset(ctx);
1523 return false;
1524 }
1525
1526 /* find the maximum batch of layers to be marked for framebuffer */
1527 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1528 if(!ret) {
1529 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1530 reset(ctx);
1531 return false;
1532 }
1533
1534 if(sEnableYUVsplit){
1535 adjustForSourceSplit(ctx, list);
1536 }
1537
1538 if(!postHeuristicsHandling(ctx, list)) {
1539 ALOGD_IF(isDebug(), "post heuristic handling failed");
1540 reset(ctx);
1541 return false;
1542 }
1543
1544 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1545 __FUNCTION__);
1546 return true;
1547}
1548
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001549/* Checks for conditions where YUV layers cannot be bypassed */
1550bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001551 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001552 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001553 return false;
1554 }
1555
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001556 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001557 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1558 return false;
1559 }
1560
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001561 if(isSecuring(ctx, layer)) {
1562 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1563 return false;
1564 }
1565
Saurabh Shah4fdde762013-04-30 18:47:33 -07001566 if(!isValidDimension(ctx, layer)) {
1567 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1568 __FUNCTION__);
1569 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001570 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001571
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001572 if(layer->planeAlpha < 0xFF) {
1573 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1574 in video only mode",
1575 __FUNCTION__);
1576 return false;
1577 }
1578
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001579 return true;
1580}
1581
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001582/* Checks for conditions where Secure RGB layers cannot be bypassed */
1583bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1584 if(isSkipLayer(layer)) {
1585 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1586 __FUNCTION__, mDpy);
1587 return false;
1588 }
1589
1590 if(isSecuring(ctx, layer)) {
1591 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1592 return false;
1593 }
1594
1595 if(not isSupportedForMDPComp(ctx, layer)) {
1596 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1597 __FUNCTION__);
1598 return false;
1599 }
1600 return true;
1601}
1602
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301603/* starts at fromIndex and check for each layer to find
1604 * if it it has overlapping with any Updating layer above it in zorder
1605 * till the end of the batch. returns true if it finds any intersection */
1606bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1607 int fromIndex, int toIndex) {
1608 for(int i = fromIndex; i < toIndex; i++) {
1609 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1610 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1611 return false;
1612 }
1613 }
1614 }
1615 return true;
1616}
1617
1618/* Checks if given layer at targetLayerIndex has any
1619 * intersection with all the updating layers in beween
1620 * fromIndex and toIndex. Returns true if it finds intersectiion */
1621bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1622 int fromIndex, int toIndex, int targetLayerIndex) {
1623 for(int i = fromIndex; i <= toIndex; i++) {
1624 if(!mCurrentFrame.isFBComposed[i]) {
1625 if(areLayersIntersecting(&list->hwLayers[i],
1626 &list->hwLayers[targetLayerIndex])) {
1627 return true;
1628 }
1629 }
1630 }
1631 return false;
1632}
1633
1634int MDPComp::getBatch(hwc_display_contents_1_t* list,
1635 int& maxBatchStart, int& maxBatchEnd,
1636 int& maxBatchCount) {
1637 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301638 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001639 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301640 while (i < mCurrentFrame.layerCount) {
1641 int batchCount = 0;
1642 int batchStart = i;
1643 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001644 /* Adjust batch Z order with the dropped layers so far */
1645 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301646 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301647 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301648 while(i < mCurrentFrame.layerCount) {
1649 if(!mCurrentFrame.isFBComposed[i]) {
1650 if(!batchCount) {
1651 i++;
1652 break;
1653 }
1654 updatingLayersAbove++;
1655 i++;
1656 continue;
1657 } else {
1658 if(mCurrentFrame.drop[i]) {
1659 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001660 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301661 continue;
1662 } else if(updatingLayersAbove <= 0) {
1663 batchCount++;
1664 batchEnd = i;
1665 i++;
1666 continue;
1667 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1668
1669 // We have a valid updating layer already. If layer-i not
1670 // have overlapping with all updating layers in between
1671 // batch-start and i, then we can add layer i to batch.
1672 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1673 batchCount++;
1674 batchEnd = i;
1675 i++;
1676 continue;
1677 } else if(canPushBatchToTop(list, batchStart, i)) {
1678 //If All the non-updating layers with in this batch
1679 //does not have intersection with the updating layers
1680 //above in z-order, then we can safely move the batch to
1681 //higher z-order. Increment fbZ as it is moving up.
1682 if( firstZReverseIndex < 0) {
1683 firstZReverseIndex = i;
1684 }
1685 batchCount++;
1686 batchEnd = i;
1687 fbZ += updatingLayersAbove;
1688 i++;
1689 updatingLayersAbove = 0;
1690 continue;
1691 } else {
1692 //both failed.start the loop again from here.
1693 if(firstZReverseIndex >= 0) {
1694 i = firstZReverseIndex;
1695 }
1696 break;
1697 }
1698 }
1699 }
1700 }
1701 if(batchCount > maxBatchCount) {
1702 maxBatchCount = batchCount;
1703 maxBatchStart = batchStart;
1704 maxBatchEnd = batchEnd;
1705 fbZOrder = fbZ;
1706 }
1707 }
1708 return fbZOrder;
1709}
1710
1711bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1712 hwc_display_contents_1_t* list) {
1713 /* Idea is to keep as many non-updating(cached) layers in FB and
1714 * send rest of them through MDP. This is done in 2 steps.
1715 * 1. Find the maximum contiguous batch of non-updating layers.
1716 * 2. See if we can improve this batch size for caching by adding
1717 * opaque layers around the batch, if they don't have
1718 * any overlapping with the updating layers in between.
1719 * NEVER mark an updating layer for caching.
1720 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001721
1722 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001723 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001724 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301725 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001726
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001727 /* Nothing is cached. No batching needed */
1728 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001729 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001730 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001731
1732 /* No MDP comp layers, try to use other comp modes */
1733 if(mCurrentFrame.mdpCount == 0) {
1734 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001735 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001736
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301737 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001738
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301739 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001740 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001741 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001742 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301743 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001744 if(!mCurrentFrame.drop[i]){
1745 //If an unsupported layer is being attempted to
1746 //be pulled out we should fail
1747 if(not isSupportedForMDPComp(ctx, layer)) {
1748 return false;
1749 }
1750 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001751 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001752 }
1753 }
1754
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301755 // update the frame data
1756 mCurrentFrame.fbZ = fbZ;
1757 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001758 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001759 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001760
1761 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301762 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001763
1764 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001765}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001766
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001767void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001768 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001769 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001770 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001771
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001772 for(int i = 0; i < numAppLayers; i++) {
1773 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001774 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001775 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001776 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001777 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001778 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001779 }
1780 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001781
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001782 frame.fbCount = fbCount;
1783 frame.mdpCount = frame.layerCount - frame.fbCount
1784 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001785
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001786 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1787 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001788}
1789
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001790// drop other non-AIV layers from external display list.
1791void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001792 hwc_display_contents_1_t* list) {
1793 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1794 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001795 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001796 mCurrentFrame.dropCount++;
1797 mCurrentFrame.drop[i] = true;
1798 }
1799 }
1800 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1801 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1802 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1803 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1804 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1805 mCurrentFrame.dropCount);
1806}
1807
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001808void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001809 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001810 int nYuvCount = ctx->listStats[mDpy].yuvCount;
radhakrishna03640472015-05-25 17:34:13 +05301811 int nVGpipes = qdutils::MDPVersion::getInstance().getVGPipes();
1812
1813 /* If number of YUV layers in the layer list is more than the number of
1814 VG pipes available in the target (non-split), try to program maximum
1815 possible number of YUV layers to MDP, instead of falling back to GPU
1816 completely.*/
1817 nYuvCount = (nYuvCount > nVGpipes) ? nVGpipes : nYuvCount;
1818
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001819 for(int index = 0;index < nYuvCount; index++){
1820 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1821 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1822
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001823 if(mCurrentFrame.drop[nYuvIndex]) {
1824 continue;
1825 }
1826
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001827 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001828 if(!frame.isFBComposed[nYuvIndex]) {
1829 frame.isFBComposed[nYuvIndex] = true;
1830 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001831 }
1832 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001833 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001834 private_handle_t *hnd = (private_handle_t *)layer->handle;
1835 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001836 frame.isFBComposed[nYuvIndex] = false;
1837 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001838 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001839 }
1840 }
1841 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001842
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001843 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1844 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001845}
1846
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001847void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1848 hwc_display_contents_1_t* list) {
1849 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1850 for(int index = 0;index < nSecureRGBCount; index++){
1851 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1852 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1853
1854 if(!isSecureRGBDoable(ctx, layer)) {
1855 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1856 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1857 mCurrentFrame.fbCount++;
1858 }
1859 } else {
1860 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1861 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1862 mCurrentFrame.fbCount--;
1863 }
1864 }
1865 }
1866
1867 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1868 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1869 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1870 mCurrentFrame.fbCount);
1871}
1872
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001873hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1874 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001875 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001876
1877 /* Update only the region of FB needed for composition */
1878 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1879 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1880 hwc_layer_1_t* layer = &list->hwLayers[i];
1881 hwc_rect_t dst = layer->displayFrame;
1882 fbRect = getUnion(fbRect, dst);
1883 }
1884 }
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08001885 trimAgainstROI(ctx, fbRect, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001886 return fbRect;
1887}
1888
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001889bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1890 hwc_display_contents_1_t* list) {
1891
1892 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001893 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001894 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1895 return false;
1896 }
1897
1898 //Limitations checks
1899 if(!hwLimitationsCheck(ctx, list)) {
1900 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1901 return false;
1902 }
1903
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001904 //Configure framebuffer first if applicable
1905 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001906 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001907 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1908 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001909 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1910 __FUNCTION__);
1911 return false;
1912 }
1913 }
1914
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001915 mCurrentFrame.map();
1916
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001917 if(!allocLayerPipes(ctx, list)) {
1918 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001919 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001920 }
1921
1922 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001923 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001924 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001925 int mdpIndex = mCurrentFrame.layerToMDP[index];
1926 hwc_layer_1_t* layer = &list->hwLayers[index];
1927
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301928 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1929 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1930 mdpNextZOrder++;
1931 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001932 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1933 cur_pipe->zOrder = mdpNextZOrder++;
1934
radhakrishnac9a67412013-09-25 17:40:42 +05301935 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301936 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301937 if(configure4k2kYuv(ctx, layer,
1938 mCurrentFrame.mdpToLayer[mdpIndex])
1939 != 0 ){
1940 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1941 for layer %d",__FUNCTION__, index);
1942 return false;
1943 }
1944 else{
1945 mdpNextZOrder++;
1946 }
1947 continue;
1948 }
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001949 if(needs3DComposition(ctx,mDpy) && get3DFormat(hnd) != HAL_NO_3D) {
1950 mdpNextZOrder++;
1951 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001952 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1953 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301954 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001955 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001956 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001957 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001958 }
1959
Saurabh Shaha36be922013-12-16 18:18:39 -08001960 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1961 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1962 ,__FUNCTION__, mDpy);
1963 return false;
1964 }
1965
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001966 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001967 return true;
1968}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001969
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001970bool MDPComp::resourceCheck(hwc_context_t* ctx,
1971 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001972 const bool fbUsed = mCurrentFrame.fbCount;
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001973 int cursorInUse = 0;
1974 if(mDpy == HWC_DISPLAY_PRIMARY) {
1975 // check if cursor is in use for primary
1976 cursorInUse = HWCursor::getInstance()->isCursorSet();
1977 }
1978 int maxStages = qdutils::MDPVersion::getInstance().getBlendStages();
1979 // HW Cursor needs one blending stage, account for that in the check below
1980 // On high end targets(8994) has 8 blending stages, HAL is configured to use < 8.
1981 // Make use of the remaining stages for HW Cursor so that the composition
1982 // strategy would not fail due to this limitation.
1983 if (maxStages > sMaxPipesPerMixer) {
1984 cursorInUse = 0;
1985 }
1986 if(mCurrentFrame.mdpCount > (sMaxPipesPerMixer - fbUsed - cursorInUse)) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001987 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1988 return false;
1989 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001990
1991 //Will benefit cases where a video has non-updating background.
1992 if((mDpy > HWC_DISPLAY_PRIMARY) and
1993 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1994 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1995 return false;
1996 }
1997
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001998 // Init rotCount to number of rotate sessions used by other displays
1999 int rotCount = ctx->mRotMgr->getNumActiveSessions();
2000 // Count the number of rotator sessions required for current display
2001 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
2002 if(!mCurrentFrame.isFBComposed[index]) {
2003 hwc_layer_1_t* layer = &list->hwLayers[index];
2004 private_handle_t *hnd = (private_handle_t *)layer->handle;
2005 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
2006 rotCount++;
2007 }
2008 }
2009 }
2010 // if number of layers to rotate exceeds max rotator sessions, bail out.
2011 if(rotCount > RotMgr::MAX_ROT_SESS) {
2012 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
2013 __FUNCTION__, mDpy);
2014 return false;
2015 }
Saurabh Shah173f4242013-11-20 09:50:12 -08002016 return true;
2017}
2018
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05302019bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
2020 hwc_display_contents_1_t* list) {
2021
2022 //A-family hw limitation:
2023 //If a layer need alpha scaling, MDP can not support.
2024 if(ctx->mMDP.version < qdutils::MDSS_V5) {
2025 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
2026 if(!mCurrentFrame.isFBComposed[i] &&
2027 isAlphaScaled( &list->hwLayers[i])) {
2028 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
2029 return false;
2030 }
2031 }
2032 }
2033
2034 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
2035 //If multiple layers requires downscaling and also they are overlapping
2036 //fall back to GPU since MDSS can not handle it.
2037 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
2038 qdutils::MDPVersion::getInstance().is8x26()) {
2039 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
2040 hwc_layer_1_t* botLayer = &list->hwLayers[i];
2041 if(!mCurrentFrame.isFBComposed[i] &&
2042 isDownscaleRequired(botLayer)) {
2043 //if layer-i is marked for MDP and needs downscaling
2044 //check if any MDP layer on top of i & overlaps with layer-i
2045 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
2046 hwc_layer_1_t* topLayer = &list->hwLayers[j];
2047 if(!mCurrentFrame.isFBComposed[j] &&
2048 isDownscaleRequired(topLayer)) {
2049 hwc_rect_t r = getIntersection(botLayer->displayFrame,
2050 topLayer->displayFrame);
2051 if(isValidRect(r))
2052 return false;
2053 }
2054 }
2055 }
2056 }
2057 }
2058 return true;
2059}
2060
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002061static bool validForCursor(hwc_context_t* ctx, int dpy, hwc_layer_1_t* layer) {
2062 private_handle_t *hnd = (private_handle_t *)layer->handle;
2063 hwc_rect dst = layer->displayFrame;
2064 hwc_rect src = integerizeSourceCrop(layer->sourceCropf);
2065 int srcW = src.right - src.left;
2066 int srcH = src.bottom - src.top;
2067 int dstW = dst.right - dst.left;
2068 int dstH = dst.bottom - dst.top;
2069 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
2070 uint32_t maxCursorSize = mdpVersion.getMaxCursorSize();
2071 uint32_t numHwCursors = mdpVersion.getCursorPipes();
2072 bool primarySplit = isDisplaySplit(ctx, HWC_DISPLAY_PRIMARY);
2073 uint32_t cursorPipesNeeded = 1; // One cursor pipe needed(default)
2074 bool ret = false;
2075
2076 if(dpy > HWC_DISPLAY_PRIMARY) {
2077 // Cursor not supported on secondary displays, as it involves scaling
2078 // in most of the cases
2079 return false;
2080 } else if (isSkipLayer(layer)) {
2081 return false;
2082 // Checks for HW limitation
2083 } else if (numHwCursors == 0 || maxCursorSize <= 0) {
2084 return false;
2085 } else if (needsScaling(layer)) {
2086 return false;
2087 } else if (layer->transform != 0) {
2088 return false;
2089 } else if (hnd->format != HAL_PIXEL_FORMAT_RGBA_8888) {
2090 return false;
2091 } else if (srcW > (int)maxCursorSize || srcH > (int)maxCursorSize) {
2092 return false;
2093 }
2094
2095 if (isDisplaySplit(ctx, dpy) && !mdpVersion.isSrcSplit()) {
2096 // In case of split display with no srcSplit, the driver allocates two
2097 // pipes to support async position update across mixers, hence
2098 // need to account for that here.
2099 cursorPipesNeeded = 2;
2100 }
2101 if (cursorPipesNeeded <= numHwCursors) {
2102 ret = true;
2103 }
2104 return ret;
2105}
2106
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002107// Checks only if videos or single layer(RGB) is updating
2108// which is used for setting dynamic fps or perf hint for single
2109// layer video playback
2110bool MDPComp::onlyVideosUpdating(hwc_context_t *ctx,
2111 hwc_display_contents_1_t* list) {
2112 bool support = false;
2113 FrameInfo frame;
2114 frame.reset(mCurrentFrame.layerCount);
2115 memset(&frame.drop, 0, sizeof(frame.drop));
2116 frame.dropCount = 0;
2117 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo", __FUNCTION__);
2118 updateLayerCache(ctx, list, frame);
2119 updateYUV(ctx, list, false /*secure only*/, frame);
2120 // There are only updating YUV layers or there is single RGB
2121 // Layer(Youtube)
2122 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
2123 (frame.layerCount == 1)) {
2124 support = true;
2125 }
2126 return support;
2127}
2128
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302129void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2130 //For primary display, set the dynamic refreshrate
2131 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
2132 ctx->mUseMetaDataRefreshRate) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302133 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
2134 MDPVersion& mdpHw = MDPVersion::getInstance();
2135 if(sIdleFallBack) {
2136 //Set minimum panel refresh rate during idle timeout
2137 refreshRate = mdpHw.getMinFpsSupported();
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002138 } else if(onlyVideosUpdating(ctx, list)) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302139 //Set the new fresh rate, if there is only one updating YUV layer
2140 //or there is one single RGB layer with this request
2141 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
2142 }
2143 setRefreshRate(ctx, mDpy, refreshRate);
2144 }
2145}
2146
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002147int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002148 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07002149 char property[PROPERTY_VALUE_MAX];
2150
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002151 if(!list) {
2152 ALOGE("%s: Invalid list", __FUNCTION__);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302153 mCachedFrame.reset();
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002154 freeHwCursor(ctx->dpyAttr[mDpy].fd, mDpy);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302155 return -1;
2156 }
2157
2158 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07002159 if(mDpy == HWC_DISPLAY_PRIMARY) {
2160 sSimulationFlags = 0;
2161 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
2162 int currentFlags = atoi(property);
2163 if(currentFlags != sSimulationFlags) {
2164 sSimulationFlags = currentFlags;
2165 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
2166 sSimulationFlags, sSimulationFlags);
2167 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07002168 }
2169 }
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07002170
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302171 //reset old data
2172 mCurrentFrame.reset(numLayers);
2173 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2174 mCurrentFrame.dropCount = 0;
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002175 mCurrentFrame.hwCursorIndex = -1;
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302176
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05302177 //Do not cache the information for next draw cycle.
2178 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
2179 ALOGI("%s: Unsupported layer count for mdp composition",
2180 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002181 mCachedFrame.reset();
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302182#ifdef DYNAMIC_FPS
2183 setDynRefreshRate(ctx, list);
2184#endif
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002185 freeHwCursor(ctx->dpyAttr[mDpy].fd, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002186 return -1;
2187 }
2188
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002189 // Detect the start of animation and fall back to GPU only once to cache
2190 // all the layers in FB and display FB content untill animation completes.
2191 if(ctx->listStats[mDpy].isDisplayAnimating) {
2192 mCurrentFrame.needsRedraw = false;
2193 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
2194 mCurrentFrame.needsRedraw = true;
2195 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
2196 }
2197 setMDPCompLayerFlags(ctx, list);
2198 mCachedFrame.updateCounts(mCurrentFrame);
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302199#ifdef DYNAMIC_FPS
2200 setDynRefreshRate(ctx, list);
2201#endif
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002202 freeHwCursor(ctx->dpyAttr[mDpy].fd, mDpy);
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002203 ret = -1;
2204 return ret;
2205 } else {
2206 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
2207 }
2208
Raj Kamalfdfdddf2015-03-16 21:59:25 +05302209 if(!mDpy and !isSecondaryConnected(ctx) and !mPrevModeOn and
2210 mCachedFrame.isSameFrame(ctx,mDpy,list)) {
2211
2212 ALOGD_IF(isDebug(),"%s: Avoid new composition",__FUNCTION__);
2213 mCurrentFrame.needsRedraw = false;
2214 setMDPCompLayerFlags(ctx, list);
2215 mCachedFrame.updateCounts(mCurrentFrame);
2216#ifdef DYNAMIC_FPS
2217 setDynRefreshRate(ctx, list);
2218#endif
2219 return -1;
2220
2221 }
2222
Saurabh Shahb39f8152013-08-22 10:21:44 -07002223 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002224 if(isFrameDoable(ctx)) {
2225 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002226 // if AIV Video mode is enabled, drop all non AIV layers from the
2227 // external display list.
2228 if(ctx->listStats[mDpy].mAIVVideoMode) {
2229 dropNonAIVLayers(ctx, list);
2230 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002231
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002232 // Configure the cursor if present
2233 int topIndex = ctx->listStats[mDpy].numAppLayers - 1;
2234 if(ctx->listStats[mDpy].cursorLayerPresent &&
2235 validForCursor(ctx, mDpy, &(list->hwLayers[topIndex]))) {
2236 if(configHwCursor(ctx->dpyAttr[mDpy].fd, mDpy,
2237 &(list->hwLayers[topIndex]))) {
2238 // As cursor is configured, mark that layer as dropped, so that
2239 // it wont be considered for composition by other strategies.
2240 mCurrentFrame.hwCursorIndex = topIndex;
2241 mCurrentFrame.drop[topIndex] = true;
2242 mCurrentFrame.dropCount++;
2243 }
2244 } else {
2245 // Release the hw cursor
2246 freeHwCursor(ctx->dpyAttr[mDpy].fd, mDpy);
2247 }
2248
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07002249 // if tryFullFrame fails, try to push all video and secure RGB layers
2250 // to MDP for composition.
2251 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002252 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302253 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002254 setMDPCompLayerFlags(ctx, list);
2255 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002256 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002257 reset(ctx);
2258 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2259 mCurrentFrame.dropCount = 0;
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002260 // Check if cursor is in use for primary and mark accordingly
2261 if(!mDpy && HWCursor::getInstance()->isCursorSet()) {
2262 int topIndex = ctx->listStats[mDpy].numAppLayers - 1;
2263 hwc_layer_1_t *layer = &(list->hwLayers[topIndex]);
2264 layer->compositionType = HWC_CURSOR_OVERLAY;
2265 }
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002266 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07002267 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
2268 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07002269 }
2270 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05302271 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
2272 enablePartialUpdateForMDP3) {
2273 generateROI(ctx, list);
2274 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
2275 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
2276 }
2277 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002278 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
2279 __FUNCTION__);
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002280 // Release the hw cursor
2281 freeHwCursor(ctx->dpyAttr[mDpy].fd, mDpy);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002282 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07002283 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002284
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002285 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002286 ALOGD("GEOMETRY change: %d",
2287 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002288 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07002289 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002290 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002291 }
2292
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002293#ifdef DYNAMIC_FPS
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302294 setDynRefreshRate(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002295#endif
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002296 setPerfHint(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002297
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002298 mCachedFrame.cacheAll(list);
2299 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002300 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002301}
2302
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002303bool MDPComp::allocSplitVGPipes(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302304
2305 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302306 int mdpIndex = mCurrentFrame.layerToMDP[index];
2307 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2308 info.pipeInfo = new MdpYUVPipeInfo;
2309 info.rot = NULL;
2310 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302311
2312 pipe_info.lIndex = ovutils::OV_INVALID;
2313 pipe_info.rIndex = ovutils::OV_INVALID;
2314
Saurabh Shahc62f3982014-03-05 14:28:26 -08002315 Overlay::PipeSpecs pipeSpecs;
2316 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2317 pipeSpecs.needsScaling = true;
2318 pipeSpecs.dpy = mDpy;
2319 pipeSpecs.fb = false;
2320
2321 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302322 if(pipe_info.lIndex == ovutils::OV_INVALID){
2323 bRet = false;
2324 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2325 __FUNCTION__);
2326 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002327 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302328 if(pipe_info.rIndex == ovutils::OV_INVALID){
2329 bRet = false;
2330 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2331 __FUNCTION__);
2332 }
2333 return bRet;
2334}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002335
2336int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2337 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002338 if (ctx->mPtorInfo.isActive()) {
2339 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002340 if (fd < 0) {
2341 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002342 }
2343 }
2344 return fd;
2345}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002346//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002347
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002348void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302349 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002350 //If 4k2k Yuv layer split is possible, and if
2351 //fbz is above 4k2k layer, increment fb zorder by 1
2352 //as we split 4k2k layer and increment zorder for right half
2353 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002354 if(!ctx)
2355 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002356 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302357 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2358 index++) {
2359 if(!mCurrentFrame.isFBComposed[index]) {
2360 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2361 mdpNextZOrder++;
2362 }
2363 mdpNextZOrder++;
2364 hwc_layer_1_t* layer = &list->hwLayers[index];
2365 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302366 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302367 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2368 mCurrentFrame.fbZ += 1;
2369 mdpNextZOrder++;
2370 //As we split 4kx2k yuv layer and program to 2 VG pipes
2371 //(if available) increase mdpcount by 1.
2372 mCurrentFrame.mdpCount++;
2373 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002374 }
2375 }
2376 }
radhakrishnac9a67412013-09-25 17:40:42 +05302377}
2378
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002379/*
2380 * Configures pipe(s) for MDP composition
2381 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002382int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002383 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002384 MdpPipeInfoNonSplit& mdp_info =
2385 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302386 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002387 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002388 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002389
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002390 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2391 __FUNCTION__, layer, zOrder, dest);
2392
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002393 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002394 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002395}
2396
Saurabh Shah88e4d272013-09-03 13:31:29 -07002397bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002398 hwc_display_contents_1_t* list) {
Saurabh Shah8cc77712015-03-31 10:48:51 -07002399 for(uint32_t formatType = FORMAT_YUV; formatType < FORMAT_MAX;
2400 formatType++) {
2401 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
2402 if(mCurrentFrame.isFBComposed[index]) continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002403
Saurabh Shah8cc77712015-03-31 10:48:51 -07002404 hwc_layer_1_t* layer = &list->hwLayers[index];
2405 private_handle_t *hnd = (private_handle_t *)layer->handle;
2406 if(formatType == FORMAT_YUV && !isYuvBuffer(hnd))
radhakrishnac9a67412013-09-25 17:40:42 +05302407 continue;
Saurabh Shah8cc77712015-03-31 10:48:51 -07002408 if(formatType == FORMAT_RGB && isYuvBuffer(hnd))
2409 continue;
2410
2411 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
2412 if(allocSplitVGPipes(ctx, index)){
2413 continue;
2414 }
radhakrishnac9a67412013-09-25 17:40:42 +05302415 }
radhakrishnac9a67412013-09-25 17:40:42 +05302416
Saurabh Shah8cc77712015-03-31 10:48:51 -07002417 int mdpIndex = mCurrentFrame.layerToMDP[index];
2418 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2419 info.pipeInfo = new MdpPipeInfoNonSplit;
2420 info.rot = NULL;
2421 MdpPipeInfoNonSplit& pipe_info =
2422 *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002423
Saurabh Shah8cc77712015-03-31 10:48:51 -07002424 Overlay::PipeSpecs pipeSpecs;
2425 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2426 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2427 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2428 (qdutils::MDPVersion::getInstance().is8x26() and
2429 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2430 pipeSpecs.dpy = mDpy;
2431 pipeSpecs.fb = false;
2432 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002433
Saurabh Shah8cc77712015-03-31 10:48:51 -07002434 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahc62f3982014-03-05 14:28:26 -08002435
Saurabh Shah8cc77712015-03-31 10:48:51 -07002436 if(pipe_info.index == ovutils::OV_INVALID) {
2437 ALOGD_IF(isDebug(), "%s: Unable to get pipe for layer %d of "\
2438 "format type %d", __FUNCTION__, index, formatType);
2439 return false;
2440 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002441 }
2442 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002443 return true;
2444}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002445
radhakrishnac9a67412013-09-25 17:40:42 +05302446int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2447 PipeLayerPair& PipeLayerPair) {
2448 MdpYUVPipeInfo& mdp_info =
2449 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2450 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302451 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302452 eDest lDest = mdp_info.lIndex;
2453 eDest rDest = mdp_info.rIndex;
2454
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002455 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302456 lDest, rDest, &PipeLayerPair.rot);
2457}
2458
Saurabh Shah88e4d272013-09-03 13:31:29 -07002459bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002460
Raj Kamal4393eaa2014-06-06 13:45:20 +05302461 if(!isEnabled() or !mModeOn) {
2462 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302463 return true;
2464 }
2465
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002466 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002467 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002468
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002469 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2470 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002471 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002472 if(mCurrentFrame.isFBComposed[i]) continue;
2473
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002474 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002475 private_handle_t *hnd = (private_handle_t *)layer->handle;
2476 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002477 if (!(layer->flags & HWC_COLOR_FILL)) {
2478 ALOGE("%s handle null", __FUNCTION__);
2479 return false;
2480 }
2481 // No PLAY for Color layer
2482 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2483 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002484 }
2485
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002486 int mdpIndex = mCurrentFrame.layerToMDP[i];
2487
Raj Kamal389d6e32014-08-04 14:43:24 +05302488 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302489 {
2490 MdpYUVPipeInfo& pipe_info =
2491 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2492 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2493 ovutils::eDest indexL = pipe_info.lIndex;
2494 ovutils::eDest indexR = pipe_info.rIndex;
2495 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302496 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302497 if(rot) {
2498 rot->queueBuffer(fd, offset);
2499 fd = rot->getDstMemId();
2500 offset = rot->getDstOffset();
2501 }
2502 if(indexL != ovutils::OV_INVALID) {
2503 ovutils::eDest destL = (ovutils::eDest)indexL;
2504 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2505 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2506 if (!ov.queueBuffer(fd, offset, destL)) {
2507 ALOGE("%s: queueBuffer failed for display:%d",
2508 __FUNCTION__, mDpy);
2509 return false;
2510 }
2511 }
2512
2513 if(indexR != ovutils::OV_INVALID) {
2514 ovutils::eDest destR = (ovutils::eDest)indexR;
2515 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2516 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2517 if (!ov.queueBuffer(fd, offset, destR)) {
2518 ALOGE("%s: queueBuffer failed for display:%d",
2519 __FUNCTION__, mDpy);
2520 return false;
2521 }
2522 }
2523 }
2524 else{
2525 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002526 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302527 ovutils::eDest dest = pipe_info.index;
2528 if(dest == ovutils::OV_INVALID) {
2529 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002530 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302531 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002532
radhakrishnac9a67412013-09-25 17:40:42 +05302533 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2534 continue;
2535 }
2536
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002537 int fd = hnd->fd;
2538 uint32_t offset = (uint32_t)hnd->offset;
2539 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2540 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002541 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002542 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002543 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002544 }
2545
radhakrishnac9a67412013-09-25 17:40:42 +05302546 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2547 using pipe: %d", __FUNCTION__, layer,
2548 hnd, dest );
2549
radhakrishnac9a67412013-09-25 17:40:42 +05302550 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2551 if(rot) {
2552 if(!rot->queueBuffer(fd, offset))
2553 return false;
2554 fd = rot->getDstMemId();
2555 offset = rot->getDstOffset();
2556 }
2557
2558 if (!ov.queueBuffer(fd, offset, dest)) {
2559 ALOGE("%s: queueBuffer failed for display:%d ",
2560 __FUNCTION__, mDpy);
2561 return false;
2562 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002563 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002564
2565 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002566 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002567 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002568}
2569
Saurabh Shah88e4d272013-09-03 13:31:29 -07002570//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002571
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002572void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302573 hwc_display_contents_1_t* list){
2574 //if 4kx2k yuv layer is totally present in either in left half
2575 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302576 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302577 if(mCurrentFrame.fbZ >= 0) {
2578 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2579 index++) {
2580 if(!mCurrentFrame.isFBComposed[index]) {
2581 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2582 mdpNextZOrder++;
2583 }
2584 mdpNextZOrder++;
2585 hwc_layer_1_t* layer = &list->hwLayers[index];
2586 private_handle_t *hnd = (private_handle_t *)layer->handle;
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002587 if(isYUVSplitNeeded(hnd) ||
2588 (needs3DComposition(ctx,mDpy) &&
2589 get3DFormat(hnd) != HAL_NO_3D)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302590 hwc_rect_t dst = layer->displayFrame;
2591 if((dst.left > lSplit) || (dst.right < lSplit)) {
2592 mCurrentFrame.mdpCount += 1;
2593 }
2594 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2595 mCurrentFrame.fbZ += 1;
2596 mdpNextZOrder++;
2597 }
2598 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002599 }
radhakrishnac9a67412013-09-25 17:40:42 +05302600 }
2601}
2602
Saurabh Shah88e4d272013-09-03 13:31:29 -07002603bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002604 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002605
Saurabh Shahc62f3982014-03-05 14:28:26 -08002606 const int lSplit = getLeftSplit(ctx, mDpy);
2607 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002608 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002609 pipe_info.lIndex = ovutils::OV_INVALID;
2610 pipe_info.rIndex = ovutils::OV_INVALID;
2611
Saurabh Shahc62f3982014-03-05 14:28:26 -08002612 Overlay::PipeSpecs pipeSpecs;
2613 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2614 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2615 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2616 pipeSpecs.dpy = mDpy;
2617 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2618 pipeSpecs.fb = false;
2619
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002620 // Acquire pipe only for the updating half
2621 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2622 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2623
2624 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002625 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002626 if(pipe_info.lIndex == ovutils::OV_INVALID)
2627 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002628 }
2629
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002630 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002631 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2632 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002633 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002634 return false;
2635 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002636
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002637 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002638}
2639
Saurabh Shah88e4d272013-09-03 13:31:29 -07002640bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002641 hwc_display_contents_1_t* list) {
Saurabh Shah8cc77712015-03-31 10:48:51 -07002642 for(uint32_t formatType = FORMAT_YUV; formatType < FORMAT_MAX;
2643 formatType++) {
2644 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
2645 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002646
Saurabh Shah8cc77712015-03-31 10:48:51 -07002647 hwc_layer_1_t* layer = &list->hwLayers[index];
2648 private_handle_t *hnd = (private_handle_t *)layer->handle;
2649 if(formatType == FORMAT_YUV && !isYuvBuffer(hnd))
2650 continue;
2651 if(formatType == FORMAT_RGB && isYuvBuffer(hnd))
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002652 continue;
2653
Saurabh Shah8cc77712015-03-31 10:48:51 -07002654 hwc_rect_t dst = layer->displayFrame;
2655 const int lSplit = getLeftSplit(ctx, mDpy);
2656 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
2657 if((dst.left > lSplit)||(dst.right < lSplit)){
2658 if(allocSplitVGPipes(ctx, index)){
2659 continue;
2660 }
2661 }
2662 }
2663 //XXX: Check for forced 2D composition
2664 if(needs3DComposition(ctx, mDpy) && get3DFormat(hnd) != HAL_NO_3D)
2665 if(allocSplitVGPipes(ctx,index))
2666 continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002667
Saurabh Shah8cc77712015-03-31 10:48:51 -07002668 int mdpIndex = mCurrentFrame.layerToMDP[index];
2669 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2670 info.pipeInfo = new MdpPipeInfoSplit;
2671 info.rot = NULL;
2672 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
2673
2674 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2675 ALOGD_IF(isDebug(), "%s: Unable to get pipe for layer %d of "\
2676 "format type %d", __FUNCTION__, index, formatType);
2677 return false;
2678 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002679 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002680 }
2681 return true;
2682}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002683
radhakrishnac9a67412013-09-25 17:40:42 +05302684int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2685 PipeLayerPair& PipeLayerPair) {
2686 const int lSplit = getLeftSplit(ctx, mDpy);
2687 hwc_rect_t dst = layer->displayFrame;
2688 if((dst.left > lSplit)||(dst.right < lSplit)){
2689 MdpYUVPipeInfo& mdp_info =
2690 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2691 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302692 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302693 eDest lDest = mdp_info.lIndex;
2694 eDest rDest = mdp_info.rIndex;
2695
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002696 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302697 lDest, rDest, &PipeLayerPair.rot);
2698 }
2699 else{
2700 return configure(ctx, layer, PipeLayerPair);
2701 }
2702}
2703
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002704/*
2705 * Configures pipe(s) for MDP composition
2706 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002707int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002708 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002709 MdpPipeInfoSplit& mdp_info =
2710 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002711 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302712 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002713 eDest lDest = mdp_info.lIndex;
2714 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002715
2716 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002717 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002718
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002719 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002720 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002721}
2722
Saurabh Shah88e4d272013-09-03 13:31:29 -07002723bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002724
Raj Kamal4393eaa2014-06-06 13:45:20 +05302725 if(!isEnabled() or !mModeOn) {
2726 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302727 return true;
2728 }
2729
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002730 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002731 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002732
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002733 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2734 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002735 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002736 if(mCurrentFrame.isFBComposed[i]) continue;
2737
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002738 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002739 private_handle_t *hnd = (private_handle_t *)layer->handle;
2740 if(!hnd) {
2741 ALOGE("%s handle null", __FUNCTION__);
2742 return false;
2743 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002744
2745 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2746 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002747 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002748
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002749 int mdpIndex = mCurrentFrame.layerToMDP[i];
2750
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002751 if((isYUVSplitNeeded(hnd) && sEnableYUVsplit) ||
2752 (needs3DComposition(ctx, mDpy) && get3DFormat(hnd) != HAL_NO_3D))
radhakrishnac9a67412013-09-25 17:40:42 +05302753 {
2754 MdpYUVPipeInfo& pipe_info =
2755 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2756 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2757 ovutils::eDest indexL = pipe_info.lIndex;
2758 ovutils::eDest indexR = pipe_info.rIndex;
2759 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302760 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302761 if(rot) {
2762 rot->queueBuffer(fd, offset);
2763 fd = rot->getDstMemId();
2764 offset = rot->getDstOffset();
2765 }
2766 if(indexL != ovutils::OV_INVALID) {
2767 ovutils::eDest destL = (ovutils::eDest)indexL;
2768 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2769 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2770 if (!ov.queueBuffer(fd, offset, destL)) {
2771 ALOGE("%s: queueBuffer failed for display:%d",
2772 __FUNCTION__, mDpy);
2773 return false;
2774 }
2775 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002776
radhakrishnac9a67412013-09-25 17:40:42 +05302777 if(indexR != ovutils::OV_INVALID) {
2778 ovutils::eDest destR = (ovutils::eDest)indexR;
2779 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2780 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2781 if (!ov.queueBuffer(fd, offset, destR)) {
2782 ALOGE("%s: queueBuffer failed for display:%d",
2783 __FUNCTION__, mDpy);
2784 return false;
2785 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002786 }
2787 }
radhakrishnac9a67412013-09-25 17:40:42 +05302788 else{
2789 MdpPipeInfoSplit& pipe_info =
2790 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2791 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002792
radhakrishnac9a67412013-09-25 17:40:42 +05302793 ovutils::eDest indexL = pipe_info.lIndex;
2794 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002795
radhakrishnac9a67412013-09-25 17:40:42 +05302796 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002797 uint32_t offset = (uint32_t)hnd->offset;
2798 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2799 if (!mDpy && (index != -1)) {
2800 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2801 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002802 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002803 }
radhakrishnac9a67412013-09-25 17:40:42 +05302804
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002805 if(ctx->mAD->draw(ctx, fd, offset)) {
2806 fd = ctx->mAD->getDstFd();
2807 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002808 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002809
radhakrishnac9a67412013-09-25 17:40:42 +05302810 if(rot) {
2811 rot->queueBuffer(fd, offset);
2812 fd = rot->getDstMemId();
2813 offset = rot->getDstOffset();
2814 }
2815
2816 //************* play left mixer **********
2817 if(indexL != ovutils::OV_INVALID) {
2818 ovutils::eDest destL = (ovutils::eDest)indexL;
2819 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2820 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2821 if (!ov.queueBuffer(fd, offset, destL)) {
2822 ALOGE("%s: queueBuffer failed for left mixer",
2823 __FUNCTION__);
2824 return false;
2825 }
2826 }
2827
2828 //************* play right mixer **********
2829 if(indexR != ovutils::OV_INVALID) {
2830 ovutils::eDest destR = (ovutils::eDest)indexR;
2831 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2832 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2833 if (!ov.queueBuffer(fd, offset, destR)) {
2834 ALOGE("%s: queueBuffer failed for right mixer",
2835 __FUNCTION__);
2836 return false;
2837 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002838 }
2839 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002840
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002841 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2842 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002843
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002844 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002845}
Saurabh Shahab47c692014-02-12 18:45:57 -08002846
2847//================MDPCompSrcSplit==============================================
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002848
2849bool MDPCompSrcSplit::validateAndApplyROI(hwc_context_t *ctx,
2850 hwc_display_contents_1_t* list) {
2851 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2852 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
2853
2854 for(int i = numAppLayers - 1; i >= 0; i--) {
2855 if(!isValidRect(visibleRect)) {
2856 mCurrentFrame.drop[i] = true;
2857 mCurrentFrame.dropCount++;
2858 continue;
2859 }
2860
2861 const hwc_layer_1_t* layer = &list->hwLayers[i];
2862 hwc_rect_t dstRect = layer->displayFrame;
2863 hwc_rect_t res = getIntersection(visibleRect, dstRect);
2864
2865 if(!isValidRect(res)) {
2866 mCurrentFrame.drop[i] = true;
2867 mCurrentFrame.dropCount++;
2868 } else {
2869 /* Reset frame ROI when any layer which needs scaling also needs ROI
2870 * cropping */
2871 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
2872 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
2873 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2874 mCurrentFrame.dropCount = 0;
2875 return false;
2876 }
2877
2878 /* deduct any opaque region from visibleRect */
2879 if (layer->blending == HWC_BLENDING_NONE &&
2880 layer->planeAlpha == 0xFF)
2881 visibleRect = deductRect(visibleRect, res);
2882 }
2883 }
2884 return true;
2885}
2886
2887/*
2888 * HW Limitation: ping pong split can always split the ping pong output
2889 * equally across two DSI's. So the ROI programmed should be of equal width
2890 * for both the halves
2891 */
2892void MDPCompSrcSplit::generateROI(hwc_context_t *ctx,
2893 hwc_display_contents_1_t* list) {
2894 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2895
2896
2897 if(!canPartialUpdate(ctx, list))
2898 return;
2899
2900 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
2901 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
2902 (int)ctx->dpyAttr[mDpy].yres};
2903
2904 for(int index = 0; index < numAppLayers; index++ ) {
2905 hwc_layer_1_t* layer = &list->hwLayers[index];
2906
2907 // If we have a RGB layer which needs rotation, no partial update
2908 if(!isYuvBuffer((private_handle_t *)layer->handle) && layer->transform)
2909 return;
2910
2911 if ((mCachedFrame.hnd[index] != layer->handle) ||
2912 isYuvBuffer((private_handle_t *)layer->handle)) {
2913 hwc_rect_t dst = layer->displayFrame;
2914 hwc_rect_t updatingRect = dst;
2915
2916#ifdef QCOM_BSP
2917 if(!needsScaling(layer) && !layer->transform)
2918 {
2919 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
2920 int x_off = dst.left - src.left;
2921 int y_off = dst.top - src.top;
2922 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
2923 }
2924#endif
2925
2926 roi = getUnion(roi, updatingRect);
2927 }
2928 }
2929
2930 /* No layer is updating. Still SF wants a refresh.*/
2931 if(!isValidRect(roi))
2932 return;
2933
2934 roi = expandROIFromMidPoint(roi, fullFrame);
2935
2936 hwc_rect lFrame = fullFrame;
2937 lFrame.right /= 2;
2938 hwc_rect lRoi = getIntersection(roi, lFrame);
2939
2940 // Align ROI coordinates to panel restrictions
2941 lRoi = getSanitizeROI(lRoi, lFrame);
2942
2943 hwc_rect rFrame = fullFrame;
2944 rFrame.left = lFrame.right;
2945 hwc_rect rRoi = getIntersection(roi, rFrame);
2946
2947 // Align ROI coordinates to panel restrictions
2948 rRoi = getSanitizeROI(rRoi, rFrame);
2949
2950 roi = getUnion(lRoi, rRoi);
2951
2952 ctx->listStats[mDpy].lRoi = roi;
2953 if(!validateAndApplyROI(ctx, list))
2954 resetROI(ctx, mDpy);
2955
2956 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d] [%d, %d, %d, %d]",
2957 __FUNCTION__,
2958 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
2959 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
2960 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
2961 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
2962}
2963
Saurabh Shahab47c692014-02-12 18:45:57 -08002964bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002965 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002966 private_handle_t *hnd = (private_handle_t *)layer->handle;
2967 hwc_rect_t dst = layer->displayFrame;
2968 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2969 pipe_info.lIndex = ovutils::OV_INVALID;
2970 pipe_info.rIndex = ovutils::OV_INVALID;
2971
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002972 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy)
2973 trimAgainstROI(ctx,crop, dst);
2974
Saurabh Shahab47c692014-02-12 18:45:57 -08002975 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2976 //should have a higher priority than the right one. Pipe priorities are
2977 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002978
Saurabh Shahc62f3982014-03-05 14:28:26 -08002979 Overlay::PipeSpecs pipeSpecs;
2980 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2981 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2982 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2983 pipeSpecs.dpy = mDpy;
2984 pipeSpecs.fb = false;
2985
Saurabh Shahab47c692014-02-12 18:45:57 -08002986 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002987 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002988 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002989 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002990 }
2991
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002992 /* Use 2 pipes IF
2993 a) Layer's crop width is > 2048 or
2994 b) Layer's dest width > 2048 or
2995 c) On primary, driver has indicated with caps to split always. This is
2996 based on an empirically derived value of panel height. Applied only
2997 if the layer's width is > mixer's width
2998 */
2999
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05303000 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07003001 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05303002 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08003003 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
3004 const uint32_t dstWidth = dst.right - dst.left;
3005 const uint32_t dstHeight = dst.bottom - dst.top;
Saurabh Shah05f4e222015-02-05 14:36:22 -08003006 uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07003007 crop.right - crop.left;
Saurabh Shah05f4e222015-02-05 14:36:22 -08003008 uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
Saurabh Shah514759d2014-11-11 18:02:24 -08003009 crop.bottom - crop.top;
3010 //Approximation to actual clock, ignoring the common factors in pipe and
3011 //mixer cases like line_time
3012 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
3013 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07003014
Saurabh Shah05f4e222015-02-05 14:36:22 -08003015 const uint32_t downscale = getRotDownscale(ctx, layer);
3016 if(downscale) {
3017 cropWidth /= downscale;
3018 cropHeight /= downscale;
3019 }
3020
Jeykumar Sankaran39305802014-12-12 17:55:57 -08003021 if(dstWidth > mdpHw.getMaxPipeWidth() or
3022 cropWidth > mdpHw.getMaxPipeWidth() or
Saurabh Shah514759d2014-11-11 18:02:24 -08003023 (primarySplitAlways and
3024 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08003025 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08003026 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08003027 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08003028 }
3029
Jeykumar Sankaran89e23ab2015-01-28 15:57:46 -08003030 if(ctx->mOverlay->needsPrioritySwap(pipe_info.lIndex,
3031 pipe_info.rIndex)) {
Saurabh Shahdd8237a2014-02-28 14:29:09 -08003032 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08003033 }
3034 }
3035
3036 return true;
3037}
3038
Saurabh Shahab47c692014-02-12 18:45:57 -08003039int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
3040 PipeLayerPair& PipeLayerPair) {
3041 private_handle_t *hnd = (private_handle_t *)layer->handle;
3042 if(!hnd) {
3043 ALOGE("%s: layer handle is NULL", __FUNCTION__);
3044 return -1;
3045 }
3046 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
3047 MdpPipeInfoSplit& mdp_info =
3048 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
3049 Rotator **rot = &PipeLayerPair.rot;
3050 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08003051 eDest lDest = mdp_info.lIndex;
3052 eDest rDest = mdp_info.rIndex;
3053 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
3054 hwc_rect_t dst = layer->displayFrame;
3055 int transform = layer->transform;
3056 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08003057 int rotFlags = ROT_FLAGS_NONE;
Sushil Chauhan65e26302015-01-14 10:48:57 -08003058 uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
Saurabh Shahab47c692014-02-12 18:45:57 -08003059 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05003060 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahab47c692014-02-12 18:45:57 -08003061
3062 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
3063 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
3064
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08003065 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy) {
3066 /* MDP driver crops layer coordinates against ROI in Non-Split
3067 * and Split MDP comp. But HWC needs to crop them for source split.
3068 * Reason: 1) Source split is efficient only when the final effective
3069 * load is distributed evenly across mixers.
3070 * 2) We have to know the effective width of the layer that
3071 * the ROI needs to find the no. of pipes the layer needs.
3072 */
3073 trimAgainstROI(ctx, crop, dst);
3074 }
3075
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05003076 if(needs3DComposition(ctx, mDpy) &&
3077 get3DFormat(hnd) != HAL_NO_3D){
3078 return configure3DVideo(ctx, layer, mDpy, mdpFlags, z, lDest,
3079 rDest, &PipeLayerPair.rot);
3080 }
3081
Saurabh Shahab47c692014-02-12 18:45:57 -08003082 // Handle R/B swap
3083 if (layer->flags & HWC_FORMAT_RB_SWAP) {
3084 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
3085 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
3086 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
3087 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
3088 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07003089 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07003090 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
3091 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07003092 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07003093 /* Calculate the external display position based on MDP downscale,
3094 ActionSafe, and extorientation features. */
3095 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08003096
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07003097 int downscale = getRotDownscale(ctx, layer);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07003098 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08003099
3100 if(lDest != OV_INVALID && rDest != OV_INVALID) {
3101 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07003102 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08003103 }
3104
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07003105 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08003106 (*rot) = ctx->mRotMgr->getNext();
3107 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07003108 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07003109 //If the video is using a single pipe, enable BWC
3110 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08003111 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
3112 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07003113 }
Saurabh Shahab47c692014-02-12 18:45:57 -08003114 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07003115 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08003116 ALOGE("%s: configRotator failed!", __FUNCTION__);
3117 return -1;
3118 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07003119 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07003120 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08003121 }
3122
3123 //If 2 pipes being used, divide layer into half, crop and dst
3124 hwc_rect_t cropL = crop;
3125 hwc_rect_t cropR = crop;
3126 hwc_rect_t dstL = dst;
3127 hwc_rect_t dstR = dst;
3128 if(lDest != OV_INVALID && rDest != OV_INVALID) {
3129 cropL.right = (crop.right + crop.left) / 2;
3130 cropR.left = cropL.right;
3131 sanitizeSourceCrop(cropL, cropR, hnd);
3132
Saurabh Shahb729b192014-08-15 18:04:24 -07003133 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08003134 //Swap crops on H flip since 2 pipes are being used
3135 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
3136 hwc_rect_t tmp = cropL;
3137 cropL = cropR;
3138 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07003139 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08003140 }
3141
Saurabh Shahb729b192014-08-15 18:04:24 -07003142 //cropSwap trick: If the src and dst widths are both odd, let us say
3143 //2507, then splitting both into half would cause left width to be 1253
3144 //and right 1254. If crop is swapped because of H flip, this will cause
3145 //left crop width to be 1254, whereas left dst width remains 1253, thus
3146 //inducing a scaling that is unaccounted for. To overcome that we add 1
3147 //to the dst width if there is a cropSwap. So if the original width was
3148 //2507, the left dst width will be 1254. Even if the original width was
3149 //even for ex: 2508, the left dst width will still remain 1254.
3150 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08003151 dstR.left = dstL.right;
3152 }
3153
3154 //For the mdp, since either we are pre-rotating or MDP does flips
3155 orient = OVERLAY_TRANSFORM_0;
3156 transform = 0;
3157
3158 //configure left pipe
3159 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07003160 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08003161 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
3162 (ovutils::eBlending) getBlending(layer->blending));
3163
3164 if(configMdp(ctx->mOverlay, pargL, orient,
3165 cropL, dstL, metadata, lDest) < 0) {
3166 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
3167 return -1;
3168 }
3169 }
3170
3171 //configure right pipe
3172 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07003173 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08003174 static_cast<eRotFlags>(rotFlags),
3175 layer->planeAlpha,
3176 (ovutils::eBlending) getBlending(layer->blending));
3177 if(configMdp(ctx->mOverlay, pargR, orient,
3178 cropR, dstR, metadata, rDest) < 0) {
3179 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
3180 return -1;
3181 }
3182 }
3183
3184 return 0;
3185}
3186
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003187bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
3188 Locker::Autolock _l(ctx->mDrawLock);
3189 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
3190 char path[MAX_SYSFS_FILE_PATH];
3191 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
3192 int fd = open(path, O_RDONLY);
3193 if(fd < 0) {
3194 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
3195 return -1;
3196 }
3197 char value[4];
3198 ssize_t size_read = read(fd, value, sizeof(value)-1);
3199 if(size_read <= 0) {
3200 ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
3201 close(fd);
3202 return -1;
3203 }
3204 close(fd);
3205 value[size_read] = '\0';
3206 return atoi(value);
3207}
3208
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003209int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
3210 Locker::Autolock _l(ctx->mDrawLock);
3211 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
3212 char path[MAX_SYSFS_FILE_PATH];
3213 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
3214 int fd = open(path, O_WRONLY);
3215 if(fd < 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003216 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003217 return -1;
3218 }
3219 char value[4];
3220 snprintf(value, sizeof(value), "%d", (int)enable);
3221 ssize_t ret = write(fd, value, strlen(value));
3222 if(ret <= 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003223 ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003224 close(fd);
3225 return -1;
3226 }
3227 close(fd);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003228 return 0;
3229}
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08003230
3231bool MDPComp::loadPerfLib() {
3232 char perfLibPath[PROPERTY_VALUE_MAX] = {0};
3233 bool success = false;
3234 if((property_get("ro.vendor.extension_library", perfLibPath, NULL) <= 0)) {
3235 ALOGE("vendor library not set in ro.vendor.extension_library");
3236 return false;
3237 }
3238
3239 sLibPerfHint = dlopen(perfLibPath, RTLD_NOW);
3240 if(sLibPerfHint) {
3241 *(void **)&sPerfLockAcquire = dlsym(sLibPerfHint, "perf_lock_acq");
3242 *(void **)&sPerfLockRelease = dlsym(sLibPerfHint, "perf_lock_rel");
3243 if (!sPerfLockAcquire || !sPerfLockRelease) {
3244 ALOGE("Failed to load symbols for perfLock");
3245 dlclose(sLibPerfHint);
3246 sLibPerfHint = NULL;
3247 return false;
3248 }
3249 success = true;
3250 ALOGI("Successfully Loaded perf hint API's");
3251 } else {
3252 ALOGE("Failed to open %s : %s", perfLibPath, dlerror());
3253 }
3254 return success;
3255}
3256
3257void MDPComp::setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
3258 if ((sPerfHintWindow < 0) || mDpy || !sLibPerfHint) {
3259 return;
3260 }
3261 static int count = sPerfHintWindow;
3262 static int perflockFlag = 0;
3263
3264 /* Send hint to mpctl when single layer is updated
3265 * for a successful number of windows. Hint release
3266 * happens immediately upon multiple layer update.
3267 */
3268 if (onlyVideosUpdating(ctx, list)) {
3269 if(count) {
3270 count--;
3271 }
3272 } else {
3273 if (perflockFlag) {
3274 perflockFlag = 0;
3275 sPerfLockRelease(sPerfLockHandle);
3276 }
3277 count = sPerfHintWindow;
3278 }
3279 if (count == 0 && !perflockFlag) {
3280 int perfHint = 0x4501; // 45-display layer hint, 01-Enable
3281 sPerfLockHandle = sPerfLockAcquire(0 /*handle*/, 0/*duration*/,
3282 &perfHint, sizeof(perfHint)/sizeof(int));
Arun Kumar K.R8b927022015-02-24 12:34:21 -08003283 if(sPerfLockHandle > 0) {
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08003284 perflockFlag = 1;
3285 }
3286 }
3287}
3288
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003289}; //namespace
3290