blob: 5bd793157a4d3d6102b7689fee60a2ea9ae5b299 [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;
Saurabh Shah19740d02015-04-10 10:05:42 -0700534 } else if(ctx->mVideoTransFlag && isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700535 //1 Padding round to shift pipes across mixers
536 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
537 __FUNCTION__);
538 ret = false;
Raj Kamalc0d34242015-03-17 20:53:14 +0530539 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
540 qdutils::MDPVersion::getInstance().is8x16() ||
Prabhanjan Kandulafc541b32015-03-30 20:56:16 +0530541 qdutils::MDPVersion::getInstance().is8x39() ||
542 qdutils::MDPVersion::getInstance().is8x52()) &&
Raj Kamalc0d34242015-03-17 20:53:14 +0530543 !mDpy && isSecondaryAnimating(ctx) &&
544 isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL)) {
545 ALOGD_IF(isDebug(),"%s: Display animation in progress",
546 __FUNCTION__);
547 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700548 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
549 /* TODO: freeing up all the resources only for the targets having total
550 number of pipes < 8. Need to analyze number of VIG pipes used
551 for primary in previous draw cycle and accordingly decide
552 whether to fall back to full GPU comp or video only comp
553 */
554 if(isSecondaryConfiguring(ctx)) {
555 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
556 __FUNCTION__);
557 ret = false;
558 } else if(ctx->isPaddingRound) {
559 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
560 __FUNCTION__,mDpy);
561 ret = false;
562 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800563 } else if (ctx->isDMAStateChanging) {
564 // Bail out if a padding round has been invoked in order to switch DMA
565 // state to block mode. We need this to cater for the case when a layer
566 // requires rotation in the current frame.
567 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
568 __FUNCTION__);
569 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700570 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800571
Saurabh Shahaa236822013-04-24 18:07:26 -0700572 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800573}
574
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800575void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
576 hwc_rect &dst) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800577 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800578 dst = getIntersection(dst, roi);
579 crop = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800580}
581
582/* 1) Identify layers that are not visible or lying outside the updating ROI and
583 * drop them from composition.
584 * 2) If we have a scaling layer which needs cropping against generated
585 * ROI, reset ROI to full resolution. */
586bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
587 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700588 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800589 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800590
591 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800592 if(!isValidRect(visibleRect)) {
593 mCurrentFrame.drop[i] = true;
594 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800595 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800596 }
597
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700598 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700599 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800600 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700601
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700602 if(!isValidRect(res)) {
603 mCurrentFrame.drop[i] = true;
604 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800605 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700606 /* Reset frame ROI when any layer which needs scaling also needs ROI
607 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800608 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800609 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700610 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
611 mCurrentFrame.dropCount = 0;
612 return false;
613 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800614
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800615 /* deduct any opaque region from visibleRect */
radhakrishna4efbdd62014-11-03 13:19:27 +0530616 if (layer->blending == HWC_BLENDING_NONE &&
617 layer->planeAlpha == 0xFF)
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800618 visibleRect = deductRect(visibleRect, res);
619 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700620 }
621 return true;
622}
623
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800624/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
625 * are updating. If DirtyRegion is applicable, calculate it by accounting all
626 * the changing layer's dirtyRegion. */
627void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
628 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700629 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800630 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700631 return;
632
633 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800634 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
635 (int)ctx->dpyAttr[mDpy].yres};
636
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700637 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800638 hwc_layer_1_t* layer = &list->hwLayers[index];
639 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800640 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700641 hwc_rect_t dst = layer->displayFrame;
642 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800643
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800644#ifdef QCOM_BSP
Dileep Kumar Reddi7399d5c2014-12-31 18:01:19 +0530645 if(!needsScaling(layer) && !layer->transform &&
646 (!isYuvBuffer((private_handle_t *)layer->handle)))
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700647 {
648 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
649 int x_off = dst.left - src.left;
650 int y_off = dst.top - src.top;
651 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
652 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800653#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800654
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800655 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700656 }
657 }
658
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800659 /* No layer is updating. Still SF wants a refresh.*/
660 if(!isValidRect(roi))
661 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800662
663 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800664 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800665
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800666 ctx->listStats[mDpy].lRoi = roi;
667 if(!validateAndApplyROI(ctx, list))
668 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700669
670 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800671 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
672 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
673}
674
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800675void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
676 hwc_rect &dst) {
677 hwc_rect roi = getUnion(ctx->listStats[mDpy].lRoi,
678 ctx->listStats[mDpy].rRoi);
679 hwc_rect tmpDst = getIntersection(dst, roi);
680 if(!isSameRect(dst, tmpDst)) {
681 crop.left = crop.left + (tmpDst.left - dst.left);
682 crop.top = crop.top + (tmpDst.top - dst.top);
683 crop.right = crop.left + (tmpDst.right - tmpDst.left);
684 crop.bottom = crop.top + (tmpDst.bottom - tmpDst.top);
685 dst = tmpDst;
686 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800687}
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800688
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800689/* 1) Identify layers that are not visible or lying outside BOTH the updating
690 * ROI's and drop them from composition. If a layer is spanning across both
691 * the halves of the screen but needed by only ROI, the non-contributing
692 * half will not be programmed for MDP.
693 * 2) If we have a scaling layer which needs cropping against generated
694 * ROI, reset ROI to full resolution. */
695bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
696 hwc_display_contents_1_t* list) {
697
698 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
699
700 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
701 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
702
703 for(int i = numAppLayers - 1; i >= 0; i--){
704 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
705 {
706 mCurrentFrame.drop[i] = true;
707 mCurrentFrame.dropCount++;
708 continue;
709 }
710
711 const hwc_layer_1_t* layer = &list->hwLayers[i];
712 hwc_rect_t dstRect = layer->displayFrame;
713
714 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
715 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
716 hwc_rect_t res = getUnion(l_res, r_res);
717
718 if(!isValidRect(l_res) && !isValidRect(r_res)) {
719 mCurrentFrame.drop[i] = true;
720 mCurrentFrame.dropCount++;
721 } else {
722 /* Reset frame ROI when any layer which needs scaling also needs ROI
723 * cropping */
724 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
725 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
726 mCurrentFrame.dropCount = 0;
727 return false;
728 }
729
radhakrishna4efbdd62014-11-03 13:19:27 +0530730 if (layer->blending == HWC_BLENDING_NONE &&
731 layer->planeAlpha == 0xFF) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800732 visibleRectL = deductRect(visibleRectL, l_res);
733 visibleRectR = deductRect(visibleRectR, r_res);
734 }
735 }
736 }
737 return true;
738}
739/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
740 * are updating. If DirtyRegion is applicable, calculate it by accounting all
741 * the changing layer's dirtyRegion. */
742void MDPCompSplit::generateROI(hwc_context_t *ctx,
743 hwc_display_contents_1_t* list) {
744 if(!canPartialUpdate(ctx, list))
745 return;
746
747 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
748 int lSplit = getLeftSplit(ctx, mDpy);
749
750 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
751 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
752
753 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
754 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
755
756 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
757 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
758
759 for(int index = 0; index < numAppLayers; index++ ) {
760 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800761 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800762 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800763 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700764 hwc_rect_t dst = layer->displayFrame;
765 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800766
767#ifdef QCOM_BSP
768 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700769 {
770 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
771 int x_off = dst.left - src.left;
772 int y_off = dst.top - src.top;
773 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
774 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800775#endif
776
777 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
778 if(isValidRect(l_dst))
779 l_roi = getUnion(l_roi, l_dst);
780
781 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
782 if(isValidRect(r_dst))
783 r_roi = getUnion(r_roi, r_dst);
784 }
785 }
786
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700787 /* For panels that cannot accept commands in both the interfaces, we cannot
788 * send two ROI's (for each half). We merge them into single ROI and split
789 * them across lSplit for MDP mixer use. The ROI's will be merged again
790 * finally before udpating the panel in the driver. */
791 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
792 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
793 l_roi = getIntersection(temp_roi, l_frame);
794 r_roi = getIntersection(temp_roi, r_frame);
795 }
796
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800797 /* No layer is updating. Still SF wants a refresh. */
798 if(!isValidRect(l_roi) && !isValidRect(r_roi))
799 return;
800
801 l_roi = getSanitizeROI(l_roi, l_frame);
802 r_roi = getSanitizeROI(r_roi, r_frame);
803
804 ctx->listStats[mDpy].lRoi = l_roi;
805 ctx->listStats[mDpy].rRoi = r_roi;
806
807 if(!validateAndApplyROI(ctx, list))
808 resetROI(ctx, mDpy);
809
810 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
811 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
812 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
813 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
814 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
815 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700816}
817
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800818/* Checks for conditions where all the layers marked for MDP comp cannot be
819 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800820bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800821 hwc_display_contents_1_t* list){
822
Saurabh Shahaa236822013-04-24 18:07:26 -0700823 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800824
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700825 // Fall back to video only composition, if AIV video mode is enabled
826 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700827 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
828 __FUNCTION__, mDpy);
829 return false;
830 }
831
Praveena Pachipulusu47346c22014-12-04 11:06:41 +0530832 /* No Idle fall back if secure display or secure RGB layers are present
833 * or if there is only a single layer being composed */
834 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI &&
835 !ctx->listStats[mDpy].secureRGBCount &&
836 (ctx->listStats[mDpy].numAppLayers > 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700837 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
838 return false;
839 }
840
Raj Kamalc0d34242015-03-17 20:53:14 +0530841 if(!mDpy && isSecondaryAnimating(ctx) &&
842 (isYuvPresent(ctx,HWC_DISPLAY_EXTERNAL) ||
843 isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL)) ) {
844 ALOGD_IF(isDebug(),"%s: Display animation in progress",
845 __FUNCTION__);
846 return false;
847 }
848
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700849 // if secondary is configuring or Padding round, fall back to video only
850 // composition and release all assigned non VIG pipes from primary.
851 if(isSecondaryConfiguring(ctx)) {
852 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
853 __FUNCTION__);
854 return false;
855 } else if(ctx->isPaddingRound) {
856 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
857 __FUNCTION__,mDpy);
858 return false;
859 }
860
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -0500861 // No MDP composition for 3D
862 if(needs3DComposition(ctx, mDpy))
863 return false;
864
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700865 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800866 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700867 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800868 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
869 return false;
870 }
871
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800872 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800873 hwc_layer_1_t* layer = &list->hwLayers[i];
874 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800875
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800876 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700877 if(!canUseRotator(ctx, mDpy)) {
878 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
879 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700880 return false;
881 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800882 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530883
884 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
885 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800886 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700887 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530888 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
889 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
890 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800891 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700892
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700893 if(ctx->mAD->isDoable()) {
894 return false;
895 }
896
Saurabh Shahaa236822013-04-24 18:07:26 -0700897 //If all above hard conditions are met we can do full or partial MDP comp.
898 bool ret = false;
899 if(fullMDPComp(ctx, list)) {
900 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700901 } else if(fullMDPCompWithPTOR(ctx, list)) {
902 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700903 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700904 ret = true;
905 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530906
Saurabh Shahaa236822013-04-24 18:07:26 -0700907 return ret;
908}
909
910bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700911
912 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
913 return false;
914
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700915 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
916 for(int i = 0; i < numAppLayers; i++) {
917 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700918 if(not mCurrentFrame.drop[i] and
919 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700920 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
921 return false;
922 }
923 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800924
Raj Kamalb5f0b4a2015-04-08 15:10:37 +0530925 if(!mDpy && isSecondaryConnected(ctx) &&
926 (qdutils::MDPVersion::getInstance().is8x16() ||
927 qdutils::MDPVersion::getInstance().is8x26() ||
928 qdutils::MDPVersion::getInstance().is8x39()) &&
929 isYuvPresent(ctx, HWC_DISPLAY_VIRTUAL)) {
930 ALOGD_IF(isDebug(), "%s: YUV layer present on secondary", __FUNCTION__);
931 return false;
932 }
933
Saurabh Shahaa236822013-04-24 18:07:26 -0700934 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700935 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
936 sizeof(mCurrentFrame.isFBComposed));
937 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
938 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700939
Raj Kamal389d6e32014-08-04 14:43:24 +0530940 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800941 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530942 }
943
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800944 if(!postHeuristicsHandling(ctx, list)) {
945 ALOGD_IF(isDebug(), "post heuristic handling failed");
946 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700947 return false;
948 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700949 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
950 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700951 return true;
952}
953
Sushil Chauhandefd3522014-05-13 18:17:12 -0700954/* Full MDP Composition with Peripheral Tiny Overlap Removal.
955 * MDP bandwidth limitations can be avoided, if the overlap region
956 * covered by the smallest layer at a higher z-order, gets composed
957 * by Copybit on a render buffer, which can be queued to MDP.
958 */
959bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
960 hwc_display_contents_1_t* list) {
961
962 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R00b84792015-03-27 11:28:36 -0700963 // PTOR does not qualify when there are layers dropped, but if
964 // dropped layer is only a cursor, PTOR could qualify
965 const int numNonCursorLayers = numAppLayers - mCurrentFrame.dropCount;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700966 const int stagesForMDP = min(sMaxPipesPerMixer,
967 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
968
969 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700970 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700971 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
972 return false;
973 }
974
Arun Kumar K.R00b84792015-03-27 11:28:36 -0700975 // Frame level checks - consider PTOR in case of dropCount only if the cursor
976 // layer is dropped, otherwise bail out of PTOR
Sushil Chauhandefd3522014-05-13 18:17:12 -0700977 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
Arun Kumar K.R00b84792015-03-27 11:28:36 -0700978 isYuvPresent(ctx, mDpy) || isSecurePresent(ctx, mDpy) ||
979 (mCurrentFrame.dropCount - (int)isCursorPresent(ctx, mDpy))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700980 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
981 return false;
982 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700983 // MDP comp checks
984 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700985 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700986 if(not isSupportedForMDPComp(ctx, layer)) {
987 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
988 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700989 }
990 }
991
Raj Kamalb5f0b4a2015-04-08 15:10:37 +0530992 if(!mDpy && isSecondaryConnected(ctx) &&
993 (qdutils::MDPVersion::getInstance().is8x16() ||
994 qdutils::MDPVersion::getInstance().is8x26() ||
995 qdutils::MDPVersion::getInstance().is8x39()) &&
996 isYuvPresent(ctx, HWC_DISPLAY_VIRTUAL)) {
997 ALOGD_IF(isDebug(), "%s: YUV layer present on secondary", __FUNCTION__);
998 return false;
999 }
1000
Sushil Chauhandefd3522014-05-13 18:17:12 -07001001 /* We cannot use this composition mode, if:
1002 1. A below layer needs scaling.
1003 2. Overlap is not peripheral to display.
1004 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001005 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -07001006 */
1007
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001008 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
1009 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
1010 memset(overlapRect, 0, sizeof(overlapRect));
1011 int layerPixelCount, minPixelCount = 0;
1012 int numPTORLayersFound = 0;
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001013 for (int i = numNonCursorLayers - 1; (i >= 0 &&
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001014 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001015 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001016 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001017 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001018 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
1019 // PTOR layer should be peripheral and cannot have transform
1020 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
1021 has90Transform(layer)) {
1022 continue;
1023 }
1024 if((3 * (layerPixelCount + minPixelCount)) >
1025 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
1026 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
1027 continue;
1028 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001029 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001030 for (int j = i-1; j >= 0; j--) {
1031 // Check if the layers below this layer qualifies for PTOR comp
1032 hwc_layer_1_t* layer = &list->hwLayers[j];
1033 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001034 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001035 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001036 if (isValidRect(getIntersection(dispFrame, disFrame))) {
1037 if (has90Transform(layer) || needsScaling(layer)) {
1038 found = false;
1039 break;
1040 }
1041 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001042 }
1043 }
1044 // Store the minLayer Index
1045 if(found) {
1046 minLayerIndex[numPTORLayersFound] = i;
1047 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
1048 minPixelCount += layerPixelCount;
1049 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001050 }
1051 }
1052
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001053 // No overlap layers
1054 if (!numPTORLayersFound)
1055 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001056
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001057 // Store the displayFrame and the sourceCrops of the layers
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001058 hwc_rect_t displayFrame[numNonCursorLayers];
1059 hwc_rect_t sourceCrop[numNonCursorLayers];
1060 for(int i = 0; i < numNonCursorLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001061 hwc_layer_1_t* layer = &list->hwLayers[i];
1062 displayFrame[i] = layer->displayFrame;
1063 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001064 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001065
Prabhanjan Kandula9889a202014-09-04 21:50:35 +05301066 /**
1067 * It's possible that 2 PTOR layers might have overlapping.
1068 * In such case, remove the intersection(again if peripheral)
1069 * from the lower PTOR layer to avoid overlapping.
1070 * If intersection is not on peripheral then compromise
1071 * by reducing number of PTOR layers.
1072 **/
1073 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
1074 if(isValidRect(commonRect)) {
1075 overlapRect[1] = deductRect(overlapRect[1], commonRect);
1076 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
1077 }
1078
1079 ctx->mPtorInfo.count = numPTORLayersFound;
1080 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
1081 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
1082 }
1083
1084 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
1085 // reset PTOR
1086 ctx->mPtorInfo.count = 0;
1087 if(isValidRect(commonRect)) {
1088 // If PTORs are intersecting restore displayframe of PTOR[1]
1089 // before returning, as we have modified it above.
1090 list->hwLayers[minLayerIndex[1]].displayFrame =
1091 displayFrame[minLayerIndex[1]];
1092 }
1093 return false;
1094 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001095 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1096 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
1097
Xu Yangcda012c2014-07-30 21:57:21 +08001098 // Store the blending mode, planeAlpha, and transform of PTOR layers
1099 int32_t blending[numPTORLayersFound];
1100 uint8_t planeAlpha[numPTORLayersFound];
1101 uint32_t transform[numPTORLayersFound];
1102
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001103 for(int j = 0; j < numPTORLayersFound; j++) {
1104 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001105
1106 // Update src crop of PTOR layer
1107 hwc_layer_1_t* layer = &list->hwLayers[index];
1108 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1109 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1110 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1111 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1112
1113 // Store & update w, h, format of PTOR layer
1114 private_handle_t *hnd = (private_handle_t *)layer->handle;
1115 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1116 layerWhf[j] = whf;
1117 hnd->width = renderBuf->width;
1118 hnd->height = renderBuf->height;
1119 hnd->format = renderBuf->format;
1120
Xu Yangcda012c2014-07-30 21:57:21 +08001121 // Store & update blending mode, planeAlpha and transform of PTOR layer
1122 blending[j] = layer->blending;
1123 planeAlpha[j] = layer->planeAlpha;
1124 transform[j] = layer->transform;
1125 layer->blending = HWC_BLENDING_NONE;
1126 layer->planeAlpha = 0xFF;
1127 layer->transform = 0;
1128
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001129 // Remove overlap from crop & displayFrame of below layers
1130 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001131 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001132 if(!isValidRect(getIntersection(layer->displayFrame,
1133 overlapRect[j]))) {
1134 continue;
1135 }
1136 // Update layer attributes
1137 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1138 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301139 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001140 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1141 layer->transform);
1142 layer->sourceCropf.left = (float)srcCrop.left;
1143 layer->sourceCropf.top = (float)srcCrop.top;
1144 layer->sourceCropf.right = (float)srcCrop.right;
1145 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1146 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001147 }
1148
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001149 mCurrentFrame.mdpCount = numNonCursorLayers;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001150 mCurrentFrame.fbCount = 0;
1151 mCurrentFrame.fbZ = -1;
1152
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001153 for (int j = 0; j < numNonCursorLayers; j++) {
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301154 if(isValidRect(list->hwLayers[j].displayFrame)) {
1155 mCurrentFrame.isFBComposed[j] = false;
1156 } else {
1157 mCurrentFrame.mdpCount--;
1158 mCurrentFrame.drop[j] = true;
1159 }
1160 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001161
1162 bool result = postHeuristicsHandling(ctx, list);
1163
1164 // Restore layer attributes
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001165 for(int i = 0; i < numNonCursorLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001166 hwc_layer_1_t* layer = &list->hwLayers[i];
1167 layer->displayFrame = displayFrame[i];
1168 layer->sourceCropf.left = (float)sourceCrop[i].left;
1169 layer->sourceCropf.top = (float)sourceCrop[i].top;
1170 layer->sourceCropf.right = (float)sourceCrop[i].right;
1171 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1172 }
1173
Xu Yangcda012c2014-07-30 21:57:21 +08001174 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001175 for (int i = 0; i < numPTORLayersFound; i++) {
1176 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001177 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001178 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1179 hnd->width = layerWhf[i].w;
1180 hnd->height = layerWhf[i].h;
1181 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001182 layer->blending = blending[i];
1183 layer->planeAlpha = planeAlpha[i];
1184 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001185 }
1186
Sushil Chauhandefd3522014-05-13 18:17:12 -07001187 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001188 // reset PTOR
1189 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001190 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001191 } else {
1192 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1193 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001194 }
1195
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001196 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1197 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001198 return result;
1199}
1200
Saurabh Shahaa236822013-04-24 18:07:26 -07001201bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1202{
radhakrishnac3198ff2015-03-10 17:10:02 +05301203 if(!sEnableMixedMode || !isAlphaPresentinFB(ctx, mDpy)) {
1204 //Mixed mode is disabled/can't be used. No need to even try caching.
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001205 return false;
1206 }
1207
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001208 bool ret = false;
Raj Kamal1179d9c2014-10-28 15:31:35 +05301209 if(isSkipPresent(ctx, mDpy) or list->flags & HWC_GEOMETRY_CHANGED) {
1210 //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001211 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001212 cacheBasedComp(ctx, list);
1213 } else {
1214 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001215 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001216 }
1217
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001218 return ret;
1219}
1220
1221bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1222 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001223 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1224 return false;
1225
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001226 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001227 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001228 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001229
1230 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1231 for(int i = 0; i < numAppLayers; i++) {
1232 if(!mCurrentFrame.isFBComposed[i]) {
1233 hwc_layer_1_t* layer = &list->hwLayers[i];
1234 if(not isSupportedForMDPComp(ctx, layer)) {
1235 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1236 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001237 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001238 return false;
1239 }
1240 }
1241 }
1242
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001243 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001244 /* mark secure RGB layers for MDP comp */
1245 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301246 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001247 if(!ret) {
1248 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001249 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001250 return false;
1251 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001252
1253 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001254
Raj Kamal389d6e32014-08-04 14:43:24 +05301255 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001256 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301257 }
1258
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001259 if(!postHeuristicsHandling(ctx, list)) {
1260 ALOGD_IF(isDebug(), "post heuristic handling failed");
1261 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001262 return false;
1263 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001264 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1265 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001266
Saurabh Shahaa236822013-04-24 18:07:26 -07001267 return true;
1268}
1269
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001270bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001271 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001272 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1273 return false;
1274
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001275 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001276 return false;
1277 }
1278
Saurabh Shahb772ae32013-11-18 15:40:02 -08001279 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001280 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1281 const int stagesForMDP = min(sMaxPipesPerMixer,
1282 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001283
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001284 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1285 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1286 int lastMDPSupportedIndex = numAppLayers;
1287 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001288
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001289 //Find the minimum MDP batch size
1290 for(int i = 0; i < numAppLayers;i++) {
1291 if(mCurrentFrame.drop[i]) {
1292 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001293 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001294 }
1295 hwc_layer_1_t* layer = &list->hwLayers[i];
1296 if(not isSupportedForMDPComp(ctx, layer)) {
1297 lastMDPSupportedIndex = i;
1298 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1299 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001300 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001301 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001302 }
1303
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001304 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1305 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1306 mCurrentFrame.dropCount);
1307
1308 //Start at a point where the fb batch should at least have 2 layers, for
1309 //this mode to be justified.
1310 while(fbBatchSize < 2) {
1311 ++fbBatchSize;
1312 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001313 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001314
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001315 //If there are no layers for MDP, this mode doesnt make sense.
1316 if(mdpBatchSize < 1) {
1317 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1318 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001319 return false;
1320 }
1321
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001322 mCurrentFrame.reset(numAppLayers);
1323
1324 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1325 while(mdpBatchSize > 0) {
1326 //Mark layers for MDP comp
1327 int mdpBatchLeft = mdpBatchSize;
1328 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1329 if(mCurrentFrame.drop[i]) {
1330 continue;
1331 }
1332 mCurrentFrame.isFBComposed[i] = false;
1333 --mdpBatchLeft;
1334 }
1335
1336 mCurrentFrame.fbZ = mdpBatchSize;
1337 mCurrentFrame.fbCount = fbBatchSize;
1338 mCurrentFrame.mdpCount = mdpBatchSize;
1339
1340 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1341 __FUNCTION__, mdpBatchSize, fbBatchSize,
1342 mCurrentFrame.dropCount);
1343
1344 if(postHeuristicsHandling(ctx, list)) {
1345 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001346 __FUNCTION__);
1347 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1348 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001349 return true;
1350 }
1351
1352 reset(ctx);
1353 --mdpBatchSize;
1354 ++fbBatchSize;
1355 }
1356
1357 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001358}
1359
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001360bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301361 if(mDpy or isSecurePresent(ctx, mDpy) or
1362 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001363 return false;
1364 }
1365 return true;
1366}
1367
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001368bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1369 hwc_display_contents_1_t* list){
1370 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1371 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001372 isCursorPresent(ctx, mDpy) || !sIsPartialUpdateActive || mDpy) {
1373 // On Async position update, the ROI becomes invalid, hence disable PU
1374 // when cursor is present
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001375 return false;
1376 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001377 if(ctx->listStats[mDpy].secureUI)
1378 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001379 return true;
1380}
1381
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001382bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1383 hwc_display_contents_1_t* list) {
1384 const bool secureOnly = true;
1385 return videoOnlyComp(ctx, list, not secureOnly) or
1386 videoOnlyComp(ctx, list, secureOnly);
1387}
1388
1389bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001390 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001391 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1392 return false;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301393
Saurabh Shahaa236822013-04-24 18:07:26 -07001394 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301395 if(!isSecurePresent(ctx, mDpy)) {
1396 /* Bail out if we are processing only secured video layers
1397 * and we dont have any */
1398 if(secureOnly) {
1399 ALOGD_IF(isDebug(),"%s: No Secure Video Layers", __FUNCTION__);
1400 return false;
1401 }
1402 /* No Idle fall back for secure video layers and if there is only
1403 * single layer being composed. */
1404 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1405 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1406 return false;
1407 }
1408 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001409
Saurabh Shahaa236822013-04-24 18:07:26 -07001410 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001411 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001412 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001413 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001414
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001415 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1416 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001417 return false;
1418 }
1419
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001420 if(mCurrentFrame.fbCount)
1421 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001422
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001423 if(sEnableYUVsplit || needs3DComposition(ctx, mDpy)){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001424 adjustForSourceSplit(ctx, list);
1425 }
1426
1427 if(!postHeuristicsHandling(ctx, list)) {
1428 ALOGD_IF(isDebug(), "post heuristic handling failed");
Justin Philip37ab9a82015-01-06 11:55:12 +05301429 if(errno == ENOBUFS) {
1430 ALOGD_IF(isDebug(), "SMP Allocation failed");
1431 //On SMP allocation failure in video only comp add padding round
1432 ctx->isPaddingRound = true;
1433 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001434 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001435 return false;
1436 }
1437
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001438 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1439 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001440 return true;
1441}
1442
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001443/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1444bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1445 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001446 // Fall back to video only composition, if AIV video mode is enabled
1447 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001448 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1449 __FUNCTION__, mDpy);
1450 return false;
1451 }
1452
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001453 // No MDP composition for 3D
1454 if(needs3DComposition(ctx,mDpy))
1455 return false;
1456
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001457 const bool secureOnly = true;
1458 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1459 mdpOnlyLayersComp(ctx, list, secureOnly);
1460
1461}
1462
1463bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1464 hwc_display_contents_1_t* list, bool secureOnly) {
1465
1466 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1467 return false;
1468
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301469 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1470 if(!isSecurePresent(ctx, mDpy) && !ctx->listStats[mDpy].secureUI) {
1471 /* Bail out if we are processing only secured video/ui layers
1472 * and we dont have any */
1473 if(secureOnly) {
1474 ALOGD_IF(isDebug(), "%s: No secure video/ui layers");
1475 return false;
1476 }
1477 /* No Idle fall back for secure video/ui layers and if there is only
1478 * single layer being composed. */
1479 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1480 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1481 return false;
1482 }
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001483 }
1484
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08001485 /* Bail out if we dont have any secure RGB layers */
1486 if (!ctx->listStats[mDpy].secureRGBCount) {
1487 reset(ctx);
1488 return false;
1489 }
1490
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001491 mCurrentFrame.reset(numAppLayers);
1492 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1493
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001494 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001495 /* mark secure RGB layers for MDP comp */
1496 updateSecureRGB(ctx, list);
1497
1498 if(mCurrentFrame.mdpCount == 0) {
1499 reset(ctx);
1500 return false;
1501 }
1502
1503 /* find the maximum batch of layers to be marked for framebuffer */
1504 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1505 if(!ret) {
1506 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1507 reset(ctx);
1508 return false;
1509 }
1510
1511 if(sEnableYUVsplit){
1512 adjustForSourceSplit(ctx, list);
1513 }
1514
1515 if(!postHeuristicsHandling(ctx, list)) {
1516 ALOGD_IF(isDebug(), "post heuristic handling failed");
1517 reset(ctx);
1518 return false;
1519 }
1520
1521 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1522 __FUNCTION__);
1523 return true;
1524}
1525
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001526/* Checks for conditions where YUV layers cannot be bypassed */
1527bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001528 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001529 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001530 return false;
1531 }
1532
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001533 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001534 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1535 return false;
1536 }
1537
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001538 if(isSecuring(ctx, layer)) {
1539 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1540 return false;
1541 }
1542
Saurabh Shah4fdde762013-04-30 18:47:33 -07001543 if(!isValidDimension(ctx, layer)) {
1544 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1545 __FUNCTION__);
1546 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001547 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001548
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001549 if(layer->planeAlpha < 0xFF) {
1550 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1551 in video only mode",
1552 __FUNCTION__);
1553 return false;
1554 }
1555
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001556 return true;
1557}
1558
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001559/* Checks for conditions where Secure RGB layers cannot be bypassed */
1560bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1561 if(isSkipLayer(layer)) {
1562 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1563 __FUNCTION__, mDpy);
1564 return false;
1565 }
1566
1567 if(isSecuring(ctx, layer)) {
1568 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1569 return false;
1570 }
1571
1572 if(not isSupportedForMDPComp(ctx, layer)) {
1573 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1574 __FUNCTION__);
1575 return false;
1576 }
1577 return true;
1578}
1579
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301580/* starts at fromIndex and check for each layer to find
1581 * if it it has overlapping with any Updating layer above it in zorder
1582 * till the end of the batch. returns true if it finds any intersection */
1583bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1584 int fromIndex, int toIndex) {
1585 for(int i = fromIndex; i < toIndex; i++) {
1586 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1587 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1588 return false;
1589 }
1590 }
1591 }
1592 return true;
1593}
1594
1595/* Checks if given layer at targetLayerIndex has any
1596 * intersection with all the updating layers in beween
1597 * fromIndex and toIndex. Returns true if it finds intersectiion */
1598bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1599 int fromIndex, int toIndex, int targetLayerIndex) {
1600 for(int i = fromIndex; i <= toIndex; i++) {
1601 if(!mCurrentFrame.isFBComposed[i]) {
1602 if(areLayersIntersecting(&list->hwLayers[i],
1603 &list->hwLayers[targetLayerIndex])) {
1604 return true;
1605 }
1606 }
1607 }
1608 return false;
1609}
1610
1611int MDPComp::getBatch(hwc_display_contents_1_t* list,
1612 int& maxBatchStart, int& maxBatchEnd,
1613 int& maxBatchCount) {
1614 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301615 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001616 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301617 while (i < mCurrentFrame.layerCount) {
1618 int batchCount = 0;
1619 int batchStart = i;
1620 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001621 /* Adjust batch Z order with the dropped layers so far */
1622 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301623 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301624 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301625 while(i < mCurrentFrame.layerCount) {
1626 if(!mCurrentFrame.isFBComposed[i]) {
1627 if(!batchCount) {
1628 i++;
1629 break;
1630 }
1631 updatingLayersAbove++;
1632 i++;
1633 continue;
1634 } else {
1635 if(mCurrentFrame.drop[i]) {
1636 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001637 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301638 continue;
1639 } else if(updatingLayersAbove <= 0) {
1640 batchCount++;
1641 batchEnd = i;
1642 i++;
1643 continue;
1644 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1645
1646 // We have a valid updating layer already. If layer-i not
1647 // have overlapping with all updating layers in between
1648 // batch-start and i, then we can add layer i to batch.
1649 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1650 batchCount++;
1651 batchEnd = i;
1652 i++;
1653 continue;
1654 } else if(canPushBatchToTop(list, batchStart, i)) {
1655 //If All the non-updating layers with in this batch
1656 //does not have intersection with the updating layers
1657 //above in z-order, then we can safely move the batch to
1658 //higher z-order. Increment fbZ as it is moving up.
1659 if( firstZReverseIndex < 0) {
1660 firstZReverseIndex = i;
1661 }
1662 batchCount++;
1663 batchEnd = i;
1664 fbZ += updatingLayersAbove;
1665 i++;
1666 updatingLayersAbove = 0;
1667 continue;
1668 } else {
1669 //both failed.start the loop again from here.
1670 if(firstZReverseIndex >= 0) {
1671 i = firstZReverseIndex;
1672 }
1673 break;
1674 }
1675 }
1676 }
1677 }
1678 if(batchCount > maxBatchCount) {
1679 maxBatchCount = batchCount;
1680 maxBatchStart = batchStart;
1681 maxBatchEnd = batchEnd;
1682 fbZOrder = fbZ;
1683 }
1684 }
1685 return fbZOrder;
1686}
1687
1688bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1689 hwc_display_contents_1_t* list) {
1690 /* Idea is to keep as many non-updating(cached) layers in FB and
1691 * send rest of them through MDP. This is done in 2 steps.
1692 * 1. Find the maximum contiguous batch of non-updating layers.
1693 * 2. See if we can improve this batch size for caching by adding
1694 * opaque layers around the batch, if they don't have
1695 * any overlapping with the updating layers in between.
1696 * NEVER mark an updating layer for caching.
1697 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001698
1699 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001700 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001701 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301702 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001703
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001704 /* Nothing is cached. No batching needed */
1705 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001706 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001707 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001708
1709 /* No MDP comp layers, try to use other comp modes */
1710 if(mCurrentFrame.mdpCount == 0) {
1711 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001712 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001713
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301714 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001715
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301716 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001717 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001718 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001719 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301720 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001721 if(!mCurrentFrame.drop[i]){
1722 //If an unsupported layer is being attempted to
1723 //be pulled out we should fail
1724 if(not isSupportedForMDPComp(ctx, layer)) {
1725 return false;
1726 }
1727 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001728 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001729 }
1730 }
1731
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301732 // update the frame data
1733 mCurrentFrame.fbZ = fbZ;
1734 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001735 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001736 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001737
1738 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301739 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001740
1741 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001742}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001743
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001744void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001745 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001746 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001747 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001748
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001749 for(int i = 0; i < numAppLayers; i++) {
1750 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001751 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001752 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001753 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001754 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001755 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001756 }
1757 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001758
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001759 frame.fbCount = fbCount;
1760 frame.mdpCount = frame.layerCount - frame.fbCount
1761 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001762
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001763 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1764 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001765}
1766
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001767// drop other non-AIV layers from external display list.
1768void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001769 hwc_display_contents_1_t* list) {
1770 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1771 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001772 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001773 mCurrentFrame.dropCount++;
1774 mCurrentFrame.drop[i] = true;
1775 }
1776 }
1777 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1778 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1779 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1780 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1781 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1782 mCurrentFrame.dropCount);
1783}
1784
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001785void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001786 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001787 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1788 for(int index = 0;index < nYuvCount; index++){
1789 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1790 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1791
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001792 if(mCurrentFrame.drop[nYuvIndex]) {
1793 continue;
1794 }
1795
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001796 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001797 if(!frame.isFBComposed[nYuvIndex]) {
1798 frame.isFBComposed[nYuvIndex] = true;
1799 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001800 }
1801 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001802 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001803 private_handle_t *hnd = (private_handle_t *)layer->handle;
1804 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001805 frame.isFBComposed[nYuvIndex] = false;
1806 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001807 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001808 }
1809 }
1810 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001811
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001812 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1813 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001814}
1815
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001816void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1817 hwc_display_contents_1_t* list) {
1818 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1819 for(int index = 0;index < nSecureRGBCount; index++){
1820 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1821 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1822
1823 if(!isSecureRGBDoable(ctx, layer)) {
1824 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1825 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1826 mCurrentFrame.fbCount++;
1827 }
1828 } else {
1829 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1830 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1831 mCurrentFrame.fbCount--;
1832 }
1833 }
1834 }
1835
1836 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1837 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1838 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1839 mCurrentFrame.fbCount);
1840}
1841
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001842hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1843 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001844 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001845
1846 /* Update only the region of FB needed for composition */
1847 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1848 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1849 hwc_layer_1_t* layer = &list->hwLayers[i];
1850 hwc_rect_t dst = layer->displayFrame;
1851 fbRect = getUnion(fbRect, dst);
1852 }
1853 }
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08001854 trimAgainstROI(ctx, fbRect, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001855 return fbRect;
1856}
1857
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001858bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1859 hwc_display_contents_1_t* list) {
1860
1861 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001862 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001863 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1864 return false;
1865 }
1866
1867 //Limitations checks
1868 if(!hwLimitationsCheck(ctx, list)) {
1869 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1870 return false;
1871 }
1872
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001873 //Configure framebuffer first if applicable
1874 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001875 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001876 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1877 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001878 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1879 __FUNCTION__);
1880 return false;
1881 }
1882 }
1883
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001884 mCurrentFrame.map();
1885
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001886 if(!allocLayerPipes(ctx, list)) {
1887 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001888 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001889 }
1890
1891 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001892 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001893 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001894 int mdpIndex = mCurrentFrame.layerToMDP[index];
1895 hwc_layer_1_t* layer = &list->hwLayers[index];
1896
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301897 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1898 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1899 mdpNextZOrder++;
1900 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001901 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1902 cur_pipe->zOrder = mdpNextZOrder++;
1903
radhakrishnac9a67412013-09-25 17:40:42 +05301904 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301905 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301906 if(configure4k2kYuv(ctx, layer,
1907 mCurrentFrame.mdpToLayer[mdpIndex])
1908 != 0 ){
1909 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1910 for layer %d",__FUNCTION__, index);
1911 return false;
1912 }
1913 else{
1914 mdpNextZOrder++;
1915 }
1916 continue;
1917 }
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001918 if(needs3DComposition(ctx,mDpy) && get3DFormat(hnd) != HAL_NO_3D) {
1919 mdpNextZOrder++;
1920 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001921 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1922 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301923 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001924 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001925 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001926 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001927 }
1928
Saurabh Shaha36be922013-12-16 18:18:39 -08001929 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1930 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1931 ,__FUNCTION__, mDpy);
1932 return false;
1933 }
1934
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001935 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001936 return true;
1937}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001938
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001939bool MDPComp::resourceCheck(hwc_context_t* ctx,
1940 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001941 const bool fbUsed = mCurrentFrame.fbCount;
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001942 int cursorInUse = 0;
1943 if(mDpy == HWC_DISPLAY_PRIMARY) {
1944 // check if cursor is in use for primary
1945 cursorInUse = HWCursor::getInstance()->isCursorSet();
1946 }
1947 int maxStages = qdutils::MDPVersion::getInstance().getBlendStages();
1948 // HW Cursor needs one blending stage, account for that in the check below
1949 // On high end targets(8994) has 8 blending stages, HAL is configured to use < 8.
1950 // Make use of the remaining stages for HW Cursor so that the composition
1951 // strategy would not fail due to this limitation.
1952 if (maxStages > sMaxPipesPerMixer) {
1953 cursorInUse = 0;
1954 }
1955 if(mCurrentFrame.mdpCount > (sMaxPipesPerMixer - fbUsed - cursorInUse)) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001956 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1957 return false;
1958 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001959
1960 //Will benefit cases where a video has non-updating background.
1961 if((mDpy > HWC_DISPLAY_PRIMARY) and
1962 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1963 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1964 return false;
1965 }
1966
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001967 // Init rotCount to number of rotate sessions used by other displays
1968 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1969 // Count the number of rotator sessions required for current display
1970 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1971 if(!mCurrentFrame.isFBComposed[index]) {
1972 hwc_layer_1_t* layer = &list->hwLayers[index];
1973 private_handle_t *hnd = (private_handle_t *)layer->handle;
1974 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1975 rotCount++;
1976 }
1977 }
1978 }
1979 // if number of layers to rotate exceeds max rotator sessions, bail out.
1980 if(rotCount > RotMgr::MAX_ROT_SESS) {
1981 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1982 __FUNCTION__, mDpy);
1983 return false;
1984 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001985 return true;
1986}
1987
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301988bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1989 hwc_display_contents_1_t* list) {
1990
1991 //A-family hw limitation:
1992 //If a layer need alpha scaling, MDP can not support.
1993 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1994 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1995 if(!mCurrentFrame.isFBComposed[i] &&
1996 isAlphaScaled( &list->hwLayers[i])) {
1997 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1998 return false;
1999 }
2000 }
2001 }
2002
2003 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
2004 //If multiple layers requires downscaling and also they are overlapping
2005 //fall back to GPU since MDSS can not handle it.
2006 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
2007 qdutils::MDPVersion::getInstance().is8x26()) {
2008 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
2009 hwc_layer_1_t* botLayer = &list->hwLayers[i];
2010 if(!mCurrentFrame.isFBComposed[i] &&
2011 isDownscaleRequired(botLayer)) {
2012 //if layer-i is marked for MDP and needs downscaling
2013 //check if any MDP layer on top of i & overlaps with layer-i
2014 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
2015 hwc_layer_1_t* topLayer = &list->hwLayers[j];
2016 if(!mCurrentFrame.isFBComposed[j] &&
2017 isDownscaleRequired(topLayer)) {
2018 hwc_rect_t r = getIntersection(botLayer->displayFrame,
2019 topLayer->displayFrame);
2020 if(isValidRect(r))
2021 return false;
2022 }
2023 }
2024 }
2025 }
2026 }
2027 return true;
2028}
2029
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002030static bool validForCursor(hwc_context_t* ctx, int dpy, hwc_layer_1_t* layer) {
2031 private_handle_t *hnd = (private_handle_t *)layer->handle;
2032 hwc_rect dst = layer->displayFrame;
2033 hwc_rect src = integerizeSourceCrop(layer->sourceCropf);
2034 int srcW = src.right - src.left;
2035 int srcH = src.bottom - src.top;
2036 int dstW = dst.right - dst.left;
2037 int dstH = dst.bottom - dst.top;
2038 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
2039 uint32_t maxCursorSize = mdpVersion.getMaxCursorSize();
2040 uint32_t numHwCursors = mdpVersion.getCursorPipes();
2041 bool primarySplit = isDisplaySplit(ctx, HWC_DISPLAY_PRIMARY);
2042 uint32_t cursorPipesNeeded = 1; // One cursor pipe needed(default)
2043 bool ret = false;
2044
2045 if(dpy > HWC_DISPLAY_PRIMARY) {
2046 // Cursor not supported on secondary displays, as it involves scaling
2047 // in most of the cases
2048 return false;
2049 } else if (isSkipLayer(layer)) {
2050 return false;
2051 // Checks for HW limitation
2052 } else if (numHwCursors == 0 || maxCursorSize <= 0) {
2053 return false;
2054 } else if (needsScaling(layer)) {
2055 return false;
2056 } else if (layer->transform != 0) {
2057 return false;
2058 } else if (hnd->format != HAL_PIXEL_FORMAT_RGBA_8888) {
2059 return false;
2060 } else if (srcW > (int)maxCursorSize || srcH > (int)maxCursorSize) {
2061 return false;
2062 }
2063
2064 if (isDisplaySplit(ctx, dpy) && !mdpVersion.isSrcSplit()) {
2065 // In case of split display with no srcSplit, the driver allocates two
2066 // pipes to support async position update across mixers, hence
2067 // need to account for that here.
2068 cursorPipesNeeded = 2;
2069 }
2070 if (cursorPipesNeeded <= numHwCursors) {
2071 ret = true;
2072 }
2073 return ret;
2074}
2075
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002076// Checks only if videos or single layer(RGB) is updating
2077// which is used for setting dynamic fps or perf hint for single
2078// layer video playback
2079bool MDPComp::onlyVideosUpdating(hwc_context_t *ctx,
2080 hwc_display_contents_1_t* list) {
2081 bool support = false;
2082 FrameInfo frame;
2083 frame.reset(mCurrentFrame.layerCount);
2084 memset(&frame.drop, 0, sizeof(frame.drop));
2085 frame.dropCount = 0;
2086 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo", __FUNCTION__);
2087 updateLayerCache(ctx, list, frame);
2088 updateYUV(ctx, list, false /*secure only*/, frame);
2089 // There are only updating YUV layers or there is single RGB
2090 // Layer(Youtube)
2091 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
2092 (frame.layerCount == 1)) {
2093 support = true;
2094 }
2095 return support;
2096}
2097
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302098void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2099 //For primary display, set the dynamic refreshrate
2100 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
2101 ctx->mUseMetaDataRefreshRate) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302102 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
2103 MDPVersion& mdpHw = MDPVersion::getInstance();
2104 if(sIdleFallBack) {
2105 //Set minimum panel refresh rate during idle timeout
2106 refreshRate = mdpHw.getMinFpsSupported();
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002107 } else if(onlyVideosUpdating(ctx, list)) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302108 //Set the new fresh rate, if there is only one updating YUV layer
2109 //or there is one single RGB layer with this request
2110 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
2111 }
2112 setRefreshRate(ctx, mDpy, refreshRate);
2113 }
2114}
2115
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002116int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002117 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07002118 char property[PROPERTY_VALUE_MAX];
2119
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002120 if(!list) {
2121 ALOGE("%s: Invalid list", __FUNCTION__);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302122 mCachedFrame.reset();
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002123 freeHwCursor(ctx->dpyAttr[mDpy].fd, mDpy);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302124 return -1;
2125 }
2126
2127 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07002128 if(mDpy == HWC_DISPLAY_PRIMARY) {
2129 sSimulationFlags = 0;
2130 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
2131 int currentFlags = atoi(property);
2132 if(currentFlags != sSimulationFlags) {
2133 sSimulationFlags = currentFlags;
2134 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
2135 sSimulationFlags, sSimulationFlags);
2136 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07002137 }
2138 }
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07002139
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302140 //reset old data
2141 mCurrentFrame.reset(numLayers);
2142 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2143 mCurrentFrame.dropCount = 0;
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002144 mCurrentFrame.hwCursorIndex = -1;
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302145
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05302146 //Do not cache the information for next draw cycle.
2147 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
2148 ALOGI("%s: Unsupported layer count for mdp composition",
2149 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002150 mCachedFrame.reset();
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302151#ifdef DYNAMIC_FPS
2152 setDynRefreshRate(ctx, list);
2153#endif
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002154 freeHwCursor(ctx->dpyAttr[mDpy].fd, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002155 return -1;
2156 }
2157
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002158 // Detect the start of animation and fall back to GPU only once to cache
2159 // all the layers in FB and display FB content untill animation completes.
2160 if(ctx->listStats[mDpy].isDisplayAnimating) {
2161 mCurrentFrame.needsRedraw = false;
2162 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
2163 mCurrentFrame.needsRedraw = true;
2164 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
2165 }
2166 setMDPCompLayerFlags(ctx, list);
2167 mCachedFrame.updateCounts(mCurrentFrame);
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302168#ifdef DYNAMIC_FPS
2169 setDynRefreshRate(ctx, list);
2170#endif
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002171 freeHwCursor(ctx->dpyAttr[mDpy].fd, mDpy);
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002172 ret = -1;
2173 return ret;
2174 } else {
2175 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
2176 }
2177
Raj Kamalfdfdddf2015-03-16 21:59:25 +05302178 if(!mDpy and !isSecondaryConnected(ctx) and !mPrevModeOn and
2179 mCachedFrame.isSameFrame(ctx,mDpy,list)) {
2180
2181 ALOGD_IF(isDebug(),"%s: Avoid new composition",__FUNCTION__);
2182 mCurrentFrame.needsRedraw = false;
2183 setMDPCompLayerFlags(ctx, list);
2184 mCachedFrame.updateCounts(mCurrentFrame);
2185#ifdef DYNAMIC_FPS
2186 setDynRefreshRate(ctx, list);
2187#endif
2188 return -1;
2189
2190 }
2191
Saurabh Shahb39f8152013-08-22 10:21:44 -07002192 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002193 if(isFrameDoable(ctx)) {
2194 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002195 // if AIV Video mode is enabled, drop all non AIV layers from the
2196 // external display list.
2197 if(ctx->listStats[mDpy].mAIVVideoMode) {
2198 dropNonAIVLayers(ctx, list);
2199 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002200
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002201 // Configure the cursor if present
2202 int topIndex = ctx->listStats[mDpy].numAppLayers - 1;
2203 if(ctx->listStats[mDpy].cursorLayerPresent &&
2204 validForCursor(ctx, mDpy, &(list->hwLayers[topIndex]))) {
2205 if(configHwCursor(ctx->dpyAttr[mDpy].fd, mDpy,
2206 &(list->hwLayers[topIndex]))) {
2207 // As cursor is configured, mark that layer as dropped, so that
2208 // it wont be considered for composition by other strategies.
2209 mCurrentFrame.hwCursorIndex = topIndex;
2210 mCurrentFrame.drop[topIndex] = true;
2211 mCurrentFrame.dropCount++;
2212 }
2213 } else {
2214 // Release the hw cursor
2215 freeHwCursor(ctx->dpyAttr[mDpy].fd, mDpy);
2216 }
2217
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07002218 // if tryFullFrame fails, try to push all video and secure RGB layers
2219 // to MDP for composition.
2220 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002221 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302222 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002223 setMDPCompLayerFlags(ctx, list);
2224 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002225 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002226 reset(ctx);
2227 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2228 mCurrentFrame.dropCount = 0;
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002229 // Check if cursor is in use for primary and mark accordingly
2230 if(!mDpy && HWCursor::getInstance()->isCursorSet()) {
2231 int topIndex = ctx->listStats[mDpy].numAppLayers - 1;
2232 hwc_layer_1_t *layer = &(list->hwLayers[topIndex]);
2233 layer->compositionType = HWC_CURSOR_OVERLAY;
2234 }
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002235 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07002236 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
2237 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07002238 }
2239 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05302240 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
2241 enablePartialUpdateForMDP3) {
2242 generateROI(ctx, list);
2243 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
2244 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
2245 }
2246 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002247 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
2248 __FUNCTION__);
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002249 // Release the hw cursor
2250 freeHwCursor(ctx->dpyAttr[mDpy].fd, mDpy);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002251 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07002252 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002253
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002254 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002255 ALOGD("GEOMETRY change: %d",
2256 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002257 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07002258 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002259 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002260 }
2261
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002262#ifdef DYNAMIC_FPS
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302263 setDynRefreshRate(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002264#endif
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002265 setPerfHint(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002266
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002267 mCachedFrame.cacheAll(list);
2268 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002269 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002270}
2271
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002272bool MDPComp::allocSplitVGPipes(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302273
2274 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302275 int mdpIndex = mCurrentFrame.layerToMDP[index];
2276 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2277 info.pipeInfo = new MdpYUVPipeInfo;
2278 info.rot = NULL;
2279 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302280
2281 pipe_info.lIndex = ovutils::OV_INVALID;
2282 pipe_info.rIndex = ovutils::OV_INVALID;
2283
Saurabh Shahc62f3982014-03-05 14:28:26 -08002284 Overlay::PipeSpecs pipeSpecs;
2285 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2286 pipeSpecs.needsScaling = true;
2287 pipeSpecs.dpy = mDpy;
2288 pipeSpecs.fb = false;
2289
2290 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302291 if(pipe_info.lIndex == ovutils::OV_INVALID){
2292 bRet = false;
2293 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2294 __FUNCTION__);
2295 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002296 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302297 if(pipe_info.rIndex == ovutils::OV_INVALID){
2298 bRet = false;
2299 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2300 __FUNCTION__);
2301 }
2302 return bRet;
2303}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002304
2305int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2306 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002307 if (ctx->mPtorInfo.isActive()) {
2308 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002309 if (fd < 0) {
2310 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002311 }
2312 }
2313 return fd;
2314}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002315//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002316
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002317void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302318 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002319 //If 4k2k Yuv layer split is possible, and if
2320 //fbz is above 4k2k layer, increment fb zorder by 1
2321 //as we split 4k2k layer and increment zorder for right half
2322 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002323 if(!ctx)
2324 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002325 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302326 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2327 index++) {
2328 if(!mCurrentFrame.isFBComposed[index]) {
2329 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2330 mdpNextZOrder++;
2331 }
2332 mdpNextZOrder++;
2333 hwc_layer_1_t* layer = &list->hwLayers[index];
2334 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302335 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302336 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2337 mCurrentFrame.fbZ += 1;
2338 mdpNextZOrder++;
2339 //As we split 4kx2k yuv layer and program to 2 VG pipes
2340 //(if available) increase mdpcount by 1.
2341 mCurrentFrame.mdpCount++;
2342 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002343 }
2344 }
2345 }
radhakrishnac9a67412013-09-25 17:40:42 +05302346}
2347
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002348/*
2349 * Configures pipe(s) for MDP composition
2350 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002351int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002352 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002353 MdpPipeInfoNonSplit& mdp_info =
2354 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302355 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002356 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002357 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002358
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002359 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2360 __FUNCTION__, layer, zOrder, dest);
2361
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002362 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002363 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002364}
2365
Saurabh Shah88e4d272013-09-03 13:31:29 -07002366bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002367 hwc_display_contents_1_t* list) {
Saurabh Shah8cc77712015-03-31 10:48:51 -07002368 for(uint32_t formatType = FORMAT_YUV; formatType < FORMAT_MAX;
2369 formatType++) {
2370 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
2371 if(mCurrentFrame.isFBComposed[index]) continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002372
Saurabh Shah8cc77712015-03-31 10:48:51 -07002373 hwc_layer_1_t* layer = &list->hwLayers[index];
2374 private_handle_t *hnd = (private_handle_t *)layer->handle;
2375 if(formatType == FORMAT_YUV && !isYuvBuffer(hnd))
radhakrishnac9a67412013-09-25 17:40:42 +05302376 continue;
Saurabh Shah8cc77712015-03-31 10:48:51 -07002377 if(formatType == FORMAT_RGB && isYuvBuffer(hnd))
2378 continue;
2379
2380 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
2381 if(allocSplitVGPipes(ctx, index)){
2382 continue;
2383 }
radhakrishnac9a67412013-09-25 17:40:42 +05302384 }
radhakrishnac9a67412013-09-25 17:40:42 +05302385
Saurabh Shah8cc77712015-03-31 10:48:51 -07002386 int mdpIndex = mCurrentFrame.layerToMDP[index];
2387 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2388 info.pipeInfo = new MdpPipeInfoNonSplit;
2389 info.rot = NULL;
2390 MdpPipeInfoNonSplit& pipe_info =
2391 *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002392
Saurabh Shah8cc77712015-03-31 10:48:51 -07002393 Overlay::PipeSpecs pipeSpecs;
2394 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2395 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2396 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2397 (qdutils::MDPVersion::getInstance().is8x26() and
2398 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2399 pipeSpecs.dpy = mDpy;
2400 pipeSpecs.fb = false;
2401 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002402
Saurabh Shah8cc77712015-03-31 10:48:51 -07002403 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahc62f3982014-03-05 14:28:26 -08002404
Saurabh Shah8cc77712015-03-31 10:48:51 -07002405 if(pipe_info.index == ovutils::OV_INVALID) {
2406 ALOGD_IF(isDebug(), "%s: Unable to get pipe for layer %d of "\
2407 "format type %d", __FUNCTION__, index, formatType);
2408 return false;
2409 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002410 }
2411 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002412 return true;
2413}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002414
radhakrishnac9a67412013-09-25 17:40:42 +05302415int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2416 PipeLayerPair& PipeLayerPair) {
2417 MdpYUVPipeInfo& mdp_info =
2418 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2419 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302420 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302421 eDest lDest = mdp_info.lIndex;
2422 eDest rDest = mdp_info.rIndex;
2423
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002424 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302425 lDest, rDest, &PipeLayerPair.rot);
2426}
2427
Saurabh Shah88e4d272013-09-03 13:31:29 -07002428bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002429
Raj Kamal4393eaa2014-06-06 13:45:20 +05302430 if(!isEnabled() or !mModeOn) {
2431 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302432 return true;
2433 }
2434
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002435 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002436 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002437
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002438 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2439 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002440 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002441 if(mCurrentFrame.isFBComposed[i]) continue;
2442
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002443 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002444 private_handle_t *hnd = (private_handle_t *)layer->handle;
2445 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002446 if (!(layer->flags & HWC_COLOR_FILL)) {
2447 ALOGE("%s handle null", __FUNCTION__);
2448 return false;
2449 }
2450 // No PLAY for Color layer
2451 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2452 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002453 }
2454
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002455 int mdpIndex = mCurrentFrame.layerToMDP[i];
2456
Raj Kamal389d6e32014-08-04 14:43:24 +05302457 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302458 {
2459 MdpYUVPipeInfo& pipe_info =
2460 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2461 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2462 ovutils::eDest indexL = pipe_info.lIndex;
2463 ovutils::eDest indexR = pipe_info.rIndex;
2464 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302465 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302466 if(rot) {
2467 rot->queueBuffer(fd, offset);
2468 fd = rot->getDstMemId();
2469 offset = rot->getDstOffset();
2470 }
2471 if(indexL != ovutils::OV_INVALID) {
2472 ovutils::eDest destL = (ovutils::eDest)indexL;
2473 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2474 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2475 if (!ov.queueBuffer(fd, offset, destL)) {
2476 ALOGE("%s: queueBuffer failed for display:%d",
2477 __FUNCTION__, mDpy);
2478 return false;
2479 }
2480 }
2481
2482 if(indexR != ovutils::OV_INVALID) {
2483 ovutils::eDest destR = (ovutils::eDest)indexR;
2484 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2485 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2486 if (!ov.queueBuffer(fd, offset, destR)) {
2487 ALOGE("%s: queueBuffer failed for display:%d",
2488 __FUNCTION__, mDpy);
2489 return false;
2490 }
2491 }
2492 }
2493 else{
2494 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002495 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302496 ovutils::eDest dest = pipe_info.index;
2497 if(dest == ovutils::OV_INVALID) {
2498 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002499 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302500 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002501
radhakrishnac9a67412013-09-25 17:40:42 +05302502 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2503 continue;
2504 }
2505
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002506 int fd = hnd->fd;
2507 uint32_t offset = (uint32_t)hnd->offset;
2508 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2509 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002510 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002511 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002512 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002513 }
2514
radhakrishnac9a67412013-09-25 17:40:42 +05302515 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2516 using pipe: %d", __FUNCTION__, layer,
2517 hnd, dest );
2518
radhakrishnac9a67412013-09-25 17:40:42 +05302519 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2520 if(rot) {
2521 if(!rot->queueBuffer(fd, offset))
2522 return false;
2523 fd = rot->getDstMemId();
2524 offset = rot->getDstOffset();
2525 }
2526
2527 if (!ov.queueBuffer(fd, offset, dest)) {
2528 ALOGE("%s: queueBuffer failed for display:%d ",
2529 __FUNCTION__, mDpy);
2530 return false;
2531 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002532 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002533
2534 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002535 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002536 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002537}
2538
Saurabh Shah88e4d272013-09-03 13:31:29 -07002539//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002540
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002541void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302542 hwc_display_contents_1_t* list){
2543 //if 4kx2k yuv layer is totally present in either in left half
2544 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302545 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302546 if(mCurrentFrame.fbZ >= 0) {
2547 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2548 index++) {
2549 if(!mCurrentFrame.isFBComposed[index]) {
2550 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2551 mdpNextZOrder++;
2552 }
2553 mdpNextZOrder++;
2554 hwc_layer_1_t* layer = &list->hwLayers[index];
2555 private_handle_t *hnd = (private_handle_t *)layer->handle;
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002556 if(isYUVSplitNeeded(hnd) ||
2557 (needs3DComposition(ctx,mDpy) &&
2558 get3DFormat(hnd) != HAL_NO_3D)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302559 hwc_rect_t dst = layer->displayFrame;
2560 if((dst.left > lSplit) || (dst.right < lSplit)) {
2561 mCurrentFrame.mdpCount += 1;
2562 }
2563 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2564 mCurrentFrame.fbZ += 1;
2565 mdpNextZOrder++;
2566 }
2567 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002568 }
radhakrishnac9a67412013-09-25 17:40:42 +05302569 }
2570}
2571
Saurabh Shah88e4d272013-09-03 13:31:29 -07002572bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002573 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002574
Saurabh Shahc62f3982014-03-05 14:28:26 -08002575 const int lSplit = getLeftSplit(ctx, mDpy);
2576 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002577 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002578 pipe_info.lIndex = ovutils::OV_INVALID;
2579 pipe_info.rIndex = ovutils::OV_INVALID;
2580
Saurabh Shahc62f3982014-03-05 14:28:26 -08002581 Overlay::PipeSpecs pipeSpecs;
2582 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2583 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2584 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2585 pipeSpecs.dpy = mDpy;
2586 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2587 pipeSpecs.fb = false;
2588
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002589 // Acquire pipe only for the updating half
2590 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2591 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2592
2593 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002594 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002595 if(pipe_info.lIndex == ovutils::OV_INVALID)
2596 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002597 }
2598
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002599 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002600 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2601 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002602 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002603 return false;
2604 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002605
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002606 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002607}
2608
Saurabh Shah88e4d272013-09-03 13:31:29 -07002609bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002610 hwc_display_contents_1_t* list) {
Saurabh Shah8cc77712015-03-31 10:48:51 -07002611 for(uint32_t formatType = FORMAT_YUV; formatType < FORMAT_MAX;
2612 formatType++) {
2613 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
2614 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002615
Saurabh Shah8cc77712015-03-31 10:48:51 -07002616 hwc_layer_1_t* layer = &list->hwLayers[index];
2617 private_handle_t *hnd = (private_handle_t *)layer->handle;
2618 if(formatType == FORMAT_YUV && !isYuvBuffer(hnd))
2619 continue;
2620 if(formatType == FORMAT_RGB && isYuvBuffer(hnd))
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002621 continue;
2622
Saurabh Shah8cc77712015-03-31 10:48:51 -07002623 hwc_rect_t dst = layer->displayFrame;
2624 const int lSplit = getLeftSplit(ctx, mDpy);
2625 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
2626 if((dst.left > lSplit)||(dst.right < lSplit)){
2627 if(allocSplitVGPipes(ctx, index)){
2628 continue;
2629 }
2630 }
2631 }
2632 //XXX: Check for forced 2D composition
2633 if(needs3DComposition(ctx, mDpy) && get3DFormat(hnd) != HAL_NO_3D)
2634 if(allocSplitVGPipes(ctx,index))
2635 continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002636
Saurabh Shah8cc77712015-03-31 10:48:51 -07002637 int mdpIndex = mCurrentFrame.layerToMDP[index];
2638 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2639 info.pipeInfo = new MdpPipeInfoSplit;
2640 info.rot = NULL;
2641 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
2642
2643 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2644 ALOGD_IF(isDebug(), "%s: Unable to get pipe for layer %d of "\
2645 "format type %d", __FUNCTION__, index, formatType);
2646 return false;
2647 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002648 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002649 }
2650 return true;
2651}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002652
radhakrishnac9a67412013-09-25 17:40:42 +05302653int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2654 PipeLayerPair& PipeLayerPair) {
2655 const int lSplit = getLeftSplit(ctx, mDpy);
2656 hwc_rect_t dst = layer->displayFrame;
2657 if((dst.left > lSplit)||(dst.right < lSplit)){
2658 MdpYUVPipeInfo& mdp_info =
2659 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2660 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302661 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302662 eDest lDest = mdp_info.lIndex;
2663 eDest rDest = mdp_info.rIndex;
2664
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002665 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302666 lDest, rDest, &PipeLayerPair.rot);
2667 }
2668 else{
2669 return configure(ctx, layer, PipeLayerPair);
2670 }
2671}
2672
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002673/*
2674 * Configures pipe(s) for MDP composition
2675 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002676int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002677 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002678 MdpPipeInfoSplit& mdp_info =
2679 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002680 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302681 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002682 eDest lDest = mdp_info.lIndex;
2683 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002684
2685 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002686 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002687
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002688 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002689 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002690}
2691
Saurabh Shah88e4d272013-09-03 13:31:29 -07002692bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002693
Raj Kamal4393eaa2014-06-06 13:45:20 +05302694 if(!isEnabled() or !mModeOn) {
2695 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302696 return true;
2697 }
2698
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002699 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002700 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002701
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002702 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2703 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002704 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002705 if(mCurrentFrame.isFBComposed[i]) continue;
2706
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002707 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002708 private_handle_t *hnd = (private_handle_t *)layer->handle;
2709 if(!hnd) {
2710 ALOGE("%s handle null", __FUNCTION__);
2711 return false;
2712 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002713
2714 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2715 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002716 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002717
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002718 int mdpIndex = mCurrentFrame.layerToMDP[i];
2719
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002720 if((isYUVSplitNeeded(hnd) && sEnableYUVsplit) ||
2721 (needs3DComposition(ctx, mDpy) && get3DFormat(hnd) != HAL_NO_3D))
radhakrishnac9a67412013-09-25 17:40:42 +05302722 {
2723 MdpYUVPipeInfo& pipe_info =
2724 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2725 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2726 ovutils::eDest indexL = pipe_info.lIndex;
2727 ovutils::eDest indexR = pipe_info.rIndex;
2728 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302729 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302730 if(rot) {
2731 rot->queueBuffer(fd, offset);
2732 fd = rot->getDstMemId();
2733 offset = rot->getDstOffset();
2734 }
2735 if(indexL != ovutils::OV_INVALID) {
2736 ovutils::eDest destL = (ovutils::eDest)indexL;
2737 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2738 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2739 if (!ov.queueBuffer(fd, offset, destL)) {
2740 ALOGE("%s: queueBuffer failed for display:%d",
2741 __FUNCTION__, mDpy);
2742 return false;
2743 }
2744 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002745
radhakrishnac9a67412013-09-25 17:40:42 +05302746 if(indexR != ovutils::OV_INVALID) {
2747 ovutils::eDest destR = (ovutils::eDest)indexR;
2748 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2749 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2750 if (!ov.queueBuffer(fd, offset, destR)) {
2751 ALOGE("%s: queueBuffer failed for display:%d",
2752 __FUNCTION__, mDpy);
2753 return false;
2754 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002755 }
2756 }
radhakrishnac9a67412013-09-25 17:40:42 +05302757 else{
2758 MdpPipeInfoSplit& pipe_info =
2759 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2760 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002761
radhakrishnac9a67412013-09-25 17:40:42 +05302762 ovutils::eDest indexL = pipe_info.lIndex;
2763 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002764
radhakrishnac9a67412013-09-25 17:40:42 +05302765 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002766 uint32_t offset = (uint32_t)hnd->offset;
2767 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2768 if (!mDpy && (index != -1)) {
2769 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2770 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002771 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002772 }
radhakrishnac9a67412013-09-25 17:40:42 +05302773
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002774 if(ctx->mAD->draw(ctx, fd, offset)) {
2775 fd = ctx->mAD->getDstFd();
2776 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002777 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002778
radhakrishnac9a67412013-09-25 17:40:42 +05302779 if(rot) {
2780 rot->queueBuffer(fd, offset);
2781 fd = rot->getDstMemId();
2782 offset = rot->getDstOffset();
2783 }
2784
2785 //************* play left mixer **********
2786 if(indexL != ovutils::OV_INVALID) {
2787 ovutils::eDest destL = (ovutils::eDest)indexL;
2788 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2789 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2790 if (!ov.queueBuffer(fd, offset, destL)) {
2791 ALOGE("%s: queueBuffer failed for left mixer",
2792 __FUNCTION__);
2793 return false;
2794 }
2795 }
2796
2797 //************* play right mixer **********
2798 if(indexR != ovutils::OV_INVALID) {
2799 ovutils::eDest destR = (ovutils::eDest)indexR;
2800 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2801 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2802 if (!ov.queueBuffer(fd, offset, destR)) {
2803 ALOGE("%s: queueBuffer failed for right mixer",
2804 __FUNCTION__);
2805 return false;
2806 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002807 }
2808 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002809
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002810 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2811 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002812
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002813 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002814}
Saurabh Shahab47c692014-02-12 18:45:57 -08002815
2816//================MDPCompSrcSplit==============================================
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002817
2818bool MDPCompSrcSplit::validateAndApplyROI(hwc_context_t *ctx,
2819 hwc_display_contents_1_t* list) {
2820 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2821 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
2822
2823 for(int i = numAppLayers - 1; i >= 0; i--) {
2824 if(!isValidRect(visibleRect)) {
2825 mCurrentFrame.drop[i] = true;
2826 mCurrentFrame.dropCount++;
2827 continue;
2828 }
2829
2830 const hwc_layer_1_t* layer = &list->hwLayers[i];
2831 hwc_rect_t dstRect = layer->displayFrame;
2832 hwc_rect_t res = getIntersection(visibleRect, dstRect);
2833
2834 if(!isValidRect(res)) {
2835 mCurrentFrame.drop[i] = true;
2836 mCurrentFrame.dropCount++;
2837 } else {
2838 /* Reset frame ROI when any layer which needs scaling also needs ROI
2839 * cropping */
2840 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
2841 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
2842 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2843 mCurrentFrame.dropCount = 0;
2844 return false;
2845 }
2846
2847 /* deduct any opaque region from visibleRect */
2848 if (layer->blending == HWC_BLENDING_NONE &&
2849 layer->planeAlpha == 0xFF)
2850 visibleRect = deductRect(visibleRect, res);
2851 }
2852 }
2853 return true;
2854}
2855
2856/*
2857 * HW Limitation: ping pong split can always split the ping pong output
2858 * equally across two DSI's. So the ROI programmed should be of equal width
2859 * for both the halves
2860 */
2861void MDPCompSrcSplit::generateROI(hwc_context_t *ctx,
2862 hwc_display_contents_1_t* list) {
2863 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2864
2865
2866 if(!canPartialUpdate(ctx, list))
2867 return;
2868
2869 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
2870 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
2871 (int)ctx->dpyAttr[mDpy].yres};
2872
2873 for(int index = 0; index < numAppLayers; index++ ) {
2874 hwc_layer_1_t* layer = &list->hwLayers[index];
2875
2876 // If we have a RGB layer which needs rotation, no partial update
2877 if(!isYuvBuffer((private_handle_t *)layer->handle) && layer->transform)
2878 return;
2879
2880 if ((mCachedFrame.hnd[index] != layer->handle) ||
2881 isYuvBuffer((private_handle_t *)layer->handle)) {
2882 hwc_rect_t dst = layer->displayFrame;
2883 hwc_rect_t updatingRect = dst;
2884
2885#ifdef QCOM_BSP
2886 if(!needsScaling(layer) && !layer->transform)
2887 {
2888 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
2889 int x_off = dst.left - src.left;
2890 int y_off = dst.top - src.top;
2891 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
2892 }
2893#endif
2894
2895 roi = getUnion(roi, updatingRect);
2896 }
2897 }
2898
2899 /* No layer is updating. Still SF wants a refresh.*/
2900 if(!isValidRect(roi))
2901 return;
2902
2903 roi = expandROIFromMidPoint(roi, fullFrame);
2904
2905 hwc_rect lFrame = fullFrame;
2906 lFrame.right /= 2;
2907 hwc_rect lRoi = getIntersection(roi, lFrame);
2908
2909 // Align ROI coordinates to panel restrictions
2910 lRoi = getSanitizeROI(lRoi, lFrame);
2911
2912 hwc_rect rFrame = fullFrame;
2913 rFrame.left = lFrame.right;
2914 hwc_rect rRoi = getIntersection(roi, rFrame);
2915
2916 // Align ROI coordinates to panel restrictions
2917 rRoi = getSanitizeROI(rRoi, rFrame);
2918
2919 roi = getUnion(lRoi, rRoi);
2920
2921 ctx->listStats[mDpy].lRoi = roi;
2922 if(!validateAndApplyROI(ctx, list))
2923 resetROI(ctx, mDpy);
2924
2925 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d] [%d, %d, %d, %d]",
2926 __FUNCTION__,
2927 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
2928 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
2929 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
2930 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
2931}
2932
Saurabh Shahab47c692014-02-12 18:45:57 -08002933bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002934 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002935 private_handle_t *hnd = (private_handle_t *)layer->handle;
2936 hwc_rect_t dst = layer->displayFrame;
2937 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2938 pipe_info.lIndex = ovutils::OV_INVALID;
2939 pipe_info.rIndex = ovutils::OV_INVALID;
2940
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002941 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy)
2942 trimAgainstROI(ctx,crop, dst);
2943
Saurabh Shahab47c692014-02-12 18:45:57 -08002944 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2945 //should have a higher priority than the right one. Pipe priorities are
2946 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002947
Saurabh Shahc62f3982014-03-05 14:28:26 -08002948 Overlay::PipeSpecs pipeSpecs;
2949 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2950 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2951 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2952 pipeSpecs.dpy = mDpy;
2953 pipeSpecs.fb = false;
2954
Saurabh Shahab47c692014-02-12 18:45:57 -08002955 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002956 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002957 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002958 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002959 }
2960
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002961 /* Use 2 pipes IF
2962 a) Layer's crop width is > 2048 or
2963 b) Layer's dest width > 2048 or
2964 c) On primary, driver has indicated with caps to split always. This is
2965 based on an empirically derived value of panel height. Applied only
2966 if the layer's width is > mixer's width
2967 */
2968
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302969 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002970 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302971 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002972 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2973 const uint32_t dstWidth = dst.right - dst.left;
2974 const uint32_t dstHeight = dst.bottom - dst.top;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002975 uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002976 crop.right - crop.left;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002977 uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
Saurabh Shah514759d2014-11-11 18:02:24 -08002978 crop.bottom - crop.top;
2979 //Approximation to actual clock, ignoring the common factors in pipe and
2980 //mixer cases like line_time
2981 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2982 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002983
Saurabh Shah05f4e222015-02-05 14:36:22 -08002984 const uint32_t downscale = getRotDownscale(ctx, layer);
2985 if(downscale) {
2986 cropWidth /= downscale;
2987 cropHeight /= downscale;
2988 }
2989
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002990 if(dstWidth > mdpHw.getMaxPipeWidth() or
2991 cropWidth > mdpHw.getMaxPipeWidth() or
Saurabh Shah514759d2014-11-11 18:02:24 -08002992 (primarySplitAlways and
2993 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002994 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002995 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002996 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002997 }
2998
Jeykumar Sankaran89e23ab2015-01-28 15:57:46 -08002999 if(ctx->mOverlay->needsPrioritySwap(pipe_info.lIndex,
3000 pipe_info.rIndex)) {
Saurabh Shahdd8237a2014-02-28 14:29:09 -08003001 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08003002 }
3003 }
3004
3005 return true;
3006}
3007
Saurabh Shahab47c692014-02-12 18:45:57 -08003008int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
3009 PipeLayerPair& PipeLayerPair) {
3010 private_handle_t *hnd = (private_handle_t *)layer->handle;
3011 if(!hnd) {
3012 ALOGE("%s: layer handle is NULL", __FUNCTION__);
3013 return -1;
3014 }
3015 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
3016 MdpPipeInfoSplit& mdp_info =
3017 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
3018 Rotator **rot = &PipeLayerPair.rot;
3019 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08003020 eDest lDest = mdp_info.lIndex;
3021 eDest rDest = mdp_info.rIndex;
3022 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
3023 hwc_rect_t dst = layer->displayFrame;
3024 int transform = layer->transform;
3025 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08003026 int rotFlags = ROT_FLAGS_NONE;
Sushil Chauhan65e26302015-01-14 10:48:57 -08003027 uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
Saurabh Shahab47c692014-02-12 18:45:57 -08003028 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05003029 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahab47c692014-02-12 18:45:57 -08003030
3031 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
3032 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
3033
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08003034 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy) {
3035 /* MDP driver crops layer coordinates against ROI in Non-Split
3036 * and Split MDP comp. But HWC needs to crop them for source split.
3037 * Reason: 1) Source split is efficient only when the final effective
3038 * load is distributed evenly across mixers.
3039 * 2) We have to know the effective width of the layer that
3040 * the ROI needs to find the no. of pipes the layer needs.
3041 */
3042 trimAgainstROI(ctx, crop, dst);
3043 }
3044
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05003045 if(needs3DComposition(ctx, mDpy) &&
3046 get3DFormat(hnd) != HAL_NO_3D){
3047 return configure3DVideo(ctx, layer, mDpy, mdpFlags, z, lDest,
3048 rDest, &PipeLayerPair.rot);
3049 }
3050
Saurabh Shahab47c692014-02-12 18:45:57 -08003051 // Handle R/B swap
3052 if (layer->flags & HWC_FORMAT_RB_SWAP) {
3053 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
3054 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
3055 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
3056 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
3057 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07003058 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07003059 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
3060 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07003061 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07003062 /* Calculate the external display position based on MDP downscale,
3063 ActionSafe, and extorientation features. */
3064 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08003065
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07003066 int downscale = getRotDownscale(ctx, layer);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07003067 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08003068
3069 if(lDest != OV_INVALID && rDest != OV_INVALID) {
3070 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07003071 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08003072 }
3073
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07003074 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08003075 (*rot) = ctx->mRotMgr->getNext();
3076 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07003077 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07003078 //If the video is using a single pipe, enable BWC
3079 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08003080 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
3081 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07003082 }
Saurabh Shahab47c692014-02-12 18:45:57 -08003083 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07003084 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08003085 ALOGE("%s: configRotator failed!", __FUNCTION__);
3086 return -1;
3087 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07003088 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07003089 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08003090 }
3091
3092 //If 2 pipes being used, divide layer into half, crop and dst
3093 hwc_rect_t cropL = crop;
3094 hwc_rect_t cropR = crop;
3095 hwc_rect_t dstL = dst;
3096 hwc_rect_t dstR = dst;
3097 if(lDest != OV_INVALID && rDest != OV_INVALID) {
3098 cropL.right = (crop.right + crop.left) / 2;
3099 cropR.left = cropL.right;
3100 sanitizeSourceCrop(cropL, cropR, hnd);
3101
Saurabh Shahb729b192014-08-15 18:04:24 -07003102 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08003103 //Swap crops on H flip since 2 pipes are being used
3104 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
3105 hwc_rect_t tmp = cropL;
3106 cropL = cropR;
3107 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07003108 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08003109 }
3110
Saurabh Shahb729b192014-08-15 18:04:24 -07003111 //cropSwap trick: If the src and dst widths are both odd, let us say
3112 //2507, then splitting both into half would cause left width to be 1253
3113 //and right 1254. If crop is swapped because of H flip, this will cause
3114 //left crop width to be 1254, whereas left dst width remains 1253, thus
3115 //inducing a scaling that is unaccounted for. To overcome that we add 1
3116 //to the dst width if there is a cropSwap. So if the original width was
3117 //2507, the left dst width will be 1254. Even if the original width was
3118 //even for ex: 2508, the left dst width will still remain 1254.
3119 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08003120 dstR.left = dstL.right;
3121 }
3122
3123 //For the mdp, since either we are pre-rotating or MDP does flips
3124 orient = OVERLAY_TRANSFORM_0;
3125 transform = 0;
3126
3127 //configure left pipe
3128 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07003129 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08003130 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
3131 (ovutils::eBlending) getBlending(layer->blending));
3132
3133 if(configMdp(ctx->mOverlay, pargL, orient,
3134 cropL, dstL, metadata, lDest) < 0) {
3135 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
3136 return -1;
3137 }
3138 }
3139
3140 //configure right pipe
3141 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07003142 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08003143 static_cast<eRotFlags>(rotFlags),
3144 layer->planeAlpha,
3145 (ovutils::eBlending) getBlending(layer->blending));
3146 if(configMdp(ctx->mOverlay, pargR, orient,
3147 cropR, dstR, metadata, rDest) < 0) {
3148 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
3149 return -1;
3150 }
3151 }
3152
3153 return 0;
3154}
3155
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003156bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
3157 Locker::Autolock _l(ctx->mDrawLock);
3158 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
3159 char path[MAX_SYSFS_FILE_PATH];
3160 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
3161 int fd = open(path, O_RDONLY);
3162 if(fd < 0) {
3163 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
3164 return -1;
3165 }
3166 char value[4];
3167 ssize_t size_read = read(fd, value, sizeof(value)-1);
3168 if(size_read <= 0) {
3169 ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
3170 close(fd);
3171 return -1;
3172 }
3173 close(fd);
3174 value[size_read] = '\0';
3175 return atoi(value);
3176}
3177
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003178int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
3179 Locker::Autolock _l(ctx->mDrawLock);
3180 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
3181 char path[MAX_SYSFS_FILE_PATH];
3182 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
3183 int fd = open(path, O_WRONLY);
3184 if(fd < 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003185 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003186 return -1;
3187 }
3188 char value[4];
3189 snprintf(value, sizeof(value), "%d", (int)enable);
3190 ssize_t ret = write(fd, value, strlen(value));
3191 if(ret <= 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003192 ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003193 close(fd);
3194 return -1;
3195 }
3196 close(fd);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003197 return 0;
3198}
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08003199
3200bool MDPComp::loadPerfLib() {
3201 char perfLibPath[PROPERTY_VALUE_MAX] = {0};
3202 bool success = false;
3203 if((property_get("ro.vendor.extension_library", perfLibPath, NULL) <= 0)) {
3204 ALOGE("vendor library not set in ro.vendor.extension_library");
3205 return false;
3206 }
3207
3208 sLibPerfHint = dlopen(perfLibPath, RTLD_NOW);
3209 if(sLibPerfHint) {
3210 *(void **)&sPerfLockAcquire = dlsym(sLibPerfHint, "perf_lock_acq");
3211 *(void **)&sPerfLockRelease = dlsym(sLibPerfHint, "perf_lock_rel");
3212 if (!sPerfLockAcquire || !sPerfLockRelease) {
3213 ALOGE("Failed to load symbols for perfLock");
3214 dlclose(sLibPerfHint);
3215 sLibPerfHint = NULL;
3216 return false;
3217 }
3218 success = true;
3219 ALOGI("Successfully Loaded perf hint API's");
3220 } else {
3221 ALOGE("Failed to open %s : %s", perfLibPath, dlerror());
3222 }
3223 return success;
3224}
3225
3226void MDPComp::setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
3227 if ((sPerfHintWindow < 0) || mDpy || !sLibPerfHint) {
3228 return;
3229 }
3230 static int count = sPerfHintWindow;
3231 static int perflockFlag = 0;
3232
3233 /* Send hint to mpctl when single layer is updated
3234 * for a successful number of windows. Hint release
3235 * happens immediately upon multiple layer update.
3236 */
3237 if (onlyVideosUpdating(ctx, list)) {
3238 if(count) {
3239 count--;
3240 }
3241 } else {
3242 if (perflockFlag) {
3243 perflockFlag = 0;
3244 sPerfLockRelease(sPerfLockHandle);
3245 }
3246 count = sPerfHintWindow;
3247 }
3248 if (count == 0 && !perflockFlag) {
3249 int perfHint = 0x4501; // 45-display layer hint, 01-Enable
3250 sPerfLockHandle = sPerfLockAcquire(0 /*handle*/, 0/*duration*/,
3251 &perfHint, sizeof(perfHint)/sizeof(int));
Arun Kumar K.R8b927022015-02-24 12:34:21 -08003252 if(sPerfLockHandle > 0) {
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08003253 perflockFlag = 1;
3254 }
3255 }
3256}
3257
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003258}; //namespace
3259