blob: 3743a8b19fff915ec7fd4cf82bef4f0e0c7bd99a [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;
58
Saurabh Shah8cc77712015-03-31 10:48:51 -070059enum AllocOrder { FORMAT_YUV, FORMAT_RGB, FORMAT_MAX };
60
Saurabh Shah88e4d272013-09-03 13:31:29 -070061MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070062 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
63 sSrcSplitEnabled = true;
64 return new MDPCompSrcSplit(dpy);
65 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070066 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080067 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070068 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080069}
70
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080071MDPComp::MDPComp(int dpy):mDpy(dpy){};
72
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070073void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080074{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070075 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
76 return;
77
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080078 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070079 (mDpy == 0) ? "\"PRIMARY\"" :
80 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070081 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
Arun Kumar K.R00b84792015-03-27 11:28:36 -070082 "fbCount:%2d dropCount:%2d\n", mCurrentFrame.layerCount,
83 mCurrentFrame.mdpCount, mCurrentFrame.fbCount, mCurrentFrame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080084 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
85 (mCurrentFrame.needsRedraw? "YES" : "NO"),
86 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070087 if(isDisplaySplit(ctx, mDpy)) {
88 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
89 "Right: [%d, %d, %d, %d] \n",
90 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
91 ctx->listStats[mDpy].lRoi.right,
92 ctx->listStats[mDpy].lRoi.bottom,
93 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
94 ctx->listStats[mDpy].rRoi.right,
95 ctx->listStats[mDpy].rRoi.bottom);
96 } else {
97 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
98 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
99 ctx->listStats[mDpy].lRoi.right,
100 ctx->listStats[mDpy].lRoi.bottom);
101 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800102 dumpsys_log(buf," --------------------------------------------- \n");
103 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
104 dumpsys_log(buf," --------------------------------------------- \n");
105 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
106 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
107 index,
108 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700109 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800110 (mCurrentFrame.isFBComposed[index] ?
Arun Kumar K.R00b84792015-03-27 11:28:36 -0700111 (mCurrentFrame.drop[index] ?
112 ((mCurrentFrame.hwCursorIndex == index) ? "CURSOR": "DROP"):
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700113 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800114 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
115 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
116 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800117}
118
119bool MDPComp::init(hwc_context_t *ctx) {
120
121 if(!ctx) {
122 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
123 return false;
124 }
125
Saurabh Shah59562ff2014-09-30 16:13:12 -0700126 char property[PROPERTY_VALUE_MAX] = {0};
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800127
128 sEnabled = false;
Dileep Kumar Reddid8e601d2014-10-28 18:20:43 +0530129 if((ctx->mMDP.version >= qdutils::MDP_V4_0) &&
130 (property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800131 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
132 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800133 sEnabled = true;
134 }
135
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700136 sEnableMixedMode = true;
137 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
138 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
139 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
140 sEnableMixedMode = false;
141 }
142
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700143 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
144
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800145 sMaxPipesPerMixer = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700146 if(property_get("persist.hwc.mdpcomp.maxpermixer", property, "-1") > 0) {
Saurabh Shah85234ec2013-04-12 17:09:00 -0700147 int val = atoi(property);
148 if(val >= 0)
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700149 sMaxPipesPerMixer = min(val, sMaxPipesPerMixer);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800150 }
151
Saurabh Shahacec8e42014-11-25 11:07:04 -0800152 /* Maximum layers allowed to use MDP on secondary panels. If property
153 * doesn't exist, default to 1. Using the property it can be set to 0 or
154 * more.
155 */
156 if(property_get("persist.hwc.maxseclayers", property, "1") > 0) {
157 int val = atoi(property);
158 sMaxSecLayers = (val >= 0) ? val : 1;
159 sMaxSecLayers = min(sMaxSecLayers, sMaxPipesPerMixer);
160 }
161
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400162 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
Saurabh Shah59562ff2014-09-30 16:13:12 -0700163 sIdleInvalidator = IdleInvalidator::getInstance();
164 if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
165 delete sIdleInvalidator;
166 sIdleInvalidator = NULL;
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400167 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800168 }
radhakrishnac9a67412013-09-25 17:40:42 +0530169
Saurabh Shah7c727642014-06-02 15:47:14 -0700170 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700171 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700172 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
173 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
174 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530175 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530176 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700177
Dileep Kumar Reddic6ef3472014-09-24 19:07:08 +0530178 bool defaultPTOR = false;
179 //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
Prabhanjan Kandulafc541b32015-03-30 20:56:16 +0530180 //Bear family targets by default
Dileep Kumar Reddic6ef3472014-09-24 19:07:08 +0530181 if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
182 (qdutils::MDPVersion::getInstance().is8x16() ||
Prabhanjan Kandulafc541b32015-03-30 20:56:16 +0530183 qdutils::MDPVersion::getInstance().is8x39() ||
184 qdutils::MDPVersion::getInstance().is8x52())) {
Dileep Kumar Reddic6ef3472014-09-24 19:07:08 +0530185 defaultPTOR = true;
186 }
187
188 if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
189 (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700190 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
191 HWC_DISPLAY_PRIMARY);
192 }
193
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +0530194 if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
195 (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
196 enablePartialUpdateForMDP3 = true;
197 }
198
199 if(!enablePartialUpdateForMDP3 &&
200 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
201 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
202 enablePartialUpdateForMDP3 = true;
203 }
204
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -0800205 sIsPartialUpdateActive = getPartialUpdatePref(ctx);
206
Arun Kumar K.R299bcda2014-12-18 19:36:40 -0800207 if(property_get("persist.mdpcomp_perfhint", property, "-1") > 0) {
208 int val = atoi(property);
209 if(val > 0 && loadPerfLib()) {
210 sPerfHintWindow = val;
211 ALOGI("PerfHintWindow = %d", sPerfHintWindow);
212 }
213 }
214
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700215 return true;
216}
217
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800218void MDPComp::reset(hwc_context_t *ctx) {
219 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700220 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800221 ctx->mOverlay->clear(mDpy);
222 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700223}
224
Raj Kamal4393eaa2014-06-06 13:45:20 +0530225void MDPComp::reset() {
Raj Kamalfdfdddf2015-03-16 21:59:25 +0530226 mPrevModeOn = mModeOn;
Raj Kamal4393eaa2014-06-06 13:45:20 +0530227 mModeOn = false;
228}
229
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700230void MDPComp::timeout_handler(void *udata) {
231 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
Raj Kamalfdfdddf2015-03-16 21:59:25 +0530232 bool handleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700233
234 if(!ctx) {
235 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
236 return;
237 }
Raj Kamal58b31a02014-12-16 15:53:53 +0530238
239 ctx->mDrawLock.lock();
Raj Kamalfdfdddf2015-03-16 21:59:25 +0530240
241 /* Handle timeout event only if the previous composition
242 on any display is MDP or MIXED*/
243 for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
244 if(ctx->mMDPComp[i])
245 handleTimeout =
246 ctx->mMDPComp[i]->isMDPComp() || handleTimeout;
247 }
248
249 if(!handleTimeout) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800250 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530251 ctx->mDrawLock.unlock();
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800252 return;
253 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700254 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700255 ALOGE("%s: HWC proc not registered", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530256 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700257 return;
258 }
259 sIdleFallBack = true;
Raj Kamal58b31a02014-12-16 15:53:53 +0530260 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700261 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700262 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700263}
264
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700265void MDPComp::setMaxPipesPerMixer(const uint32_t value) {
266 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800267 uint32_t maxSupported = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700268 if(value > maxSupported) {
269 ALOGW("%s: Input exceeds max value supported. Setting to"
270 "max value: %d", __FUNCTION__, maxSupported);
271 }
272 sMaxPipesPerMixer = min(value, maxSupported);
273}
274
Saurabh Shah59562ff2014-09-30 16:13:12 -0700275void MDPComp::setIdleTimeout(const uint32_t& timeout) {
276 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
277
278 if(sIdleInvalidator) {
279 if(timeout <= ONE_REFRESH_PERIOD_MS) {
280 //If the specified timeout is < 1 draw cycle worth, "virtually"
281 //disable idle timeout. The ideal way for clients to disable
282 //timeout is to set it to 0
283 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
284 ALOGI("Disabled idle timeout");
285 return;
286 }
287 sIdleInvalidator->setIdleTimeout(timeout);
288 ALOGI("Idle timeout set to %u", timeout);
289 } else {
290 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
291 }
292}
293
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800294void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800295 hwc_display_contents_1_t* list) {
296 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800297
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800298 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800299 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800300 if(!mCurrentFrame.isFBComposed[index]) {
301 layerProp[index].mFlags |= HWC_MDPCOMP;
302 layer->compositionType = HWC_OVERLAY;
303 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800304 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700305 /* Drop the layer when its already present in FB OR when it lies
306 * outside frame's ROI */
307 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Arun Kumar K.R00b84792015-03-27 11:28:36 -0700308 if(index == mCurrentFrame.hwCursorIndex) {
309 layer->compositionType = HWC_CURSOR_OVERLAY;
310 } else {
311 layer->compositionType = HWC_OVERLAY;
312 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700313 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800314 }
315 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700316}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500317
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800318void MDPComp::setRedraw(hwc_context_t *ctx,
319 hwc_display_contents_1_t* list) {
320 mCurrentFrame.needsRedraw = false;
321 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
322 (list->flags & HWC_GEOMETRY_CHANGED) ||
323 isSkipPresent(ctx, mDpy)) {
324 mCurrentFrame.needsRedraw = true;
325 }
326}
327
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800328MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700329 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700330 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800331}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800332
Saurabh Shahaa236822013-04-24 18:07:26 -0700333void MDPComp::FrameInfo::reset(const int& numLayers) {
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700334 for(int i = 0 ; i < MAX_NUM_BLEND_STAGES; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800335 if(mdpToLayer[i].pipeInfo) {
336 delete mdpToLayer[i].pipeInfo;
337 mdpToLayer[i].pipeInfo = NULL;
338 //We dont own the rotator
339 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800340 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800341 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800342
343 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
344 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700345 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800346
Saurabh Shahaa236822013-04-24 18:07:26 -0700347 layerCount = numLayers;
348 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800349 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700350 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800351 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800352}
353
Saurabh Shahaa236822013-04-24 18:07:26 -0700354void MDPComp::FrameInfo::map() {
355 // populate layer and MDP maps
356 int mdpIdx = 0;
357 for(int idx = 0; idx < layerCount; idx++) {
358 if(!isFBComposed[idx]) {
359 mdpToLayer[mdpIdx].listIndex = idx;
360 layerToMDP[idx] = mdpIdx++;
361 }
362 }
363}
364
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800365MDPComp::LayerCache::LayerCache() {
366 reset();
367}
368
369void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700370 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530371 memset(&isFBComposed, true, sizeof(isFBComposed));
372 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800373 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700374}
375
376void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530377 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700378 for(int i = 0; i < numAppLayers; i++) {
379 hnd[i] = list->hwLayers[i].handle;
380 }
381}
382
383void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700384 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530385 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
386 memcpy(&drop, &curFrame.drop, sizeof(drop));
387}
388
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800389bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
390 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530391 if(layerCount != curFrame.layerCount)
392 return false;
393 for(int i = 0; i < curFrame.layerCount; i++) {
394 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
395 (curFrame.drop[i] != drop[i])) {
396 return false;
397 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800398 if(curFrame.isFBComposed[i] &&
399 (hnd[i] != list->hwLayers[i].handle)){
400 return false;
401 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530402 }
403 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800404}
405
Raj Kamalfdfdddf2015-03-16 21:59:25 +0530406bool MDPComp::LayerCache::isSameFrame(hwc_context_t *ctx, int dpy,
407 hwc_display_contents_1_t* list) {
408
409 if(layerCount != ctx->listStats[dpy].numAppLayers)
410 return false;
411
412 if((list->flags & HWC_GEOMETRY_CHANGED) ||
413 isSkipPresent(ctx, dpy)) {
414 return false;
415 }
416
417 for(int i = 0; i < layerCount; i++) {
418 if(hnd[i] != list->hwLayers[i].handle)
419 return false;
420 }
421
422 return true;
423}
424
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700425bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
426 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800427 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Raj Kamal1179d9c2014-10-28 15:31:35 +0530428 (not isValidDimension(ctx,layer)) ||
429 isSkipLayer(layer)) {
430 //More conditions here, sRGB+Blend etc
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700431 return false;
432 }
433 return true;
434}
435
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530436bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800437 private_handle_t *hnd = (private_handle_t *)layer->handle;
438
439 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700440 if (layer->flags & HWC_COLOR_FILL) {
441 // Color layer
442 return true;
443 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700444 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800445 return false;
446 }
447
Naseer Ahmede850a802013-09-06 13:12:52 -0400448 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400449 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400450 return false;
451
Saurabh Shah62e1d732013-09-17 10:44:05 -0700452 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700453 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700454 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700455 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
456 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700457 int dst_w = dst.right - dst.left;
458 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800459 float w_scale = ((float)crop_w / (float)dst_w);
460 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530461 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700462
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800463 /* Workaround for MDP HW limitation in DSI command mode panels where
464 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
465 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530466 * There also is a HW limilation in MDP, minimum block size is 2x2
467 * Fallback to GPU if height is less than 2.
468 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700469 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800470 return false;
471
Ramkumar Radhakrishnan1a763e92015-03-19 16:46:46 -0700472 /* crop_w and crop_h should be even for yuv layer, so fallback to GPU for
473 * those cases
474 */
475 if(isYuvBuffer(hnd) && (crop_w < 2 || crop_h < 2)) {
476 return false;
477 }
478
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800479 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530480 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800481 const float w_dscale = w_scale;
482 const float h_dscale = h_scale;
483
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800484 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700485
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530486 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700487 /* On targets that doesnt support Decimation (eg.,8x26)
488 * maximum downscale support is overlay pipe downscale.
489 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800490 if(crop_w > (int) mdpHw.getMaxPipeWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530491 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700492 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800493 return false;
494 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700495 // Decimation on macrotile format layers is not supported.
496 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530497 /* Bail out if
498 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700499 * 2. exceeds maximum downscale limit
500 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800501 if(((crop_w > (int) mdpHw.getMaxPipeWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530502 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700503 w_dscale > maxMDPDownscale ||
504 h_dscale > maxMDPDownscale) {
505 return false;
506 }
507 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800508 return false;
509 }
510 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700511 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700512 return false;
513 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700514 }
515
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800516 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530517 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800518 const float w_uscale = 1.0f / w_scale;
519 const float h_uscale = 1.0f / h_scale;
520
521 if(w_uscale > upscale || h_uscale > upscale)
522 return false;
523 }
524
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800525 return true;
526}
527
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800528bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700529 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800530
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800531 if(!isEnabled()) {
532 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700533 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530534 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530535 qdutils::MDPVersion::getInstance().is8x16() ||
Prabhanjan Kandulafc541b32015-03-30 20:56:16 +0530536 qdutils::MDPVersion::getInstance().is8x39() ||
537 qdutils::MDPVersion::getInstance().is8x52()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800538 ctx->mVideoTransFlag &&
539 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700540 //1 Padding round to shift pipes across mixers
541 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
542 __FUNCTION__);
543 ret = false;
Raj Kamalc0d34242015-03-17 20:53:14 +0530544 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
545 qdutils::MDPVersion::getInstance().is8x16() ||
Prabhanjan Kandulafc541b32015-03-30 20:56:16 +0530546 qdutils::MDPVersion::getInstance().is8x39() ||
547 qdutils::MDPVersion::getInstance().is8x52()) &&
Raj Kamalc0d34242015-03-17 20:53:14 +0530548 !mDpy && isSecondaryAnimating(ctx) &&
549 isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL)) {
550 ALOGD_IF(isDebug(),"%s: Display animation in progress",
551 __FUNCTION__);
552 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700553 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
554 /* TODO: freeing up all the resources only for the targets having total
555 number of pipes < 8. Need to analyze number of VIG pipes used
556 for primary in previous draw cycle and accordingly decide
557 whether to fall back to full GPU comp or video only comp
558 */
559 if(isSecondaryConfiguring(ctx)) {
560 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
561 __FUNCTION__);
562 ret = false;
563 } else if(ctx->isPaddingRound) {
564 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
565 __FUNCTION__,mDpy);
566 ret = false;
567 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800568 } else if (ctx->isDMAStateChanging) {
569 // Bail out if a padding round has been invoked in order to switch DMA
570 // state to block mode. We need this to cater for the case when a layer
571 // requires rotation in the current frame.
572 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
573 __FUNCTION__);
574 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700575 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800576
Saurabh Shahaa236822013-04-24 18:07:26 -0700577 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800578}
579
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800580void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
581 hwc_rect &dst) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800582 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800583 dst = getIntersection(dst, roi);
584 crop = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800585}
586
587/* 1) Identify layers that are not visible or lying outside the updating ROI and
588 * drop them from composition.
589 * 2) If we have a scaling layer which needs cropping against generated
590 * ROI, reset ROI to full resolution. */
591bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
592 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700593 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800594 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800595
596 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800597 if(!isValidRect(visibleRect)) {
598 mCurrentFrame.drop[i] = true;
599 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800600 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800601 }
602
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700603 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700604 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800605 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700606
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700607 if(!isValidRect(res)) {
608 mCurrentFrame.drop[i] = true;
609 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800610 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700611 /* Reset frame ROI when any layer which needs scaling also needs ROI
612 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800613 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800614 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700615 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
616 mCurrentFrame.dropCount = 0;
617 return false;
618 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800619
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800620 /* deduct any opaque region from visibleRect */
radhakrishna4efbdd62014-11-03 13:19:27 +0530621 if (layer->blending == HWC_BLENDING_NONE &&
622 layer->planeAlpha == 0xFF)
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800623 visibleRect = deductRect(visibleRect, res);
624 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700625 }
626 return true;
627}
628
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800629/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
630 * are updating. If DirtyRegion is applicable, calculate it by accounting all
631 * the changing layer's dirtyRegion. */
632void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
633 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700634 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800635 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700636 return;
637
638 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800639 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
640 (int)ctx->dpyAttr[mDpy].yres};
641
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700642 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800643 hwc_layer_1_t* layer = &list->hwLayers[index];
644 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800645 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700646 hwc_rect_t dst = layer->displayFrame;
647 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800648
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800649#ifdef QCOM_BSP
Dileep Kumar Reddi7399d5c2014-12-31 18:01:19 +0530650 if(!needsScaling(layer) && !layer->transform &&
651 (!isYuvBuffer((private_handle_t *)layer->handle)))
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700652 {
653 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
654 int x_off = dst.left - src.left;
655 int y_off = dst.top - src.top;
656 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
657 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800658#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800659
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800660 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700661 }
662 }
663
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800664 /* No layer is updating. Still SF wants a refresh.*/
665 if(!isValidRect(roi))
666 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800667
668 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800669 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800670
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800671 ctx->listStats[mDpy].lRoi = roi;
672 if(!validateAndApplyROI(ctx, list))
673 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700674
675 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800676 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
677 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
678}
679
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800680void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
681 hwc_rect &dst) {
682 hwc_rect roi = getUnion(ctx->listStats[mDpy].lRoi,
683 ctx->listStats[mDpy].rRoi);
684 hwc_rect tmpDst = getIntersection(dst, roi);
685 if(!isSameRect(dst, tmpDst)) {
686 crop.left = crop.left + (tmpDst.left - dst.left);
687 crop.top = crop.top + (tmpDst.top - dst.top);
688 crop.right = crop.left + (tmpDst.right - tmpDst.left);
689 crop.bottom = crop.top + (tmpDst.bottom - tmpDst.top);
690 dst = tmpDst;
691 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800692}
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800693
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800694/* 1) Identify layers that are not visible or lying outside BOTH the updating
695 * ROI's and drop them from composition. If a layer is spanning across both
696 * the halves of the screen but needed by only ROI, the non-contributing
697 * half will not be programmed for MDP.
698 * 2) If we have a scaling layer which needs cropping against generated
699 * ROI, reset ROI to full resolution. */
700bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
701 hwc_display_contents_1_t* list) {
702
703 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
704
705 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
706 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
707
708 for(int i = numAppLayers - 1; i >= 0; i--){
709 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
710 {
711 mCurrentFrame.drop[i] = true;
712 mCurrentFrame.dropCount++;
713 continue;
714 }
715
716 const hwc_layer_1_t* layer = &list->hwLayers[i];
717 hwc_rect_t dstRect = layer->displayFrame;
718
719 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
720 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
721 hwc_rect_t res = getUnion(l_res, r_res);
722
723 if(!isValidRect(l_res) && !isValidRect(r_res)) {
724 mCurrentFrame.drop[i] = true;
725 mCurrentFrame.dropCount++;
726 } else {
727 /* Reset frame ROI when any layer which needs scaling also needs ROI
728 * cropping */
729 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
730 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
731 mCurrentFrame.dropCount = 0;
732 return false;
733 }
734
radhakrishna4efbdd62014-11-03 13:19:27 +0530735 if (layer->blending == HWC_BLENDING_NONE &&
736 layer->planeAlpha == 0xFF) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800737 visibleRectL = deductRect(visibleRectL, l_res);
738 visibleRectR = deductRect(visibleRectR, r_res);
739 }
740 }
741 }
742 return true;
743}
744/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
745 * are updating. If DirtyRegion is applicable, calculate it by accounting all
746 * the changing layer's dirtyRegion. */
747void MDPCompSplit::generateROI(hwc_context_t *ctx,
748 hwc_display_contents_1_t* list) {
749 if(!canPartialUpdate(ctx, list))
750 return;
751
752 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
753 int lSplit = getLeftSplit(ctx, mDpy);
754
755 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
756 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
757
758 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
759 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
760
761 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
762 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
763
764 for(int index = 0; index < numAppLayers; index++ ) {
765 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800766 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800767 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800768 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700769 hwc_rect_t dst = layer->displayFrame;
770 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800771
772#ifdef QCOM_BSP
773 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700774 {
775 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
776 int x_off = dst.left - src.left;
777 int y_off = dst.top - src.top;
778 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
779 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800780#endif
781
782 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
783 if(isValidRect(l_dst))
784 l_roi = getUnion(l_roi, l_dst);
785
786 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
787 if(isValidRect(r_dst))
788 r_roi = getUnion(r_roi, r_dst);
789 }
790 }
791
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700792 /* For panels that cannot accept commands in both the interfaces, we cannot
793 * send two ROI's (for each half). We merge them into single ROI and split
794 * them across lSplit for MDP mixer use. The ROI's will be merged again
795 * finally before udpating the panel in the driver. */
796 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
797 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
798 l_roi = getIntersection(temp_roi, l_frame);
799 r_roi = getIntersection(temp_roi, r_frame);
800 }
801
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800802 /* No layer is updating. Still SF wants a refresh. */
803 if(!isValidRect(l_roi) && !isValidRect(r_roi))
804 return;
805
806 l_roi = getSanitizeROI(l_roi, l_frame);
807 r_roi = getSanitizeROI(r_roi, r_frame);
808
809 ctx->listStats[mDpy].lRoi = l_roi;
810 ctx->listStats[mDpy].rRoi = r_roi;
811
812 if(!validateAndApplyROI(ctx, list))
813 resetROI(ctx, mDpy);
814
815 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
816 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
817 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
818 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
819 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
820 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700821}
822
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800823/* Checks for conditions where all the layers marked for MDP comp cannot be
824 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800825bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800826 hwc_display_contents_1_t* list){
827
Saurabh Shahaa236822013-04-24 18:07:26 -0700828 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800829
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700830 // Fall back to video only composition, if AIV video mode is enabled
831 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700832 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
833 __FUNCTION__, mDpy);
834 return false;
835 }
836
Praveena Pachipulusu47346c22014-12-04 11:06:41 +0530837 /* No Idle fall back if secure display or secure RGB layers are present
838 * or if there is only a single layer being composed */
839 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI &&
840 !ctx->listStats[mDpy].secureRGBCount &&
841 (ctx->listStats[mDpy].numAppLayers > 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700842 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
843 return false;
844 }
845
Raj Kamalc0d34242015-03-17 20:53:14 +0530846 if(!mDpy && isSecondaryAnimating(ctx) &&
847 (isYuvPresent(ctx,HWC_DISPLAY_EXTERNAL) ||
848 isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL)) ) {
849 ALOGD_IF(isDebug(),"%s: Display animation in progress",
850 __FUNCTION__);
851 return false;
852 }
853
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700854 // if secondary is configuring or Padding round, fall back to video only
855 // composition and release all assigned non VIG pipes from primary.
856 if(isSecondaryConfiguring(ctx)) {
857 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
858 __FUNCTION__);
859 return false;
860 } else if(ctx->isPaddingRound) {
861 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
862 __FUNCTION__,mDpy);
863 return false;
864 }
865
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -0500866 // No MDP composition for 3D
867 if(needs3DComposition(ctx, mDpy))
868 return false;
869
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700870 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800871 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700872 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800873 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
874 return false;
875 }
876
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800877 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800878 hwc_layer_1_t* layer = &list->hwLayers[i];
879 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800880
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800881 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700882 if(!canUseRotator(ctx, mDpy)) {
883 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
884 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700885 return false;
886 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800887 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530888
889 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
890 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800891 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700892 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530893 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
894 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
895 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800896 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700897
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700898 if(ctx->mAD->isDoable()) {
899 return false;
900 }
901
Saurabh Shahaa236822013-04-24 18:07:26 -0700902 //If all above hard conditions are met we can do full or partial MDP comp.
903 bool ret = false;
904 if(fullMDPComp(ctx, list)) {
905 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700906 } else if(fullMDPCompWithPTOR(ctx, list)) {
907 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700908 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700909 ret = true;
910 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530911
Saurabh Shahaa236822013-04-24 18:07:26 -0700912 return ret;
913}
914
915bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700916
917 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
918 return false;
919
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700920 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
921 for(int i = 0; i < numAppLayers; i++) {
922 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700923 if(not mCurrentFrame.drop[i] and
924 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700925 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
926 return false;
927 }
928 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800929
Raj Kamalb5f0b4a2015-04-08 15:10:37 +0530930 if(!mDpy && isSecondaryConnected(ctx) &&
931 (qdutils::MDPVersion::getInstance().is8x16() ||
932 qdutils::MDPVersion::getInstance().is8x26() ||
933 qdutils::MDPVersion::getInstance().is8x39()) &&
934 isYuvPresent(ctx, HWC_DISPLAY_VIRTUAL)) {
935 ALOGD_IF(isDebug(), "%s: YUV layer present on secondary", __FUNCTION__);
936 return false;
937 }
938
Saurabh Shahaa236822013-04-24 18:07:26 -0700939 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700940 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
941 sizeof(mCurrentFrame.isFBComposed));
942 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
943 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700944
Raj Kamal389d6e32014-08-04 14:43:24 +0530945 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800946 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530947 }
948
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800949 if(!postHeuristicsHandling(ctx, list)) {
950 ALOGD_IF(isDebug(), "post heuristic handling failed");
951 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700952 return false;
953 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700954 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
955 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700956 return true;
957}
958
Sushil Chauhandefd3522014-05-13 18:17:12 -0700959/* Full MDP Composition with Peripheral Tiny Overlap Removal.
960 * MDP bandwidth limitations can be avoided, if the overlap region
961 * covered by the smallest layer at a higher z-order, gets composed
962 * by Copybit on a render buffer, which can be queued to MDP.
963 */
964bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
965 hwc_display_contents_1_t* list) {
966
967 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R00b84792015-03-27 11:28:36 -0700968 // PTOR does not qualify when there are layers dropped, but if
969 // dropped layer is only a cursor, PTOR could qualify
970 const int numNonCursorLayers = numAppLayers - mCurrentFrame.dropCount;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700971 const int stagesForMDP = min(sMaxPipesPerMixer,
972 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
973
974 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700975 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700976 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
977 return false;
978 }
979
Arun Kumar K.R00b84792015-03-27 11:28:36 -0700980 // Frame level checks - consider PTOR in case of dropCount only if the cursor
981 // layer is dropped, otherwise bail out of PTOR
Sushil Chauhandefd3522014-05-13 18:17:12 -0700982 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
Arun Kumar K.R00b84792015-03-27 11:28:36 -0700983 isYuvPresent(ctx, mDpy) || isSecurePresent(ctx, mDpy) ||
984 (mCurrentFrame.dropCount - (int)isCursorPresent(ctx, mDpy))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700985 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
986 return false;
987 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700988 // MDP comp checks
989 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700990 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700991 if(not isSupportedForMDPComp(ctx, layer)) {
992 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
993 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700994 }
995 }
996
Raj Kamalb5f0b4a2015-04-08 15:10:37 +0530997 if(!mDpy && isSecondaryConnected(ctx) &&
998 (qdutils::MDPVersion::getInstance().is8x16() ||
999 qdutils::MDPVersion::getInstance().is8x26() ||
1000 qdutils::MDPVersion::getInstance().is8x39()) &&
1001 isYuvPresent(ctx, HWC_DISPLAY_VIRTUAL)) {
1002 ALOGD_IF(isDebug(), "%s: YUV layer present on secondary", __FUNCTION__);
1003 return false;
1004 }
1005
Sushil Chauhandefd3522014-05-13 18:17:12 -07001006 /* We cannot use this composition mode, if:
1007 1. A below layer needs scaling.
1008 2. Overlap is not peripheral to display.
1009 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001010 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -07001011 */
1012
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001013 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
1014 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
1015 memset(overlapRect, 0, sizeof(overlapRect));
1016 int layerPixelCount, minPixelCount = 0;
1017 int numPTORLayersFound = 0;
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001018 for (int i = numNonCursorLayers - 1; (i >= 0 &&
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001019 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001020 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001021 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001022 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001023 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
1024 // PTOR layer should be peripheral and cannot have transform
1025 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
1026 has90Transform(layer)) {
1027 continue;
1028 }
1029 if((3 * (layerPixelCount + minPixelCount)) >
1030 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
1031 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
1032 continue;
1033 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001034 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001035 for (int j = i-1; j >= 0; j--) {
1036 // Check if the layers below this layer qualifies for PTOR comp
1037 hwc_layer_1_t* layer = &list->hwLayers[j];
1038 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001039 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001040 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001041 if (isValidRect(getIntersection(dispFrame, disFrame))) {
1042 if (has90Transform(layer) || needsScaling(layer)) {
1043 found = false;
1044 break;
1045 }
1046 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001047 }
1048 }
1049 // Store the minLayer Index
1050 if(found) {
1051 minLayerIndex[numPTORLayersFound] = i;
1052 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
1053 minPixelCount += layerPixelCount;
1054 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001055 }
1056 }
1057
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001058 // No overlap layers
1059 if (!numPTORLayersFound)
1060 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001061
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001062 // Store the displayFrame and the sourceCrops of the layers
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001063 hwc_rect_t displayFrame[numNonCursorLayers];
1064 hwc_rect_t sourceCrop[numNonCursorLayers];
1065 for(int i = 0; i < numNonCursorLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001066 hwc_layer_1_t* layer = &list->hwLayers[i];
1067 displayFrame[i] = layer->displayFrame;
1068 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001069 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001070
Prabhanjan Kandula9889a202014-09-04 21:50:35 +05301071 /**
1072 * It's possible that 2 PTOR layers might have overlapping.
1073 * In such case, remove the intersection(again if peripheral)
1074 * from the lower PTOR layer to avoid overlapping.
1075 * If intersection is not on peripheral then compromise
1076 * by reducing number of PTOR layers.
1077 **/
1078 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
1079 if(isValidRect(commonRect)) {
1080 overlapRect[1] = deductRect(overlapRect[1], commonRect);
1081 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
1082 }
1083
1084 ctx->mPtorInfo.count = numPTORLayersFound;
1085 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
1086 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
1087 }
1088
1089 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
1090 // reset PTOR
1091 ctx->mPtorInfo.count = 0;
1092 if(isValidRect(commonRect)) {
1093 // If PTORs are intersecting restore displayframe of PTOR[1]
1094 // before returning, as we have modified it above.
1095 list->hwLayers[minLayerIndex[1]].displayFrame =
1096 displayFrame[minLayerIndex[1]];
1097 }
1098 return false;
1099 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001100 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1101 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
1102
Xu Yangcda012c2014-07-30 21:57:21 +08001103 // Store the blending mode, planeAlpha, and transform of PTOR layers
1104 int32_t blending[numPTORLayersFound];
1105 uint8_t planeAlpha[numPTORLayersFound];
1106 uint32_t transform[numPTORLayersFound];
1107
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001108 for(int j = 0; j < numPTORLayersFound; j++) {
1109 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001110
1111 // Update src crop of PTOR layer
1112 hwc_layer_1_t* layer = &list->hwLayers[index];
1113 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1114 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1115 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1116 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1117
1118 // Store & update w, h, format of PTOR layer
1119 private_handle_t *hnd = (private_handle_t *)layer->handle;
1120 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1121 layerWhf[j] = whf;
1122 hnd->width = renderBuf->width;
1123 hnd->height = renderBuf->height;
1124 hnd->format = renderBuf->format;
1125
Xu Yangcda012c2014-07-30 21:57:21 +08001126 // Store & update blending mode, planeAlpha and transform of PTOR layer
1127 blending[j] = layer->blending;
1128 planeAlpha[j] = layer->planeAlpha;
1129 transform[j] = layer->transform;
1130 layer->blending = HWC_BLENDING_NONE;
1131 layer->planeAlpha = 0xFF;
1132 layer->transform = 0;
1133
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001134 // Remove overlap from crop & displayFrame of below layers
1135 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001136 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001137 if(!isValidRect(getIntersection(layer->displayFrame,
1138 overlapRect[j]))) {
1139 continue;
1140 }
1141 // Update layer attributes
1142 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1143 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301144 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001145 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1146 layer->transform);
1147 layer->sourceCropf.left = (float)srcCrop.left;
1148 layer->sourceCropf.top = (float)srcCrop.top;
1149 layer->sourceCropf.right = (float)srcCrop.right;
1150 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1151 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001152 }
1153
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001154 mCurrentFrame.mdpCount = numNonCursorLayers;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001155 mCurrentFrame.fbCount = 0;
1156 mCurrentFrame.fbZ = -1;
1157
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001158 for (int j = 0; j < numNonCursorLayers; j++) {
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301159 if(isValidRect(list->hwLayers[j].displayFrame)) {
1160 mCurrentFrame.isFBComposed[j] = false;
1161 } else {
1162 mCurrentFrame.mdpCount--;
1163 mCurrentFrame.drop[j] = true;
1164 }
1165 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001166
1167 bool result = postHeuristicsHandling(ctx, list);
1168
1169 // Restore layer attributes
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001170 for(int i = 0; i < numNonCursorLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001171 hwc_layer_1_t* layer = &list->hwLayers[i];
1172 layer->displayFrame = displayFrame[i];
1173 layer->sourceCropf.left = (float)sourceCrop[i].left;
1174 layer->sourceCropf.top = (float)sourceCrop[i].top;
1175 layer->sourceCropf.right = (float)sourceCrop[i].right;
1176 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1177 }
1178
Xu Yangcda012c2014-07-30 21:57:21 +08001179 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001180 for (int i = 0; i < numPTORLayersFound; i++) {
1181 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001182 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001183 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1184 hnd->width = layerWhf[i].w;
1185 hnd->height = layerWhf[i].h;
1186 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001187 layer->blending = blending[i];
1188 layer->planeAlpha = planeAlpha[i];
1189 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001190 }
1191
Sushil Chauhandefd3522014-05-13 18:17:12 -07001192 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001193 // reset PTOR
1194 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001195 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001196 } else {
1197 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1198 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001199 }
1200
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001201 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1202 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001203 return result;
1204}
1205
Saurabh Shahaa236822013-04-24 18:07:26 -07001206bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1207{
radhakrishnac3198ff2015-03-10 17:10:02 +05301208 if(!sEnableMixedMode || !isAlphaPresentinFB(ctx, mDpy)) {
1209 //Mixed mode is disabled/can't be used. No need to even try caching.
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001210 return false;
1211 }
1212
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001213 bool ret = false;
Raj Kamal1179d9c2014-10-28 15:31:35 +05301214 if(isSkipPresent(ctx, mDpy) or list->flags & HWC_GEOMETRY_CHANGED) {
1215 //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001216 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001217 cacheBasedComp(ctx, list);
1218 } else {
1219 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001220 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001221 }
1222
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001223 return ret;
1224}
1225
1226bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1227 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001228 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1229 return false;
1230
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001231 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001232 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001233 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001234
1235 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1236 for(int i = 0; i < numAppLayers; i++) {
1237 if(!mCurrentFrame.isFBComposed[i]) {
1238 hwc_layer_1_t* layer = &list->hwLayers[i];
1239 if(not isSupportedForMDPComp(ctx, layer)) {
1240 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1241 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001242 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001243 return false;
1244 }
1245 }
1246 }
1247
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001248 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001249 /* mark secure RGB layers for MDP comp */
1250 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301251 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001252 if(!ret) {
1253 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001254 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001255 return false;
1256 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001257
1258 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001259
Raj Kamal389d6e32014-08-04 14:43:24 +05301260 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001261 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301262 }
1263
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001264 if(!postHeuristicsHandling(ctx, list)) {
1265 ALOGD_IF(isDebug(), "post heuristic handling failed");
1266 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001267 return false;
1268 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001269 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1270 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001271
Saurabh Shahaa236822013-04-24 18:07:26 -07001272 return true;
1273}
1274
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001275bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001276 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001277 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1278 return false;
1279
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001280 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001281 return false;
1282 }
1283
Saurabh Shahb772ae32013-11-18 15:40:02 -08001284 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001285 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1286 const int stagesForMDP = min(sMaxPipesPerMixer,
1287 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001288
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001289 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1290 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1291 int lastMDPSupportedIndex = numAppLayers;
1292 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001293
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001294 //Find the minimum MDP batch size
1295 for(int i = 0; i < numAppLayers;i++) {
1296 if(mCurrentFrame.drop[i]) {
1297 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001298 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001299 }
1300 hwc_layer_1_t* layer = &list->hwLayers[i];
1301 if(not isSupportedForMDPComp(ctx, layer)) {
1302 lastMDPSupportedIndex = i;
1303 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1304 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001305 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001306 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001307 }
1308
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001309 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1310 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1311 mCurrentFrame.dropCount);
1312
1313 //Start at a point where the fb batch should at least have 2 layers, for
1314 //this mode to be justified.
1315 while(fbBatchSize < 2) {
1316 ++fbBatchSize;
1317 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001318 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001319
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001320 //If there are no layers for MDP, this mode doesnt make sense.
1321 if(mdpBatchSize < 1) {
1322 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1323 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001324 return false;
1325 }
1326
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001327 mCurrentFrame.reset(numAppLayers);
1328
1329 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1330 while(mdpBatchSize > 0) {
1331 //Mark layers for MDP comp
1332 int mdpBatchLeft = mdpBatchSize;
1333 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1334 if(mCurrentFrame.drop[i]) {
1335 continue;
1336 }
1337 mCurrentFrame.isFBComposed[i] = false;
1338 --mdpBatchLeft;
1339 }
1340
1341 mCurrentFrame.fbZ = mdpBatchSize;
1342 mCurrentFrame.fbCount = fbBatchSize;
1343 mCurrentFrame.mdpCount = mdpBatchSize;
1344
1345 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1346 __FUNCTION__, mdpBatchSize, fbBatchSize,
1347 mCurrentFrame.dropCount);
1348
1349 if(postHeuristicsHandling(ctx, list)) {
1350 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001351 __FUNCTION__);
1352 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1353 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001354 return true;
1355 }
1356
1357 reset(ctx);
1358 --mdpBatchSize;
1359 ++fbBatchSize;
1360 }
1361
1362 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001363}
1364
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001365bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301366 if(mDpy or isSecurePresent(ctx, mDpy) or
1367 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001368 return false;
1369 }
1370 return true;
1371}
1372
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001373bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1374 hwc_display_contents_1_t* list){
1375 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1376 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001377 isCursorPresent(ctx, mDpy) || !sIsPartialUpdateActive || mDpy) {
1378 // On Async position update, the ROI becomes invalid, hence disable PU
1379 // when cursor is present
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001380 return false;
1381 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001382 if(ctx->listStats[mDpy].secureUI)
1383 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001384 return true;
1385}
1386
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001387bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1388 hwc_display_contents_1_t* list) {
1389 const bool secureOnly = true;
1390 return videoOnlyComp(ctx, list, not secureOnly) or
1391 videoOnlyComp(ctx, list, secureOnly);
1392}
1393
1394bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001395 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001396 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1397 return false;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301398
Saurabh Shahaa236822013-04-24 18:07:26 -07001399 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301400 if(!isSecurePresent(ctx, mDpy)) {
1401 /* Bail out if we are processing only secured video layers
1402 * and we dont have any */
1403 if(secureOnly) {
1404 ALOGD_IF(isDebug(),"%s: No Secure Video Layers", __FUNCTION__);
1405 return false;
1406 }
1407 /* No Idle fall back for secure video layers and if there is only
1408 * single layer being composed. */
1409 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1410 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1411 return false;
1412 }
1413 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001414
Saurabh Shahaa236822013-04-24 18:07:26 -07001415 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001416 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001417 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001418 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001419
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001420 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1421 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001422 return false;
1423 }
1424
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001425 if(mCurrentFrame.fbCount)
1426 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001427
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001428 if(sEnableYUVsplit || needs3DComposition(ctx, mDpy)){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001429 adjustForSourceSplit(ctx, list);
1430 }
1431
1432 if(!postHeuristicsHandling(ctx, list)) {
1433 ALOGD_IF(isDebug(), "post heuristic handling failed");
Justin Philip37ab9a82015-01-06 11:55:12 +05301434 if(errno == ENOBUFS) {
1435 ALOGD_IF(isDebug(), "SMP Allocation failed");
1436 //On SMP allocation failure in video only comp add padding round
1437 ctx->isPaddingRound = true;
1438 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001439 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001440 return false;
1441 }
1442
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001443 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1444 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001445 return true;
1446}
1447
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001448/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1449bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1450 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001451 // Fall back to video only composition, if AIV video mode is enabled
1452 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001453 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1454 __FUNCTION__, mDpy);
1455 return false;
1456 }
1457
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001458 // No MDP composition for 3D
1459 if(needs3DComposition(ctx,mDpy))
1460 return false;
1461
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001462 const bool secureOnly = true;
1463 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1464 mdpOnlyLayersComp(ctx, list, secureOnly);
1465
1466}
1467
1468bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1469 hwc_display_contents_1_t* list, bool secureOnly) {
1470
1471 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1472 return false;
1473
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301474 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1475 if(!isSecurePresent(ctx, mDpy) && !ctx->listStats[mDpy].secureUI) {
1476 /* Bail out if we are processing only secured video/ui layers
1477 * and we dont have any */
1478 if(secureOnly) {
1479 ALOGD_IF(isDebug(), "%s: No secure video/ui layers");
1480 return false;
1481 }
1482 /* No Idle fall back for secure video/ui layers and if there is only
1483 * single layer being composed. */
1484 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1485 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1486 return false;
1487 }
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001488 }
1489
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08001490 /* Bail out if we dont have any secure RGB layers */
1491 if (!ctx->listStats[mDpy].secureRGBCount) {
1492 reset(ctx);
1493 return false;
1494 }
1495
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001496 mCurrentFrame.reset(numAppLayers);
1497 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1498
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001499 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001500 /* mark secure RGB layers for MDP comp */
1501 updateSecureRGB(ctx, list);
1502
1503 if(mCurrentFrame.mdpCount == 0) {
1504 reset(ctx);
1505 return false;
1506 }
1507
1508 /* find the maximum batch of layers to be marked for framebuffer */
1509 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1510 if(!ret) {
1511 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1512 reset(ctx);
1513 return false;
1514 }
1515
1516 if(sEnableYUVsplit){
1517 adjustForSourceSplit(ctx, list);
1518 }
1519
1520 if(!postHeuristicsHandling(ctx, list)) {
1521 ALOGD_IF(isDebug(), "post heuristic handling failed");
1522 reset(ctx);
1523 return false;
1524 }
1525
1526 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1527 __FUNCTION__);
1528 return true;
1529}
1530
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001531/* Checks for conditions where YUV layers cannot be bypassed */
1532bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001533 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001534 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001535 return false;
1536 }
1537
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001538 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001539 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1540 return false;
1541 }
1542
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001543 if(isSecuring(ctx, layer)) {
1544 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1545 return false;
1546 }
1547
Saurabh Shah4fdde762013-04-30 18:47:33 -07001548 if(!isValidDimension(ctx, layer)) {
1549 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1550 __FUNCTION__);
1551 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001552 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001553
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001554 if(layer->planeAlpha < 0xFF) {
1555 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1556 in video only mode",
1557 __FUNCTION__);
1558 return false;
1559 }
1560
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001561 return true;
1562}
1563
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001564/* Checks for conditions where Secure RGB layers cannot be bypassed */
1565bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1566 if(isSkipLayer(layer)) {
1567 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1568 __FUNCTION__, mDpy);
1569 return false;
1570 }
1571
1572 if(isSecuring(ctx, layer)) {
1573 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1574 return false;
1575 }
1576
1577 if(not isSupportedForMDPComp(ctx, layer)) {
1578 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1579 __FUNCTION__);
1580 return false;
1581 }
1582 return true;
1583}
1584
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301585/* starts at fromIndex and check for each layer to find
1586 * if it it has overlapping with any Updating layer above it in zorder
1587 * till the end of the batch. returns true if it finds any intersection */
1588bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1589 int fromIndex, int toIndex) {
1590 for(int i = fromIndex; i < toIndex; i++) {
1591 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1592 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1593 return false;
1594 }
1595 }
1596 }
1597 return true;
1598}
1599
1600/* Checks if given layer at targetLayerIndex has any
1601 * intersection with all the updating layers in beween
1602 * fromIndex and toIndex. Returns true if it finds intersectiion */
1603bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1604 int fromIndex, int toIndex, int targetLayerIndex) {
1605 for(int i = fromIndex; i <= toIndex; i++) {
1606 if(!mCurrentFrame.isFBComposed[i]) {
1607 if(areLayersIntersecting(&list->hwLayers[i],
1608 &list->hwLayers[targetLayerIndex])) {
1609 return true;
1610 }
1611 }
1612 }
1613 return false;
1614}
1615
1616int MDPComp::getBatch(hwc_display_contents_1_t* list,
1617 int& maxBatchStart, int& maxBatchEnd,
1618 int& maxBatchCount) {
1619 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301620 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001621 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301622 while (i < mCurrentFrame.layerCount) {
1623 int batchCount = 0;
1624 int batchStart = i;
1625 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001626 /* Adjust batch Z order with the dropped layers so far */
1627 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301628 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301629 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301630 while(i < mCurrentFrame.layerCount) {
1631 if(!mCurrentFrame.isFBComposed[i]) {
1632 if(!batchCount) {
1633 i++;
1634 break;
1635 }
1636 updatingLayersAbove++;
1637 i++;
1638 continue;
1639 } else {
1640 if(mCurrentFrame.drop[i]) {
1641 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001642 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301643 continue;
1644 } else if(updatingLayersAbove <= 0) {
1645 batchCount++;
1646 batchEnd = i;
1647 i++;
1648 continue;
1649 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1650
1651 // We have a valid updating layer already. If layer-i not
1652 // have overlapping with all updating layers in between
1653 // batch-start and i, then we can add layer i to batch.
1654 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1655 batchCount++;
1656 batchEnd = i;
1657 i++;
1658 continue;
1659 } else if(canPushBatchToTop(list, batchStart, i)) {
1660 //If All the non-updating layers with in this batch
1661 //does not have intersection with the updating layers
1662 //above in z-order, then we can safely move the batch to
1663 //higher z-order. Increment fbZ as it is moving up.
1664 if( firstZReverseIndex < 0) {
1665 firstZReverseIndex = i;
1666 }
1667 batchCount++;
1668 batchEnd = i;
1669 fbZ += updatingLayersAbove;
1670 i++;
1671 updatingLayersAbove = 0;
1672 continue;
1673 } else {
1674 //both failed.start the loop again from here.
1675 if(firstZReverseIndex >= 0) {
1676 i = firstZReverseIndex;
1677 }
1678 break;
1679 }
1680 }
1681 }
1682 }
1683 if(batchCount > maxBatchCount) {
1684 maxBatchCount = batchCount;
1685 maxBatchStart = batchStart;
1686 maxBatchEnd = batchEnd;
1687 fbZOrder = fbZ;
1688 }
1689 }
1690 return fbZOrder;
1691}
1692
1693bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1694 hwc_display_contents_1_t* list) {
1695 /* Idea is to keep as many non-updating(cached) layers in FB and
1696 * send rest of them through MDP. This is done in 2 steps.
1697 * 1. Find the maximum contiguous batch of non-updating layers.
1698 * 2. See if we can improve this batch size for caching by adding
1699 * opaque layers around the batch, if they don't have
1700 * any overlapping with the updating layers in between.
1701 * NEVER mark an updating layer for caching.
1702 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001703
1704 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001705 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001706 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301707 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001708
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001709 /* Nothing is cached. No batching needed */
1710 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001711 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001712 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001713
1714 /* No MDP comp layers, try to use other comp modes */
1715 if(mCurrentFrame.mdpCount == 0) {
1716 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001717 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001718
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301719 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001720
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301721 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001722 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001723 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001724 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301725 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001726 if(!mCurrentFrame.drop[i]){
1727 //If an unsupported layer is being attempted to
1728 //be pulled out we should fail
1729 if(not isSupportedForMDPComp(ctx, layer)) {
1730 return false;
1731 }
1732 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001733 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001734 }
1735 }
1736
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301737 // update the frame data
1738 mCurrentFrame.fbZ = fbZ;
1739 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001740 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001741 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001742
1743 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301744 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001745
1746 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001747}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001748
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001749void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001750 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001751 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001752 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001753
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001754 for(int i = 0; i < numAppLayers; i++) {
1755 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001756 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001757 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001758 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001759 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001760 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001761 }
1762 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001763
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001764 frame.fbCount = fbCount;
1765 frame.mdpCount = frame.layerCount - frame.fbCount
1766 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001767
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001768 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1769 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001770}
1771
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001772// drop other non-AIV layers from external display list.
1773void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001774 hwc_display_contents_1_t* list) {
1775 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1776 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001777 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001778 mCurrentFrame.dropCount++;
1779 mCurrentFrame.drop[i] = true;
1780 }
1781 }
1782 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1783 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1784 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1785 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1786 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1787 mCurrentFrame.dropCount);
1788}
1789
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001790void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001791 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001792 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1793 for(int index = 0;index < nYuvCount; index++){
1794 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1795 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1796
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001797 if(mCurrentFrame.drop[nYuvIndex]) {
1798 continue;
1799 }
1800
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001801 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001802 if(!frame.isFBComposed[nYuvIndex]) {
1803 frame.isFBComposed[nYuvIndex] = true;
1804 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001805 }
1806 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001807 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001808 private_handle_t *hnd = (private_handle_t *)layer->handle;
1809 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001810 frame.isFBComposed[nYuvIndex] = false;
1811 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001812 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001813 }
1814 }
1815 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001816
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001817 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1818 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001819}
1820
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001821void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1822 hwc_display_contents_1_t* list) {
1823 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1824 for(int index = 0;index < nSecureRGBCount; index++){
1825 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1826 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1827
1828 if(!isSecureRGBDoable(ctx, layer)) {
1829 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1830 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1831 mCurrentFrame.fbCount++;
1832 }
1833 } else {
1834 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1835 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1836 mCurrentFrame.fbCount--;
1837 }
1838 }
1839 }
1840
1841 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1842 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1843 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1844 mCurrentFrame.fbCount);
1845}
1846
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001847hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1848 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001849 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001850
1851 /* Update only the region of FB needed for composition */
1852 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1853 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1854 hwc_layer_1_t* layer = &list->hwLayers[i];
1855 hwc_rect_t dst = layer->displayFrame;
1856 fbRect = getUnion(fbRect, dst);
1857 }
1858 }
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08001859 trimAgainstROI(ctx, fbRect, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001860 return fbRect;
1861}
1862
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001863bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1864 hwc_display_contents_1_t* list) {
1865
1866 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001867 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001868 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1869 return false;
1870 }
1871
1872 //Limitations checks
1873 if(!hwLimitationsCheck(ctx, list)) {
1874 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1875 return false;
1876 }
1877
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001878 //Configure framebuffer first if applicable
1879 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001880 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001881 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1882 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001883 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1884 __FUNCTION__);
1885 return false;
1886 }
1887 }
1888
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001889 mCurrentFrame.map();
1890
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001891 if(!allocLayerPipes(ctx, list)) {
1892 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001893 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001894 }
1895
1896 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001897 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001898 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001899 int mdpIndex = mCurrentFrame.layerToMDP[index];
1900 hwc_layer_1_t* layer = &list->hwLayers[index];
1901
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301902 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1903 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1904 mdpNextZOrder++;
1905 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001906 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1907 cur_pipe->zOrder = mdpNextZOrder++;
1908
radhakrishnac9a67412013-09-25 17:40:42 +05301909 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301910 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301911 if(configure4k2kYuv(ctx, layer,
1912 mCurrentFrame.mdpToLayer[mdpIndex])
1913 != 0 ){
1914 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1915 for layer %d",__FUNCTION__, index);
1916 return false;
1917 }
1918 else{
1919 mdpNextZOrder++;
1920 }
1921 continue;
1922 }
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001923 if(needs3DComposition(ctx,mDpy) && get3DFormat(hnd) != HAL_NO_3D) {
1924 mdpNextZOrder++;
1925 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001926 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1927 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301928 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001929 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001930 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001931 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001932 }
1933
Saurabh Shaha36be922013-12-16 18:18:39 -08001934 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1935 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1936 ,__FUNCTION__, mDpy);
1937 return false;
1938 }
1939
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001940 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001941 return true;
1942}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001943
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001944bool MDPComp::resourceCheck(hwc_context_t* ctx,
1945 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001946 const bool fbUsed = mCurrentFrame.fbCount;
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001947 int cursorInUse = 0;
1948 if(mDpy == HWC_DISPLAY_PRIMARY) {
1949 // check if cursor is in use for primary
1950 cursorInUse = HWCursor::getInstance()->isCursorSet();
1951 }
1952 int maxStages = qdutils::MDPVersion::getInstance().getBlendStages();
1953 // HW Cursor needs one blending stage, account for that in the check below
1954 // On high end targets(8994) has 8 blending stages, HAL is configured to use < 8.
1955 // Make use of the remaining stages for HW Cursor so that the composition
1956 // strategy would not fail due to this limitation.
1957 if (maxStages > sMaxPipesPerMixer) {
1958 cursorInUse = 0;
1959 }
1960 if(mCurrentFrame.mdpCount > (sMaxPipesPerMixer - fbUsed - cursorInUse)) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001961 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1962 return false;
1963 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001964
1965 //Will benefit cases where a video has non-updating background.
1966 if((mDpy > HWC_DISPLAY_PRIMARY) and
1967 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1968 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1969 return false;
1970 }
1971
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001972 // Init rotCount to number of rotate sessions used by other displays
1973 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1974 // Count the number of rotator sessions required for current display
1975 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1976 if(!mCurrentFrame.isFBComposed[index]) {
1977 hwc_layer_1_t* layer = &list->hwLayers[index];
1978 private_handle_t *hnd = (private_handle_t *)layer->handle;
1979 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1980 rotCount++;
1981 }
1982 }
1983 }
1984 // if number of layers to rotate exceeds max rotator sessions, bail out.
1985 if(rotCount > RotMgr::MAX_ROT_SESS) {
1986 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1987 __FUNCTION__, mDpy);
1988 return false;
1989 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001990 return true;
1991}
1992
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301993bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1994 hwc_display_contents_1_t* list) {
1995
1996 //A-family hw limitation:
1997 //If a layer need alpha scaling, MDP can not support.
1998 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1999 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
2000 if(!mCurrentFrame.isFBComposed[i] &&
2001 isAlphaScaled( &list->hwLayers[i])) {
2002 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
2003 return false;
2004 }
2005 }
2006 }
2007
2008 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
2009 //If multiple layers requires downscaling and also they are overlapping
2010 //fall back to GPU since MDSS can not handle it.
2011 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
2012 qdutils::MDPVersion::getInstance().is8x26()) {
2013 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
2014 hwc_layer_1_t* botLayer = &list->hwLayers[i];
2015 if(!mCurrentFrame.isFBComposed[i] &&
2016 isDownscaleRequired(botLayer)) {
2017 //if layer-i is marked for MDP and needs downscaling
2018 //check if any MDP layer on top of i & overlaps with layer-i
2019 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
2020 hwc_layer_1_t* topLayer = &list->hwLayers[j];
2021 if(!mCurrentFrame.isFBComposed[j] &&
2022 isDownscaleRequired(topLayer)) {
2023 hwc_rect_t r = getIntersection(botLayer->displayFrame,
2024 topLayer->displayFrame);
2025 if(isValidRect(r))
2026 return false;
2027 }
2028 }
2029 }
2030 }
2031 }
2032 return true;
2033}
2034
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002035static bool validForCursor(hwc_context_t* ctx, int dpy, hwc_layer_1_t* layer) {
2036 private_handle_t *hnd = (private_handle_t *)layer->handle;
2037 hwc_rect dst = layer->displayFrame;
2038 hwc_rect src = integerizeSourceCrop(layer->sourceCropf);
2039 int srcW = src.right - src.left;
2040 int srcH = src.bottom - src.top;
2041 int dstW = dst.right - dst.left;
2042 int dstH = dst.bottom - dst.top;
2043 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
2044 uint32_t maxCursorSize = mdpVersion.getMaxCursorSize();
2045 uint32_t numHwCursors = mdpVersion.getCursorPipes();
2046 bool primarySplit = isDisplaySplit(ctx, HWC_DISPLAY_PRIMARY);
2047 uint32_t cursorPipesNeeded = 1; // One cursor pipe needed(default)
2048 bool ret = false;
2049
2050 if(dpy > HWC_DISPLAY_PRIMARY) {
2051 // Cursor not supported on secondary displays, as it involves scaling
2052 // in most of the cases
2053 return false;
2054 } else if (isSkipLayer(layer)) {
2055 return false;
2056 // Checks for HW limitation
2057 } else if (numHwCursors == 0 || maxCursorSize <= 0) {
2058 return false;
2059 } else if (needsScaling(layer)) {
2060 return false;
2061 } else if (layer->transform != 0) {
2062 return false;
2063 } else if (hnd->format != HAL_PIXEL_FORMAT_RGBA_8888) {
2064 return false;
2065 } else if (srcW > (int)maxCursorSize || srcH > (int)maxCursorSize) {
2066 return false;
2067 }
2068
2069 if (isDisplaySplit(ctx, dpy) && !mdpVersion.isSrcSplit()) {
2070 // In case of split display with no srcSplit, the driver allocates two
2071 // pipes to support async position update across mixers, hence
2072 // need to account for that here.
2073 cursorPipesNeeded = 2;
2074 }
2075 if (cursorPipesNeeded <= numHwCursors) {
2076 ret = true;
2077 }
2078 return ret;
2079}
2080
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002081// Checks only if videos or single layer(RGB) is updating
2082// which is used for setting dynamic fps or perf hint for single
2083// layer video playback
2084bool MDPComp::onlyVideosUpdating(hwc_context_t *ctx,
2085 hwc_display_contents_1_t* list) {
2086 bool support = false;
2087 FrameInfo frame;
2088 frame.reset(mCurrentFrame.layerCount);
2089 memset(&frame.drop, 0, sizeof(frame.drop));
2090 frame.dropCount = 0;
2091 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo", __FUNCTION__);
2092 updateLayerCache(ctx, list, frame);
2093 updateYUV(ctx, list, false /*secure only*/, frame);
2094 // There are only updating YUV layers or there is single RGB
2095 // Layer(Youtube)
2096 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
2097 (frame.layerCount == 1)) {
2098 support = true;
2099 }
2100 return support;
2101}
2102
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302103void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2104 //For primary display, set the dynamic refreshrate
2105 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
2106 ctx->mUseMetaDataRefreshRate) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302107 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
2108 MDPVersion& mdpHw = MDPVersion::getInstance();
2109 if(sIdleFallBack) {
2110 //Set minimum panel refresh rate during idle timeout
2111 refreshRate = mdpHw.getMinFpsSupported();
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002112 } else if(onlyVideosUpdating(ctx, list)) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302113 //Set the new fresh rate, if there is only one updating YUV layer
2114 //or there is one single RGB layer with this request
2115 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
2116 }
2117 setRefreshRate(ctx, mDpy, refreshRate);
2118 }
2119}
2120
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002121int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002122 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07002123 char property[PROPERTY_VALUE_MAX];
2124
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002125 if(!list) {
2126 ALOGE("%s: Invalid list", __FUNCTION__);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302127 mCachedFrame.reset();
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002128 freeHwCursor(ctx->dpyAttr[mDpy].fd, mDpy);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302129 return -1;
2130 }
2131
2132 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07002133 if(mDpy == HWC_DISPLAY_PRIMARY) {
2134 sSimulationFlags = 0;
2135 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
2136 int currentFlags = atoi(property);
2137 if(currentFlags != sSimulationFlags) {
2138 sSimulationFlags = currentFlags;
2139 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
2140 sSimulationFlags, sSimulationFlags);
2141 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07002142 }
2143 }
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07002144
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302145 //reset old data
2146 mCurrentFrame.reset(numLayers);
2147 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2148 mCurrentFrame.dropCount = 0;
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002149 mCurrentFrame.hwCursorIndex = -1;
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302150
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05302151 //Do not cache the information for next draw cycle.
2152 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
2153 ALOGI("%s: Unsupported layer count for mdp composition",
2154 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002155 mCachedFrame.reset();
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302156#ifdef DYNAMIC_FPS
2157 setDynRefreshRate(ctx, list);
2158#endif
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002159 freeHwCursor(ctx->dpyAttr[mDpy].fd, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002160 return -1;
2161 }
2162
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002163 // Detect the start of animation and fall back to GPU only once to cache
2164 // all the layers in FB and display FB content untill animation completes.
2165 if(ctx->listStats[mDpy].isDisplayAnimating) {
2166 mCurrentFrame.needsRedraw = false;
2167 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
2168 mCurrentFrame.needsRedraw = true;
2169 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
2170 }
2171 setMDPCompLayerFlags(ctx, list);
2172 mCachedFrame.updateCounts(mCurrentFrame);
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302173#ifdef DYNAMIC_FPS
2174 setDynRefreshRate(ctx, list);
2175#endif
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002176 freeHwCursor(ctx->dpyAttr[mDpy].fd, mDpy);
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002177 ret = -1;
2178 return ret;
2179 } else {
2180 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
2181 }
2182
Raj Kamalfdfdddf2015-03-16 21:59:25 +05302183 if(!mDpy and !isSecondaryConnected(ctx) and !mPrevModeOn and
2184 mCachedFrame.isSameFrame(ctx,mDpy,list)) {
2185
2186 ALOGD_IF(isDebug(),"%s: Avoid new composition",__FUNCTION__);
2187 mCurrentFrame.needsRedraw = false;
2188 setMDPCompLayerFlags(ctx, list);
2189 mCachedFrame.updateCounts(mCurrentFrame);
2190#ifdef DYNAMIC_FPS
2191 setDynRefreshRate(ctx, list);
2192#endif
2193 return -1;
2194
2195 }
2196
Saurabh Shahb39f8152013-08-22 10:21:44 -07002197 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002198 if(isFrameDoable(ctx)) {
2199 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002200 // if AIV Video mode is enabled, drop all non AIV layers from the
2201 // external display list.
2202 if(ctx->listStats[mDpy].mAIVVideoMode) {
2203 dropNonAIVLayers(ctx, list);
2204 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002205
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002206 // Configure the cursor if present
2207 int topIndex = ctx->listStats[mDpy].numAppLayers - 1;
2208 if(ctx->listStats[mDpy].cursorLayerPresent &&
2209 validForCursor(ctx, mDpy, &(list->hwLayers[topIndex]))) {
2210 if(configHwCursor(ctx->dpyAttr[mDpy].fd, mDpy,
2211 &(list->hwLayers[topIndex]))) {
2212 // As cursor is configured, mark that layer as dropped, so that
2213 // it wont be considered for composition by other strategies.
2214 mCurrentFrame.hwCursorIndex = topIndex;
2215 mCurrentFrame.drop[topIndex] = true;
2216 mCurrentFrame.dropCount++;
2217 }
2218 } else {
2219 // Release the hw cursor
2220 freeHwCursor(ctx->dpyAttr[mDpy].fd, mDpy);
2221 }
2222
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07002223 // if tryFullFrame fails, try to push all video and secure RGB layers
2224 // to MDP for composition.
2225 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002226 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302227 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002228 setMDPCompLayerFlags(ctx, list);
2229 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002230 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002231 reset(ctx);
2232 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2233 mCurrentFrame.dropCount = 0;
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002234 // Check if cursor is in use for primary and mark accordingly
2235 if(!mDpy && HWCursor::getInstance()->isCursorSet()) {
2236 int topIndex = ctx->listStats[mDpy].numAppLayers - 1;
2237 hwc_layer_1_t *layer = &(list->hwLayers[topIndex]);
2238 layer->compositionType = HWC_CURSOR_OVERLAY;
2239 }
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002240 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07002241 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
2242 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07002243 }
2244 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05302245 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
2246 enablePartialUpdateForMDP3) {
2247 generateROI(ctx, list);
2248 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
2249 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
2250 }
2251 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002252 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
2253 __FUNCTION__);
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002254 // Release the hw cursor
2255 freeHwCursor(ctx->dpyAttr[mDpy].fd, mDpy);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002256 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07002257 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002258
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002259 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002260 ALOGD("GEOMETRY change: %d",
2261 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002262 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07002263 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002264 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002265 }
2266
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002267#ifdef DYNAMIC_FPS
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302268 setDynRefreshRate(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002269#endif
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002270 setPerfHint(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002271
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002272 mCachedFrame.cacheAll(list);
2273 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002274 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002275}
2276
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002277bool MDPComp::allocSplitVGPipes(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302278
2279 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302280 int mdpIndex = mCurrentFrame.layerToMDP[index];
2281 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2282 info.pipeInfo = new MdpYUVPipeInfo;
2283 info.rot = NULL;
2284 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302285
2286 pipe_info.lIndex = ovutils::OV_INVALID;
2287 pipe_info.rIndex = ovutils::OV_INVALID;
2288
Saurabh Shahc62f3982014-03-05 14:28:26 -08002289 Overlay::PipeSpecs pipeSpecs;
2290 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2291 pipeSpecs.needsScaling = true;
2292 pipeSpecs.dpy = mDpy;
2293 pipeSpecs.fb = false;
2294
2295 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302296 if(pipe_info.lIndex == ovutils::OV_INVALID){
2297 bRet = false;
2298 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2299 __FUNCTION__);
2300 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002301 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302302 if(pipe_info.rIndex == ovutils::OV_INVALID){
2303 bRet = false;
2304 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2305 __FUNCTION__);
2306 }
2307 return bRet;
2308}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002309
2310int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2311 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002312 if (ctx->mPtorInfo.isActive()) {
2313 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002314 if (fd < 0) {
2315 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002316 }
2317 }
2318 return fd;
2319}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002320//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002321
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002322void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302323 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002324 //If 4k2k Yuv layer split is possible, and if
2325 //fbz is above 4k2k layer, increment fb zorder by 1
2326 //as we split 4k2k layer and increment zorder for right half
2327 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002328 if(!ctx)
2329 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002330 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302331 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2332 index++) {
2333 if(!mCurrentFrame.isFBComposed[index]) {
2334 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2335 mdpNextZOrder++;
2336 }
2337 mdpNextZOrder++;
2338 hwc_layer_1_t* layer = &list->hwLayers[index];
2339 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302340 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302341 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2342 mCurrentFrame.fbZ += 1;
2343 mdpNextZOrder++;
2344 //As we split 4kx2k yuv layer and program to 2 VG pipes
2345 //(if available) increase mdpcount by 1.
2346 mCurrentFrame.mdpCount++;
2347 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002348 }
2349 }
2350 }
radhakrishnac9a67412013-09-25 17:40:42 +05302351}
2352
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002353/*
2354 * Configures pipe(s) for MDP composition
2355 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002356int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002357 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002358 MdpPipeInfoNonSplit& mdp_info =
2359 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302360 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002361 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002362 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002363
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002364 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2365 __FUNCTION__, layer, zOrder, dest);
2366
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002367 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002368 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002369}
2370
Saurabh Shah88e4d272013-09-03 13:31:29 -07002371bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002372 hwc_display_contents_1_t* list) {
Saurabh Shah8cc77712015-03-31 10:48:51 -07002373 for(uint32_t formatType = FORMAT_YUV; formatType < FORMAT_MAX;
2374 formatType++) {
2375 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
2376 if(mCurrentFrame.isFBComposed[index]) continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002377
Saurabh Shah8cc77712015-03-31 10:48:51 -07002378 hwc_layer_1_t* layer = &list->hwLayers[index];
2379 private_handle_t *hnd = (private_handle_t *)layer->handle;
2380 if(formatType == FORMAT_YUV && !isYuvBuffer(hnd))
radhakrishnac9a67412013-09-25 17:40:42 +05302381 continue;
Saurabh Shah8cc77712015-03-31 10:48:51 -07002382 if(formatType == FORMAT_RGB && isYuvBuffer(hnd))
2383 continue;
2384
2385 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
2386 if(allocSplitVGPipes(ctx, index)){
2387 continue;
2388 }
radhakrishnac9a67412013-09-25 17:40:42 +05302389 }
radhakrishnac9a67412013-09-25 17:40:42 +05302390
Saurabh Shah8cc77712015-03-31 10:48:51 -07002391 int mdpIndex = mCurrentFrame.layerToMDP[index];
2392 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2393 info.pipeInfo = new MdpPipeInfoNonSplit;
2394 info.rot = NULL;
2395 MdpPipeInfoNonSplit& pipe_info =
2396 *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002397
Saurabh Shah8cc77712015-03-31 10:48:51 -07002398 Overlay::PipeSpecs pipeSpecs;
2399 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2400 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2401 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2402 (qdutils::MDPVersion::getInstance().is8x26() and
2403 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2404 pipeSpecs.dpy = mDpy;
2405 pipeSpecs.fb = false;
2406 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002407
Saurabh Shah8cc77712015-03-31 10:48:51 -07002408 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahc62f3982014-03-05 14:28:26 -08002409
Saurabh Shah8cc77712015-03-31 10:48:51 -07002410 if(pipe_info.index == ovutils::OV_INVALID) {
2411 ALOGD_IF(isDebug(), "%s: Unable to get pipe for layer %d of "\
2412 "format type %d", __FUNCTION__, index, formatType);
2413 return false;
2414 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002415 }
2416 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002417 return true;
2418}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002419
radhakrishnac9a67412013-09-25 17:40:42 +05302420int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2421 PipeLayerPair& PipeLayerPair) {
2422 MdpYUVPipeInfo& mdp_info =
2423 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2424 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302425 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302426 eDest lDest = mdp_info.lIndex;
2427 eDest rDest = mdp_info.rIndex;
2428
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002429 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302430 lDest, rDest, &PipeLayerPair.rot);
2431}
2432
Saurabh Shah88e4d272013-09-03 13:31:29 -07002433bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002434
Raj Kamal4393eaa2014-06-06 13:45:20 +05302435 if(!isEnabled() or !mModeOn) {
2436 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302437 return true;
2438 }
2439
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002440 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002441 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002442
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002443 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2444 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002445 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002446 if(mCurrentFrame.isFBComposed[i]) continue;
2447
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002448 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002449 private_handle_t *hnd = (private_handle_t *)layer->handle;
2450 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002451 if (!(layer->flags & HWC_COLOR_FILL)) {
2452 ALOGE("%s handle null", __FUNCTION__);
2453 return false;
2454 }
2455 // No PLAY for Color layer
2456 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2457 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002458 }
2459
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002460 int mdpIndex = mCurrentFrame.layerToMDP[i];
2461
Raj Kamal389d6e32014-08-04 14:43:24 +05302462 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302463 {
2464 MdpYUVPipeInfo& pipe_info =
2465 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2466 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2467 ovutils::eDest indexL = pipe_info.lIndex;
2468 ovutils::eDest indexR = pipe_info.rIndex;
2469 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302470 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302471 if(rot) {
2472 rot->queueBuffer(fd, offset);
2473 fd = rot->getDstMemId();
2474 offset = rot->getDstOffset();
2475 }
2476 if(indexL != ovutils::OV_INVALID) {
2477 ovutils::eDest destL = (ovutils::eDest)indexL;
2478 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2479 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2480 if (!ov.queueBuffer(fd, offset, destL)) {
2481 ALOGE("%s: queueBuffer failed for display:%d",
2482 __FUNCTION__, mDpy);
2483 return false;
2484 }
2485 }
2486
2487 if(indexR != ovutils::OV_INVALID) {
2488 ovutils::eDest destR = (ovutils::eDest)indexR;
2489 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2490 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2491 if (!ov.queueBuffer(fd, offset, destR)) {
2492 ALOGE("%s: queueBuffer failed for display:%d",
2493 __FUNCTION__, mDpy);
2494 return false;
2495 }
2496 }
2497 }
2498 else{
2499 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002500 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302501 ovutils::eDest dest = pipe_info.index;
2502 if(dest == ovutils::OV_INVALID) {
2503 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002504 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302505 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002506
radhakrishnac9a67412013-09-25 17:40:42 +05302507 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2508 continue;
2509 }
2510
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002511 int fd = hnd->fd;
2512 uint32_t offset = (uint32_t)hnd->offset;
2513 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2514 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002515 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002516 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002517 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002518 }
2519
radhakrishnac9a67412013-09-25 17:40:42 +05302520 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2521 using pipe: %d", __FUNCTION__, layer,
2522 hnd, dest );
2523
radhakrishnac9a67412013-09-25 17:40:42 +05302524 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2525 if(rot) {
2526 if(!rot->queueBuffer(fd, offset))
2527 return false;
2528 fd = rot->getDstMemId();
2529 offset = rot->getDstOffset();
2530 }
2531
2532 if (!ov.queueBuffer(fd, offset, dest)) {
2533 ALOGE("%s: queueBuffer failed for display:%d ",
2534 __FUNCTION__, mDpy);
2535 return false;
2536 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002537 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002538
2539 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002540 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002541 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002542}
2543
Saurabh Shah88e4d272013-09-03 13:31:29 -07002544//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002545
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002546void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302547 hwc_display_contents_1_t* list){
2548 //if 4kx2k yuv layer is totally present in either in left half
2549 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302550 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302551 if(mCurrentFrame.fbZ >= 0) {
2552 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2553 index++) {
2554 if(!mCurrentFrame.isFBComposed[index]) {
2555 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2556 mdpNextZOrder++;
2557 }
2558 mdpNextZOrder++;
2559 hwc_layer_1_t* layer = &list->hwLayers[index];
2560 private_handle_t *hnd = (private_handle_t *)layer->handle;
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002561 if(isYUVSplitNeeded(hnd) ||
2562 (needs3DComposition(ctx,mDpy) &&
2563 get3DFormat(hnd) != HAL_NO_3D)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302564 hwc_rect_t dst = layer->displayFrame;
2565 if((dst.left > lSplit) || (dst.right < lSplit)) {
2566 mCurrentFrame.mdpCount += 1;
2567 }
2568 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2569 mCurrentFrame.fbZ += 1;
2570 mdpNextZOrder++;
2571 }
2572 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002573 }
radhakrishnac9a67412013-09-25 17:40:42 +05302574 }
2575}
2576
Saurabh Shah88e4d272013-09-03 13:31:29 -07002577bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002578 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002579
Saurabh Shahc62f3982014-03-05 14:28:26 -08002580 const int lSplit = getLeftSplit(ctx, mDpy);
2581 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002582 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002583 pipe_info.lIndex = ovutils::OV_INVALID;
2584 pipe_info.rIndex = ovutils::OV_INVALID;
2585
Saurabh Shahc62f3982014-03-05 14:28:26 -08002586 Overlay::PipeSpecs pipeSpecs;
2587 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2588 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2589 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2590 pipeSpecs.dpy = mDpy;
2591 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2592 pipeSpecs.fb = false;
2593
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002594 // Acquire pipe only for the updating half
2595 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2596 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2597
2598 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002599 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002600 if(pipe_info.lIndex == ovutils::OV_INVALID)
2601 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002602 }
2603
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002604 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002605 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2606 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002607 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002608 return false;
2609 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002610
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002611 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002612}
2613
Saurabh Shah88e4d272013-09-03 13:31:29 -07002614bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002615 hwc_display_contents_1_t* list) {
Saurabh Shah8cc77712015-03-31 10:48:51 -07002616 for(uint32_t formatType = FORMAT_YUV; formatType < FORMAT_MAX;
2617 formatType++) {
2618 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
2619 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002620
Saurabh Shah8cc77712015-03-31 10:48:51 -07002621 hwc_layer_1_t* layer = &list->hwLayers[index];
2622 private_handle_t *hnd = (private_handle_t *)layer->handle;
2623 if(formatType == FORMAT_YUV && !isYuvBuffer(hnd))
2624 continue;
2625 if(formatType == FORMAT_RGB && isYuvBuffer(hnd))
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002626 continue;
2627
Saurabh Shah8cc77712015-03-31 10:48:51 -07002628 hwc_rect_t dst = layer->displayFrame;
2629 const int lSplit = getLeftSplit(ctx, mDpy);
2630 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
2631 if((dst.left > lSplit)||(dst.right < lSplit)){
2632 if(allocSplitVGPipes(ctx, index)){
2633 continue;
2634 }
2635 }
2636 }
2637 //XXX: Check for forced 2D composition
2638 if(needs3DComposition(ctx, mDpy) && get3DFormat(hnd) != HAL_NO_3D)
2639 if(allocSplitVGPipes(ctx,index))
2640 continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002641
Saurabh Shah8cc77712015-03-31 10:48:51 -07002642 int mdpIndex = mCurrentFrame.layerToMDP[index];
2643 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2644 info.pipeInfo = new MdpPipeInfoSplit;
2645 info.rot = NULL;
2646 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
2647
2648 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2649 ALOGD_IF(isDebug(), "%s: Unable to get pipe for layer %d of "\
2650 "format type %d", __FUNCTION__, index, formatType);
2651 return false;
2652 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002653 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002654 }
2655 return true;
2656}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002657
radhakrishnac9a67412013-09-25 17:40:42 +05302658int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2659 PipeLayerPair& PipeLayerPair) {
2660 const int lSplit = getLeftSplit(ctx, mDpy);
2661 hwc_rect_t dst = layer->displayFrame;
2662 if((dst.left > lSplit)||(dst.right < lSplit)){
2663 MdpYUVPipeInfo& mdp_info =
2664 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2665 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302666 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302667 eDest lDest = mdp_info.lIndex;
2668 eDest rDest = mdp_info.rIndex;
2669
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002670 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302671 lDest, rDest, &PipeLayerPair.rot);
2672 }
2673 else{
2674 return configure(ctx, layer, PipeLayerPair);
2675 }
2676}
2677
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002678/*
2679 * Configures pipe(s) for MDP composition
2680 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002681int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002682 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002683 MdpPipeInfoSplit& mdp_info =
2684 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002685 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302686 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002687 eDest lDest = mdp_info.lIndex;
2688 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002689
2690 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002691 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002692
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002693 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002694 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002695}
2696
Saurabh Shah88e4d272013-09-03 13:31:29 -07002697bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002698
Raj Kamal4393eaa2014-06-06 13:45:20 +05302699 if(!isEnabled() or !mModeOn) {
2700 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302701 return true;
2702 }
2703
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002704 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002705 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002706
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002707 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2708 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002709 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002710 if(mCurrentFrame.isFBComposed[i]) continue;
2711
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002712 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002713 private_handle_t *hnd = (private_handle_t *)layer->handle;
2714 if(!hnd) {
2715 ALOGE("%s handle null", __FUNCTION__);
2716 return false;
2717 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002718
2719 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2720 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002721 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002722
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002723 int mdpIndex = mCurrentFrame.layerToMDP[i];
2724
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002725 if((isYUVSplitNeeded(hnd) && sEnableYUVsplit) ||
2726 (needs3DComposition(ctx, mDpy) && get3DFormat(hnd) != HAL_NO_3D))
radhakrishnac9a67412013-09-25 17:40:42 +05302727 {
2728 MdpYUVPipeInfo& pipe_info =
2729 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2730 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2731 ovutils::eDest indexL = pipe_info.lIndex;
2732 ovutils::eDest indexR = pipe_info.rIndex;
2733 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302734 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302735 if(rot) {
2736 rot->queueBuffer(fd, offset);
2737 fd = rot->getDstMemId();
2738 offset = rot->getDstOffset();
2739 }
2740 if(indexL != ovutils::OV_INVALID) {
2741 ovutils::eDest destL = (ovutils::eDest)indexL;
2742 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2743 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2744 if (!ov.queueBuffer(fd, offset, destL)) {
2745 ALOGE("%s: queueBuffer failed for display:%d",
2746 __FUNCTION__, mDpy);
2747 return false;
2748 }
2749 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002750
radhakrishnac9a67412013-09-25 17:40:42 +05302751 if(indexR != ovutils::OV_INVALID) {
2752 ovutils::eDest destR = (ovutils::eDest)indexR;
2753 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2754 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2755 if (!ov.queueBuffer(fd, offset, destR)) {
2756 ALOGE("%s: queueBuffer failed for display:%d",
2757 __FUNCTION__, mDpy);
2758 return false;
2759 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002760 }
2761 }
radhakrishnac9a67412013-09-25 17:40:42 +05302762 else{
2763 MdpPipeInfoSplit& pipe_info =
2764 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2765 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002766
radhakrishnac9a67412013-09-25 17:40:42 +05302767 ovutils::eDest indexL = pipe_info.lIndex;
2768 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002769
radhakrishnac9a67412013-09-25 17:40:42 +05302770 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002771 uint32_t offset = (uint32_t)hnd->offset;
2772 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2773 if (!mDpy && (index != -1)) {
2774 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2775 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002776 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002777 }
radhakrishnac9a67412013-09-25 17:40:42 +05302778
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002779 if(ctx->mAD->draw(ctx, fd, offset)) {
2780 fd = ctx->mAD->getDstFd();
2781 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002782 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002783
radhakrishnac9a67412013-09-25 17:40:42 +05302784 if(rot) {
2785 rot->queueBuffer(fd, offset);
2786 fd = rot->getDstMemId();
2787 offset = rot->getDstOffset();
2788 }
2789
2790 //************* play left mixer **********
2791 if(indexL != ovutils::OV_INVALID) {
2792 ovutils::eDest destL = (ovutils::eDest)indexL;
2793 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2794 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2795 if (!ov.queueBuffer(fd, offset, destL)) {
2796 ALOGE("%s: queueBuffer failed for left mixer",
2797 __FUNCTION__);
2798 return false;
2799 }
2800 }
2801
2802 //************* play right mixer **********
2803 if(indexR != ovutils::OV_INVALID) {
2804 ovutils::eDest destR = (ovutils::eDest)indexR;
2805 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2806 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2807 if (!ov.queueBuffer(fd, offset, destR)) {
2808 ALOGE("%s: queueBuffer failed for right mixer",
2809 __FUNCTION__);
2810 return false;
2811 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002812 }
2813 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002814
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002815 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2816 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002817
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002818 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002819}
Saurabh Shahab47c692014-02-12 18:45:57 -08002820
2821//================MDPCompSrcSplit==============================================
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002822
2823bool MDPCompSrcSplit::validateAndApplyROI(hwc_context_t *ctx,
2824 hwc_display_contents_1_t* list) {
2825 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2826 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
2827
2828 for(int i = numAppLayers - 1; i >= 0; i--) {
2829 if(!isValidRect(visibleRect)) {
2830 mCurrentFrame.drop[i] = true;
2831 mCurrentFrame.dropCount++;
2832 continue;
2833 }
2834
2835 const hwc_layer_1_t* layer = &list->hwLayers[i];
2836 hwc_rect_t dstRect = layer->displayFrame;
2837 hwc_rect_t res = getIntersection(visibleRect, dstRect);
2838
2839 if(!isValidRect(res)) {
2840 mCurrentFrame.drop[i] = true;
2841 mCurrentFrame.dropCount++;
2842 } else {
2843 /* Reset frame ROI when any layer which needs scaling also needs ROI
2844 * cropping */
2845 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
2846 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
2847 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2848 mCurrentFrame.dropCount = 0;
2849 return false;
2850 }
2851
2852 /* deduct any opaque region from visibleRect */
2853 if (layer->blending == HWC_BLENDING_NONE &&
2854 layer->planeAlpha == 0xFF)
2855 visibleRect = deductRect(visibleRect, res);
2856 }
2857 }
2858 return true;
2859}
2860
2861/*
2862 * HW Limitation: ping pong split can always split the ping pong output
2863 * equally across two DSI's. So the ROI programmed should be of equal width
2864 * for both the halves
2865 */
2866void MDPCompSrcSplit::generateROI(hwc_context_t *ctx,
2867 hwc_display_contents_1_t* list) {
2868 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2869
2870
2871 if(!canPartialUpdate(ctx, list))
2872 return;
2873
2874 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
2875 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
2876 (int)ctx->dpyAttr[mDpy].yres};
2877
2878 for(int index = 0; index < numAppLayers; index++ ) {
2879 hwc_layer_1_t* layer = &list->hwLayers[index];
2880
2881 // If we have a RGB layer which needs rotation, no partial update
2882 if(!isYuvBuffer((private_handle_t *)layer->handle) && layer->transform)
2883 return;
2884
2885 if ((mCachedFrame.hnd[index] != layer->handle) ||
2886 isYuvBuffer((private_handle_t *)layer->handle)) {
2887 hwc_rect_t dst = layer->displayFrame;
2888 hwc_rect_t updatingRect = dst;
2889
2890#ifdef QCOM_BSP
2891 if(!needsScaling(layer) && !layer->transform)
2892 {
2893 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
2894 int x_off = dst.left - src.left;
2895 int y_off = dst.top - src.top;
2896 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
2897 }
2898#endif
2899
2900 roi = getUnion(roi, updatingRect);
2901 }
2902 }
2903
2904 /* No layer is updating. Still SF wants a refresh.*/
2905 if(!isValidRect(roi))
2906 return;
2907
2908 roi = expandROIFromMidPoint(roi, fullFrame);
2909
2910 hwc_rect lFrame = fullFrame;
2911 lFrame.right /= 2;
2912 hwc_rect lRoi = getIntersection(roi, lFrame);
2913
2914 // Align ROI coordinates to panel restrictions
2915 lRoi = getSanitizeROI(lRoi, lFrame);
2916
2917 hwc_rect rFrame = fullFrame;
2918 rFrame.left = lFrame.right;
2919 hwc_rect rRoi = getIntersection(roi, rFrame);
2920
2921 // Align ROI coordinates to panel restrictions
2922 rRoi = getSanitizeROI(rRoi, rFrame);
2923
2924 roi = getUnion(lRoi, rRoi);
2925
2926 ctx->listStats[mDpy].lRoi = roi;
2927 if(!validateAndApplyROI(ctx, list))
2928 resetROI(ctx, mDpy);
2929
2930 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d] [%d, %d, %d, %d]",
2931 __FUNCTION__,
2932 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
2933 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
2934 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
2935 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
2936}
2937
Saurabh Shahab47c692014-02-12 18:45:57 -08002938bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002939 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002940 private_handle_t *hnd = (private_handle_t *)layer->handle;
2941 hwc_rect_t dst = layer->displayFrame;
2942 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2943 pipe_info.lIndex = ovutils::OV_INVALID;
2944 pipe_info.rIndex = ovutils::OV_INVALID;
2945
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002946 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy)
2947 trimAgainstROI(ctx,crop, dst);
2948
Saurabh Shahab47c692014-02-12 18:45:57 -08002949 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2950 //should have a higher priority than the right one. Pipe priorities are
2951 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002952
Saurabh Shahc62f3982014-03-05 14:28:26 -08002953 Overlay::PipeSpecs pipeSpecs;
2954 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2955 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2956 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2957 pipeSpecs.dpy = mDpy;
2958 pipeSpecs.fb = false;
2959
Saurabh Shahab47c692014-02-12 18:45:57 -08002960 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002961 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002962 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002963 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002964 }
2965
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002966 /* Use 2 pipes IF
2967 a) Layer's crop width is > 2048 or
2968 b) Layer's dest width > 2048 or
2969 c) On primary, driver has indicated with caps to split always. This is
2970 based on an empirically derived value of panel height. Applied only
2971 if the layer's width is > mixer's width
2972 */
2973
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302974 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002975 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302976 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002977 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2978 const uint32_t dstWidth = dst.right - dst.left;
2979 const uint32_t dstHeight = dst.bottom - dst.top;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002980 uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002981 crop.right - crop.left;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002982 uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
Saurabh Shah514759d2014-11-11 18:02:24 -08002983 crop.bottom - crop.top;
2984 //Approximation to actual clock, ignoring the common factors in pipe and
2985 //mixer cases like line_time
2986 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2987 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002988
Saurabh Shah05f4e222015-02-05 14:36:22 -08002989 const uint32_t downscale = getRotDownscale(ctx, layer);
2990 if(downscale) {
2991 cropWidth /= downscale;
2992 cropHeight /= downscale;
2993 }
2994
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002995 if(dstWidth > mdpHw.getMaxPipeWidth() or
2996 cropWidth > mdpHw.getMaxPipeWidth() or
Saurabh Shah514759d2014-11-11 18:02:24 -08002997 (primarySplitAlways and
2998 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002999 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08003000 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08003001 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08003002 }
3003
Jeykumar Sankaran89e23ab2015-01-28 15:57:46 -08003004 if(ctx->mOverlay->needsPrioritySwap(pipe_info.lIndex,
3005 pipe_info.rIndex)) {
Saurabh Shahdd8237a2014-02-28 14:29:09 -08003006 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08003007 }
3008 }
3009
3010 return true;
3011}
3012
Saurabh Shahab47c692014-02-12 18:45:57 -08003013int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
3014 PipeLayerPair& PipeLayerPair) {
3015 private_handle_t *hnd = (private_handle_t *)layer->handle;
3016 if(!hnd) {
3017 ALOGE("%s: layer handle is NULL", __FUNCTION__);
3018 return -1;
3019 }
3020 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
3021 MdpPipeInfoSplit& mdp_info =
3022 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
3023 Rotator **rot = &PipeLayerPair.rot;
3024 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08003025 eDest lDest = mdp_info.lIndex;
3026 eDest rDest = mdp_info.rIndex;
3027 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
3028 hwc_rect_t dst = layer->displayFrame;
3029 int transform = layer->transform;
3030 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08003031 int rotFlags = ROT_FLAGS_NONE;
Sushil Chauhan65e26302015-01-14 10:48:57 -08003032 uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
Saurabh Shahab47c692014-02-12 18:45:57 -08003033 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05003034 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahab47c692014-02-12 18:45:57 -08003035
3036 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
3037 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
3038
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08003039 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy) {
3040 /* MDP driver crops layer coordinates against ROI in Non-Split
3041 * and Split MDP comp. But HWC needs to crop them for source split.
3042 * Reason: 1) Source split is efficient only when the final effective
3043 * load is distributed evenly across mixers.
3044 * 2) We have to know the effective width of the layer that
3045 * the ROI needs to find the no. of pipes the layer needs.
3046 */
3047 trimAgainstROI(ctx, crop, dst);
3048 }
3049
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05003050 if(needs3DComposition(ctx, mDpy) &&
3051 get3DFormat(hnd) != HAL_NO_3D){
3052 return configure3DVideo(ctx, layer, mDpy, mdpFlags, z, lDest,
3053 rDest, &PipeLayerPair.rot);
3054 }
3055
Saurabh Shahab47c692014-02-12 18:45:57 -08003056 // Handle R/B swap
3057 if (layer->flags & HWC_FORMAT_RB_SWAP) {
3058 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
3059 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
3060 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
3061 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
3062 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07003063 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07003064 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
3065 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07003066 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07003067 /* Calculate the external display position based on MDP downscale,
3068 ActionSafe, and extorientation features. */
3069 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08003070
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07003071 int downscale = getRotDownscale(ctx, layer);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07003072 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08003073
3074 if(lDest != OV_INVALID && rDest != OV_INVALID) {
3075 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07003076 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08003077 }
3078
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07003079 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08003080 (*rot) = ctx->mRotMgr->getNext();
3081 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07003082 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07003083 //If the video is using a single pipe, enable BWC
3084 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08003085 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
3086 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07003087 }
Saurabh Shahab47c692014-02-12 18:45:57 -08003088 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07003089 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08003090 ALOGE("%s: configRotator failed!", __FUNCTION__);
3091 return -1;
3092 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07003093 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07003094 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08003095 }
3096
3097 //If 2 pipes being used, divide layer into half, crop and dst
3098 hwc_rect_t cropL = crop;
3099 hwc_rect_t cropR = crop;
3100 hwc_rect_t dstL = dst;
3101 hwc_rect_t dstR = dst;
3102 if(lDest != OV_INVALID && rDest != OV_INVALID) {
3103 cropL.right = (crop.right + crop.left) / 2;
3104 cropR.left = cropL.right;
3105 sanitizeSourceCrop(cropL, cropR, hnd);
3106
Saurabh Shahb729b192014-08-15 18:04:24 -07003107 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08003108 //Swap crops on H flip since 2 pipes are being used
3109 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
3110 hwc_rect_t tmp = cropL;
3111 cropL = cropR;
3112 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07003113 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08003114 }
3115
Saurabh Shahb729b192014-08-15 18:04:24 -07003116 //cropSwap trick: If the src and dst widths are both odd, let us say
3117 //2507, then splitting both into half would cause left width to be 1253
3118 //and right 1254. If crop is swapped because of H flip, this will cause
3119 //left crop width to be 1254, whereas left dst width remains 1253, thus
3120 //inducing a scaling that is unaccounted for. To overcome that we add 1
3121 //to the dst width if there is a cropSwap. So if the original width was
3122 //2507, the left dst width will be 1254. Even if the original width was
3123 //even for ex: 2508, the left dst width will still remain 1254.
3124 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08003125 dstR.left = dstL.right;
3126 }
3127
3128 //For the mdp, since either we are pre-rotating or MDP does flips
3129 orient = OVERLAY_TRANSFORM_0;
3130 transform = 0;
3131
3132 //configure left pipe
3133 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07003134 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08003135 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
3136 (ovutils::eBlending) getBlending(layer->blending));
3137
3138 if(configMdp(ctx->mOverlay, pargL, orient,
3139 cropL, dstL, metadata, lDest) < 0) {
3140 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
3141 return -1;
3142 }
3143 }
3144
3145 //configure right pipe
3146 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07003147 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08003148 static_cast<eRotFlags>(rotFlags),
3149 layer->planeAlpha,
3150 (ovutils::eBlending) getBlending(layer->blending));
3151 if(configMdp(ctx->mOverlay, pargR, orient,
3152 cropR, dstR, metadata, rDest) < 0) {
3153 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
3154 return -1;
3155 }
3156 }
3157
3158 return 0;
3159}
3160
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003161bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
3162 Locker::Autolock _l(ctx->mDrawLock);
3163 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
3164 char path[MAX_SYSFS_FILE_PATH];
3165 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
3166 int fd = open(path, O_RDONLY);
3167 if(fd < 0) {
3168 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
3169 return -1;
3170 }
3171 char value[4];
3172 ssize_t size_read = read(fd, value, sizeof(value)-1);
3173 if(size_read <= 0) {
3174 ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
3175 close(fd);
3176 return -1;
3177 }
3178 close(fd);
3179 value[size_read] = '\0';
3180 return atoi(value);
3181}
3182
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003183int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
3184 Locker::Autolock _l(ctx->mDrawLock);
3185 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
3186 char path[MAX_SYSFS_FILE_PATH];
3187 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
3188 int fd = open(path, O_WRONLY);
3189 if(fd < 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003190 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003191 return -1;
3192 }
3193 char value[4];
3194 snprintf(value, sizeof(value), "%d", (int)enable);
3195 ssize_t ret = write(fd, value, strlen(value));
3196 if(ret <= 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003197 ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003198 close(fd);
3199 return -1;
3200 }
3201 close(fd);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003202 return 0;
3203}
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08003204
3205bool MDPComp::loadPerfLib() {
3206 char perfLibPath[PROPERTY_VALUE_MAX] = {0};
3207 bool success = false;
3208 if((property_get("ro.vendor.extension_library", perfLibPath, NULL) <= 0)) {
3209 ALOGE("vendor library not set in ro.vendor.extension_library");
3210 return false;
3211 }
3212
3213 sLibPerfHint = dlopen(perfLibPath, RTLD_NOW);
3214 if(sLibPerfHint) {
3215 *(void **)&sPerfLockAcquire = dlsym(sLibPerfHint, "perf_lock_acq");
3216 *(void **)&sPerfLockRelease = dlsym(sLibPerfHint, "perf_lock_rel");
3217 if (!sPerfLockAcquire || !sPerfLockRelease) {
3218 ALOGE("Failed to load symbols for perfLock");
3219 dlclose(sLibPerfHint);
3220 sLibPerfHint = NULL;
3221 return false;
3222 }
3223 success = true;
3224 ALOGI("Successfully Loaded perf hint API's");
3225 } else {
3226 ALOGE("Failed to open %s : %s", perfLibPath, dlerror());
3227 }
3228 return success;
3229}
3230
3231void MDPComp::setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
3232 if ((sPerfHintWindow < 0) || mDpy || !sLibPerfHint) {
3233 return;
3234 }
3235 static int count = sPerfHintWindow;
3236 static int perflockFlag = 0;
3237
3238 /* Send hint to mpctl when single layer is updated
3239 * for a successful number of windows. Hint release
3240 * happens immediately upon multiple layer update.
3241 */
3242 if (onlyVideosUpdating(ctx, list)) {
3243 if(count) {
3244 count--;
3245 }
3246 } else {
3247 if (perflockFlag) {
3248 perflockFlag = 0;
3249 sPerfLockRelease(sPerfLockHandle);
3250 }
3251 count = sPerfHintWindow;
3252 }
3253 if (count == 0 && !perflockFlag) {
3254 int perfHint = 0x4501; // 45-display layer hint, 01-Enable
3255 sPerfLockHandle = sPerfLockAcquire(0 /*handle*/, 0/*duration*/,
3256 &perfHint, sizeof(perfHint)/sizeof(int));
Arun Kumar K.R8b927022015-02-24 12:34:21 -08003257 if(sPerfLockHandle > 0) {
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08003258 perflockFlag = 1;
3259 }
3260 }
3261}
3262
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003263}; //namespace
3264